Minetest-WorldEdit/worldedit/queue.lua

124 lines
4.3 KiB
Lua

worldedit = worldedit or {}
local minetest = minetest --local copy of global
worldedit.queue = {}
worldedit.lower = 1
worldedit.higher = 0
worldedit.ENABLE_QUEUE = true --enable the WorldEdit block queue
worldedit.MAXIMUM_TIME = 0.08 --maximum time each step alloted for WorldEdit operations
minetest.register_globalstep(function(dtime)
local elapsed = 0
local env = minetest.env
while worldedit.lower <= worldedit.higher and elapsed <= worldedit.MAXIMUM_TIME do
local entry = worldedit.queue[worldedit.lower]
if entry.t == "set_node" then
env:set_node(entry.pos, entry.node)
elapsed = elapsed + 0.0002
elseif entry.t == "remove_node" then
env:remove_node(entry.pos)
elapsed = elapsed + 0.0002
elseif entry.t == "place_node" then
env:place_node(entry.pos, entry.node)
elapsed = elapsed + 0.001
elseif entry.t == "dig_node" then
env:dig_node(entry.pos)
elapsed = elapsed + 0.001
elseif entry.t == "add_entity" then
env:add_entity(entry.pos, entry.name)
elapsed = elapsed + 0.005
elseif entry.t == "add_item" then
env:add_item(entry.pos, entry.item)
elapsed = elapsed + 0.005
elseif entry.t == "meta_from_table" then
env:get_meta(entry.pos):from_table(entry.table)
elapsed = elapsed + 0.0002
else
print("Unknown queue event type: " .. entry.t)
end
worldedit.queue[worldedit.lower] = nil
worldedit.lower = worldedit.lower + 1
end
end)
worldedit.enqueue = function(value)
worldedit.higher = worldedit.higher + 1
worldedit.queue[worldedit.higher] = value
end
function table.copy(t, seen)
seen = seen or {}
if t == nil then return nil end
if seen[t] then return seen[t] end
local nt = {}
for k, v in pairs(t) do
if type(v) == 'table' then
nt[k] = table.copy(v, seen)
else
nt[k] = v
end
end
seen[t] = nt
return nt
end
local queue_setnode = function(self, pos_, node_)
worldedit.enqueue({pos=table.copy(pos_), node=table.copy(node_), t="set_node"})
end
local queue_removenode = function(self, pos_)
worldedit.enqueue({pos=table.copy(pos_), t="remove_node"})
end
local queue_placenode = function(self, pos_, node_)
worldedit.enqueue({pos=table.copy(pos_), node=table.copy(node_), t="place_node"})
end
local queue_dignode = function(self, pos_)
worldedit.enqueue({pos=table.copy(pos_), t="dig_node"})
end
local queue_addentity = function(self, pos_, name_)
worldedit.enqueue({pos=table.copy(pos_), name=name_.."", t="add_entity"})
end
local queue_additem = function(self, pos_, item_)
worldedit.enqueue({pos=table.copy(pos_), item=item_.."", t="add_item"})
end
local queue_setmeta = function(self, pos_, table_)
worldedit.enqueue({pos=table.copy(pos_), table=table.copy(table_), t="meta_from_table"})
end
local aliasmeta = {
-- the other functions are left out because they are not used in worldedit
to_table = function(self) return minetest.env:get_meta(self._pos):to_table() end,
set_string = function(self, name_, value_) minetest.env:get_meta(self._pos):set_string(name_, value_) end,
from_table = function(self, tbl) queue_setmeta(nil, self._pos, tbl) end,
}
local get_meta_alias = function(self, pos)
local am = table.copy(aliasmeta)
am._pos = pos
return am
end
worldedit.queue_aliasenv = {
-- ALL functions that are not just piped to the real minetest.env function must copy the arguments, not just reference them
set_node = queue_setnode,
add_node = queue_setnode,
remove_node = queue_removenode,
get_node = function(self, pos) return minetest.env:get_node(pos) end,
get_node_or_nil = function(self, pos) return minetest.env:get_node_or_nil(pos) end,
get_node_light = function(self, pos, timeofday) return minetest.env:get_node_light(pos, timeofday) end,
place_node = queue_placenode,
dig_node = queue_dignode,
punch_node = function(self, pos) return minetest.env:punch_node(pos) end,
get_meta = get_meta_alias,
get_node_timer = function(self, pos) return minetest.env:get_node_timer(pos) end,
add_entity = queue_addentity,
add_item = queue_additem,
}