Add more "rip nodes in radius" functionality
Refactor out the single "rip radius now" command, and add one that works constantly while the player is walking, so e.g. a player can explore an existing map or load schematics and rip their nodes automatically.
This commit is contained in:
parent
589372a1c3
commit
262340c945
125
commands.lua
125
commands.lua
@ -1,6 +1,6 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local minetest, pairs, pcall, string, tonumber, vector
|
||||
= minetest, pairs, pcall, string, tonumber, vector
|
||||
local minetest, next, pairs, pcall, string, tonumber, vector
|
||||
= minetest, next, pairs, pcall, string, tonumber, vector
|
||||
local string_format, string_gsub, string_match
|
||||
= string.format, string.gsub, string.match
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
@ -49,35 +49,6 @@ minetest.register_chatcommand(modname .. "_inv", {
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand(modname .. "_here", {
|
||||
description = "Rip all nodes within a radius",
|
||||
params = "[radius = 100]",
|
||||
privs = {server = true},
|
||||
func = function(name, param)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if not player then return false, "invalid player" end
|
||||
|
||||
local radius = tonumber(param) or 100
|
||||
local pos = player:get_pos()
|
||||
|
||||
local foundids = {}
|
||||
do
|
||||
local vm = minetest.get_voxel_manip(
|
||||
vector.subtract(pos, radius),
|
||||
vector.add(pos, radius))
|
||||
local data = vm:get_data()
|
||||
for i = 1, #data do foundids[data[i]] = true end
|
||||
end
|
||||
|
||||
for k in pairs(foundids) do
|
||||
local n = minetest.get_name_from_content_id(k)
|
||||
if n then exportdb[n] = true end
|
||||
end
|
||||
|
||||
return save_export_report()
|
||||
end
|
||||
})
|
||||
|
||||
local function patternfunc(setto)
|
||||
return function(_, param)
|
||||
if param == "" then return false, "must supply pattern" end
|
||||
@ -104,3 +75,95 @@ minetest.register_chatcommand(modname .. "_rm", {
|
||||
privs = {server = true},
|
||||
func = patternfunc(nil)
|
||||
})
|
||||
|
||||
local function ripradius(pos, radius)
|
||||
local foundids = {}
|
||||
do
|
||||
local vm = minetest.get_voxel_manip(
|
||||
vector.subtract(pos, radius),
|
||||
vector.add(pos, radius))
|
||||
local data = vm:get_data()
|
||||
for i = 1, #data do foundids[data[i]] = true end
|
||||
end
|
||||
|
||||
local dirty
|
||||
for k in pairs(foundids) do
|
||||
local n = minetest.get_name_from_content_id(k)
|
||||
if n and not exportdb[n] then
|
||||
exportdb[n] = true
|
||||
dirty = true
|
||||
end
|
||||
end
|
||||
|
||||
return dirty
|
||||
end
|
||||
|
||||
minetest.register_chatcommand(modname .. "_here", {
|
||||
description = "Rip all nodes within a radius",
|
||||
params = "[radius_x=100 [radius_y=radius_x [radius_z=radius_x]]]",
|
||||
privs = {server = true},
|
||||
func = function(name, param)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if not player then return false, "invalid player" end
|
||||
|
||||
local parts = param:split(" ")
|
||||
local rx = parts[1] and tonumber(parts[1]) or 100
|
||||
local ry = parts[2] and tonumber(parts[2]) or rx
|
||||
local rz = parts[3] and tonumber(parts[3]) or rx
|
||||
|
||||
ripradius(player:get_pos(), vector.new(rx, ry, rz))
|
||||
|
||||
return save_export_report()
|
||||
end
|
||||
})
|
||||
|
||||
local steprippers = {}
|
||||
local stepripstart
|
||||
do
|
||||
local pended
|
||||
local function stepriprun()
|
||||
pended = false
|
||||
if next(steprippers) == nil then return end
|
||||
|
||||
for pname, pdata in pairs(steprippers) do
|
||||
local player = minetest.get_player_by_name(pname)
|
||||
if player then
|
||||
local pos = player:get_pos()
|
||||
local oldpos = pdata.pos
|
||||
if (not oldpos) or (vector.distance(pos, oldpos) >= pdata.step) then
|
||||
pdata.pos = pos
|
||||
if ripradius(pos, pdata.radius) then
|
||||
minetest.chat_send_player(pname, "exporting...")
|
||||
local _, rpt = save_export_report()
|
||||
minetest.chat_send_player(pname, rpt)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return stepripstart()
|
||||
end
|
||||
stepripstart = function()
|
||||
if pended then return end
|
||||
minetest.after(0, stepriprun)
|
||||
pended = true
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_chatcommand(modname .. "_step", {
|
||||
description = "Rip nodes in radius every step",
|
||||
params = "[radius_x=100 [radius_y=radius_x [radius_z=radius_x [stepsize=2]]]]",
|
||||
privs = {server = true},
|
||||
func = function(name, param)
|
||||
local parts = param:split(" ")
|
||||
local rx = parts[1] and tonumber(parts[1]) or 100
|
||||
local ry = parts[2] and tonumber(parts[2]) or rx
|
||||
local rz = parts[3] and tonumber(parts[3]) or rx
|
||||
|
||||
steprippers[name] = rx > 0 and {
|
||||
radius = vector.new(rx, ry, rz),
|
||||
step = parts[4] and tonumber(parts[4]) or 2
|
||||
} or nil
|
||||
stepripstart()
|
||||
end
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user