Skip to content

Commit c22b556

Browse files
author
Cy
committedJun 30, 2014
Improved stacking
This stack / copy uses a direction vector, so it's not limited to only along the X/Y/Z axis, and can go diagonally. This enables things like building staircases.
1 parent 174416b commit c22b556

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed
 

‎worldedit/manipulations.lua

+123
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,129 @@ worldedit.copy = function(pos1, pos2, axis, amount) --wip: replace the old versi
172172
return worldedit.volume(pos1, pos2)
173173
end
174174

175+
worldedit.copy2 = function(pos1, pos2, direction, volume)
176+
-- the overlap shouldn't matter as long as we
177+
-- 1) start at the furthest separated corner
178+
-- 2) complete an edge before moving inward, either edge works
179+
-- 3) complete a face before moving inward, similarly
180+
--
181+
-- to do this I
182+
-- 1) find the furthest destination in the direction, of each axis
183+
-- 2) call those the furthest separated corner
184+
-- 3) make sure to iterate inward from there
185+
-- 4) nested loop to make sure complete edge, complete face, then complete cube.
186+
187+
local get_node, get_meta, add_node = minetest.get_node, minetest.get_meta, minetest.add_node
188+
local somemeta = get_meta(pos1) -- hax lol
189+
local to_table = somemeta.to_table
190+
local from_table = somemeta.from_table
191+
somemeta = nil
192+
193+
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
194+
local manip = minetest.get_voxel_manip()
195+
manip:read_from_map(pos1, pos2)
196+
197+
local sx,sy,sz -- direction sign
198+
local ix,iy,iz -- initial destination
199+
local ex,ey,ez -- final destination
200+
local originalx,originaly,originalz -- source
201+
-- vim -> :'<,'>s/\<\([ioes]\?\)x\>/\1y/g
202+
if direction.x > 0 then
203+
originalx = pos2.x
204+
ix = originalx + direction.x
205+
ex = pos1.x + direction.x
206+
sx = -1
207+
elseif direction.x < 0 then
208+
originalx = pos1.x
209+
ix = originalx + direction.x
210+
ex = pos2.x + direction.x
211+
sx = 1
212+
else
213+
originalx = pos1.x
214+
ix = originalx -- whatever
215+
ex = pos2.x
216+
sx = 1
217+
end
218+
219+
if direction.y > 0 then
220+
originaly = pos2.y
221+
iy = originaly + direction.y
222+
ey = pos1.y + direction.y
223+
sy = -1
224+
elseif direction.y < 0 then
225+
originaly = pos1.y
226+
iy = originaly + direction.y
227+
ey = pos2.y + direction.y
228+
sy = 1
229+
else
230+
originaly = pos1.y
231+
iy = originaly -- whatever
232+
ey = pos2.y
233+
sy = 1
234+
end
235+
236+
if direction.z > 0 then
237+
originalz = pos2.z
238+
iz = originalz + direction.z
239+
ez = pos1.z + direction.z
240+
sz = -1
241+
elseif direction.z < 0 then
242+
originalz = pos1.z
243+
iz = originalz + direction.z
244+
ez = pos2.z + direction.z
245+
sz = 1
246+
else
247+
originalz = pos1.z
248+
iz = originalz -- whatever
249+
ez = pos2.z
250+
sz = 1
251+
end
252+
-- print('copy',originalx,ix,ex,sx,originaly,iy,ey,sy,originalz,iz,ez,sz)
253+
254+
local ox,oy,oz
255+
256+
ox = originalx
257+
for x = ix,ex,sx do
258+
oy = originaly
259+
for y = iy,ey,sy do
260+
oz = originalz
261+
for z = iz,ez,sz do
262+
-- reusing pos1/pos2 as source/dest here
263+
pos1.x = ox; pos1.y = oy; pos1.z = oz
264+
pos2.x = x; pos2.y = y; pos2.z = z
265+
local node = get_node(pos1)
266+
local meta = to_table(get_meta(pos1)) --get meta of current node
267+
add_node(pos2,node)
268+
from_table(get_meta(pos2),meta)
269+
oz = oz + sz
270+
end
271+
oy = oy + sy
272+
end
273+
ox = ox + sx
274+
end
275+
end
276+
277+
worldedit.stack2 = function(pos1, pos2, direction, amount, finished)
278+
local i = 0
279+
local translated = {x=0,y=0,z=0}
280+
local function nextone()
281+
if i <= amount then
282+
i = i + 1
283+
translated.x = translated.x + direction.x
284+
translated.y = translated.y + direction.y
285+
translated.z = translated.z + direction.z
286+
worldedit.copy2(pos1,pos2,translated,volume)
287+
minetest.after(0,nextone)
288+
else
289+
if finished then
290+
finished()
291+
end
292+
end
293+
end
294+
nextone()
295+
return nil
296+
end
297+
175298
--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
176299
worldedit.copy = function(pos1, pos2, axis, amount)
177300
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)

‎worldedit_commands/init.lua

+46
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,52 @@ minetest.register_chatcommand("/stack", {
619619
end),
620620
})
621621

622+
minetest.register_chatcommand("/stack2", {
623+
params = "<count> <x>/<y>/<z>",
624+
description = "Stack the current WorldEdit region <count> times translating each time by x, y and z in the respective directions.",
625+
privs = {worldedit=true},
626+
func = function(name, param)
627+
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
628+
if pos1 == nil or pos2 == nil then
629+
worldedit.player_notify(name, "Select a position first!")
630+
return
631+
end
632+
local repetitions, incs = param:match("([0-9]+)%s*(.+)")
633+
repetitions = repetitions and tonumber(repetitions)
634+
if repetitions == nil then
635+
worldedit.player_notify(name, "invalid count: " .. param)
636+
return
637+
end
638+
639+
local x,y,z = incs:match("(.+)/(.+)/(.+)")
640+
if x == nil then
641+
worldedit.player_notify(name, "invalid increments: " .. param)
642+
return
643+
end
644+
x = tonumber(x)
645+
y = tonumber(y)
646+
z = tonumber(z)
647+
if x == nil or y == nil or z == nil then
648+
worldedit.player_notify(name, "increments must be numbers: " .. param)
649+
return
650+
end
651+
652+
local count = worldedit.volume(pos1,pos2) * repetitions
653+
654+
return safe_region(function()
655+
worldedit.stack2(pos1, pos2, {x=x,y=y,z=z}, repetitions,
656+
function()
657+
worldedit.player_notify(name, count .. " nodes stacked")
658+
end)
659+
660+
end,
661+
function()
662+
return count
663+
end)(name,param) -- more hax
664+
end
665+
})
666+
667+
622668
minetest.register_chatcommand("/stretch", {
623669
params = "<stretchx> <stretchy> <stretchz>",
624670
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",

0 commit comments

Comments
 (0)
Please sign in to comment.