Version MFF

This commit is contained in:
sys4-fr 2018-09-05 00:44:21 +02:00
parent bb8456b711
commit f10da8c9f6
34 changed files with 1162 additions and 221 deletions

View File

@ -22,6 +22,9 @@ Many commands also have shorter names that can be typed faster. For example, if
| `//hdo` | `//hollowdome` |
| `//do` | `//dome` |
| `//hcyl` | `//hollowcylinder` |
| `//cyl` | `//cylinder` |
| `//hpyr` | `//hollowpyramid` |
| `//pyr` | `//pyramid` |
### `//about`
@ -98,6 +101,12 @@ Display the volume of the current WorldEdit region.
//volume
### `//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. Note that active entities are not part of a MapBlock and do not get deleted.
//deleteblocks
### `//set <node>`
Set the current WorldEdit region to `<node>`.
@ -184,6 +193,15 @@ Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length `<length
//cylinder z -12 3 mesecons:wire_00000000_off
//cylinder ? 2 4 default:stone
### `//hollowpyramid x/y/z? <height> <node>`
Add hollow pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height `<height>`, composed of `<node>`.
//hollowpyramid x 8 Diamond Block
//hollowpyramid y -5 glass
//hollowpyramid z 2 mesecons:wire_00000000_off
//hollowpyramid ? 12 mesecons:wire_00000000_off
### `//pyramid x/y/z? <height> <node>`
Add pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height `<height>`, composed of `<node>`.
@ -285,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.
@ -374,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

0
LICENSE.txt Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

0
Tutorial.md Normal file → Executable file
View File

View File

@ -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.
@ -127,9 +133,9 @@ Adds a cylinder at `pos` along the `axis` axis ("x" or "y" or "z") with length `
Returns the number of nodes added.
### count = worldedit.pyramid(pos, axis, height, node_name)
### count = worldedit.pyramid(pos, axis, height, node_name, hollow)
Adds a pyramid centered at `pos` along the `axis` axis ("x" or "y" or "z") with height `height`.
Adds a pyramid centered at `pos` along the `axis` axis ("x" or "y" or "z") with height `height`, composed of `node_name`.
Returns the number of nodes added.

0
config.ld Normal file → Executable file
View File

0
modpack.txt Normal file → Executable file
View File

0
worldedit/code.lua Normal file → Executable file
View File

0
worldedit/common.lua Normal file → Executable file
View File

0
worldedit/compatibility.lua Normal file → Executable file
View File

258
worldedit/cuboid.lua Normal file
View File

@ -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

3
worldedit/init.lua Normal file → Executable file
View File

@ -23,7 +23,7 @@ end
local path = minetest.get_modpath(minetest.get_current_modname())
local function load_module(path)
local file = io.open(path)
local file = io.open(path, "r")
if not file then return end
file:close()
return dofile(path)
@ -36,6 +36,7 @@ load_module(path .. "/visualization.lua")
load_module(path .. "/serialization.lua")
load_module(path .. "/code.lua")
load_module(path .. "/compatibility.lua")
load_module(path .. "/cuboid.lua")
if minetest.setting_getbool("log_mods") then

View File

@ -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.
@ -503,8 +535,8 @@ function worldedit.orient(pos1, pos2, angle)
worldedit.keep_loaded(pos1, pos2)
local count = 0
local get_node, get_meta, swap_node = minetest.get_node,
minetest.get_meta, minetest.swap_node
local set_node, get_node, get_meta, swap_node = minetest.set_node,
minetest.get_node, minetest.get_meta, minetest.swap_node
local pos = {x=pos1.x, y=0, z=0}
while pos.x <= pos2.x do
pos.y = pos1.y
@ -543,14 +575,11 @@ end
function worldedit.fixlight(pos1, pos2)
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
worldedit.keep_loaded(pos1, pos2)
local vmanip = minetest.get_voxel_manip(pos1, pos2)
vmanip:write_to_map()
vmanip:update_map() -- this updates the lighting
local nodes = minetest.find_nodes_in_area(pos1, pos2, "air")
local dig_node = minetest.dig_node
for _, pos in ipairs(nodes) do
dig_node(pos)
end
return #nodes
return worldedit.volume(pos1, pos2)
end

View File

@ -150,14 +150,15 @@ end
-- @param axis Axis ("x", "y", or "z")
-- @param height Pyramid height.
-- @param node_name Name of node to make pyramid of.
-- @param hollow Whether the pyramid should be hollow.
-- @return The number of nodes added.
function worldedit.pyramid(pos, axis, height, node_name)
function worldedit.pyramid(pos, axis, height, node_name, hollow)
local other1, other2 = worldedit.get_axis_others(axis)
-- 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
@ -177,7 +178,7 @@ function worldedit.pyramid(pos, axis, height, node_name)
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
@ -187,10 +188,12 @@ function worldedit.pyramid(pos, axis, height, node_name)
local new_index2 = new_index1 + (index2 + offset[other1]) * stride[other1]
for index3 = -size, size do
local i = new_index2 + (index3 + offset[other2]) * stride[other2]
data[i] = node_id
if (not hollow or size - math.abs(index2) < 2 or size - math.abs(index3) < 2) then
data[i] = node_id
count = count + 1
end
end
end
count = count + (size * 2 + 1) ^ 2
size = size - 1
end

View File

@ -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,
@ -159,20 +159,20 @@ local function load_schematic(value)
else
-- XXX: This is a filthy hack that works surprisingly well - in LuaJIT, `minetest.deserialize` will fail due to the register limit
nodes = {}
value = value:gsub("return%s*{", "", 1):gsub("}%s*$", "", 1) -- remove the starting and ending values to leave only the node data
local escaped = value:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end)
content = content:gsub("return%s*{", "", 1):gsub("}%s*$", "", 1) -- remove the starting and ending values to leave only the node data
local escaped = content:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end)
local startpos, startpos1, endpos = 1, 1
while true do -- go through each individual node entry (except the last)
startpos, endpos = escaped:find("},%s*{", startpos)
if not startpos then
break
end
local current = value:sub(startpos1, startpos)
local current = content:sub(startpos1, startpos)
local entry = minetest.deserialize("return " .. current)
table.insert(nodes, entry)
startpos, startpos1 = endpos, endpos
end
local entry = minetest.deserialize("return " .. value:sub(startpos1)) -- process the last entry
local entry = minetest.deserialize("return " .. content:sub(startpos1)) -- process the last entry
table.insert(nodes, entry)
end
else

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

0
worldedit/visualization.lua Normal file → Executable file
View File

1
worldedit_commands/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*~

View File

@ -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,
}
)

0
worldedit_commands/depends.txt Normal file → Executable file
View File

View File

@ -10,10 +10,12 @@ 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")
dofile(minetest.get_modpath("worldedit_commands") .. "/safe.lua"); safe_region = safe_region or function(callback) return callback end
dofile(minetest.get_modpath("worldedit_commands") .. "/wand.lua")
local safe_region, check_region, reset_pending = dofile(minetest.get_modpath("worldedit_commands") .. "/safe.lua")
local get_position = function(name) --position 1 retrieval function for when not using `safe_region`
local function get_position(name) --position 1 retrieval function for when not using `safe_region`
local pos1 = worldedit.pos1[name]
if pos1 == nil then
worldedit.player_notify(name, "no position 1 selected")
@ -21,7 +23,7 @@ local get_position = function(name) --position 1 retrieval function for when not
return pos1
end
local get_node = function(name, nodename)
local function get_node(name, nodename)
local node = worldedit.normalize_nodename(nodename)
if not node then
worldedit.player_notify(name, "invalid node name: " .. nodename)
@ -30,7 +32,7 @@ local get_node = function(name, nodename)
return node
end
worldedit.player_notify = function(name, message)
function worldedit.player_notify(name, message)
minetest.chat_send_player(name, "WorldEdit -!- " .. message, false)
end
@ -56,8 +58,8 @@ worldedit.normalize_nodename = function(nodename)
return nil
end
--determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1)
worldedit.player_axis = function(name)
-- Determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1)
function worldedit.player_axis(name)
local dir = minetest.get_player_by_name(name):get_look_dir()
local x, y, z = math.abs(dir.x), math.abs(dir.y), math.abs(dir.z)
if x > y then
@ -70,6 +72,19 @@ worldedit.player_axis = function(name)
return "z", dir.z > 0 and 1 or -1
end
local function mkdir(path)
if minetest.mkdir then
minetest.mkdir(path)
else
os.execute('mkdir "' .. path .. '"')
end
end
local function check_filename(name)
return name:find("^[%w%s%^&'@{}%[%],%$=!%-#%(%)%%%.%+~_]+$") ~= nil
end
minetest.register_chatcommand("/about", {
params = "",
description = "Get information about the mod",
@ -78,6 +93,56 @@ minetest.register_chatcommand("/about", {
end,
})
-- mostly copied from builtin/chatcommands.lua with minor modifications
minetest.register_chatcommand("/help", {
privs = {},
params = "[all/<cmd>]",
description = "Get help for WorldEdit commands",
func = function(name, param)
local function is_we_command(cmd)
return cmd:sub(0, 1) == "/"
end
local function format_help_line(cmd, def)
local msg = minetest.colorize("#00ffff", "/"..cmd)
if def.params and def.params ~= "" then
msg = msg .. " " .. def.params
end
if def.description and def.description ~= "" then
msg = msg .. ": " .. def.description
end
return msg
end
if not minetest.check_player_privs(name, "worldedit") then
return false, "You are not allowed to use any WorldEdit commands."
end
if param == "" then
local msg = ""
local cmds = {}
for cmd, def in pairs(minetest.chatcommands) do
if is_we_command(cmd) and minetest.check_player_privs(name, def.privs) then
cmds[#cmds + 1] = cmd:sub(2) -- strip the /
end
end
table.sort(cmds)
return true, "Available commands: " .. table.concat(cmds, " ") .. "\n"
.. "Use '//help <cmd>' to get more information,"
.. " or '//help all' to list everything."
elseif param == "all" then
local cmds = {}
for cmd, def in pairs(minetest.chatcommands) do
if is_we_command(cmd) and minetest.check_player_privs(name, def.privs) then
cmds[#cmds + 1] = format_help_line(cmd, def)
end
end
table.sort(cmds)
return true, "Available commands:\n"..table.concat(cmds, "\n")
else
return minetest.chatcommands["help"].func(name, "/" .. param)
end
end,
})
minetest.register_chatcommand("/inspect", {
params = "on/off/1/0/true/false/yes/no/enable/disable/<blank>",
description = "Enable or disable node inspection",
@ -97,16 +162,28 @@ minetest.register_chatcommand("/inspect", {
end,
})
local function get_node_rlight(pos)
local vecs = { -- neighboring nodes
{x= 1, y= 0, z= 0},
{x=-1, y= 0, z= 0},
{x= 0, y= 1, z= 0},
{x= 0, y=-1, z= 0},
{x= 0, y= 0, z= 1},
{x= 0, y= 0, z=-1},
}
local ret = 0
for _, v in ipairs(vecs) do
ret = math.max(ret, minetest.get_node_light(vector.add(pos, v)))
end
return ret
end
minetest.register_on_punchnode(function(pos, node, puncher)
local name = puncher:get_player_name()
if worldedit.inspect[name] then
if minetest.check_player_privs(name, {worldedit=true}) then
local axis, sign = worldedit.player_axis(name)
message = string.format("inspector: %s at %s (param1=%d, param2=%d) punched by %s facing the %s axis",
node.name, minetest.pos_to_string(pos), node.param1, node.param2, name, axis .. (sign > 0 and "+" or "-"))
else
message = "inspector: worldedit privileges required"
end
local axis, sign = worldedit.player_axis(name)
message = string.format("inspector: %s at %s (param1=%d, param2=%d, received light=%d) punched facing the %s axis",
node.name, minetest.pos_to_string(pos), node.param1, node.param2, get_node_rlight(pos), axis .. (sign > 0 and "+" or "-"))
worldedit.player_notify(name, message)
end
end)
@ -121,6 +198,8 @@ minetest.register_chatcommand("/reset", {
worldedit.mark_pos1(name)
worldedit.mark_pos2(name)
worldedit.set_pos[name] = nil
--make sure the user does not try to confirm an operation after resetting pos:
reset_pending(name)
worldedit.player_notify(name, "region reset")
end,
})
@ -277,6 +356,21 @@ minetest.register_chatcommand("/volume", {
end,
})
minetest.register_chatcommand("/deleteblocks", {
params = "",
description = "remove all MapBlocks (16x16x16) containing the selected area from the map",
privs = {worldedit=true},
func = safe_region(function(name, param)
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
local success = minetest.delete_area(pos1, pos2)
if success then
worldedit.player_notify(name, "Area deleted.")
else
worldedit.player_notify(name, "There was an error during deletion of the area.")
end
end),
})
minetest.register_chatcommand("/set", {
params = "<node>",
description = "Set the current WorldEdit region to <node>",
@ -488,6 +582,39 @@ minetest.register_chatcommand("/cylinder", {
end, check_cylinder),
})
local check_pyramid = function(name, param)
if worldedit.pos1[name] == nil then
worldedit.player_notify(name, "no position 1 selected")
return nil
end
local found, _, axis, height, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return nil
end
local node = get_node(name, nodename)
if not node then return nil end
height = tonumber(height)
return math.ceil(((height * 2 + 1) ^ 2) * height / 3)
end
minetest.register_chatcommand("/hollowpyramid", {
params = "x/y/z/? <height> <node>",
description = "Add hollow pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height <height>, composed of <node>",
privs = {worldedit=true},
func = safe_region(function(name, param)
local found, _, axis, height, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(.+)$")
height = tonumber(height)
if axis == "?" then
axis, sign = worldedit.player_axis(name)
height = height * sign
end
local node = get_node(name, nodename)
local count = worldedit.pyramid(worldedit.pos1[name], axis, height, node, true)
worldedit.player_notify(name, count .. " nodes added")
end, check_pyramid),
})
minetest.register_chatcommand("/pyramid", {
params = "x/y/z/? <height> <node>",
description = "Add pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height <height>, composed of <node>",
@ -502,22 +629,7 @@ minetest.register_chatcommand("/pyramid", {
local node = get_node(name, nodename)
local count = worldedit.pyramid(worldedit.pos1[name], axis, height, node)
worldedit.player_notify(name, count .. " nodes added")
end,
function(name, param)
if worldedit.pos1[name] == nil then
worldedit.player_notify(name, "no position 1 selected")
return nil
end
local found, _, axis, height, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(.+)$")
if found == nil then
worldedit.player_notify(name, "invalid usage: " .. param)
return nil
end
local node = get_node(name, nodename)
if not node then return nil end
height = tonumber(height)
return math.ceil(((height * 2 + 1) ^ 2) * height / 3)
end),
end, check_pyramid),
})
minetest.register_chatcommand("/spiral", {
@ -542,7 +654,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),
})
@ -810,6 +922,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",
@ -861,20 +997,21 @@ minetest.register_chatcommand("/save", {
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not string.find(param, "^[%w \t.,+-_=!@#$%%^&*()%[%]{};'\"]+$") then
worldedit.player_notify(name, "invalid file name: " .. param)
if not check_filename(param) then
worldedit.player_notify(name, "Disallowed file name: " .. param)
return
end
local result, count = worldedit.serialize(worldedit.pos1[name], worldedit.pos2[name])
local result, count = worldedit.serialize(worldedit.pos1[name],
worldedit.pos2[name])
local path = minetest.get_worldpath() .. "/schems"
-- Create directory if it does not already exist
mkdir(path)
local filename = path .. "/" .. param .. ".we"
filename = filename:gsub("\"", "\\\""):gsub("\\", "\\\\") --escape any nasty characters
os.execute("mkdir \"" .. path .. "\"") --create directory if it does not already exist
local file, err = io.open(filename, "wb")
if err ~= nil then
worldedit.player_notify(name, "could not save file to \"" .. filename .. "\"")
worldedit.player_notify(name, "Could not save file to \"" .. filename .. "\"")
return
end
file:write(result)
@ -897,8 +1034,8 @@ minetest.register_chatcommand("/allocate", {
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not string.find(param, "^[%w \t.,+-_=!@#$%%^&*()%[%]{};'\"]+$") then
worldedit.player_notify(name, "invalid file name: " .. param)
if not check_filename(param) then
worldedit.player_notify(name, "Disallowed file name: " .. param)
return
end
@ -986,11 +1123,6 @@ minetest.register_chatcommand("/lua", {
description = "Executes <code> as a Lua chunk in the global namespace",
privs = {worldedit=true, server=true},
func = function(name, param)
local admin = minetest.setting_get("name")
if not admin or not name == admin then
worldedit.player_notify(name, "this command can only be run by the server administrator")
return
end
local err = worldedit.lua(param)
if err then
worldedit.player_notify(name, "code error: " .. err)
@ -1005,12 +1137,6 @@ minetest.register_chatcommand("/luatransform", {
description = "Executes <code> as a Lua chunk in the global namespace with the variable pos available, for each node in the current WorldEdit region",
privs = {worldedit=true, server=true},
func = safe_region(function(name, param)
local admin = minetest.setting_get("name")
if not admin or not name == admin then
worldedit.player_notify(name, "this command can only be run by the server administrator")
return
end
local err = worldedit.luatransform(worldedit.pos1[name], worldedit.pos2[name], param)
if err then
worldedit.player_notify(name, "code error: " .. err, false)
@ -1022,24 +1148,31 @@ minetest.register_chatcommand("/luatransform", {
minetest.register_chatcommand("/mtschemcreate", {
params = "<file>",
description = "Save the current WorldEdit region using the Minetest Schematic format to \"(world folder)/schems/<filename>.mts\"",
description = "Save the current WorldEdit region using the Minetest "..
"Schematic format to \"(world folder)/schems/<filename>.mts\"",
privs = {worldedit=true},
func = safe_region(function(name, param)
if param == nil then
worldedit.player_notify(name, "No filename specified")
return
end
if not check_filename(param) then
worldedit.player_notify(name, "Disallowed file name: " .. param)
return
end
local path = minetest.get_worldpath() .. "/schems"
local filename = path .. "/" .. param .. ".mts"
filename = filename:gsub("\"", "\\\""):gsub("\\", "\\\\") --escape any nasty characters
os.execute("mkdir \"" .. path .. "\"") --create directory if it does not already exist
-- Create directory if it does not already exist
mkdir(path)
local ret = minetest.create_schematic(worldedit.pos1[name], worldedit.pos2[name], worldedit.prob_list[name], filename)
local filename = path .. "/" .. param .. ".mts"
local ret = minetest.create_schematic(worldedit.pos1[name],
worldedit.pos2[name], worldedit.prob_list[name],
filename)
if ret == nil then
worldedit.player_notify(name, "failed to create Minetest schematic", false)
worldedit.player_notify(name, "Failed to create Minetest schematic", false)
else
worldedit.player_notify(name, "saved Minetest schematic to " .. param, false)
worldedit.player_notify(name, "Saved Minetest schematic to " .. param, false)
end
worldedit.prob_list[name] = {}
end),
@ -1050,10 +1183,14 @@ minetest.register_chatcommand("/mtschemplace", {
description = "Load nodes from \"(world folder)/schems/<file>.mts\" with position 1 of the current WorldEdit region as the origin",
privs = {worldedit=true},
func = function(name, param)
if param == nil then
if param == "" then
worldedit.player_notify(name, "no filename specified")
return
end
if not check_filename(param) then
worldedit.player_notify(name, "Disallowed file name: " .. param)
return
end
local pos = get_position(name)
if pos == nil then return end
@ -1087,8 +1224,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)
@ -1098,16 +1235,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 = "",

View File

@ -58,8 +58,19 @@ worldedit.mark_region = function(name)
end
worldedit.marker_region[name] = nil
end
if pos1 ~= nil and pos2 ~= nil then
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
local vec = vector.subtract(pos2, pos1)
local maxside = math.max(vec.x, math.max(vec.y, vec.z))
local limit = tonumber(minetest.setting_get("active_object_send_range_blocks")) * 16
if maxside > limit * 1.5 then
-- The client likely won't be able to see the plane markers as intended anyway,
-- thus don't place them and also don't load the area into memory
return
end
local thickness = 0.2
local sizex, sizey, sizez = (1 + pos2.x - pos1.x) / 2, (1 + pos2.y - pos1.y) / 2, (1 + pos2.z - pos1.z) / 2
@ -72,24 +83,28 @@ worldedit.mark_region = function(name)
--XY plane markers
for _, z in ipairs({pos1.z - 0.5, pos2.z + 0.5}) do
local marker = minetest.add_entity({x=pos1.x + sizex - 0.5, y=pos1.y + sizey - 0.5, z=z}, "worldedit:region_cube")
marker:set_properties({
visual_size={x=sizex * 2, y=sizey * 2},
collisionbox = {-sizex, -sizey, -thickness, sizex, sizey, thickness},
})
marker:get_luaentity().player_name = name
table.insert(markers, marker)
if marker ~= nil then
marker:set_properties({
visual_size={x=sizex * 2, y=sizey * 2},
collisionbox = {-sizex, -sizey, -thickness, sizex, sizey, thickness},
})
marker:get_luaentity().player_name = name
table.insert(markers, marker)
end
end
--YZ plane markers
for _, x in ipairs({pos1.x - 0.5, pos2.x + 0.5}) do
local marker = minetest.add_entity({x=x, y=pos1.y + sizey - 0.5, z=pos1.z + sizez - 0.5}, "worldedit:region_cube")
marker:set_properties({
visual_size={x=sizez * 2, y=sizey * 2},
collisionbox = {-thickness, -sizey, -sizez, thickness, sizey, sizez},
})
marker:setyaw(math.pi / 2)
marker:get_luaentity().player_name = name
table.insert(markers, marker)
if marker ~= nil then
marker:set_properties({
visual_size={x=sizez * 2, y=sizey * 2},
collisionbox = {-thickness, -sizey, -sizez, thickness, sizey, sizez},
})
marker:setyaw(math.pi / 2)
marker:get_luaentity().player_name = name
table.insert(markers, marker)
end
end
worldedit.marker_region[name] = markers
@ -153,7 +168,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

View File

@ -1,7 +1,7 @@
local safe_region_callback = {}
local safe_region_param = {}
check_region = function(name, param)
local function check_region(name, param)
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name] --obtain positions
if pos1 == nil or pos2 == nil then
worldedit.player_notify(name, "no region selected")
@ -12,7 +12,7 @@ end
--`callback` is a callback to run when the user confirms
--`nodes_needed` is a function accepting `param`, `pos1`, and `pos2` to calculate the number of nodes needed
safe_region = function(callback, nodes_needed)
local function safe_region(callback, nodes_needed)
--default node volume calculation
nodes_needed = nodes_needed or check_region
@ -30,6 +30,10 @@ safe_region = function(callback, nodes_needed)
end
end
local function reset_pending(name)
safe_region_callback[name], safe_region_param[name] = nil, nil
end
minetest.register_chatcommand("/y", {
params = "",
description = "Confirm a pending operation",
@ -40,15 +44,8 @@ minetest.register_chatcommand("/y", {
return
end
--obtain positions
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
if pos1 == nil or pos2 == nil then
worldedit.player_notify(name, "no region selected")
return
end
safe_region_callback[name], safe_region_param[name] = nil, nil --reset pending operation
callback(name, param, pos1, pos2)
callback(name, param)
end,
})
@ -63,3 +60,6 @@ minetest.register_chatcommand("/n", {
safe_region_callback[name], safe_region_param[name] = nil, nil
end,
})
return safe_region, check_region, reset_pending

View File

@ -0,0 +1,24 @@
minetest.register_tool(":worldedit:wand", {
description = "WorldEdit Wand tool, Left-click to set 1st position, right-click to set 2nd",
inventory_image = "worldedit_wand.png",
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
on_use = function(itemstack, placer, pointed_thing)
if placer ~= nil and pointed_thing ~= nil and pointed_thing.type == "node" then
local name = placer:get_player_name()
worldedit.pos1[name] = pointed_thing.under
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 and pointed_thing.type == "node" then
local name = placer:get_player_name()
worldedit.pos2[name] = pointed_thing.under
worldedit.mark_pos2(name)
end
return itemstack -- nothing consumed, nothing changed
end,
})

View File

@ -2,4 +2,5 @@ worldedit
worldedit_commands
unified_inventory?
inventory_plus?
creative?
sfinv?
creative?

291
worldedit_gui/functionality.lua Normal file → Executable file
View File

@ -40,13 +40,13 @@ local angle_values = {90, 180, 270}
setmetatable(angle_indices, {__index = function () return 1 end})
setmetatable(angle_values, {__index = function () return 90 end})
--given multiple sets of privileges, produces a single set of privs that would have the same effect as requiring all of them at the same time
-- given multiple sets of privileges, produces a single set of privs that would have the same effect as requiring all of them at the same time
local combine_privs = function(...)
local result = {}
for i, privs in ipairs({...}) do
for name, value in pairs(privs) do
if result[name] ~= nil and result[name] ~= value then --the priv must be both true and false, which can never happen
return {__fake_priv_that_nobody_has__=true} --priviledge table that can never be satisfied
return {__fake_priv_that_nobody_has__=true} --privilege table that can never be satisfied
end
result[name] = value
end
@ -54,22 +54,44 @@ local combine_privs = function(...)
return result
end
-- display node (or unknown_node image otherwise) at specified pos in formspec
local formspec_node = function(pos, nodename)
return nodename and string.format("item_image[%s;1,1;%s]", pos, nodename)
or string.format("image[%s;1,1;worldedit_gui_unknown.png]", pos)
end
-- two further priv helpers
local function we_privs(command)
return minetest.chatcommands["/" .. command].privs
end
local function combine_we_privs(list)
local args = {}
for _, t in ipairs(list) do
table.insert(args, we_privs(t))
end
return combine_privs(unpack(args))
end
worldedit.register_gui_function("worldedit_gui_about", {
name = "About", privs = minetest.chatcommands["/about"].privs,
name = "About",
privs = {interact=true},
on_select = function(name)
minetest.chatcommands["/about"].func(name, "")
end,
})
worldedit.register_gui_function("worldedit_gui_inspect", {
name = "Toggle Inspect", privs = minetest.chatcommands["/inspect"].privs,
name = "Toggle Inspect",
privs = we_privs("inspect"),
on_select = function(name)
minetest.chatcommands["/inspect"].func(name, worldedit.inspect[name] and "disable" or "enable")
end,
})
worldedit.register_gui_function("worldedit_gui_region", {
name = "Get/Set Region", privs = combine_privs(minetest.chatcommands["/p"].privs, minetest.chatcommands["/pos1"].privs, minetest.chatcommands["/pos2"].privs, minetest.chatcommands["/reset"].privs, minetest.chatcommands["/mark"].privs, minetest.chatcommands["/unmark"].privs, minetest.chatcommands["/volume"].privs, minetest.chatcommands["/fixedpos"].privs),
name = "Get/Set Region",
privs = combine_we_privs({"p", "pos1", "pos2", "reset", "mark", "unmark", "volume", "fixedpos"}),
get_formspec = function(name)
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
return "size[9,7]" .. worldedit.get_formspec_header("worldedit_gui_region") ..
@ -148,15 +170,15 @@ worldedit.register_gui_handler("worldedit_gui_region", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_set", {
name = "Set Nodes", privs = minetest.chatcommands["/set"].privs,
name = "Set Nodes",
privs = we_privs("set"),
get_formspec = function(name)
local node = gui_nodename1[name]
local nodename = worldedit.normalize_nodename(node)
return "size[6.5,3]" .. worldedit.get_formspec_header("worldedit_gui_set") ..
string.format("field[0.5,1.5;4,0.8;worldedit_gui_set_node;Name;%s]", minetest.formspec_escape(node)) ..
"button[4,1.18;1.5,0.8;worldedit_gui_set_search;Search]" ..
(nodename and string.format("item_image[5.5,1.1;1,1;%s]", nodename)
or "image[5.5,1.1;1,1;unknown_node.png]") ..
formspec_node("5.5,1.1", nodename) ..
"button_exit[0,2.5;3,0.8;worldedit_gui_set_submit;Set Nodes]"
end,
})
@ -166,7 +188,10 @@ worldedit.register_gui_handler("worldedit_gui_set", function(name, fields)
gui_nodename1[name] = tostring(fields.worldedit_gui_set_node)
worldedit.show_page(name, "worldedit_gui_set")
if fields.worldedit_gui_set_submit then
minetest.chatcommands["/set"].func(name, gui_nodename1[name])
local n = worldedit.normalize_nodename(gui_nodename1[name])
if n then
minetest.chatcommands["/set"].func(name, n)
end
end
return true
end
@ -174,19 +199,18 @@ worldedit.register_gui_handler("worldedit_gui_set", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_replace", {
name = "Replace Nodes", privs = combine_privs(minetest.chatcommands["/replace"].privs, minetest.chatcommands["/replaceinverse"].privs),
name = "Replace Nodes",
privs = combine_we_privs({"replace", "replaceinverse"}),
get_formspec = function(name)
local search, replace = gui_nodename1[name], gui_nodename2[name]
local search_nodename, replace_nodename = worldedit.normalize_nodename(search), worldedit.normalize_nodename(replace)
return "size[6.5,4]" .. worldedit.get_formspec_header("worldedit_gui_replace") ..
string.format("field[0.5,1.5;4,0.8;worldedit_gui_replace_search;Name;%s]", minetest.formspec_escape(search)) ..
"button[4,1.18;1.5,0.8;worldedit_gui_replace_search_search;Search]" ..
(search_nodename and string.format("item_image[5.5,1.1;1,1;%s]", search_nodename)
or "image[5.5,1.1;1,1;unknown_node.png]") ..
formspec_node("5.5,1.1", search_nodename) ..
string.format("field[0.5,2.5;4,0.8;worldedit_gui_replace_replace;Name;%s]", minetest.formspec_escape(replace)) ..
"button[4,2.18;1.5,0.8;worldedit_gui_replace_replace_search;Search]" ..
(replace_nodename and string.format("item_image[5.5,2.1;1,1;%s]", replace_nodename)
or "image[5.5,2.1;1,1;unknown_node.png]") ..
formspec_node("5.5,2.1", replace_nodename) ..
"button_exit[0,3.5;3,0.8;worldedit_gui_replace_submit;Replace Nodes]" ..
"button_exit[3.5,3.5;3,0.8;worldedit_gui_replace_submit_inverse;Replace Inverse]"
end,
@ -198,10 +222,19 @@ worldedit.register_gui_handler("worldedit_gui_replace", function(name, fields)
gui_nodename1[name] = tostring(fields.worldedit_gui_replace_search)
gui_nodename2[name] = tostring(fields.worldedit_gui_replace_replace)
worldedit.show_page(name, "worldedit_gui_replace")
local submit = nil
if fields.worldedit_gui_replace_submit then
minetest.chatcommands["/replace"].func(name, string.format("%s %s", gui_nodename1[name], gui_nodename2[name]))
submit = "replace"
elseif fields.worldedit_gui_replace_submit_inverse then
minetest.chatcommands["/replaceinverse"].func(name, string.format("%s %s", gui_nodename1[name], gui_nodename2[name]))
submit = "replaceinverse"
end
if submit then
local n1 = worldedit.normalize_nodename(gui_nodename1[name])
local n2 = worldedit.normalize_nodename(gui_nodename2[name])
if n1 and n2 then
minetest.chatcommands["/"..submit].func(name, string.format("%s %s", n1, n2))
end
end
return true
end
@ -209,15 +242,15 @@ worldedit.register_gui_handler("worldedit_gui_replace", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_sphere_dome", {
name = "Sphere/Dome", privs = combine_privs(minetest.chatcommands["/hollowsphere"].privs, minetest.chatcommands["/sphere"].privs, minetest.chatcommands["/hollowdome"].privs, minetest.chatcommands["/dome"].privs),
name = "Sphere/Dome",
privs = combine_we_privs({"hollowsphere", "sphere", "hollowdome", "dome"}),
get_formspec = function(name)
local node, radius = gui_nodename1[name], gui_distance2[name]
local nodename = worldedit.normalize_nodename(node)
return "size[6.5,5]" .. worldedit.get_formspec_header("worldedit_gui_sphere_dome") ..
string.format("field[0.5,1.5;4,0.8;worldedit_gui_sphere_dome_node;Name;%s]", minetest.formspec_escape(node)) ..
"button[4,1.18;1.5,0.8;worldedit_gui_sphere_dome_search;Search]" ..
(nodename and string.format("item_image[5.5,1.1;1,1;%s]", nodename)
or "image[5.5,1.1;1,1;unknown_node.png]") ..
formspec_node("5.5,1.1", nodename) ..
string.format("field[0.5,2.5;4,0.8;worldedit_gui_sphere_dome_radius;Radius;%s]", minetest.formspec_escape(radius)) ..
"button_exit[0,3.5;3,0.8;worldedit_gui_sphere_dome_submit_hollow;Hollow Sphere]" ..
"button_exit[3.5,3.5;3,0.8;worldedit_gui_sphere_dome_submit_solid;Solid Sphere]" ..
@ -233,14 +266,22 @@ worldedit.register_gui_handler("worldedit_gui_sphere_dome", function(name, field
gui_nodename1[name] = tostring(fields.worldedit_gui_sphere_dome_node)
gui_distance2[name] = tostring(fields.worldedit_gui_sphere_dome_radius)
worldedit.show_page(name, "worldedit_gui_sphere_dome")
local submit = nil
if fields.worldedit_gui_sphere_dome_submit_hollow then
minetest.chatcommands["/hollowsphere"].func(name, string.format("%s %s", gui_distance2[name], gui_nodename1[name]))
submit = "hollowsphere"
elseif fields.worldedit_gui_sphere_dome_submit_solid then
minetest.chatcommands["/sphere"].func(name, string.format("%s %s", gui_distance2[name], gui_nodename1[name]))
submit = "sphere"
elseif fields.worldedit_gui_sphere_dome_submit_hollow_dome then
minetest.chatcommands["/hollowdome"].func(name, string.format("%s %s", gui_distance2[name], gui_nodename1[name]))
submit = "hollowdome"
elseif fields.worldedit_gui_sphere_dome_submit_solid_dome then
minetest.chatcommands["/dome"].func(name, string.format("%s %s", gui_distance2[name], gui_nodename1[name]))
submit = "dome"
end
if submit then
local n = worldedit.normalize_nodename(gui_nodename1[name])
if n then
minetest.chatcommands["/"..submit].func(name, string.format("%s %s", gui_distance2[name], n))
end
end
return true
end
@ -248,15 +289,15 @@ worldedit.register_gui_handler("worldedit_gui_sphere_dome", function(name, field
end)
worldedit.register_gui_function("worldedit_gui_cylinder", {
name = "Cylinder", privs = combine_privs(minetest.chatcommands["/hollowcylinder"].privs, minetest.chatcommands["/cylinder"].privs),
name = "Cylinder",
privs = combine_we_privs({"hollowcylinder", "cylinder"}),
get_formspec = function(name)
local node, axis, length, radius = gui_nodename1[name], gui_axis1[name], gui_distance1[name], gui_distance2[name]
local nodename = worldedit.normalize_nodename(node)
return "size[6.5,5]" .. worldedit.get_formspec_header("worldedit_gui_cylinder") ..
string.format("field[0.5,1.5;4,0.8;worldedit_gui_cylinder_node;Name;%s]", minetest.formspec_escape(node)) ..
"button[4,1.18;1.5,0.8;worldedit_gui_cylinder_search;Search]" ..
(nodename and string.format("item_image[5.5,1.1;1,1;%s]", nodename)
or "image[5.5,1.1;1,1;unknown_node.png]") ..
formspec_node("5.5,1.1", nodename) ..
string.format("field[0.5,2.5;4,0.8;worldedit_gui_cylinder_length;Length;%s]", minetest.formspec_escape(length)) ..
string.format("dropdown[4,2.18;2.5;worldedit_gui_cylinder_axis;X axis,Y axis,Z axis,Look direction;%d]", axis) ..
string.format("field[0.5,3.5;4,0.8;worldedit_gui_cylinder_radius;Radius;%s]", minetest.formspec_escape(radius)) ..
@ -273,56 +314,85 @@ worldedit.register_gui_handler("worldedit_gui_cylinder", function(name, fields)
gui_distance1[name] = tostring(fields.worldedit_gui_cylinder_length)
gui_distance2[name] = tostring(fields.worldedit_gui_cylinder_radius)
worldedit.show_page(name, "worldedit_gui_cylinder")
local submit = nil
if fields.worldedit_gui_cylinder_submit_hollow then
minetest.chatcommands["/hollowcylinder"].func(name, string.format("%s %s %s %s", axis_values[gui_axis1[name]], gui_distance1[name], gui_distance2[name], gui_nodename1[name]))
submit = "hollowcylinder"
elseif fields.worldedit_gui_cylinder_submit_solid then
minetest.chatcommands["/cylinder"].func(name, string.format("%s %s %s %s", axis_values[gui_axis1[name]], gui_distance1[name], gui_distance2[name], gui_nodename1[name]))
submit = "cylinder"
end
if submit then
local n = worldedit.normalize_nodename(gui_nodename1[name])
if n then
minetest.chatcommands["/"..submit].func(name, string.format("%s %s %s %s", axis_values[gui_axis1[name]], gui_distance1[name], gui_distance2[name], n))
end
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)
worldedit.register_gui_function("worldedit_gui_pyramid", {
name = "Pyramid", privs = minetest.chatcommands["/pyramid"].privs,
name = "Pyramid",
privs = we_privs("pyramid"),
get_formspec = function(name)
local node, axis, length = gui_nodename1[name], gui_axis1[name], gui_distance1[name]
local nodename = worldedit.normalize_nodename(node)
return "size[6.5,4]" .. worldedit.get_formspec_header("worldedit_gui_pyramid") ..
string.format("field[0.5,1.5;4,0.8;worldedit_gui_pyramid_node;Name;%s]", minetest.formspec_escape(node)) ..
"button[4,1.18;1.5,0.8;worldedit_gui_pyramid_search;Search]" ..
(nodename and string.format("item_image[5.5,1.1;1,1;%s]", nodename)
or "image[5.5,1.1;1,1;unknown_node.png]") ..
formspec_node("5.5,1.1", nodename) ..
string.format("field[0.5,2.5;4,0.8;worldedit_gui_pyramid_length;Length;%s]", minetest.formspec_escape(length)) ..
string.format("dropdown[4,2.18;2.5;worldedit_gui_pyramid_axis;X axis,Y axis,Z axis,Look direction;%d]", axis) ..
"button_exit[0,3.5;3,0.8;worldedit_gui_pyramid_submit;Pyramid]"
"button_exit[0,3.5;3,0.8;worldedit_gui_pyramid_submit_hollow;Hollow Pyramid]" ..
"button_exit[3.5,3.5;3,0.8;worldedit_gui_pyramid_submit_solid;Solid Pyramid]"
end,
})
worldedit.register_gui_handler("worldedit_gui_pyramid", function(name, fields)
if fields.worldedit_gui_pyramid_search or fields.worldedit_gui_pyramid_submit then
if fields.worldedit_gui_pyramid_search or fields.worldedit_gui_pyramid_submit_solid or fields.worldedit_gui_pyramid_submit_hollow or fields.worldedit_gui_pyramid_axis then
gui_nodename1[name] = tostring(fields.worldedit_gui_pyramid_node)
gui_axis1[name] = axis_indices[fields.worldedit_gui_pyramid_axis]
gui_distance1[name] = tostring(fields.worldedit_gui_pyramid_length)
worldedit.show_page(name, "worldedit_gui_pyramid")
if fields.worldedit_gui_pyramid_submit then
minetest.chatcommands["/pyramid"].func(name, string.format("%s %s %s", axis_values[gui_axis1[name]], gui_distance1[name], gui_nodename1[name]))
local submit = nil
if fields.worldedit_gui_pyramid_submit_solid then
submit = "pyramid"
elseif fields.worldedit_gui_pyramid_submit_hollow then
submit = "hollowpyramid"
end
if submit then
local n = worldedit.normalize_nodename(gui_nodename1[name])
if n then
minetest.chatcommands["/"..submit].func(name, string.format("%s %s %s", axis_values[gui_axis1[name]], gui_distance1[name], n))
end
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)
worldedit.register_gui_function("worldedit_gui_spiral", {
name = "Spiral", privs = minetest.chatcommands["/spiral"].privs,
name = "Spiral",
privs = we_privs("spiral"),
get_formspec = function(name)
local node, length, height, space = gui_nodename1[name], gui_distance1[name], gui_distance2[name], gui_distance3[name]
local nodename = worldedit.normalize_nodename(node)
return "size[6.5,6]" .. worldedit.get_formspec_header("worldedit_gui_spiral") ..
string.format("field[0.5,1.5;4,0.8;worldedit_gui_spiral_node;Name;%s]", minetest.formspec_escape(node)) ..
"button[4,1.18;1.5,0.8;worldedit_gui_spiral_search;Search]" ..
(nodename and string.format("item_image[5.5,1.1;1,1;%s]", nodename)
or "image[5.5,1.1;1,1;unknown_node.png]") ..
formspec_node("5.5,1.1", nodename) ..
string.format("field[0.5,2.5;4,0.8;worldedit_gui_spiral_length;Side Length;%s]", minetest.formspec_escape(length)) ..
string.format("field[0.5,3.5;4,0.8;worldedit_gui_spiral_height;Height;%s]", minetest.formspec_escape(height)) ..
string.format("field[0.5,4.5;4,0.8;worldedit_gui_spiral_space;Wall Spacing;%s]", minetest.formspec_escape(space)) ..
@ -338,7 +408,10 @@ worldedit.register_gui_handler("worldedit_gui_spiral", function(name, fields)
gui_distance3[name] = tostring(fields.worldedit_gui_spiral_space)
worldedit.show_page(name, "worldedit_gui_spiral")
if fields.worldedit_gui_spiral_submit then
minetest.chatcommands["/spiral"].func(name, string.format("%s %s %s %s", gui_distance1[name], gui_distance2[name], gui_distance3[name], gui_nodename1[name]))
local n = worldedit.normalize_nodename(gui_nodename1[name])
if n then
minetest.chatcommands["/spiral"].func(name, string.format("%s %s %s %s", gui_distance1[name], gui_distance2[name], gui_distance3[name], n))
end
end
return true
end
@ -346,7 +419,8 @@ worldedit.register_gui_handler("worldedit_gui_spiral", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_copy_move", {
name = "Copy/Move", privs = combine_privs(minetest.chatcommands["/copy"].privs, minetest.chatcommands["/move"].privs),
name = "Copy/Move",
privs = combine_we_privs({"copy", "move"}),
get_formspec = function(name)
local axis = gui_axis1[name] or 4
local amount = gui_distance1[name] or "10"
@ -370,11 +444,17 @@ 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)
worldedit.register_gui_function("worldedit_gui_stack", {
name = "Stack", privs = minetest.chatcommands["/stack"].privs,
name = "Stack",
privs = we_privs("stack"),
get_formspec = function(name)
local axis, count = gui_axis1[name], gui_count1[name]
return "size[6.5,3]" .. worldedit.get_formspec_header("worldedit_gui_stack") ..
@ -392,11 +472,17 @@ 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)
worldedit.register_gui_function("worldedit_gui_stretch", {
name = "Stretch", privs = minetest.chatcommands["/stretch"].privs,
name = "Stretch",
privs = we_privs("stretch"),
get_formspec = function(name)
local stretchx, stretchy, stretchz = gui_count1[name], gui_count2[name], gui_count3[name]
return "size[5,5]" .. worldedit.get_formspec_header("worldedit_gui_stretch") ..
@ -420,7 +506,8 @@ worldedit.register_gui_handler("worldedit_gui_stretch", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_transpose", {
name = "Transpose", privs = minetest.chatcommands["/transpose"].privs,
name = "Transpose",
privs = we_privs("transpose"),
get_formspec = function(name)
local axis1, axis2 = gui_axis1[name], gui_axis2[name]
return "size[5.5,3]" .. worldedit.get_formspec_header("worldedit_gui_transpose") ..
@ -433,18 +520,28 @@ worldedit.register_gui_function("worldedit_gui_transpose", {
worldedit.register_gui_handler("worldedit_gui_transpose", function(name, fields)
if fields.worldedit_gui_transpose_submit then
gui_axis1[name] = axis_indices[fields.worldedit_gui_transpose_axis1]
gui_axis2[name] = axis_indices[fields.worldedit_gui_transpose_axis2]
worldedit.show_page(name, "worldedit_gui_transpose")
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,
name = "Flip",
privs = we_privs("flip"),
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]"
@ -453,16 +550,22 @@ 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
end)
worldedit.register_gui_function("worldedit_gui_rotate", {
name = "Rotate", privs = minetest.chatcommands["/rotate"].privs,
name = "Rotate",
privs = we_privs("rotate"),
get_formspec = function(name)
local axis, angle = gui_axis1[name], gui_angle[name]
return "size[5.5,3]" .. worldedit.get_formspec_header("worldedit_gui_rotate") ..
@ -480,15 +583,26 @@ 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)
worldedit.register_gui_function("worldedit_gui_orient", {
name = "Orient", privs = minetest.chatcommands["/orient"].privs,
name = "Orient",
privs = we_privs("orient"),
get_formspec = function(name)
local angle = gui_angle[name]
return "size[5,3]" .. worldedit.get_formspec_header("worldedit_gui_orient") ..
string.format("dropdown[0,1;2.5;worldedit_gui_rotate_angle;90 degrees,180 degrees,270 degrees;%s]", angle) ..
string.format("dropdown[0,1;2.5;worldedit_gui_orient_angle;90 degrees,180 degrees,270 degrees;%s]", angle) ..
"button_exit[0,2.5;3,0.8;worldedit_gui_orient_submit;Orient]"
end,
})
@ -497,36 +611,43 @@ 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
end)
worldedit.register_gui_function("worldedit_gui_fixlight", {
name = "Fix Lighting", privs = minetest.chatcommands["/fixlight"].privs,
name = "Fix Lighting",
privs = we_privs("fixlight"),
on_select = function(name)
minetest.chatcommands["/fixlight"].func(name, "")
end,
})
worldedit.register_gui_function("worldedit_gui_hide", {
name = "Hide Region", privs = minetest.chatcommands["/hide"].privs,
name = "Hide Region",
privs = we_privs("hide"),
on_select = function(name)
minetest.chatcommands["/hide"].func(name, "")
end,
})
worldedit.register_gui_function("worldedit_gui_suppress", {
name = "Suppress Nodes", privs = minetest.chatcommands["/suppress"].privs,
name = "Suppress Nodes",
privs = we_privs("suppress"),
get_formspec = function(name)
local node = gui_nodename1[name]
local nodename = worldedit.normalize_nodename(node)
return "size[6.5,3]" .. worldedit.get_formspec_header("worldedit_gui_suppress") ..
string.format("field[0.5,1.5;4,0.8;worldedit_gui_suppress_node;Name;%s]", minetest.formspec_escape(node)) ..
"button[4,1.18;1.5,0.8;worldedit_gui_suppress_search;Search]" ..
(nodename and string.format("item_image[5.5,1.1;1,1;%s]", nodename)
or "image[5.5,1.1;1,1;unknown_node.png]") ..
formspec_node("5.5,1.1", nodename) ..
"button_exit[0,2.5;3,0.8;worldedit_gui_suppress_submit;Suppress Nodes]"
end,
})
@ -536,7 +657,10 @@ worldedit.register_gui_handler("worldedit_gui_suppress", function(name, fields)
gui_nodename1[name] = tostring(fields.worldedit_gui_suppress_node)
worldedit.show_page(name, "worldedit_gui_suppress")
if fields.worldedit_gui_suppress_submit then
minetest.chatcommands["/suppress"].func(name, gui_nodename1[name])
local n = worldedit.normalize_nodename(gui_nodename1[name])
if n then
minetest.chatcommands["/suppress"].func(name, n)
end
end
return true
end
@ -544,15 +668,15 @@ worldedit.register_gui_handler("worldedit_gui_suppress", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_highlight", {
name = "Highlight Nodes", privs = minetest.chatcommands["/highlight"].privs,
name = "Highlight Nodes",
privs = we_privs("highlight"),
get_formspec = function(name)
local node = gui_nodename1[name]
local nodename = worldedit.normalize_nodename(node)
return "size[6.5,3]" .. worldedit.get_formspec_header("worldedit_gui_highlight") ..
string.format("field[0.5,1.5;4,0.8;worldedit_gui_highlight_node;Name;%s]", minetest.formspec_escape(node)) ..
"button[4,1.18;1.5,0.8;worldedit_gui_highlight_search;Search]" ..
(nodename and string.format("item_image[5.5,1.1;1,1;%s]", nodename)
or "image[5.5,1.1;1,1;unknown_node.png]") ..
formspec_node("5.5,1.1", nodename) ..
"button_exit[0,2.5;3,0.8;worldedit_gui_highlight_submit;Highlight Nodes]"
end,
})
@ -562,7 +686,10 @@ worldedit.register_gui_handler("worldedit_gui_highlight", function(name, fields)
gui_nodename1[name] = tostring(fields.worldedit_gui_highlight_node)
worldedit.show_page(name, "worldedit_gui_highlight")
if fields.worldedit_gui_highlight_submit then
minetest.chatcommands["/highlight"].func(name, gui_nodename1[name])
local n = worldedit.normalize_nodename(gui_nodename1[name])
if n then
minetest.chatcommands["/highlight"].func(name, n)
end
end
return true
end
@ -570,14 +697,16 @@ worldedit.register_gui_handler("worldedit_gui_highlight", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_restore", {
name = "Restore Region", privs = minetest.chatcommands["/restore"].privs,
name = "Restore Region",
privs = we_privs("restore"),
on_select = function(name)
minetest.chatcommands["/restore"].func(name, "")
end,
})
worldedit.register_gui_function("worldedit_gui_save_load", {
name = "Save/Load", privs = combine_privs(minetest.chatcommands["/save"].privs, minetest.chatcommands["/allocate"].privs, minetest.chatcommands["/load"].privs),
name = "Save/Load",
privs = combine_we_privs({"save", "allocate", "load"}),
get_formspec = function(name)
local filename = gui_filename[name]
return "size[6,4]" .. worldedit.get_formspec_header("worldedit_gui_save_load") ..
@ -588,9 +717,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])
@ -605,7 +734,8 @@ worldedit.register_gui_handler("worldedit_gui_save", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_lua", {
name = "Run Lua",
name = "Run Lua", privs = minetest.chatcommands["/clearobjects"].privs,
privs = we_privs("lua"),
get_formspec = function(name)
local code = gui_code[name]
return "size[8,6.5]" .. worldedit.get_formspec_header("worldedit_gui_lua") ..
@ -617,7 +747,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])
@ -630,28 +760,9 @@ worldedit.register_gui_handler("worldedit_gui_lua", function(name, fields)
end)
worldedit.register_gui_function("worldedit_gui_clearobjects", {
name = "Clear Objects", privs = minetest.chatcommands["/clearobjects"].privs,
name = "Clear Objects",
privs = we_privs("clearobjects"),
on_select = function(name)
minetest.chatcommands["/clearobjects"].func(name, "")
end,
})
worldedit.register_gui_function("worldedit_gui_formspec_tester", {
name = "Formspec Tester",
get_formspec = function(name)
local value = gui_formspec[name]
return "size[8,6.5]" .. worldedit.get_formspec_header("worldedit_gui_formspec_tester") ..
string.format("textarea[0.5,1;7.5,5.5;worldedit_gui_formspec_tester_value;Formspec Code;%s]", minetest.formspec_escape(value)) ..
"button_exit[0,6;3,0.8;worldedit_gui_formspec_tester_show;Show Formspec]"
end,
})
worldedit.register_gui_handler("worldedit_gui_formspec_tester", function(name, fields)
if fields.worldedit_gui_formspec_tester_show then
gui_formspec[name] = fields.worldedit_gui_formspec_tester_value or ""
worldedit.show_page(name, "worldedit_gui_formspec_tester")
minetest.show_formspec(name, "worldedit:formspec_tester", gui_formspec[name])
return true
end
return false
end)

70
worldedit_gui/init.lua Normal file → Executable file
View File

@ -14,7 +14,7 @@ Use `nil` for the `options` parameter to unregister the function associated with
Use `nil` for the `get_formspec` field to denote that the function does not have its own screen.
Use `nil` for the `privs` field to denote that no special privileges are required to use the function.
The `privs` field may not be `nil`.
If the identifier is already registered to another function, it will be replaced by the new one.
@ -24,6 +24,9 @@ The `on_select` function must not call `worldedit.show_page`
worldedit.pages = {} --mapping of identifiers to options
local identifiers = {} --ordered list of identifiers
worldedit.register_gui_function = function(identifier, options)
if options.privs == nil or next(options.privs) == nil then
error("privs unset")
end
worldedit.pages[identifier] = options
table.insert(identifiers, identifier)
end
@ -46,7 +49,7 @@ worldedit.register_gui_handler = function(identifier, handler)
--ensure the player has permission to perform the action
local entry = worldedit.pages[identifier]
if entry and minetest.check_player_privs(name, entry.privs or {}) then
if entry and minetest.check_player_privs(name, entry.privs) then
return handler(name, fields)
end
return false
@ -67,7 +70,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)
@ -77,6 +80,8 @@ if unified_inventory then --unified inventory installed
unified_inventory.register_button("worldedit_gui", {
type = "image",
image = "inventory_plus_worldedit_gui.png",
tooltip = "Worldedit GUI",
show_with = "worldedit", --Modiff MFF (Crabman 30/06/2015)
})
minetest.register_on_player_receive_fields(function(player, formname, fields)
@ -100,9 +105,12 @@ 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)
inventory_plus.register_button(player, "worldedit_gui", "WorldEdit")
local can_worldedit = minetest.check_player_privs(player:get_player_name(), {worldedit=true})
if can_worldedit then
inventory_plus.register_button(player, "worldedit_gui", "WorldEdit")
end
end)
--show the form when the button is pressed and hide it when done
@ -115,7 +123,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
@ -128,7 +136,37 @@ elseif inventory_plus then --inventory++ installed
inventory_plus.set_inventory_formspec(player, get_formspec(name, page))
end
end
elseif rawget(_G, "sfinv") then --sfinv installed (part of minetest_game since 0.4.15)
assert(sfinv.enabled)
local orig_get = sfinv.pages["sfinv:crafting"].get
sfinv.override_page("sfinv:crafting", {
get = function(self, player, context)
local can_worldedit = minetest.check_player_privs(player, {worldedit=true})
local fs = orig_get(self, player, context)
return fs .. (can_worldedit and "image_button[0,0;1,1;inventory_plus_worldedit_gui.png;worldedit_gui;]" or "")
end
})
--show the form when the button is pressed and hide it when done
minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields.worldedit_gui then --main page
worldedit.show_page(player:get_player_name(), "worldedit_gui")
return true
elseif fields.worldedit_gui_exit then --return to original page
sfinv.set_page(player, "sfinv:crafting")
return true
end
return false
end)
worldedit.show_page = function(name, page)
local player = minetest.get_player_by_name(name)
if player then
player:set_inventory_formspec(get_formspec(name, page))
end
end
else --fallback button
-- FIXME: this is a huge clusterfuck and the back button is broken
local player_formspecs = {}
local update_main_formspec = function(name)
@ -140,8 +178,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
@ -194,6 +245,7 @@ end
worldedit.register_gui_function("worldedit_gui", {
name = "WorldEdit GUI",
privs = {interact=true},
get_formspec = function(name)
--create a form with all the buttons arranged in a grid
local buttons, x, y, index = {}, 0, 1, 0
@ -226,7 +278,7 @@ worldedit.register_gui_handler("worldedit_gui", function(name, fields)
for identifier, entry in pairs(worldedit.pages) do --check for WorldEdit GUI main formspec button selection
if fields[identifier] and identifier ~= "worldedit_gui" then
--ensure player has permission to perform action
local has_privs, missing_privs = minetest.check_player_privs(name, entry.privs or {})
local has_privs, missing_privs = minetest.check_player_privs(name, entry.privs)
if not has_privs then
worldedit.player_notify(name, "you are not allowed to use this function (missing privileges: " .. table.concat(missing_privs, ", ") .. ")")
return false

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

1
worldedit_infinity/depends.txt Executable file
View File

@ -0,0 +1 @@
worldedit?

4
worldedit_infinity/init.lua Normal file → Executable file
View File

@ -1,4 +1,4 @@
worldedit = worldedit or {}
worldedit = rawget(_G, "worldedit") or {}
local minetest = minetest --local copy of global
local get_pointed = function(pos, nearest, distance)
@ -100,4 +100,4 @@ worldedit.raytrace = function(pos, dir, callback)
intersectz = intersectz + componentz
end
end
end
end

0
worldedit_limited/depends.txt Normal file → Executable file
View File

0
worldedit_limited/init.lua Normal file → Executable file
View File

0
worldedit_shortcommands/depends.txt Normal file → Executable file
View File

3
worldedit_shortcommands/init.lua Normal file → Executable file
View File

@ -31,6 +31,7 @@ worldedit.alias_chatcommand("/hdo", "/hollowdome")
worldedit.alias_chatcommand("/do", "/dome")
worldedit.alias_chatcommand("/hcyl", "/hollowcylinder")
worldedit.alias_chatcommand("/cyl", "/cylinder")
worldedit.alias_chatcommand("/hpyr", "/hollowpyramid")
worldedit.alias_chatcommand("/pyr", "/pyramid")
worldedit.alias_chatcommand("/spl", "/spiral")
worldedit.alias_chatcommand("/m", "/move")
@ -47,4 +48,4 @@ worldedit.alias_chatcommand("/hlt", "/highlight")
worldedit.alias_chatcommand("/rsr", "/restore")
worldedit.alias_chatcommand("/l", "/lua")
worldedit.alias_chatcommand("/lt", "/luatransform")
worldedit.alias_chatcommand("/clro", "/clearobjects")
worldedit.alias_chatcommand("/clro", "/clearobjects")