summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChatCommands.md43
-rw-r--r--WorldEdit API.md6
-rw-r--r--worldedit/cuboid.lua258
-rw-r--r--worldedit/init.lua2
-rw-r--r--worldedit/manipulations.lua34
-rw-r--r--worldedit/primitives.lua4
-rw-r--r--worldedit/serialization.lua6
-rw-r--r--worldedit/textures/worldedit_wand.pngbin0 -> 442 bytes
-rw-r--r--worldedit/wand.lua51
-rw-r--r--worldedit_commands/.gitignore1
-rw-r--r--worldedit_commands/cuboid.lua240
-rw-r--r--worldedit_commands/init.lua47
-rw-r--r--worldedit_commands/mark.lua6
-rw-r--r--worldedit_gui/functionality.lua66
-rw-r--r--worldedit_gui/init.lua23
15 files changed, 754 insertions, 33 deletions
diff --git a/ChatCommands.md b/ChatCommands.md
index 5b6c0c4..be885c0 100644
--- a/ChatCommands.md
+++ b/ChatCommands.md
@@ -103,7 +103,7 @@ Display the volume of the current WorldEdit region.
### `//deleteblocks`
-Delete the MapBlocks (16x16x16 units) that contain the selected region. This means that mapgen will be invoked for that area. As only whole MapBlocks get removed, the deleted area is usually larger than the selected one. Also, mapgen can trigger mechanisms like mud reflow or cavegen, which affects nodes (up to 112 nodes away) outside the MapBlock, so dont use this near buildings.
+Delete the MapBlocks (16x16x16 units) that contain the selected region. This means that mapgen will be invoked for that area. As only whole MapBlocks get removed, the deleted area is usually larger than the selected one. Also, mapgen can trigger mechanisms like mud reflow or cavegen, which affects nodes (up to 112 nodes away) outside the MapBlock, so dont use this near buildings. Note that active entities are not part of a MapBlock and do not get deleted.
//deleteblocks
@@ -303,6 +303,12 @@ Fixes the lighting in the current WorldEdit region.
//fixlight
+### `//drain`
+
+Removes any fluid node within the current WorldEdit region.
+
+ //drain
+
### `//hide`
Hide all nodes in the current WorldEdit region non-destructively.
@@ -392,3 +398,38 @@ This mode can be left with `//mtschemprob finish`. `//mtschemprob get` will disp
Clears all objects within the WorldEdit region.
//clearobjects
+
+### `//shift x/y/z/?/up/down/left/right/front/back [+|-]<amount>`
+
+Shifts the selection area by `[+|-]<amount>` without touching its contents. The shifting axis can be absolute (`x/y/z`) or
+relative (`up/down/left/right/front/back`).
+
+ //shift left 5
+
+### `//expand [+|-]x/y/z/?/up/down/left/right/front/back <amount> [reverse-amount]`
+
+Expands the selection by `<amount>` in the selected absolute or relative axis. If specified, the selection can be expanded in the
+opposite direction over the same axis by `[reverse-amount]`.
+
+ //expand right 7 5
+
+### `//contract [+|-]x/y/z/?/up/down/left/right/front/back <amount> [reverse-amount]`
+
+Contracts the selection by `<amount>` in the selected absolute or relative axis. If specified, the selection can be contracted in the
+opposite direction over the same axis by `[reverse-amount]`.
+
+ //expand right 7 5
+
+### `//outset [hv] <amount>`
+
+Expands the selection in all directions by `<amount>`. If specified, the selection can be expanded horizontally in the x and z axes `[h]`
+or vertically in the y axis `[v]`.
+
+ //outset v 5
+
+### `//inset [hv] <amount>`
+
+Contracts the selection in all directions by `<amount>`. If specified, the selection can be contracted horizontally in the x and z axes `[h]`
+or vertically in the y axis `[v]`.
+
+ //outset v 5 \ No newline at end of file
diff --git a/WorldEdit API.md b/WorldEdit API.md
index d1cd7d0..5867dfc 100644
--- a/WorldEdit API.md
+++ b/WorldEdit API.md
@@ -45,6 +45,12 @@ Copies the region defined by positions `pos1` and `pos2` along the `axis` axis (
Returns the number of nodes copied.
+### count = worldedit.copy2(pos1, pos2, off)
+
+Copies the region defined by positions `pos1` and `pos2` by the offset vector `off`.
+
+Returns the number of nodes copied.
+
### count = worldedit.move(pos1, pos2, axis, amount)
Moves the region defined by positions `pos1` and `pos2` along the `axis` axis ("x" or "y" or "z") by `amount` nodes.
diff --git a/worldedit/cuboid.lua b/worldedit/cuboid.lua
new file mode 100644
index 0000000..ce20761
--- /dev/null
+++ b/worldedit/cuboid.lua
@@ -0,0 +1,258 @@
+-- Expands or contracts the cuboid in all axes by amount (positive or negative)
+worldedit.cuboid_volumetric_expand = function(name, amount)
+ local pos1 = worldedit.pos1[name]
+ local pos2 = worldedit.pos2[name]
+
+ if pos1 == nil or pos2 == nil then
+ return false, "Undefined cuboid"
+ end
+
+ local delta1 = vector.new()
+ local delta2 = vector.new()
+ local delta_dir1
+ local delta_dir2
+
+ delta1 = vector.add(delta1, amount)
+ delta2 = vector.add(delta2, amount)
+ delta_dir1, delta_dir2 = worldedit.get_expansion_directions(pos1, pos2)
+ delta1 = vector.multiply(delta1, delta_dir1)
+ delta2 = vector.multiply(delta2, delta_dir2)
+ worldedit.pos1[name] = vector.add(pos1, delta1)
+ worldedit.pos2[name] = vector.add(pos2, delta2)
+
+ return true
+end
+
+
+-- Expands or contracts the cuboid in a single axis by amount (positive or negative)
+worldedit.cuboid_linear_expand = function(name, axis, direction, amount)
+ local pos1 = worldedit.pos1[name]
+ local pos2 = worldedit.pos2[name]
+
+ if pos1 == nil or pos2 == nil then
+ return false, "undefined cuboid"
+ end
+
+ if direction ~= 1 and direction ~= -1 then
+ return false, "invalid marker"
+ end
+
+ local marker = worldedit.marker_get_closest_to_axis(name, axis, direction)
+ local deltavect = vector.new()
+
+ if axis == 'x' then
+ deltavect.x = amount * direction
+ elseif axis == 'y' then
+ deltavect.y = amount * direction
+ elseif axis == 'z' then
+ deltavect.z = amount * direction
+ else
+ return false, "invalid axis"
+ end
+
+ worldedit.marker_move(name, marker, deltavect)
+ return true
+end
+
+
+-- Shifts the cuboid by '+-amount' in axis 'axis'
+worldedit.cuboid_shift = function(name, axis, amount)
+ local pos1 = worldedit.pos1[name]
+ local pos2 = worldedit.pos2[name]
+
+ if pos1 == nil or pos2 == nil then
+ return false, "undefined cuboid"
+ end
+
+ if axis == 'x' then
+ worldedit.pos1[name].x = pos1.x + amount
+ worldedit.pos2[name].x = pos2.x + amount
+ elseif axis == 'y' then
+ worldedit.pos1[name].y = pos1.y + amount
+ worldedit.pos2[name].y = pos2.y + amount
+ elseif axis == 'z' then
+ worldedit.pos1[name].z = pos1.z + amount
+ worldedit.pos2[name].z = pos2.z + amount
+ else
+ return false, "invalid axis"
+ end
+
+ return true
+end
+
+
+-- Moves the location of a single marker by adding deltavector
+worldedit.marker_move = function(name, marker, deltavector)
+ if marker ~= 1 and marker ~= 2 then
+ return false
+ end
+
+ if marker == 1 then
+ local pos = worldedit.pos1[name]
+ worldedit.pos1[name] = vector.add(deltavector, pos)
+ else
+ local pos = worldedit.pos2[name]
+ worldedit.pos2[name] = vector.add(deltavector, pos)
+ end
+
+ return true
+end
+
+-- Updates the location ingame of the markers
+worldedit.marker_update = function(name, marker)
+ if marker == nil then
+ worldedit.mark_pos1(name)
+ worldedit.mark_pos2(name)
+ elseif marker == 1 then
+ worldedit.mark_pos1(name)
+ elseif marker == 2 then
+ worldedit.mark_pos2(name)
+ else
+ minetest.debug(
+ "worldedit: Invalid execution of function update_markers")
+ end
+end
+
+
+-- Returns two vectors with the directions for volumetric expansion
+worldedit.get_expansion_directions = function(mark1, mark2)
+ if mark1 == nil or mark2 == nil then
+ return
+ end
+ local dir1 = vector.new()
+ local dir2 = vector.new()
+
+ if mark1.x < mark2.x then
+ dir1.x = -1
+ dir2.x = 1
+ else
+ dir1.x = 1
+ dir2.x = -1
+ end
+ if mark1.y < mark2.y then
+ dir1.y = -1
+ dir2.y = 1
+ else
+ dir1.y = 1
+ dir2.y = -1
+ end
+ if mark1.z < mark2.z then
+ dir1.z = -1
+ dir2.z = 1
+ else
+ dir1.z = 1
+ dir2.z = -1
+ end
+ return dir1, dir2
+end
+
+
+-- Return the marker that is closest to the player
+worldedit.marker_get_closest_to_player = function(name)
+ local playerpos = minetest.get_player_by_name(name):getpos()
+ local dist1 = vector.distance(playerpos, worldedit.pos1[name])
+ local dist2 = vector.distance(playerpos, worldedit.pos2[name])
+
+ if dist1 < dist2 then
+ return 1
+ else
+ return 2
+ end
+end
+
+
+-- Returns the closest marker to the specified axis and direction
+worldedit.marker_get_closest_to_axis = function(name, axis, direction)
+ local pos1 = vector.new()
+ local pos2 = vector.new()
+
+ if direction ~= 1 and direction ~= -1 then
+ return nil
+ end
+
+ if axis == 'x' then
+ pos1.x = worldedit.pos1[name].x * direction
+ pos2.x = worldedit.pos2[name].x * direction
+ if pos1.x > pos2.x then
+ return 1
+ else
+ return 2
+ end
+ elseif axis == 'y' then
+ pos1.y = worldedit.pos1[name].y * direction
+ pos2.y = worldedit.pos2[name].y * direction
+ if pos1.y > pos2.y then
+ return 1
+ else
+ return 2
+ end
+ elseif axis == 'z' then
+ pos1.z = worldedit.pos1[name].z * direction
+ pos2.z = worldedit.pos2[name].z * direction
+ if pos1.z > pos2.z then
+ return 1
+ else
+ return 2
+ end
+ else
+ return nil
+ end
+end
+
+
+-- Translates up, down, left, right, front, back to their corresponding axes and
+-- directions according to faced direction
+worldedit.translate_direction = function(name, direction)
+ local axis, dir = worldedit.player_axis(name)
+ local resaxis, resdir
+
+ if direction == "up" then
+ return 'y', 1
+ end
+
+ if direction == "down" then
+ return 'y', -1
+ end
+
+ if direction == "front" then
+ if axis == "y" then
+ resaxis = nil
+ resdir = nil
+ else
+ resaxis = axis
+ resdir = dir
+ end
+ end
+
+ if direction == "back" then
+ if axis == "y" then
+ resaxis = nil
+ resdir = nil
+ else
+ resaxis = axis
+ resdir = -dir
+ end
+ end
+
+ if direction == "left" then
+ if axis == 'x' then
+ resaxis = 'z'
+ resdir = dir
+ elseif axis == 'z' then
+ resaxis = 'x'
+ resdir = -dir
+ end
+ end
+
+ if direction == "right" then
+ if axis == 'x' then
+ resaxis = 'z'
+ resdir = -dir
+ elseif axis == 'z' then
+ resaxis = 'x'
+ resdir = dir
+ end
+ end
+
+ return resaxis, resdir
+end \ No newline at end of file
diff --git a/worldedit/init.lua b/worldedit/init.lua
index e193454..343a1e4 100644
--- a/worldedit/init.lua
+++ b/worldedit/init.lua
@@ -36,6 +36,8 @@ load_module(path .. "/visualization.lua")
load_module(path .. "/serialization.lua")
load_module(path .. "/code.lua")
load_module(path .. "/compatibility.lua")
+load_module(path .. "/wand.lua")
+load_module(path .. "/cuboid.lua")
if minetest.setting_getbool("log_mods") then
diff --git a/worldedit/manipulations.lua b/worldedit/manipulations.lua
index 365d7b3..cf95517 100644
--- a/worldedit/manipulations.lua
+++ b/worldedit/manipulations.lua
@@ -90,7 +90,7 @@ function worldedit.stack2(pos1, pos2, direction, amount, finished)
translated.x = translated.x + direction.x
translated.y = translated.y + direction.y
translated.z = translated.z + direction.z
- worldedit.copy2(pos1, pos2, translated, volume)
+ worldedit.copy2(pos1, pos2, translated)
minetest.after(0, next_one)
else
if finished then
@@ -164,6 +164,38 @@ function worldedit.copy(pos1, pos2, axis, amount)
return worldedit.volume(pos1, pos2)
end
+--- Copies a region by offset vector `off`.
+-- @param pos1
+-- @param pos2
+-- @param off
+-- @return The number of nodes copied.
+function worldedit.copy2(pos1, pos2, off)
+ local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
+
+ worldedit.keep_loaded(pos1, pos2)
+
+ local get_node, get_meta, set_node = minetest.get_node,
+ minetest.get_meta, minetest.set_node
+ local pos = {}
+ pos.x = pos2.x
+ while pos.x >= pos1.x do
+ pos.y = pos2.y
+ while pos.y >= pos1.y do
+ pos.z = pos2.z
+ while pos.z >= pos1.z do
+ local node = get_node(pos) -- Obtain current node
+ local meta = get_meta(pos):to_table() -- Get meta of current node
+ local newpos = vector.add(pos, off) -- Calculate new position
+ set_node(newpos, node) -- Copy node to new position
+ get_meta(newpos):from_table(meta) -- Set metadata of new node
+ pos.z = pos.z - 1
+ end
+ pos.y = pos.y - 1
+ end
+ pos.x = pos.x - 1
+ end
+ return worldedit.volume(pos1, pos2)
+end
--- Moves a region along `axis` by `amount` nodes.
-- @return The number of nodes moved.
diff --git a/worldedit/primitives.lua b/worldedit/primitives.lua
index edb7db6..fe22fff 100644
--- a/worldedit/primitives.lua
+++ b/worldedit/primitives.lua
@@ -158,7 +158,7 @@ function worldedit.pyramid(pos, axis, height, node_name, hollow)
-- Set up voxel manipulator
local manip, area = mh.init_axis_radius(pos, axis,
height >= 0 and height or -height)
- local data = mh.get_empty_data()
+ local data = mh.get_empty_data(area)
-- Handle inverted pyramids
local start_axis, end_axis, step
@@ -178,7 +178,7 @@ function worldedit.pyramid(pos, axis, height, node_name, hollow)
y = pos.y - area.MinEdge.y,
z = pos.z - area.MinEdge.z,
}
- local size = height * step
+ local size = math.abs(height * step)
local count = 0
-- For each level of the pyramid
for index1 = 0, height, step do
diff --git a/worldedit/serialization.lua b/worldedit/serialization.lua
index 00d984d..a0848e2 100644
--- a/worldedit/serialization.lua
+++ b/worldedit/serialization.lua
@@ -144,9 +144,9 @@ local function load_schematic(value)
"([^%s]+)%s+(%d+)%s+(%d+)[^\r\n]*[\r\n]*") do
param1, param2 = tonumber(param1), tonumber(param2)
table.insert(nodes, {
- x = originx + tonumber(x),
- y = originy + tonumber(y),
- z = originz + tonumber(z),
+ x = tonumber(x),
+ y = tonumber(y),
+ z = tonumber(z),
name = name,
param1 = param1 ~= 0 and param1 or nil,
param2 = param2 ~= 0 and param2 or nil,
diff --git a/worldedit/textures/worldedit_wand.png b/worldedit/textures/worldedit_wand.png
new file mode 100644
index 0000000..13eb121
--- /dev/null
+++ b/worldedit/textures/worldedit_wand.png
Binary files differ
diff --git a/worldedit/wand.lua b/worldedit/wand.lua
new file mode 100644
index 0000000..415e7ca
--- /dev/null
+++ b/worldedit/wand.lua
@@ -0,0 +1,51 @@
+minetest.register_tool("worldedit:wand", {
+ description = "WorldEdit wand tool. Left-click to set the 1st position, Right-click to set the 2nd position.",
+ groups = {},
+ inventory_image = "worldedit_wand.png",
+ wield_image = "",
+ wield_scale = {x=1,y=1,z=1},
+ stack_max = 1, -- there is no need to have more than one
+ liquids_pointable = true, -- ground with only water on can be selected as well
+ -- the tool_capabilities are completely irrelevant here - no need to dig
+ tool_capabilities = {
+ full_punch_interval = 1.0,
+ max_drop_level=0,
+ groupcaps={
+ fleshy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
+ snappy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
+ choppy={times={[3]=0.90}, maxwear=0.05, maxlevel=0}
+ }
+ },
+ node_placement_prediction = nil,
+
+ on_use = function(itemstack, placer, pointed_thing)
+ if placer ~= nil and pointed_thing ~= nil then
+ local name = placer:get_player_name()
+ local pos = minetest.get_pointed_thing_position( pointed_thing, false ) -- not above
+
+ if not pos then
+ return itemstack
+ end
+
+ worldedit.pos1[name] = pos
+ worldedit.mark_pos1(name)
+
+ end
+ return itemstack -- nothing consumed, nothing changed
+ end,
+
+ on_place = function(itemstack, placer, pointed_thing) -- Left Click
+ if placer ~= nil and pointed_thing ~= nil then
+ local name = placer:get_player_name()
+ local pos = minetest.get_pointed_thing_position( pointed_thing, false ) -- not above
+
+ if not pos then
+ return itemstack
+ end
+
+ worldedit.pos2[name] = pos
+ worldedit.mark_pos2(name)
+ end
+ return itemstack -- nothing consumed, nothing changed
+ end,
+})
diff --git a/worldedit_commands/.gitignore b/worldedit_commands/.gitignore
new file mode 100644
index 0000000..e4e5f6c
--- /dev/null
+++ b/worldedit_commands/.gitignore
@@ -0,0 +1 @@
+*~ \ No newline at end of file
diff --git a/worldedit_commands/cuboid.lua b/worldedit_commands/cuboid.lua
new file mode 100644
index 0000000..88f0260
--- /dev/null
+++ b/worldedit_commands/cuboid.lua
@@ -0,0 +1,240 @@
+minetest.register_chatcommand("/outset", {
+ params = "[h|v] <amount>",
+ description = "outset the selection",
+ privs = {worldedit=true},
+ func = function(name, param)
+ local find, _, dir, amount = param:find("(%a*)%s*([+-]?%d+)")
+
+ if find == nil then
+ return false, "invalid usage: " .. param
+ end
+
+ local pos1 = worldedit.pos1[name]
+ local pos2 = worldedit.pos2[name]
+
+ if pos1 == nil or pos2 == nil then
+ return false,
+ "Undefined region. Region must be defined beforehand."
+ end
+
+ local hv_test = dir:find("[^hv]+")
+
+ if hv_test ~= nil then
+ return false, "Invalid direction."
+ end
+
+ if dir == "" or dir == "hv" or dir == "vh" then
+ assert(worldedit.cuboid_volumetric_expand(name, amount))
+ elseif dir == "h" then
+ assert(worldedit.cuboid_linear_expand(name, 'x', 1, amount))
+ assert(worldedit.cuboid_linear_expand(name, 'x', -1, amount))
+ assert(worldedit.cuboid_linear_expand(name, 'z', 1, amount))
+ assert(worldedit.cuboid_linear_expand(name, 'z', -1, amount))
+ elseif dir == "v" then
+ assert(worldedit.cuboid_linear_expand(name, 'y', 1, amount))
+ assert(worldedit.cuboid_linear_expand(name, 'y', -1, amount))
+ else
+ return false, "Invalid number of arguments"
+ end
+
+ worldedit.marker_update(name)
+ return true, "Region outset by " .. amount .. " blocks"
+ end,
+ }
+)
+
+
+minetest.register_chatcommand("/inset", {
+ params = "[h|v] <amount>",
+ description = "inset the selection",
+ privs = {worldedit=true},
+ func = function(name, param)
+ local find, _, dir, amount = param:find("(%a*)%s*([+-]?%d+)")
+
+ if find == nil then
+ return false, "invalid usage: " .. param
+ end
+
+ local pos1 = worldedit.pos1[name]
+ local pos2 = worldedit.pos2[name]
+
+ if pos1 == nil or pos2 == nil then
+ return false,
+ "Undefined region. Region must be defined beforehand."
+ end
+
+ local hv_test = dir:find("[^hv]+")
+
+ if hv_test ~= nil then
+ return false, "Invalid direction."
+ end
+
+ if dir == "" or dir == "vh" or dir == "hv" then
+ assert(worldedit.cuboid_volumetric_expand(name, -amount))
+ elseif dir == "h" then
+ assert(worldedit.cuboid_linear_expand(name, 'x', 1, -amount))
+ assert(worldedit.cuboid_linear_expand(name, 'x', -1, -amount))
+ assert(worldedit.cuboid_linear_expand(name, 'z', 1, -amount))
+ assert(worldedit.cuboid_linear_expand(name, 'z', -1, -amount))
+ elseif dir == "v" then
+ assert(worldedit.cuboid_linear_expand(name, 'y', 1, -amount))
+ assert(worldedit.cuboid_linear_expand(name, 'y', -1, -amount))
+ else
+ return false, "Invalid number of arguments"
+ end
+
+ worldedit.marker_update(name)
+ return true, "Region inset by " .. amount .. " blocks"
+ end,
+ }
+)
+
+
+minetest.register_chatcommand("/shift", {
+ params = "[x|y|z|?|up|down|left|right|front|back] [+|-]<amount>",
+ description = "Moves the selection region. Does not move contents.",
+ privs = {worldedit=true},
+ func = function(name, param)
+ local pos1 = worldedit.pos1[name]
+ local pos2 = worldedit.pos2[name]
+ local find, _, direction, amount = param:find("([%?%l]+)%s*([+-]?%d+)")
+
+ if find == nil then
+ worldedit.player_notify(name, "invalid usage: " .. param)
+ return
+ end
+
+ if pos1 == nil or pos2 == nil then
+ worldedit.player_notify(name,
+ "Undefined region. Region must be defined beforehand.")
+ return
+ end
+
+ local axis, dir
+ if direction == "x" or direction == "y" or direction == "z" then
+ axis, dir = direction, 1
+ elseif direction == "?" then
+ axis, dir = worldedit.player_axis(name)
+ else
+ axis, dir = worldedit.translate_direction(name, direction)
+ end
+
+ if axis == nil or dir == nil then
+ return false, "Invalid if looking straight up or down"
+ end
+
+ assert(worldedit.cuboid_shift(name, axis, amount * dir))
+ worldedit.marker_update(name)
+
+ return true, "Region shifted by " .. amount .. " nodes"
+ end,
+ }
+)
+
+
+minetest.register_chatcommand("/expand", {
+ params = "[+|-]<x|y|z|?|up|down|left|right|front|back> <amount> [reverse-amount]",
+ description = "expand the selection in one or two directions at once",
+ privs = {worldedit=true},
+ func = function(name, param)
+ local find, _, sign, direction, amount,
+ rev_amount = param:find("([+-]?)([%?%l]+)%s*(%d+)%s*(%d*)")
+
+ if find == nil then
+ worldedit.player_notify(name, "invalid use: " .. param)
+ return
+ end
+
+ if worldedit.pos1[name] == nil or worldedit.pos2[name] == nil then
+ worldedit.player_notify(name,
+ "Undefined region. Region must be defined beforehand.")
+ return
+ end
+
+ local absolute = direction:find("[xyz?]")
+ local dir, axis
+
+ if rev_amount == "" then
+ rev_amount = 0
+ end
+
+ if absolute == nil then
+ axis, dir = worldedit.translate_direction(name, direction)
+
+ if axis == nil or dir == nil then
+ return false, "Invalid if looking straight up or down"
+ end
+ else
+ if direction == "?" then
+ axis, dir = worldedit.player_axis(name)
+ else
+ axis = direction
+ dir = 1
+ end
+ end
+
+ if sign == "-" then
+ dir = -dir
+ end
+
+ worldedit.cuboid_linear_expand(name, axis, dir, amount)
+ worldedit.cuboid_linear_expand(name, axis, -dir, rev_amount)
+ worldedit.marker_update(name)
+ return true, "Region expanded by " .. (amount + rev_amount) .. " nodes"
+ end,
+ }
+)
+
+
+minetest.register_chatcommand("/contract", {
+ params = "[+|-]<x|y|z|?|up|down|left|right|front|back> <amount> [reverse-amount]",
+ description = "contract the selection in one or two directions at once",
+ privs = {worldedit=true},
+ func = function(name, param)
+ local find, _, sign, direction, amount,
+ rev_amount = param:find("([+-]?)([%?%l]+)%s*(%d+)%s*(%d*)")
+
+ if find == nil then
+ worldedit.player_notify(name, "invalid use: " .. param)
+ return
+ end
+
+ if worldedit.pos1[name] == nil or worldedit.pos2[name] == nil then
+ worldedit.player_notify(name,
+ "Undefined region. Region must be defined beforehand.")
+ return
+ end
+
+ local absolute = direction:find("[xyz?]")
+ local dir, axis
+
+ if rev_amount == "" then
+ rev_amount = 0
+ end
+
+ if absolute == nil then
+ axis, dir = worldedit.translate_direction(name, direction)
+
+ if axis == nil or dir == nil then
+ return false, "Invalid if looking straight up or down"
+ end
+ else
+ if direction == "?" then
+ axis, dir = worldedit.player_axis(name)
+ else
+ axis = direction
+ dir = 1
+ end
+ end
+
+ if sign == "-" then
+ dir = -dir
+ end
+
+ worldedit.cuboid_linear_expand(name, axis, dir, -amount)
+ worldedit.cuboid_linear_expand(name, axis, -dir, -rev_amount)
+ worldedit.marker_update(name)
+ return true, "Region contracted by " .. (amount + rev_amount) .. " nodes"
+ end,
+ }
+)
diff --git a/worldedit_commands/init.lua b/worldedit_commands/init.lua
index 08a9811..b9313cc 100644
--- a/worldedit_commands/init.lua
+++ b/worldedit_commands/init.lua
@@ -10,6 +10,7 @@ if minetest.place_schematic then
worldedit.prob_list = {}
end
+dofile(minetest.get_modpath("worldedit_commands") .. "/cuboid.lua")
dofile(minetest.get_modpath("worldedit_commands") .. "/mark.lua")
local safe_region, check_region = dofile(minetest.get_modpath("worldedit_commands") .. "/safe.lua")
@@ -588,7 +589,7 @@ minetest.register_chatcommand("/spiral", {
end
local node = get_node(name, nodename)
if not node then return nil end
- return check_region(name, param)
+ return 1 -- TODO: return an useful value
end),
})
@@ -856,6 +857,30 @@ minetest.register_chatcommand("/fixlight", {
end),
})
+minetest.register_chatcommand("/drain", {
+ params = "",
+ description = "Remove any fluid node within the current WorldEdit region",
+ privs = {worldedit=true},
+ func = safe_region(function(name, param)
+ -- TODO: make an API function for this
+ local count = 0
+ local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
+ for x = pos1.x, pos2.x do
+ for y = pos1.y, pos2.y do
+ for z = pos1.z, pos2.z do
+ local n = minetest.get_node({x=x, y=y, z=z}).name
+ local d = minetest.registered_nodes[n]
+ if d ~= nil and (d["drawtype"] == "liquid" or d["drawtype"] == "flowingliquid") then
+ minetest.remove_node({x=x, y=y, z=z})
+ count = count + 1
+ end
+ end
+ end
+ end
+ worldedit.player_notify(name, count .. " nodes updated")
+ end),
+})
+
minetest.register_chatcommand("/hide", {
params = "",
description = "Hide all nodes in the current WorldEdit region non-destructively",
@@ -1145,8 +1170,8 @@ minetest.register_chatcommand("/mtschemprob", {
return
end
for k,v in pairs(problist) do
- local prob = math.floor(((v["prob"] / 256) * 100) * 100 + 0.5) / 100
- text = text .. minetest.pos_to_string(v["pos"]) .. ": " .. prob .. "% | "
+ local prob = math.floor(((v.prob / 256) * 100) * 100 + 0.5) / 100
+ text = text .. minetest.pos_to_string(v.pos) .. ": " .. prob .. "% | "
end
worldedit.player_notify(name, "currently set node probabilities:")
worldedit.player_notify(name, text)
@@ -1156,16 +1181,14 @@ minetest.register_chatcommand("/mtschemprob", {
end,
})
-minetest.register_on_player_receive_fields(
- function(player, formname, fields)
- if (formname == "prob_val_enter") and (fields.text ~= "") then
- local name = player:get_player_name()
- local prob_entry = {pos=worldedit.prob_pos[name], prob=tonumber(fields.text)}
- local index = table.getn(worldedit.prob_list[name]) + 1
- worldedit.prob_list[name][index] = prob_entry
- end
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if formname == "prob_val_enter" and not (fields.text == "" or fields.text == nil) then
+ local name = player:get_player_name()
+ local prob_entry = {pos=worldedit.prob_pos[name], prob=tonumber(fields.text)}
+ local index = table.getn(worldedit.prob_list[name]) + 1
+ worldedit.prob_list[name][index] = prob_entry
end
-)
+end)
minetest.register_chatcommand("/clearobjects", {
params = "",
diff --git a/worldedit_commands/mark.lua b/worldedit_commands/mark.lua
index 4062cae..7f880ea 100644
--- a/worldedit_commands/mark.lua
+++ b/worldedit_commands/mark.lua
@@ -153,7 +153,11 @@ minetest.register_entity(":worldedit:region_cube", {
end
end,
on_punch = function(self, hitter)
- for _, entity in ipairs(worldedit.marker_region[self.player_name]) do
+ local markers = worldedit.marker_region[self.player_name]
+ if not markers then
+ return
+ end
+ for _, entity in ipairs(markers) do
entity:remove()
end
worldedit.marker_region[self.player_name] = nil
diff --git a/worldedit_gui/functionality.lua b/worldedit_gui/functionality.lua
index d3b78f6..7010b14 100644
--- a/worldedit_gui/functionality.lua
+++ b/worldedit_gui/functionality.lua
@@ -280,6 +280,11 @@ worldedit.register_gui_handler("worldedit_gui_cylinder", function(name, fields)
end
return true
end
+ if fields.worldedit_gui_cylinder_axis then
+ gui_axis1[name] = axis_indices[fields.worldedit_gui_cylinder_axis]
+ worldedit.show_page(name, "worldedit_gui_cylinder")
+ return true
+ end
return false
end)
@@ -313,6 +318,11 @@ worldedit.register_gui_handler("worldedit_gui_pyramid", function(name, fields)
end
return true
end
+ if fields.worldedit_gui_pyramid_axis then
+ gui_axis1[name] = axis_indices[fields.worldedit_gui_pyramid_axis]
+ worldedit.show_page(name, "worldedit_gui_pyramid")
+ return true
+ end
return false
end)
@@ -373,6 +383,11 @@ worldedit.register_gui_handler("worldedit_gui_copy_move", function(name, fields)
end
return true
end
+ if fields.worldedit_gui_copy_move_axis then
+ gui_axis1[name] = axis_indices[fields.worldedit_gui_copy_move_axis] or 4
+ worldedit.show_page(name, "worldedit_gui_copy_move")
+ return true
+ end
return false
end)
@@ -395,6 +410,11 @@ worldedit.register_gui_handler("worldedit_gui_stack", function(name, fields)
minetest.chatcommands["/stack"].func(name, string.format("%s %s", axis_values[gui_axis1[name]], gui_count1[name]))
return true
end
+ if fields.worldedit_gui_stack_axis then
+ gui_axis1[name] = axis_indices[fields.worldedit_gui_stack_axis]
+ worldedit.show_page(name, "worldedit_gui_stack")
+ return true
+ end
return false
end)
@@ -441,13 +461,23 @@ worldedit.register_gui_handler("worldedit_gui_transpose", function(name, fields)
minetest.chatcommands["/transpose"].func(name, string.format("%s %s", axis_values[gui_axis1[name]], axis_values[gui_axis2[name]]))
return true
end
+ if fields.worldedit_gui_transpose_axis1 then
+ gui_axis1[name] = axis_indices[fields.worldedit_gui_transpose_axis1]
+ worldedit.show_page(name, "worldedit_gui_transpose")
+ return true
+ end
+ if fields.worldedit_gui_transpose_axis2 then
+ gui_axis2[name] = axis_indices[fields.worldedit_gui_transpose_axis2]
+ worldedit.show_page(name, "worldedit_gui_transpose")
+ return true
+ end
return false
end)
worldedit.register_gui_function("worldedit_gui_flip", {
name = "Flip", privs = minetest.chatcommands["/flip"].privs,
get_formspec = function(name)
- local axis = gui_axis2[name]
+ local axis = gui_axis1[name]
return "size[5,3]" .. worldedit.get_formspec_header("worldedit_gui_flip") ..
string.format("dropdown[0,1;2.5;worldedit_gui_flip_axis;X axis,Y axis,Z axis,Look direction;%d]", axis) ..
"button_exit[0,2.5;3,0.8;worldedit_gui_flip_submit;Flip]"
@@ -456,9 +486,14 @@ worldedit.register_gui_function("worldedit_gui_flip", {
worldedit.register_gui_handler("worldedit_gui_flip", function(name, fields)
if fields.worldedit_gui_flip_submit then
- gui_axis2[name] = axis_indices[fields.worldedit_gui_flip_axis]
+ gui_axis1[name] = axis_indices[fields.worldedit_gui_flip_axis]
+ worldedit.show_page(name, "worldedit_gui_flip")
+ minetest.chatcommands["/flip"].func(name, axis_values[gui_axis1[name]])
+ return true
+ end
+ if fields.worldedit_gui_flip_axis then
+ gui_axis1[name] = axis_indices[fields.worldedit_gui_flip_axis]
worldedit.show_page(name, "worldedit_gui_flip")
- minetest.chatcommands["/flip"].func(name, axis_values[gui_axis2[name]])
return true
end
return false
@@ -483,6 +518,16 @@ worldedit.register_gui_handler("worldedit_gui_rotate", function(name, fields)
minetest.chatcommands["/rotate"].func(name, string.format("%s %s", axis_values[gui_axis1[name]], angle_values[gui_angle[name]]))
return true
end
+ if fields.worldedit_gui_rotate_axis then
+ gui_axis1[name] = axis_indices[fields.worldedit_gui_rotate_axis]
+ worldedit.show_page(name, "worldedit_gui_rotate")
+ return true
+ end
+ if fields.worldedit_gui_rotate_angle then
+ gui_angle[name] = angle_indices[fields.worldedit_gui_rotate_angle]
+ worldedit.show_page(name, "worldedit_gui_rotate")
+ return true
+ end
return false
end)
@@ -500,7 +545,12 @@ worldedit.register_gui_handler("worldedit_gui_orient", function(name, fields)
if fields.worldedit_gui_orient_submit then
gui_angle[name] = angle_indices[fields.worldedit_gui_orient_angle]
worldedit.show_page(name, "worldedit_gui_orient")
- minetest.chatcommands["/orient"].func(name, angle_values[gui_angle[name]])
+ minetest.chatcommands["/orient"].func(name, tostring(angle_values[gui_angle[name]]))
+ return true
+ end
+ if fields.worldedit_gui_orient_angle then
+ gui_angle[name] = angle_indices[fields.worldedit_gui_orient_angle]
+ worldedit.show_page(name, "worldedit_gui_orient")
return true
end
return false
@@ -591,9 +641,9 @@ worldedit.register_gui_function("worldedit_gui_save_load", {
end,
})
-worldedit.register_gui_handler("worldedit_gui_save", function(name, fields)
- if fields.worldedit_gui_save_load_submit_save or worldedit_gui_save_load_submit_allocate or worldedit_gui_save_load_submit_load then
- gui_filename[name] = tostring(fields.worldedit_gui_save_axis)
+worldedit.register_gui_handler("worldedit_gui_save_load", function(name, fields)
+ if fields.worldedit_gui_save_load_submit_save or fields.worldedit_gui_save_load_submit_allocate or fields.worldedit_gui_save_load_submit_load then
+ gui_filename[name] = tostring(fields.worldedit_gui_save_filename)
worldedit.show_page(name, "worldedit_gui_save_load")
if fields.worldedit_gui_save_load_submit_save then
minetest.chatcommands["/save"].func(name, gui_filename[name])
@@ -620,7 +670,7 @@ worldedit.register_gui_function("worldedit_gui_lua", {
worldedit.register_gui_handler("worldedit_gui_lua", function(name, fields)
if fields.worldedit_gui_lua_run or fields.worldedit_gui_lua_transform then
- gui_code[name] = fields.worldedit_gui_lua_value
+ gui_code[name] = fields.worldedit_gui_lua_code
worldedit.show_page(name, "worldedit_gui_lua")
if fields.worldedit_gui_lua_run then
minetest.chatcommands["/lua"].func(name, gui_code[name])
diff --git a/worldedit_gui/init.lua b/worldedit_gui/init.lua
index afd8c2c..57fd9a8 100644
--- a/worldedit_gui/init.lua
+++ b/worldedit_gui/init.lua
@@ -67,7 +67,7 @@ local get_formspec = function(name, identifier)
end
--implement worldedit.show_page(name, page) in different ways depending on the available APIs
-if unified_inventory then --unified inventory installed
+if rawget(_G, "unified_inventory") then --unified inventory installed
local old_func = worldedit.register_gui_function
worldedit.register_gui_function = function(identifier, options)
old_func(identifier, options)
@@ -100,7 +100,7 @@ if unified_inventory then --unified inventory installed
player:set_inventory_formspec(get_formspec(name, page))
end
end
-elseif inventory_plus then --inventory++ installed
+elseif rawget(_G, "inventory_plus") then --inventory++ installed
minetest.register_on_joinplayer(function(player)
local can_worldedit = minetest.check_player_privs(player:get_player_name(), {worldedit=true})
if can_worldedit then
@@ -118,7 +118,7 @@ elseif inventory_plus then --inventory++ installed
return true
elseif fields.worldedit_gui_exit then --return to original page
if gui_player_formspecs[name] then
- inventory_plus.set_inventory_formspec(player, gui_player_formspecs[name])
+ inventory_plus.set_inventory_formspec(player, inventory_plus.get_formspec(player, "main"))
end
return true
end
@@ -143,8 +143,21 @@ else --fallback button
if not player then --this is in case the player signs off while the media is loading
return
end
- if (minetest.check_player_privs(name, {creative=true}) or minetest.setting_getbool("creative_mode")) and creative_inventory then --creative_inventory is active, add button to modified formspec
- formspec = player:get_inventory_formspec() .. "image_button[6,0;1,1;inventory_plus_worldedit_gui.png;worldedit_gui;]"
+ if (minetest.check_player_privs(name, {creative=true}) or
+ minetest.setting_getbool("creative_mode")) and
+ creative then --creative is active, add button to modified formspec
+ local creative_formspec = player:get_inventory_formspec()
+ local tab_id = tonumber(creative_formspec:match("tabheader%[.-;(%d+)%;"))
+
+ if tab_id == 1 then
+ formspec = creative_formspec ..
+ "image_button[0,1;1,1;inventory_plus_worldedit_gui.png;worldedit_gui;]"
+ elseif not tab_id then
+ formspec = creative_formspec ..
+ "image_button[6,0;1,1;inventory_plus_worldedit_gui.png;worldedit_gui;]"
+ else
+ return
+ end
else
formspec = formspec .. "image_button[0,0;1,1;inventory_plus_worldedit_gui.png;worldedit_gui;]"
end