forked from mtcontrib/Minetest-WorldEdit
commit
b32aadd7fa
|
@ -24,7 +24,11 @@ worldedit.volume = function(pos1, pos2)
|
||||||
end
|
end
|
||||||
|
|
||||||
--sets a region defined by positions `pos1` and `pos2` to `nodename`, returning the number of nodes filled
|
--sets a region defined by positions `pos1` and `pos2` to `nodename`, returning the number of nodes filled
|
||||||
worldedit.set = function(pos1, pos2, nodename)
|
worldedit.set = function(pos1, pos2, nodenames)
|
||||||
|
if type(nodenames) == 'string' then
|
||||||
|
nodenames = {nodenames}
|
||||||
|
end
|
||||||
|
|
||||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||||
|
|
||||||
--set up voxel manipulator
|
--set up voxel manipulator
|
||||||
|
@ -40,9 +44,12 @@ worldedit.set = function(pos1, pos2, nodename)
|
||||||
end
|
end
|
||||||
|
|
||||||
--fill selected area with node
|
--fill selected area with node
|
||||||
local node_id = minetest.get_content_id(nodename)
|
local node_ids = {}
|
||||||
|
for i,v in ipairs(nodenames) do
|
||||||
|
node_ids[i] = minetest.get_content_id(nodenames[i])
|
||||||
|
end
|
||||||
for i in area:iterp(pos1, pos2) do
|
for i in area:iterp(pos1, pos2) do
|
||||||
nodes[i] = node_id
|
nodes[i] = node_ids[math.random(#node_ids)]
|
||||||
end
|
end
|
||||||
|
|
||||||
--update map nodes
|
--update map nodes
|
||||||
|
@ -165,6 +172,129 @@ worldedit.copy = function(pos1, pos2, axis, amount) --wip: replace the old versi
|
||||||
return worldedit.volume(pos1, pos2)
|
return worldedit.volume(pos1, pos2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
worldedit.copy2 = function(pos1, pos2, direction, volume)
|
||||||
|
-- the overlap shouldn't matter as long as we
|
||||||
|
-- 1) start at the furthest separated corner
|
||||||
|
-- 2) complete an edge before moving inward, either edge works
|
||||||
|
-- 3) complete a face before moving inward, similarly
|
||||||
|
--
|
||||||
|
-- to do this I
|
||||||
|
-- 1) find the furthest destination in the direction, of each axis
|
||||||
|
-- 2) call those the furthest separated corner
|
||||||
|
-- 3) make sure to iterate inward from there
|
||||||
|
-- 4) nested loop to make sure complete edge, complete face, then complete cube.
|
||||||
|
|
||||||
|
local get_node, get_meta, add_node = minetest.get_node, minetest.get_meta, minetest.add_node
|
||||||
|
local somemeta = get_meta(pos1) -- hax lol
|
||||||
|
local to_table = somemeta.to_table
|
||||||
|
local from_table = somemeta.from_table
|
||||||
|
somemeta = nil
|
||||||
|
|
||||||
|
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||||
|
local manip = minetest.get_voxel_manip()
|
||||||
|
manip:read_from_map(pos1, pos2)
|
||||||
|
|
||||||
|
local sx,sy,sz -- direction sign
|
||||||
|
local ix,iy,iz -- initial destination
|
||||||
|
local ex,ey,ez -- final destination
|
||||||
|
local originalx,originaly,originalz -- source
|
||||||
|
-- vim -> :'<,'>s/\<\([ioes]\?\)x\>/\1y/g
|
||||||
|
if direction.x > 0 then
|
||||||
|
originalx = pos2.x
|
||||||
|
ix = originalx + direction.x
|
||||||
|
ex = pos1.x + direction.x
|
||||||
|
sx = -1
|
||||||
|
elseif direction.x < 0 then
|
||||||
|
originalx = pos1.x
|
||||||
|
ix = originalx + direction.x
|
||||||
|
ex = pos2.x + direction.x
|
||||||
|
sx = 1
|
||||||
|
else
|
||||||
|
originalx = pos1.x
|
||||||
|
ix = originalx -- whatever
|
||||||
|
ex = pos2.x
|
||||||
|
sx = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if direction.y > 0 then
|
||||||
|
originaly = pos2.y
|
||||||
|
iy = originaly + direction.y
|
||||||
|
ey = pos1.y + direction.y
|
||||||
|
sy = -1
|
||||||
|
elseif direction.y < 0 then
|
||||||
|
originaly = pos1.y
|
||||||
|
iy = originaly + direction.y
|
||||||
|
ey = pos2.y + direction.y
|
||||||
|
sy = 1
|
||||||
|
else
|
||||||
|
originaly = pos1.y
|
||||||
|
iy = originaly -- whatever
|
||||||
|
ey = pos2.y
|
||||||
|
sy = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if direction.z > 0 then
|
||||||
|
originalz = pos2.z
|
||||||
|
iz = originalz + direction.z
|
||||||
|
ez = pos1.z + direction.z
|
||||||
|
sz = -1
|
||||||
|
elseif direction.z < 0 then
|
||||||
|
originalz = pos1.z
|
||||||
|
iz = originalz + direction.z
|
||||||
|
ez = pos2.z + direction.z
|
||||||
|
sz = 1
|
||||||
|
else
|
||||||
|
originalz = pos1.z
|
||||||
|
iz = originalz -- whatever
|
||||||
|
ez = pos2.z
|
||||||
|
sz = 1
|
||||||
|
end
|
||||||
|
-- print('copy',originalx,ix,ex,sx,originaly,iy,ey,sy,originalz,iz,ez,sz)
|
||||||
|
|
||||||
|
local ox,oy,oz
|
||||||
|
|
||||||
|
ox = originalx
|
||||||
|
for x = ix,ex,sx do
|
||||||
|
oy = originaly
|
||||||
|
for y = iy,ey,sy do
|
||||||
|
oz = originalz
|
||||||
|
for z = iz,ez,sz do
|
||||||
|
-- reusing pos1/pos2 as source/dest here
|
||||||
|
pos1.x = ox; pos1.y = oy; pos1.z = oz
|
||||||
|
pos2.x = x; pos2.y = y; pos2.z = z
|
||||||
|
local node = get_node(pos1)
|
||||||
|
local meta = to_table(get_meta(pos1)) --get meta of current node
|
||||||
|
add_node(pos2,node)
|
||||||
|
from_table(get_meta(pos2),meta)
|
||||||
|
oz = oz + sz
|
||||||
|
end
|
||||||
|
oy = oy + sy
|
||||||
|
end
|
||||||
|
ox = ox + sx
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
worldedit.stack2 = function(pos1, pos2, direction, amount, finished)
|
||||||
|
local i = 0
|
||||||
|
local translated = {x=0,y=0,z=0}
|
||||||
|
local function nextone()
|
||||||
|
if i <= amount then
|
||||||
|
i = i + 1
|
||||||
|
translated.x = translated.x + direction.x
|
||||||
|
translated.y = translated.y + direction.y
|
||||||
|
translated.z = translated.z + direction.z
|
||||||
|
worldedit.copy2(pos1,pos2,translated,volume)
|
||||||
|
minetest.after(0,nextone)
|
||||||
|
else
|
||||||
|
if finished then
|
||||||
|
finished()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
nextone()
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--copies the region defined by positions `pos1` and `pos2` along the `axis` axis ("x" or "y" or "z") by `amount` nodes, returning the number of nodes copied
|
--copies the region defined by positions `pos1` and `pos2` along the `axis` axis ("x" or "y" or "z") by `amount` nodes, returning the number of nodes copied
|
||||||
worldedit.copy = function(pos1, pos2, axis, amount)
|
worldedit.copy = function(pos1, pos2, axis, amount)
|
||||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||||
|
|
|
@ -278,22 +278,26 @@ minetest.register_chatcommand("/volume", {
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
local check_set = function(name, param)
|
|
||||||
local node = get_node(name, param)
|
|
||||||
if not node then return nil end
|
|
||||||
return check_region(name, param)
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_chatcommand("/set", {
|
minetest.register_chatcommand("/set", {
|
||||||
params = "<node>",
|
params = "<node>",
|
||||||
description = "Set the current WorldEdit region to <node>",
|
description = "Set the current WorldEdit region to <node>",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
func = safe_region(function(name, param)
|
func = safe_region(function(name, param)
|
||||||
|
local nodes = {}
|
||||||
|
|
||||||
|
for nodename in param:gmatch("[^%s]+") do
|
||||||
|
local node = get_node(name, nodename)
|
||||||
|
if not node then
|
||||||
|
worldedit.player_notify(name, 'Could not identify node "'..name..'"')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
nodes[#nodes+1] = node
|
||||||
|
end
|
||||||
|
|
||||||
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
||||||
local node = get_node(name, param)
|
local count = worldedit.set(pos1, pos2, nodes)
|
||||||
local count = worldedit.set(pos1, pos2, node)
|
|
||||||
worldedit.player_notify(name, count .. " nodes set")
|
worldedit.player_notify(name, count .. " nodes set")
|
||||||
end, check_set),
|
end, check_region),
|
||||||
})
|
})
|
||||||
|
|
||||||
local check_replace = function(name, param)
|
local check_replace = function(name, param)
|
||||||
|
@ -615,6 +619,52 @@ minetest.register_chatcommand("/stack", {
|
||||||
end),
|
end),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("/stack2", {
|
||||||
|
params = "<count> <x>/<y>/<z>",
|
||||||
|
description = "Stack the current WorldEdit region <count> times translating each time by x, y and z in the respective directions.",
|
||||||
|
privs = {worldedit=true},
|
||||||
|
func = function(name, param)
|
||||||
|
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
||||||
|
if pos1 == nil or pos2 == nil then
|
||||||
|
worldedit.player_notify(name, "Select a position first!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local repetitions, incs = param:match("([0-9]+)%s*(.+)")
|
||||||
|
repetitions = repetitions and tonumber(repetitions)
|
||||||
|
if repetitions == nil then
|
||||||
|
worldedit.player_notify(name, "invalid count: " .. param)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local x,y,z = incs:match("(.+)/(.+)/(.+)")
|
||||||
|
if x == nil then
|
||||||
|
worldedit.player_notify(name, "invalid increments: " .. param)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
x = tonumber(x)
|
||||||
|
y = tonumber(y)
|
||||||
|
z = tonumber(z)
|
||||||
|
if x == nil or y == nil or z == nil then
|
||||||
|
worldedit.player_notify(name, "increments must be numbers: " .. param)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local count = worldedit.volume(pos1,pos2) * repetitions
|
||||||
|
|
||||||
|
return safe_region(function()
|
||||||
|
worldedit.stack2(pos1, pos2, {x=x,y=y,z=z}, repetitions,
|
||||||
|
function()
|
||||||
|
worldedit.player_notify(name, count .. " nodes stacked")
|
||||||
|
end)
|
||||||
|
|
||||||
|
end,
|
||||||
|
function()
|
||||||
|
return count
|
||||||
|
end)(name,param) -- more hax
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
minetest.register_chatcommand("/stretch", {
|
minetest.register_chatcommand("/stretch", {
|
||||||
params = "<stretchx> <stretchy> <stretchz>",
|
params = "<stretchx> <stretchy> <stretchz>",
|
||||||
description = "Scale the current WorldEdit positions and region by a factor of <stretchx>, <stretchy>, <stretchz> along the X, Y, and Z axes, repectively, with position 1 as the origin",
|
description = "Scale the current WorldEdit positions and region by a factor of <stretchx>, <stretchy>, <stretchz> along the X, Y, and Z axes, repectively, with position 1 as the origin",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user