mirror of
https://github.com/Uberi/Minetest-WorldEdit.git
synced 2025-07-22 17:40:25 +02:00
Compare commits
37 Commits
supports_m
...
116ae25ebd
Author | SHA1 | Date | |
---|---|---|---|
116ae25ebd | |||
18444379a1 | |||
974dcaa918 | |||
abdecd4239 | |||
9c38b9f6ad | |||
7833b68c85 | |||
03bef18272 | |||
91d02f6f5b | |||
8feaf8a21d | |||
5bab991e0b | |||
9bb0ad0442 | |||
63a7069671 | |||
79097dc6c8 | |||
3bc7a0f97d | |||
45acf09e4a | |||
adab528f8a | |||
26b6682587 | |||
b4826aa821 | |||
a0181ea897 | |||
2a4aaae8a2 | |||
f6298d7b87 | |||
68f7bcc728 | |||
0919f7cab3 | |||
de566d2e3e | |||
cc897150f2 | |||
f39a8e264d | |||
da5abec273 | |||
ff53a71d58 | |||
0edcd1a59d | |||
a1b6a34e61 | |||
f589c988b1 | |||
f28d9b8d35 | |||
b8453a0e0b | |||
0a16f11d93 | |||
b50294d10c | |||
324eb556f6 | |||
3ffecdd9c4 |
36
README.md
36
README.md
@ -47,11 +47,11 @@ The chat interface adds many chat commands that perform various WorldEdit powere
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
This mod supports Minetest versions 0.4.8 and newer. Older versions of WorldEdit may work with older versions of Minetest, but are not recommended or supported.
|
||||
This mod supports Minetest versions 5.0 and newer. Older versions of WorldEdit may work with older versions of Minetest, but are not recommended or supported.
|
||||
|
||||
WorldEdit works quite well with other mods, and does not have any known mod conflicts.
|
||||
|
||||
WorldEdit GUI requires one of [sfinv](https://github.com/minetest/minetest_game/tree/master/mods/sfinv) (included in minetest_game since 0.4.15), [Unified Inventory](https://forum.minetest.net/viewtopic.php?id=3933) or [Inventory++](https://forum.minetest.net/viewtopic.php?id=6204).
|
||||
WorldEdit GUI requires one of [sfinv](https://github.com/minetest/minetest_game/tree/master/mods/sfinv) (included in minetest_game), [Unified Inventory](https://forum.minetest.net/viewtopic.php?t=12767) or [Inventory++](https://forum.minetest.net/viewtopic.php?id=6204) or [Smart Inventory](https://forum.minetest.net/viewtopic.php?t=16597).
|
||||
|
||||
If you use any other inventory manager mods, note that they may conflict with the WorldEdit GUI. If this is the case, it may be necessary to disable them.
|
||||
|
||||
@ -59,9 +59,9 @@ WorldEdit API
|
||||
-------------
|
||||
WorldEdit exposes all significant functionality in a simple Lua interface.
|
||||
|
||||
Adding WorldEdit to the file "depends.txt" in your mod gives you access to all of the `worldedit` functions. The API is useful for tasks such as high-performance node manipulation, alternative interfaces, and map creation.
|
||||
Adding WorldEdit as a dependency to your mod gives you access to all of the `worldedit` functions. The API is useful for tasks such as high-performance node manipulation, alternative interfaces, and map creation.
|
||||
|
||||
AGPLv3 compatible mods may further include WorldEdit files in their own mods. This may be useful if a modder wishes to completely avoid any dependencies on WorldEdit. Note that it is required to give credit to the authors.
|
||||
AGPLv3 compatible mods may further include WorldEdit files in their own mods. This can be useful if a modder wishes to completely avoid any dependency on WorldEdit. Note that it is required to give credit to the authors in this case.
|
||||
|
||||
This API is documented in the [WorldEdit API Reference](WorldEdit%20API.md).
|
||||
|
||||
@ -136,20 +136,38 @@ Authors
|
||||
-------
|
||||
WorldEdit would not be possible without the contributions of many developers and designers. Below, they are listed alphabetically:
|
||||
|
||||
cheapie
|
||||
Alexander Weber
|
||||
beyondlimits
|
||||
Carter Kolwey
|
||||
cornernote
|
||||
cyisfor
|
||||
danierukun
|
||||
Cy
|
||||
Daniel Sosa
|
||||
electricface
|
||||
est31
|
||||
Eugen Wesseloh
|
||||
HybridDog
|
||||
Isidor Zeuner
|
||||
Jean-Patrick Guerrero
|
||||
Joseph Pickard
|
||||
kaeza
|
||||
khonkhortisan
|
||||
pickardjoe
|
||||
kilbith
|
||||
KodexKy
|
||||
Kyle
|
||||
MT-Modder
|
||||
Niwla23
|
||||
Panquesito7
|
||||
Pedro Gimeno
|
||||
Rui
|
||||
Sebastien Ponce
|
||||
sfan5
|
||||
ShadowNinja
|
||||
shivajiva101
|
||||
spillz
|
||||
Starbeamrainbowlabs
|
||||
TalkLounge
|
||||
tenplus1
|
||||
Uberi/Temperest
|
||||
Wuzzy
|
||||
|
||||
License
|
||||
-------
|
||||
|
@ -24,6 +24,7 @@ Contained in manipulations.lua, this module allows several node operations to be
|
||||
### count = worldedit.set(pos1, pos2, node_name)
|
||||
|
||||
Sets a region defined by positions `pos1` and `pos2` to `node_name`. To clear a region, use "air" as the value of `node_name`.
|
||||
If `node_name` is a list of nodes, each set node is randomly picked from it.
|
||||
|
||||
Returns the number of nodes set.
|
||||
|
||||
@ -54,6 +55,7 @@ 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`.
|
||||
Note that the offset needs to be big enough that there is no overlap.
|
||||
|
||||
Returns the number of nodes copied.
|
||||
|
||||
@ -72,6 +74,7 @@ Returns the number of nodes stacked.
|
||||
### count = worldedit.stack2(pos1, pos2, direction, amount)
|
||||
|
||||
Duplicates the region defined by positions `pos1` and `pos2` `amount` times with offset vector `direction`.
|
||||
Note that the offset vector needs to be big enough that there is no overlap.
|
||||
|
||||
Returns the number of nodes stacked.
|
||||
|
||||
|
2
modpack.conf
Normal file
2
modpack.conf
Normal file
@ -0,0 +1,2 @@
|
||||
name = Minetest-WorldEdit
|
||||
description = WorldEdit is an in-game world editor. Use it to repair griefing, or just create awesome buildings in seconds.
|
@ -107,7 +107,9 @@ end
|
||||
|
||||
function mh.finish(manip, data)
|
||||
-- Update map
|
||||
manip:set_data(data)
|
||||
if data ~= nil then
|
||||
manip:set_data(data)
|
||||
end
|
||||
manip:write_to_map()
|
||||
manip:update_map()
|
||||
end
|
||||
|
@ -149,7 +149,7 @@ 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 playerpos = minetest.get_player_by_name(name):get_pos()
|
||||
local dist1 = vector.distance(playerpos, worldedit.pos1[name])
|
||||
local dist2 = vector.distance(playerpos, worldedit.pos2[name])
|
||||
|
||||
@ -255,4 +255,4 @@ worldedit.translate_direction = function(name, direction)
|
||||
end
|
||||
|
||||
return resaxis, resdir
|
||||
end
|
||||
end
|
||||
|
@ -15,14 +15,6 @@ local ver = {major=1, minor=2}
|
||||
worldedit.version = ver
|
||||
worldedit.version_string = string.format("%d.%d", ver.major, ver.minor)
|
||||
|
||||
if not minetest.get_voxel_manip then
|
||||
local err_msg = "This version of WorldEdit requires Minetest 0.4.8 or later! You have an old version."
|
||||
minetest.log("error", string.rep("#", 128))
|
||||
minetest.log("error", err_msg)
|
||||
minetest.log("error", string.rep("#", 128))
|
||||
error(err_msg)
|
||||
end
|
||||
|
||||
local path = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
local function load_module(path)
|
||||
|
@ -76,9 +76,6 @@ function worldedit.replace(pos1, pos2, search_node, replace_node, inverse)
|
||||
|
||||
local count = 0
|
||||
|
||||
--- TODO: This could be shortened by checking `inverse` in the loop,
|
||||
-- but that would have a speed penalty. Is the penalty big enough
|
||||
-- to matter?
|
||||
if not inverse then
|
||||
for i in area:iterp(pos1, pos2) do
|
||||
if data[i] == search_id then
|
||||
@ -101,27 +98,47 @@ function worldedit.replace(pos1, pos2, search_node, replace_node, inverse)
|
||||
end
|
||||
|
||||
|
||||
local function deferred_execution(next_one, finished)
|
||||
-- Allocate 100% of server step for execution (might lag a little)
|
||||
local allocated_usecs =
|
||||
tonumber(minetest.settings:get("dedicated_server_step")) * 1000000
|
||||
local function f()
|
||||
local deadline = minetest.get_us_time() + allocated_usecs
|
||||
repeat
|
||||
local is_done = next_one()
|
||||
if is_done then
|
||||
if finished then
|
||||
finished()
|
||||
end
|
||||
return
|
||||
end
|
||||
until minetest.get_us_time() >= deadline
|
||||
minetest.after(0, f)
|
||||
end
|
||||
f()
|
||||
end
|
||||
|
||||
--- Duplicates a region `amount` times with offset vector `direction`.
|
||||
-- Stacking is spread across server steps, one copy per step.
|
||||
-- Stacking is spread across server steps.
|
||||
-- @return The number of nodes stacked.
|
||||
function worldedit.stack2(pos1, pos2, direction, amount, finished)
|
||||
-- Protect arguments from external changes during execution
|
||||
pos1 = table.copy(pos1)
|
||||
pos2 = table.copy(pos2)
|
||||
direction = table.copy(direction)
|
||||
|
||||
local i = 0
|
||||
local translated = {x=0, y=0, z=0}
|
||||
local function next_one()
|
||||
if i < amount then
|
||||
i = i + 1
|
||||
translated.x = translated.x + direction.x
|
||||
translated.y = translated.y + direction.y
|
||||
translated.z = translated.z + direction.z
|
||||
worldedit.copy2(pos1, pos2, translated)
|
||||
minetest.after(0, next_one)
|
||||
else
|
||||
if finished then
|
||||
finished()
|
||||
end
|
||||
end
|
||||
local function step()
|
||||
translated.x = translated.x + direction.x
|
||||
translated.y = translated.y + direction.y
|
||||
translated.z = translated.z + direction.z
|
||||
worldedit.copy2(pos1, pos2, translated)
|
||||
i = i + 1
|
||||
return i >= amount
|
||||
end
|
||||
next_one()
|
||||
deferred_execution(step, finished)
|
||||
|
||||
return worldedit.volume(pos1, pos2) * amount
|
||||
end
|
||||
|
||||
@ -135,181 +152,187 @@ end
|
||||
function worldedit.copy(pos1, pos2, axis, amount)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
|
||||
worldedit.keep_loaded(pos1, pos2)
|
||||
-- Decide if we need to copy stuff backwards (only applies to metadata)
|
||||
local backwards = amount > 0 and amount < (pos2[axis] - pos1[axis] + 1)
|
||||
|
||||
local get_node, get_meta, set_node = minetest.get_node,
|
||||
minetest.get_meta, minetest.set_node
|
||||
-- Copy things backwards when negative to avoid corruption.
|
||||
-- FIXME: Lots of code duplication here.
|
||||
if amount < 0 then
|
||||
local pos = {}
|
||||
pos.x = pos1.x
|
||||
while pos.x <= pos2.x do
|
||||
pos.y = pos1.y
|
||||
while pos.y <= pos2.y do
|
||||
pos.z = pos1.z
|
||||
while pos.z <= pos2.z do
|
||||
local node = get_node(pos) -- Obtain current node
|
||||
local meta = get_meta(pos):to_table() -- Get meta of current node
|
||||
local value = pos[axis] -- Store current position
|
||||
pos[axis] = value + amount -- Move along axis
|
||||
set_node(pos, node) -- Copy node to new position
|
||||
get_meta(pos):from_table(meta) -- Set metadata of new node
|
||||
pos[axis] = value -- Restore old position
|
||||
pos.z = pos.z + 1
|
||||
end
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
pos.x = pos.x + 1
|
||||
end
|
||||
else
|
||||
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 value = pos[axis] -- Store current position
|
||||
pos[axis] = value + amount -- Move along axis
|
||||
set_node(pos, node) -- Copy node to new position
|
||||
get_meta(pos):from_table(meta) -- Set metadata of new node
|
||||
pos[axis] = value -- Restore old position
|
||||
pos.z = pos.z - 1
|
||||
end
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
pos.x = pos.x - 1
|
||||
end
|
||||
end
|
||||
return worldedit.volume(pos1, pos2)
|
||||
local off = {x=0, y=0, z=0}
|
||||
off[axis] = amount
|
||||
return worldedit.copy2(pos1, pos2, off, backwards)
|
||||
end
|
||||
|
||||
--- Copies a region by offset vector `off`.
|
||||
-- @param pos1
|
||||
-- @param pos2
|
||||
-- @param off
|
||||
-- @param meta_backwards (not officially part of API)
|
||||
-- @return The number of nodes copied.
|
||||
function worldedit.copy2(pos1, pos2, off)
|
||||
function worldedit.copy2(pos1, pos2, off, meta_backwards)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
|
||||
worldedit.keep_loaded(pos1, pos2)
|
||||
local src_manip, src_area = mh.init(pos1, pos2)
|
||||
local src_stride = {x=1, y=src_area.ystride, z=src_area.zstride}
|
||||
local src_offset = vector.subtract(pos1, src_area.MinEdge)
|
||||
|
||||
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
|
||||
local dpos1 = vector.add(pos1, off)
|
||||
local dpos2 = vector.add(pos2, off)
|
||||
local dim = vector.add(vector.subtract(pos2, pos1), 1)
|
||||
|
||||
local dst_manip, dst_area = mh.init(dpos1, dpos2)
|
||||
local dst_stride = {x=1, y=dst_area.ystride, z=dst_area.zstride}
|
||||
local dst_offset = vector.subtract(dpos1, dst_area.MinEdge)
|
||||
|
||||
local function do_copy(src_data, dst_data)
|
||||
for z = 0, dim.z-1 do
|
||||
local src_index_z = (src_offset.z + z) * src_stride.z + 1 -- +1 for 1-based indexing
|
||||
local dst_index_z = (dst_offset.z + z) * dst_stride.z + 1
|
||||
for y = 0, dim.y-1 do
|
||||
local src_index_y = src_index_z + (src_offset.y + y) * src_stride.y
|
||||
local dst_index_y = dst_index_z + (dst_offset.y + y) * dst_stride.y
|
||||
-- Copy entire row at once
|
||||
local src_index_x = src_index_y + src_offset.x
|
||||
local dst_index_x = dst_index_y + dst_offset.x
|
||||
for x = 0, dim.x-1 do
|
||||
dst_data[dst_index_x + x] = src_data[src_index_x + x]
|
||||
end
|
||||
end
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
pos.x = pos.x - 1
|
||||
end
|
||||
|
||||
-- Copy node data
|
||||
local src_data = src_manip:get_data()
|
||||
local dst_data = dst_manip:get_data()
|
||||
do_copy(src_data, dst_data)
|
||||
dst_manip:set_data(dst_data)
|
||||
|
||||
-- Copy param1
|
||||
src_manip:get_light_data(src_data)
|
||||
dst_manip:get_light_data(dst_data)
|
||||
do_copy(src_data, dst_data)
|
||||
dst_manip:set_light_data(dst_data)
|
||||
|
||||
-- Copy param2
|
||||
src_manip:get_param2_data(src_data)
|
||||
dst_manip:get_param2_data(dst_data)
|
||||
do_copy(src_data, dst_data)
|
||||
dst_manip:set_param2_data(dst_data)
|
||||
|
||||
mh.finish(dst_manip)
|
||||
src_data = nil
|
||||
dst_data = nil
|
||||
|
||||
-- Copy metadata
|
||||
local get_meta = minetest.get_meta
|
||||
if meta_backwards then
|
||||
for z = dim.z-1, 0, -1 do
|
||||
for y = dim.y-1, 0, -1 do
|
||||
for x = dim.x-1, 0, -1 do
|
||||
local pos = {x=pos1.x+x, y=pos1.y+y, z=pos1.z+z}
|
||||
local meta = get_meta(pos):to_table()
|
||||
pos = vector.add(pos, off)
|
||||
get_meta(pos):from_table(meta)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for z = 0, dim.z-1 do
|
||||
for y = 0, dim.y-1 do
|
||||
for x = 0, dim.x-1 do
|
||||
local pos = {x=pos1.x+x, y=pos1.y+y, z=pos1.z+z}
|
||||
local meta = get_meta(pos):to_table()
|
||||
pos = vector.add(pos, off)
|
||||
get_meta(pos):from_table(meta)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return worldedit.volume(pos1, pos2)
|
||||
end
|
||||
|
||||
--- Deletes all node metadata in the region
|
||||
-- @param pos1
|
||||
-- @param pos2
|
||||
-- @return The number of nodes that had their meta deleted.
|
||||
function worldedit.delete_meta(pos1, pos2)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
|
||||
local meta_positions = minetest.find_nodes_with_meta(pos1, pos2)
|
||||
local get_meta = minetest.get_meta
|
||||
for _, pos in ipairs(meta_positions) do
|
||||
get_meta(pos):from_table(nil)
|
||||
end
|
||||
|
||||
return #meta_positions
|
||||
end
|
||||
|
||||
--- Moves a region along `axis` by `amount` nodes.
|
||||
-- @return The number of nodes moved.
|
||||
function worldedit.move(pos1, pos2, axis, amount)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
|
||||
worldedit.keep_loaded(pos1, pos2)
|
||||
local dim = vector.add(vector.subtract(pos2, pos1), 1)
|
||||
local overlap = math.abs(amount) < dim[axis]
|
||||
-- Decide if we need to copy metadata backwards
|
||||
local backwards = overlap and amount > 0
|
||||
|
||||
--- TODO: Move slice by slice using schematic method in the move axis
|
||||
-- and transfer metadata in separate loop (and if the amount is
|
||||
-- greater than the length in the axis, copy whole thing at a time and
|
||||
-- erase original after, using schematic method).
|
||||
local get_node, get_meta, set_node, remove_node = minetest.get_node,
|
||||
minetest.get_meta, minetest.set_node, minetest.remove_node
|
||||
-- Copy things backwards when negative to avoid corruption.
|
||||
--- FIXME: Lots of code duplication here.
|
||||
if amount < 0 then
|
||||
local pos = {}
|
||||
pos.x = pos1.x
|
||||
while pos.x <= pos2.x do
|
||||
pos.y = pos1.y
|
||||
while pos.y <= pos2.y do
|
||||
pos.z = pos1.z
|
||||
while pos.z <= pos2.z do
|
||||
local node = get_node(pos) -- Obtain current node
|
||||
local meta = get_meta(pos):to_table() -- Get metadata of current node
|
||||
remove_node(pos) -- Remove current node
|
||||
local value = pos[axis] -- Store current position
|
||||
pos[axis] = value + amount -- Move along axis
|
||||
set_node(pos, node) -- Move node to new position
|
||||
get_meta(pos):from_table(meta) -- Set metadata of new node
|
||||
pos[axis] = value -- Restore old position
|
||||
pos.z = pos.z + 1
|
||||
end
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
pos.x = pos.x + 1
|
||||
local function nuke_area(my_off, my_dim)
|
||||
if my_dim.x == 0 or my_dim.y == 0 or my_dim.z == 0 then
|
||||
return
|
||||
end
|
||||
local my_pos1 = vector.add(pos1, my_off)
|
||||
local my_pos2 = vector.subtract(vector.add(my_pos1, my_dim), 1)
|
||||
worldedit.set(my_pos1, my_pos2, "air")
|
||||
worldedit.delete_meta(my_pos1, my_pos2)
|
||||
end
|
||||
|
||||
-- Copy stuff to new location
|
||||
local off = {x=0, y=0, z=0}
|
||||
off[axis] = amount
|
||||
worldedit.copy2(pos1, pos2, off, backwards)
|
||||
-- Nuke old area
|
||||
if not overlap then
|
||||
nuke_area({x=0, y=0, z=0}, dim)
|
||||
else
|
||||
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 metadata of current node
|
||||
remove_node(pos) -- Remove current node
|
||||
local value = pos[axis] -- Store current position
|
||||
pos[axis] = value + amount -- Move along axis
|
||||
set_node(pos, node) -- Move node to new position
|
||||
get_meta(pos):from_table(meta) -- Set metadata of new node
|
||||
pos[axis] = value -- Restore old position
|
||||
pos.z = pos.z - 1
|
||||
end
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
pos.x = pos.x - 1
|
||||
-- Source and destination region are overlapping, which means we can't
|
||||
-- blindly delete the [pos1, pos2] area
|
||||
local leftover = vector.new(dim) -- size of the leftover slice
|
||||
leftover[axis] = math.abs(amount)
|
||||
if amount > 0 then
|
||||
nuke_area({x=0, y=0, z=0}, leftover)
|
||||
else
|
||||
local top = {x=0, y=0, z=0} -- offset of the leftover slice from pos1
|
||||
top[axis] = dim[axis] - math.abs(amount)
|
||||
nuke_area(top, leftover)
|
||||
end
|
||||
end
|
||||
|
||||
return worldedit.volume(pos1, pos2)
|
||||
end
|
||||
|
||||
|
||||
--- Duplicates a region along `axis` `amount` times.
|
||||
-- Stacking is spread across server steps, one copy per step.
|
||||
-- Stacking is spread across server steps.
|
||||
-- @param pos1
|
||||
-- @param pos2
|
||||
-- @param axis Axis direction, "x", "y", or "z".
|
||||
-- @param count
|
||||
-- @return The number of nodes stacked.
|
||||
function worldedit.stack(pos1, pos2, axis, count)
|
||||
function worldedit.stack(pos1, pos2, axis, count, finished)
|
||||
local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||
local length = pos2[axis] - pos1[axis] + 1
|
||||
if count < 0 then
|
||||
count = -count
|
||||
length = -length
|
||||
end
|
||||
local amount = 0
|
||||
local copy = worldedit.copy
|
||||
local i = 1
|
||||
local function next_one()
|
||||
if i <= count then
|
||||
i = i + 1
|
||||
amount = amount + length
|
||||
copy(pos1, pos2, axis, amount)
|
||||
minetest.after(0, next_one)
|
||||
end
|
||||
|
||||
local i, distance = 0, 0
|
||||
local function step()
|
||||
distance = distance + length
|
||||
worldedit.copy(pos1, pos2, axis, distance)
|
||||
i = i + 1
|
||||
return i >= count
|
||||
end
|
||||
next_one()
|
||||
deferred_execution(step, finished)
|
||||
|
||||
return worldedit.volume(pos1, pos2) * count
|
||||
end
|
||||
|
||||
@ -638,7 +661,7 @@ function worldedit.clear_objects(pos1, pos2)
|
||||
-- Avoid players and WorldEdit entities
|
||||
if not obj:is_player() and (not entity or
|
||||
not entity.name:find("^worldedit:")) then
|
||||
local pos = obj:getpos()
|
||||
local pos = obj:get_pos()
|
||||
if pos.x >= pos1x and pos.x <= pos2x and
|
||||
pos.y >= pos1y and pos.y <= pos2y and
|
||||
pos.z >= pos1z and pos.z <= pos2z then
|
||||
|
2
worldedit/mod.conf
Normal file
2
worldedit/mod.conf
Normal file
@ -0,0 +1,2 @@
|
||||
name = worldedit
|
||||
description = WorldEdit main functionality & API
|
@ -24,7 +24,7 @@ Serialization version history:
|
||||
-- @return Extra header fields as a list of strings, or nil if not supported.
|
||||
-- @return Content (data after header).
|
||||
function worldedit.read_header(value)
|
||||
if value:find("^[0-9]+[%-:]") then
|
||||
if value:find("^[0-9]+[,:]") then
|
||||
local header_end = value:find(":", 1, true)
|
||||
local header = value:sub(1, header_end - 1):split(",")
|
||||
local version = tonumber(header[1])
|
||||
|
@ -1,2 +0,0 @@
|
||||
worldedit
|
||||
worldedit_commands
|
@ -1,57 +1,10 @@
|
||||
local modname = minetest.get_current_modname()
|
||||
|
||||
-- check compatibility
|
||||
if minetest.raycast == nil then
|
||||
function log_unavailable_error()
|
||||
minetest.log("error",
|
||||
"[MOD] " .. modname .. " is not compatible with current game version, " ..
|
||||
"you can disable it in the game settings!"
|
||||
)
|
||||
minetest.log("verbose",
|
||||
"[MOD] " .. modname .. " requires a suitable version of 0.4.16-dev or higher, " ..
|
||||
"that includes support for minetest.raycast() [since 7th July 2017]"
|
||||
)
|
||||
end
|
||||
|
||||
if minetest.is_singleplayer() then
|
||||
-- delay message until player is connected
|
||||
minetest.register_on_joinplayer(log_unavailable_error)
|
||||
else
|
||||
log_unavailable_error()
|
||||
end
|
||||
|
||||
-- exit here / do not load this mod
|
||||
return
|
||||
error(
|
||||
"worldedit_brush requires at least Minetest 5.0"
|
||||
)
|
||||
end
|
||||
|
||||
local BRUSH_MAX_DIST = 150
|
||||
local BRUSH_ALLOWED_COMMANDS = {
|
||||
-- basically everything that only needs pos1
|
||||
"cube",
|
||||
"cylinder",
|
||||
"dome",
|
||||
"hollowcube",
|
||||
"hollowcylinder",
|
||||
"hollowdome",
|
||||
"hollowpyramid",
|
||||
"hollowsphere",
|
||||
"load",
|
||||
"pyramid",
|
||||
"sphere",
|
||||
"spiral",
|
||||
|
||||
"cyl",
|
||||
"do",
|
||||
"hcube",
|
||||
"hcyl",
|
||||
"hdo",
|
||||
"hpyr",
|
||||
"hspr",
|
||||
"l",
|
||||
"pyr",
|
||||
"spr",
|
||||
"spl",
|
||||
}
|
||||
local brush_on_use = function(itemstack, placer)
|
||||
local meta = itemstack:get_meta()
|
||||
local name = placer:get_player_name()
|
||||
@ -62,8 +15,10 @@ local brush_on_use = function(itemstack, placer)
|
||||
"This brush is not bound, use //brush to bind a command to it.")
|
||||
return false
|
||||
end
|
||||
local cmddef = minetest.registered_chatcommands["/" .. cmd]
|
||||
|
||||
local cmddef = worldedit.registered_commands[cmd]
|
||||
if cmddef == nil then return false end -- shouldn't happen as //brush checks this
|
||||
|
||||
local has_privs, missing_privs = minetest.check_player_privs(name, cmddef.privs)
|
||||
if not has_privs then
|
||||
worldedit.player_notify(name,
|
||||
@ -71,7 +26,8 @@ local brush_on_use = function(itemstack, placer)
|
||||
return false
|
||||
end
|
||||
|
||||
local raybegin = vector.add(placer:get_pos(), {x=0, y=2, z=0}) -- player head
|
||||
local raybegin = vector.add(placer:get_pos(),
|
||||
{x=0, y=placer:get_properties().eye_height, z=0})
|
||||
local rayend = vector.add(raybegin, vector.multiply(placer:get_look_dir(), BRUSH_MAX_DIST))
|
||||
local ray = minetest.raycast(raybegin, rayend, false, true)
|
||||
local pointed_thing = ray:next()
|
||||
@ -84,19 +40,22 @@ local brush_on_use = function(itemstack, placer)
|
||||
worldedit.pos1[name] = pointed_thing.under
|
||||
worldedit.pos2[name] = nil
|
||||
worldedit.mark_region(name)
|
||||
-- is this a horrible hack? oh yes.
|
||||
worldedit._override_safe_regions = true
|
||||
|
||||
-- this isn't really clean...
|
||||
local player_notify_old = worldedit.player_notify
|
||||
worldedit.player_notify = function(name, msg)
|
||||
if string.match(msg, "^%d") then return end -- discard "1234 nodes added."
|
||||
return player_notify_old(name, msg)
|
||||
end
|
||||
|
||||
assert(cmddef.require_pos < 2)
|
||||
local parsed = {cmddef.parse(meta:get_string("params"))}
|
||||
if not table.remove(parsed, 1) then return false end -- shouldn't happen
|
||||
|
||||
minetest.log("action", string.format("%s uses WorldEdit brush (//%s) at %s",
|
||||
name, cmd, minetest.pos_to_string(pointed_thing.under)))
|
||||
cmddef.func(name, meta:get_string("params"))
|
||||
cmddef.func(name, unpack(parsed))
|
||||
|
||||
worldedit._override_safe_regions = false
|
||||
worldedit.player_notify = player_notify_old
|
||||
return true
|
||||
end
|
||||
@ -112,21 +71,22 @@ minetest.register_tool(":worldedit:brush", {
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("/brush", {
|
||||
worldedit.register_command("brush", {
|
||||
privs = {worldedit=true},
|
||||
params = "none/<cmd> [parameters]",
|
||||
description = "Assign command to WorldEdit brush item",
|
||||
func = function(name, param)
|
||||
parse = function(param)
|
||||
local found, _, cmd, params = param:find("^([^%s]+)%s+(.+)$")
|
||||
if not found then
|
||||
params = ""
|
||||
found, _, cmd = param:find("^(.+)$")
|
||||
end
|
||||
if not found then
|
||||
worldedit.player_notify(name, "Invalid usage.")
|
||||
return
|
||||
return false
|
||||
end
|
||||
|
||||
return true, cmd, params
|
||||
end,
|
||||
func = function(name, cmd, params)
|
||||
local itemstack = minetest.get_player_by_name(name):get_wielded_item()
|
||||
if itemstack == nil or itemstack:get_name() ~= "worldedit:brush" then
|
||||
worldedit.player_notify(name, "Not holding brush item.")
|
||||
@ -139,16 +99,20 @@ minetest.register_chatcommand("/brush", {
|
||||
meta:from_table(nil)
|
||||
worldedit.player_notify(name, "Brush assignment cleared.")
|
||||
else
|
||||
local cmddef
|
||||
if table.indexof(BRUSH_ALLOWED_COMMANDS, cmd) ~= -1 then
|
||||
cmddef = minetest.registered_chatcommands["/" .. cmd]
|
||||
else
|
||||
cmddef = nil
|
||||
end
|
||||
if cmddef == nil then
|
||||
local cmddef = worldedit.registered_commands[cmd]
|
||||
if cmddef == nil or cmddef.require_pos ~= 1 then
|
||||
worldedit.player_notify(name, "Invalid command for brush use: //" .. cmd)
|
||||
return
|
||||
end
|
||||
|
||||
-- Try parsing command params so we can give the user feedback
|
||||
local ok, err = cmddef.parse(params)
|
||||
if not ok then
|
||||
err = err or "invalid usage"
|
||||
worldedit.player_notify(name, "Brush command: " .. err)
|
||||
return
|
||||
end
|
||||
|
||||
meta:set_string("command", cmd)
|
||||
meta:set_string("params", params)
|
||||
local fullcmd = "//" .. cmd .. " " .. params
|
||||
|
3
worldedit_brush/mod.conf
Normal file
3
worldedit_brush/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = worldedit_brush
|
||||
description = WorldEdit brush
|
||||
depends = worldedit, worldedit_commands
|
@ -1,28 +1,22 @@
|
||||
minetest.register_chatcommand("/outset", {
|
||||
worldedit.register_command("outset", {
|
||||
params = "[h|v] <amount>",
|
||||
description = "outset the selection",
|
||||
description = "Outset the selected region.",
|
||||
privs = {worldedit=true},
|
||||
func = function(name, param)
|
||||
require_pos = 2,
|
||||
parse = function(param)
|
||||
local find, _, dir, amount = param:find("(%a*)%s*([+-]?%d+)")
|
||||
|
||||
if find == nil then
|
||||
return false, "invalid usage: " .. param
|
||||
return false
|
||||
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
|
||||
|
||||
|
||||
return true, dir, tonumber(amount)
|
||||
end,
|
||||
func = function(name, dir, amount)
|
||||
if dir == "" or dir == "hv" or dir == "vh" then
|
||||
assert(worldedit.cuboid_volumetric_expand(name, amount))
|
||||
elseif dir == "h" then
|
||||
@ -36,39 +30,32 @@ minetest.register_chatcommand("/outset", {
|
||||
else
|
||||
return false, "Invalid number of arguments"
|
||||
end
|
||||
|
||||
|
||||
worldedit.marker_update(name)
|
||||
return true, "Region outset by " .. amount .. " blocks"
|
||||
end,
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("/inset", {
|
||||
worldedit.register_command("inset", {
|
||||
params = "[h|v] <amount>",
|
||||
description = "inset the selection",
|
||||
description = "Inset the selected region.",
|
||||
privs = {worldedit=true},
|
||||
func = function(name, param)
|
||||
require_pos = 2,
|
||||
parse = function(param)
|
||||
local find, _, dir, amount = param:find("(%a*)%s*([+-]?%d+)")
|
||||
|
||||
if find == nil then
|
||||
return false, "invalid usage: " .. param
|
||||
return false
|
||||
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
|
||||
|
||||
|
||||
return true, dir, tonumber(amount)
|
||||
end,
|
||||
func = function(name, dir, amount)
|
||||
if dir == "" or dir == "vh" or dir == "hv" then
|
||||
assert(worldedit.cuboid_volumetric_expand(name, -amount))
|
||||
elseif dir == "h" then
|
||||
@ -82,34 +69,27 @@ minetest.register_chatcommand("/inset", {
|
||||
else
|
||||
return false, "Invalid number of arguments"
|
||||
end
|
||||
|
||||
|
||||
worldedit.marker_update(name)
|
||||
return true, "Region inset by " .. amount .. " blocks"
|
||||
end,
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("/shift", {
|
||||
worldedit.register_command("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]
|
||||
require_pos = 2,
|
||||
parse = function(param)
|
||||
local find, _, direction, amount = param:find("([%?%l]+)%s*([+-]?%d+)")
|
||||
|
||||
if find == nil then
|
||||
worldedit.player_notify(name, "invalid usage: " .. param)
|
||||
return
|
||||
return false
|
||||
end
|
||||
|
||||
if pos1 == nil or pos2 == nil then
|
||||
worldedit.player_notify(name,
|
||||
"Undefined region. Region must be defined beforehand.")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
return true, direction, tonumber(amount)
|
||||
end,
|
||||
func = function(name, direction, amount)
|
||||
local axis, dir
|
||||
if direction == "x" or direction == "y" or direction == "z" then
|
||||
axis, dir = direction, 1
|
||||
@ -118,123 +98,112 @@ minetest.register_chatcommand("/shift", {
|
||||
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", {
|
||||
worldedit.register_command("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"
|
||||
require_pos = 2,
|
||||
parse = function(param)
|
||||
local find, _, sign, direction, amount,
|
||||
rev_amount = param:find("([+-]?)([%?%l]+)%s*(%d+)%s*(%d*)")
|
||||
if find == nil then
|
||||
return false
|
||||
end
|
||||
else
|
||||
if direction == "?" then
|
||||
axis, dir = worldedit.player_axis(name)
|
||||
|
||||
if rev_amount == "" then
|
||||
rev_amount = "0"
|
||||
end
|
||||
|
||||
return true, sign, direction, tonumber(amount), tonumber(rev_amount)
|
||||
end,
|
||||
func = function(name, sign, direction, amount, rev_amount)
|
||||
local absolute = direction:find("[xyz?]")
|
||||
local dir, axis
|
||||
|
||||
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
|
||||
axis = direction
|
||||
dir = 1
|
||||
if direction == "?" then
|
||||
axis, dir = worldedit.player_axis(name)
|
||||
else
|
||||
axis = direction
|
||||
dir = 1
|
||||
end
|
||||
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,
|
||||
}
|
||||
)
|
||||
|
||||
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", {
|
||||
worldedit.register_command("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"
|
||||
require_pos = 2,
|
||||
parse = function(param)
|
||||
local find, _, sign, direction, amount,
|
||||
rev_amount = param:find("([+-]?)([%?%l]+)%s*(%d+)%s*(%d*)")
|
||||
if find == nil then
|
||||
return false
|
||||
end
|
||||
else
|
||||
if direction == "?" then
|
||||
axis, dir = worldedit.player_axis(name)
|
||||
|
||||
if rev_amount == "" then
|
||||
rev_amount = "0"
|
||||
end
|
||||
|
||||
return true, sign, direction, tonumber(amount), tonumber(rev_amount)
|
||||
end,
|
||||
func = function(name, sign, direction, amount, rev_amount)
|
||||
local absolute = direction:find("[xyz?]")
|
||||
local dir, axis
|
||||
|
||||
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
|
||||
axis = direction
|
||||
dir = 1
|
||||
if direction == "?" then
|
||||
axis, dir = worldedit.player_axis(name)
|
||||
else
|
||||
axis = direction
|
||||
dir = 1
|
||||
end
|
||||
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,
|
||||
}
|
||||
)
|
||||
|
||||
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,
|
||||
})
|
||||
|
@ -1 +0,0 @@
|
||||
worldedit
|
File diff suppressed because it is too large
Load Diff
@ -64,7 +64,7 @@ worldedit.mark_region = function(name)
|
||||
|
||||
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
|
||||
local limit = tonumber(minetest.settings: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
|
||||
@ -101,7 +101,7 @@ worldedit.mark_region = function(name)
|
||||
visual_size={x=sizez * 2, y=sizey * 2},
|
||||
collisionbox = {-thickness, -sizey, -sizez, thickness, sizey, sizez},
|
||||
})
|
||||
marker:setyaw(math.pi / 2)
|
||||
marker:set_yaw(math.pi / 2)
|
||||
marker:get_luaentity().player_name = name
|
||||
table.insert(markers, marker)
|
||||
end
|
||||
@ -156,7 +156,6 @@ minetest.register_entity(":worldedit:pos2", {
|
||||
minetest.register_entity(":worldedit:region_cube", {
|
||||
initial_properties = {
|
||||
visual = "upright_sprite",
|
||||
visual_size = {x=1.1, y=1.1},
|
||||
textures = {"worldedit_cube.png"},
|
||||
visual_size = {x=10, y=10},
|
||||
physical = false,
|
||||
|
3
worldedit_commands/mod.conf
Normal file
3
worldedit_commands/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = worldedit_commands
|
||||
description = WorldEdit chat commands
|
||||
depends = worldedit
|
@ -1,53 +1,33 @@
|
||||
local safe_region_callback = {}
|
||||
local safe_region_param = {}
|
||||
|
||||
worldedit._override_safe_regions = false -- internal use ONLY!
|
||||
|
||||
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")
|
||||
return nil
|
||||
end
|
||||
return worldedit.volume(pos1, pos2)
|
||||
end
|
||||
|
||||
--`count` is the number of nodes that would possibly be modified
|
||||
--`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
|
||||
local function safe_region(callback, nodes_needed)
|
||||
--default node volume calculation
|
||||
nodes_needed = nodes_needed or check_region
|
||||
|
||||
return function(name, param)
|
||||
--check if the operation applies to a safe number of nodes
|
||||
local count = nodes_needed(name, param)
|
||||
if count == nil then return end --invalid command
|
||||
if worldedit._override_safe_regions or count < 10000 then
|
||||
return callback(name, param)
|
||||
end
|
||||
|
||||
--save callback to call later
|
||||
safe_region_callback[name], safe_region_param[name] = callback, param
|
||||
worldedit.player_notify(name, "WARNING: this operation could affect up to " .. count .. " nodes; type //y to continue or //n to cancel")
|
||||
local function safe_region(name, count, callback)
|
||||
if count < 10000 then
|
||||
return callback()
|
||||
end
|
||||
|
||||
--save callback to call later
|
||||
safe_region_callback[name] = callback
|
||||
worldedit.player_notify(name, "WARNING: this operation could affect up to " .. count .. " nodes; type //y to continue or //n to cancel")
|
||||
end
|
||||
|
||||
local function reset_pending(name)
|
||||
safe_region_callback[name], safe_region_param[name] = nil, nil
|
||||
safe_region_callback[name] = nil
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("/y", {
|
||||
params = "",
|
||||
description = "Confirm a pending operation",
|
||||
func = function(name)
|
||||
local callback, param = safe_region_callback[name], safe_region_param[name]
|
||||
local callback = safe_region_callback[name]
|
||||
if not callback then
|
||||
worldedit.player_notify(name, "no operation pending")
|
||||
return
|
||||
end
|
||||
|
||||
reset_pending(name)
|
||||
callback(name, param)
|
||||
callback(name)
|
||||
end,
|
||||
})
|
||||
|
||||
@ -65,4 +45,4 @@ minetest.register_chatcommand("/n", {
|
||||
})
|
||||
|
||||
|
||||
return safe_region, check_region, reset_pending
|
||||
return safe_region, reset_pending
|
||||
|
@ -6,25 +6,58 @@ local function above_or_under(placer, pointed_thing)
|
||||
end
|
||||
end
|
||||
|
||||
local punched_air_time = {}
|
||||
|
||||
minetest.register_tool(":worldedit:wand", {
|
||||
description = "WorldEdit Wand tool, Left-click to set 1st position, right-click to set 2nd",
|
||||
description = "WorldEdit Wand tool\nLeft-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()
|
||||
if placer == nil or pointed_thing == nil then return end
|
||||
local name = placer:get_player_name()
|
||||
if pointed_thing.type == "node" then
|
||||
-- set and mark pos1
|
||||
worldedit.pos1[name] = above_or_under(placer, pointed_thing)
|
||||
worldedit.mark_pos1(name)
|
||||
elseif pointed_thing.type == "nothing" then
|
||||
local now = minetest.get_us_time()
|
||||
if now - (punched_air_time[name] or 0) < 1000 * 1000 then
|
||||
-- reset markers
|
||||
worldedit.registered_commands["reset"].func(name)
|
||||
end
|
||||
punched_air_time[name] = now
|
||||
elseif pointed_thing.type == "object" then
|
||||
local entity = pointed_thing.ref:get_luaentity()
|
||||
if entity and entity.name == "worldedit:pos2" then
|
||||
-- set pos1 = pos2
|
||||
worldedit.pos1[name] = worldedit.pos2[name]
|
||||
worldedit.mark_pos1(name)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
if placer == nil or (pointed_thing or {}).type ~= "node" then
|
||||
return itemstack
|
||||
end
|
||||
local name = placer:get_player_name()
|
||||
-- set and mark pos2
|
||||
worldedit.pos2[name] = above_or_under(placer, pointed_thing)
|
||||
worldedit.mark_pos2(name)
|
||||
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] = above_or_under(placer, pointed_thing)
|
||||
on_secondary_use = function(itemstack, user, pointed_thing)
|
||||
if user == nil or (pointed_thing or {}).type ~= "object" then
|
||||
return itemstack
|
||||
end
|
||||
local name = user:get_player_name()
|
||||
local entity = pointed_thing.ref:get_luaentity()
|
||||
if entity and entity.name == "worldedit:pos1" then
|
||||
-- set pos2 = pos1
|
||||
worldedit.pos2[name] = worldedit.pos1[name]
|
||||
worldedit.mark_pos2(name)
|
||||
end
|
||||
return itemstack -- nothing consumed, nothing changed
|
||||
|
@ -1,7 +0,0 @@
|
||||
worldedit
|
||||
worldedit_commands
|
||||
unified_inventory?
|
||||
inventory_plus?
|
||||
sfinv?
|
||||
creative?
|
||||
smart_inventory?
|
@ -52,13 +52,18 @@ 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)
|
||||
local ndef = nodename and minetest.registered_nodes[nodename]
|
||||
if nodename and ndef then
|
||||
return string.format("item_image[%s;1,1;%s]", pos, nodename) ..
|
||||
string.format("tooltip[%s;1,1;%s]", pos, minetest.formspec_escape(ndef.description))
|
||||
else
|
||||
return string.format("image[%s;1,1;worldedit_gui_unknown.png]", pos)
|
||||
end
|
||||
end
|
||||
|
||||
-- two further priv helpers
|
||||
local function we_privs(command)
|
||||
return minetest.chatcommands["/" .. command].privs
|
||||
return worldedit.registered_commands[command].privs
|
||||
end
|
||||
|
||||
local function combine_we_privs(list)
|
||||
@ -69,6 +74,64 @@ local function combine_we_privs(list)
|
||||
return combine_privs(unpack(args))
|
||||
end
|
||||
|
||||
-- functions that handle value changing & page reshowing (without submitting)
|
||||
local function copy_changes(name, fields, def)
|
||||
for field, into in pairs(def) do
|
||||
if into ~= true and fields[field] then
|
||||
local value = tostring(fields[field])
|
||||
if into == gui_axis1 or into == gui_axis2 then
|
||||
into[name] = axis_indices[value]
|
||||
elseif into == gui_angle then
|
||||
into[name] = angle_indices[value]
|
||||
else
|
||||
into[name] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_changes(name, identifier, fields, def)
|
||||
local any = false
|
||||
for field, into in pairs(def) do
|
||||
if fields.key_enter_field == field then
|
||||
any = true
|
||||
end
|
||||
-- first condition: buttons (value not saved)
|
||||
-- others: dropdowns which will be sent when their value changes
|
||||
if into == true or into == gui_axis1 or into == gui_axis2 or into == gui_angle then
|
||||
if fields[field] then
|
||||
any = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not any then
|
||||
return false
|
||||
end
|
||||
|
||||
any = false
|
||||
for field, into in pairs(def) do
|
||||
if into ~= true and fields[field] then
|
||||
local value = tostring(fields[field])
|
||||
if into == gui_axis1 or into == gui_axis2 then
|
||||
into[name] = axis_indices[value]
|
||||
elseif into == gui_angle then
|
||||
into[name] = angle_indices[value]
|
||||
else
|
||||
into[name] = value
|
||||
end
|
||||
|
||||
if into == gui_nodename1 or into == gui_nodename2 then
|
||||
any = true
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Only nodename fields change based on the value, so only re-show the page if necessary
|
||||
if any then
|
||||
worldedit.show_page(name, identifier)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_about", {
|
||||
name = "About",
|
||||
privs = {interact=true},
|
||||
@ -173,6 +236,7 @@ worldedit.register_gui_function("worldedit_gui_set", {
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_set_node;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_set_search;Search]" ..
|
||||
formspec_node("5.5,1.1", nodename) ..
|
||||
"button_exit[0,2.5;3,0.8;worldedit_gui_set_submit;Set Nodes]"
|
||||
@ -180,18 +244,22 @@ worldedit.register_gui_function("worldedit_gui_set", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_set", function(name, fields)
|
||||
if fields.worldedit_gui_set_search or fields.worldedit_gui_set_submit then
|
||||
gui_nodename1[name] = tostring(fields.worldedit_gui_set_node)
|
||||
local cg = {
|
||||
worldedit_gui_set_search = true,
|
||||
worldedit_gui_set_node = gui_nodename1,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_set", fields, cg)
|
||||
if fields.worldedit_gui_set_submit then
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_set")
|
||||
if fields.worldedit_gui_set_submit then
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
minetest.chatcommands["/set"].func(name, n)
|
||||
end
|
||||
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
minetest.chatcommands["/set"].func(name, n)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_replace", {
|
||||
@ -202,9 +270,11 @@ worldedit.register_gui_function("worldedit_gui_replace", {
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_replace_search;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_replace_search_search;Search]" ..
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_replace_replace;false]" ..
|
||||
"button[4,2.18;1.5,0.8;worldedit_gui_replace_replace_search;Search]" ..
|
||||
formspec_node("5.5,2.1", replace_nodename) ..
|
||||
"button_exit[0,3.5;3,0.8;worldedit_gui_replace_submit;Replace Nodes]" ..
|
||||
@ -213,28 +283,29 @@ worldedit.register_gui_function("worldedit_gui_replace", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_replace", function(name, fields)
|
||||
if fields.worldedit_gui_replace_search_search or fields.worldedit_gui_replace_replace_search
|
||||
or fields.worldedit_gui_replace_submit or fields.worldedit_gui_replace_submit_inverse then
|
||||
gui_nodename1[name] = tostring(fields.worldedit_gui_replace_search)
|
||||
gui_nodename2[name] = tostring(fields.worldedit_gui_replace_replace)
|
||||
local cg = {
|
||||
worldedit_gui_replace_search_search = true,
|
||||
worldedit_gui_replace_replace_search = true,
|
||||
worldedit_gui_replace_search = gui_nodename1,
|
||||
worldedit_gui_replace_replace = gui_nodename2,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_replace", fields, cg)
|
||||
if fields.worldedit_gui_replace_submit or fields.worldedit_gui_replace_submit_inverse then
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_replace")
|
||||
|
||||
local submit = nil
|
||||
if fields.worldedit_gui_replace_submit then
|
||||
submit = "replace"
|
||||
elseif fields.worldedit_gui_replace_submit_inverse then
|
||||
local submit = "replace"
|
||||
if fields.worldedit_gui_replace_submit_inverse then
|
||||
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
|
||||
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
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_sphere_dome", {
|
||||
@ -245,9 +316,11 @@ worldedit.register_gui_function("worldedit_gui_sphere_dome", {
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_sphere_dome_node;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_sphere_dome_search;Search]" ..
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_sphere_dome_radius;false]" ..
|
||||
"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]" ..
|
||||
"button_exit[0,4.5;3,0.8;worldedit_gui_sphere_dome_submit_hollow_dome;Hollow Dome]" ..
|
||||
@ -256,32 +329,32 @@ worldedit.register_gui_function("worldedit_gui_sphere_dome", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_sphere_dome", function(name, fields)
|
||||
if fields.worldedit_gui_sphere_dome_search
|
||||
or fields.worldedit_gui_sphere_dome_submit_hollow or fields.worldedit_gui_sphere_dome_submit_solid
|
||||
local cg = {
|
||||
worldedit_gui_sphere_dome_search = true,
|
||||
worldedit_gui_sphere_dome_node = gui_nodename1,
|
||||
worldedit_gui_sphere_dome_radius = gui_distance2,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_sphere_dome", fields, cg)
|
||||
if fields.worldedit_gui_sphere_dome_submit_hollow or fields.worldedit_gui_sphere_dome_submit_solid
|
||||
or fields.worldedit_gui_sphere_dome_submit_hollow_dome or fields.worldedit_gui_sphere_dome_submit_solid_dome then
|
||||
gui_nodename1[name] = tostring(fields.worldedit_gui_sphere_dome_node)
|
||||
gui_distance2[name] = tostring(fields.worldedit_gui_sphere_dome_radius)
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_sphere_dome")
|
||||
|
||||
local submit = nil
|
||||
if fields.worldedit_gui_sphere_dome_submit_hollow then
|
||||
submit = "hollowsphere"
|
||||
elseif fields.worldedit_gui_sphere_dome_submit_solid then
|
||||
local submit = "hollowsphere"
|
||||
if fields.worldedit_gui_sphere_dome_submit_solid then
|
||||
submit = "sphere"
|
||||
elseif fields.worldedit_gui_sphere_dome_submit_hollow_dome then
|
||||
submit = "hollowdome"
|
||||
elseif fields.worldedit_gui_sphere_dome_submit_solid_dome then
|
||||
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
|
||||
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
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_cylinder", {
|
||||
@ -293,12 +366,16 @@ worldedit.register_gui_function("worldedit_gui_cylinder", {
|
||||
local nodename = worldedit.normalize_nodename(node)
|
||||
return "size[6.5,6]" .. 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)) ..
|
||||
"field_close_on_enter[worldedit_gui_cylinder_node;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_cylinder_search;Search]" ..
|
||||
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;2,0.8;worldedit_gui_cylinder_radius1;Base Radius;%s]", minetest.formspec_escape(radius1)) ..
|
||||
string.format("field[2.5,3.5;2,0.8;worldedit_gui_cylinder_radius2;Top Radius;%s]", minetest.formspec_escape(radius2)) ..
|
||||
"field_close_on_enter[worldedit_gui_cylinder_length;false]" ..
|
||||
"field_close_on_enter[worldedit_gui_cylinder_radius1;false]" ..
|
||||
"field_close_on_enter[worldedit_gui_cylinder_radius2;false]" ..
|
||||
"label[0.25,4;Equal base and top radius creates a cylinder,\n"..
|
||||
"zero top radius creates a cone.\nConsult documentation for more information.]"..
|
||||
"button_exit[0,5.5;3,0.8;worldedit_gui_cylinder_submit_hollow;Hollow Cylinder]" ..
|
||||
@ -307,36 +384,31 @@ worldedit.register_gui_function("worldedit_gui_cylinder", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_cylinder", function(name, fields)
|
||||
if fields.worldedit_gui_cylinder_search
|
||||
or fields.worldedit_gui_cylinder_submit_hollow or fields.worldedit_gui_cylinder_submit_solid then
|
||||
gui_nodename1[name] = tostring(fields.worldedit_gui_cylinder_node)
|
||||
gui_axis1[name] = axis_indices[fields.worldedit_gui_cylinder_axis]
|
||||
gui_distance1[name] = tostring(fields.worldedit_gui_cylinder_length)
|
||||
gui_distance2[name] = tostring(fields.worldedit_gui_cylinder_radius1)
|
||||
gui_distance3[name] = tostring(fields.worldedit_gui_cylinder_radius2)
|
||||
local cg = {
|
||||
worldedit_gui_cylinder_search = true,
|
||||
worldedit_gui_cylinder_node = gui_nodename1,
|
||||
worldedit_gui_cylinder_axis = gui_axis1,
|
||||
worldedit_gui_cylinder_length = gui_distance1,
|
||||
worldedit_gui_cylinder_radius1 = gui_distance2,
|
||||
worldedit_gui_cylinder_radius2 = gui_distance3,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_cylinder", fields, cg)
|
||||
if fields.worldedit_gui_cylinder_submit_hollow or fields.worldedit_gui_cylinder_submit_solid then
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_cylinder")
|
||||
|
||||
local submit = nil
|
||||
if fields.worldedit_gui_cylinder_submit_hollow then
|
||||
submit = "hollowcylinder"
|
||||
elseif fields.worldedit_gui_cylinder_submit_solid then
|
||||
local submit = "hollowcylinder"
|
||||
if fields.worldedit_gui_cylinder_submit_solid then
|
||||
submit = "cylinder"
|
||||
end
|
||||
if submit then
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
local args = string.format("%s %s %s %s %s", axis_values[gui_axis1[name]], gui_distance1[name], gui_distance2[name], gui_distance3[name], n)
|
||||
minetest.chatcommands["/"..submit].func(name, args)
|
||||
end
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
local args = string.format("%s %s %s %s %s", axis_values[gui_axis1[name]], gui_distance1[name], gui_distance2[name], gui_distance3[name], n)
|
||||
minetest.chatcommands["/"..submit].func(name, args)
|
||||
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
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_pyramid", {
|
||||
@ -347,42 +419,40 @@ worldedit.register_gui_function("worldedit_gui_pyramid", {
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_pyramid_node;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_pyramid_search;Search]" ..
|
||||
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) ..
|
||||
"field_close_on_enter[worldedit_gui_pyramid_length;false]" ..
|
||||
"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_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)
|
||||
local cg = {
|
||||
worldedit_gui_pyramid_search = true,
|
||||
worldedit_gui_pyramid_node = gui_nodename1,
|
||||
worldedit_gui_pyramid_axis = gui_axis1,
|
||||
worldedit_gui_pyramid_length = gui_distance1,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_pyramid", fields, cg)
|
||||
if fields.worldedit_gui_pyramid_submit_solid or fields.worldedit_gui_pyramid_submit_hollow then
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_pyramid")
|
||||
|
||||
local submit = nil
|
||||
if fields.worldedit_gui_pyramid_submit_solid then
|
||||
submit = "pyramid"
|
||||
elseif fields.worldedit_gui_pyramid_submit_hollow then
|
||||
local submit = "pyramid"
|
||||
if 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
|
||||
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
|
||||
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
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_spiral", {
|
||||
@ -393,31 +463,39 @@ worldedit.register_gui_function("worldedit_gui_spiral", {
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_spiral_node;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_spiral_search;Search]" ..
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_spiral_length;false]" ..
|
||||
"field_close_on_enter[worldedit_gui_spiral_height;false]" ..
|
||||
"field_close_on_enter[worldedit_gui_spiral_space;false]" ..
|
||||
"button_exit[0,5.5;3,0.8;worldedit_gui_spiral_submit;Spiral]"
|
||||
end,
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_spiral", function(name, fields)
|
||||
if fields.worldedit_gui_spiral_search or fields.worldedit_gui_spiral_submit then
|
||||
gui_nodename1[name] = fields.worldedit_gui_spiral_node
|
||||
gui_distance1[name] = tostring(fields.worldedit_gui_spiral_length)
|
||||
gui_distance2[name] = tostring(fields.worldedit_gui_spiral_height)
|
||||
gui_distance3[name] = tostring(fields.worldedit_gui_spiral_space)
|
||||
local cg = {
|
||||
worldedit_gui_spiral_search = true,
|
||||
worldedit_gui_spiral_node = gui_nodename1,
|
||||
worldedit_gui_spiral_length = gui_distance1,
|
||||
worldedit_gui_spiral_height = gui_distance2,
|
||||
worldedit_gui_spiral_space = gui_distance3,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_spiral", fields, cg)
|
||||
if fields.worldedit_gui_spiral_submit then
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_spiral")
|
||||
if fields.worldedit_gui_spiral_submit then
|
||||
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
|
||||
|
||||
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
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_copy_move", {
|
||||
@ -429,29 +507,30 @@ worldedit.register_gui_function("worldedit_gui_copy_move", {
|
||||
return "size[6.5,3]" .. worldedit.get_formspec_header("worldedit_gui_copy_move") ..
|
||||
string.format("field[0.5,1.5;4,0.8;worldedit_gui_copy_move_amount;Amount;%s]", minetest.formspec_escape(amount)) ..
|
||||
string.format("dropdown[4,1.18;2.5;worldedit_gui_copy_move_axis;X axis,Y axis,Z axis,Look direction;%d]", axis) ..
|
||||
"field_close_on_enter[worldedit_gui_copy_move_amount;false]" ..
|
||||
"button_exit[0,2.5;3,0.8;worldedit_gui_copy_move_copy;Copy Region]" ..
|
||||
"button_exit[3.5,2.5;3,0.8;worldedit_gui_copy_move_move;Move Region]"
|
||||
end,
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_copy_move", function(name, fields)
|
||||
local cg = {
|
||||
worldedit_gui_copy_move_amount = gui_distance1,
|
||||
worldedit_gui_copy_move_axis = gui_axis1,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_spiral", fields, cg)
|
||||
if fields.worldedit_gui_copy_move_copy or fields.worldedit_gui_copy_move_move then
|
||||
gui_axis1[name] = axis_indices[fields.worldedit_gui_copy_move_axis] or 4
|
||||
gui_distance1[name] = tostring(fields.worldedit_gui_copy_move_amount)
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_copy_move")
|
||||
if fields.worldedit_gui_copy_move_copy then
|
||||
minetest.chatcommands["/copy"].func(name, string.format("%s %s", axis_values[gui_axis1[name]], gui_distance1[name]))
|
||||
else --fields.worldedit_gui_copy_move_move
|
||||
minetest.chatcommands["/move"].func(name, string.format("%s %s", axis_values[gui_axis1[name]], gui_distance1[name]))
|
||||
|
||||
local submit = "copy"
|
||||
if fields.worldedit_gui_copy_move_move then
|
||||
submit = "move"
|
||||
end
|
||||
minetest.chatcommands["/"..submit].func(name, string.format("%s %s", axis_values[gui_axis1[name]], gui_distance1[name]))
|
||||
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
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_stack", {
|
||||
@ -462,24 +541,25 @@ worldedit.register_gui_function("worldedit_gui_stack", {
|
||||
return "size[6.5,3]" .. worldedit.get_formspec_header("worldedit_gui_stack") ..
|
||||
string.format("field[0.5,1.5;4,0.8;worldedit_gui_stack_count;Count;%s]", minetest.formspec_escape(count)) ..
|
||||
string.format("dropdown[4,1.18;2.5;worldedit_gui_stack_axis;X axis,Y axis,Z axis,Look direction;%d]", axis) ..
|
||||
"field_close_on_enter[worldedit_gui_stack_count;false]" ..
|
||||
"button_exit[0,2.5;3,0.8;worldedit_gui_stack_submit;Stack]"
|
||||
end,
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_stack", function(name, fields)
|
||||
local cg = {
|
||||
worldedit_gui_stack_axis = gui_axis1,
|
||||
worldedit_gui_stack_count = gui_count1,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_stack", fields, cg)
|
||||
if fields.worldedit_gui_stack_submit then
|
||||
gui_axis1[name] = axis_indices[fields.worldedit_gui_stack_axis]
|
||||
gui_count1[name] = tostring(fields.worldedit_gui_stack_count)
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_stack")
|
||||
|
||||
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
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_stretch", {
|
||||
@ -491,20 +571,28 @@ worldedit.register_gui_function("worldedit_gui_stretch", {
|
||||
string.format("field[0.5,1.5;4,0.8;worldedit_gui_stretch_x;Stretch X;%s]", minetest.formspec_escape(stretchx)) ..
|
||||
string.format("field[0.5,2.5;4,0.8;worldedit_gui_stretch_y;Stretch Y;%s]", minetest.formspec_escape(stretchy)) ..
|
||||
string.format("field[0.5,3.5;4,0.8;worldedit_gui_stretch_z;Stretch Z;%s]", minetest.formspec_escape(stretchz)) ..
|
||||
"field_close_on_enter[worldedit_gui_stretch_x;false]" ..
|
||||
"field_close_on_enter[worldedit_gui_stretch_y;false]" ..
|
||||
"field_close_on_enter[worldedit_gui_stretch_z;false]" ..
|
||||
"button_exit[0,4.5;3,0.8;worldedit_gui_stretch_submit;Stretch]"
|
||||
end,
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_stretch", function(name, fields)
|
||||
local cg = {
|
||||
worldedit_gui_stretch_x = gui_count1,
|
||||
worldedit_gui_stretch_y = gui_count2,
|
||||
worldedit_gui_stretch_z = gui_count3,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_stretch", fields, cg)
|
||||
if fields.worldedit_gui_stretch_submit then
|
||||
gui_count1[name] = tostring(fields.worldedit_gui_stretch_x)
|
||||
gui_count2[name] = tostring(fields.worldedit_gui_stretch_y)
|
||||
gui_count3[name] = tostring(fields.worldedit_gui_stretch_z)
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_stretch")
|
||||
|
||||
minetest.chatcommands["/stretch"].func(name, string.format("%s %s %s", gui_count1[name], gui_count2[name], gui_count3[name]))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_transpose", {
|
||||
@ -520,23 +608,18 @@ worldedit.register_gui_function("worldedit_gui_transpose", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_transpose", function(name, fields)
|
||||
local cg = {
|
||||
worldedit_gui_transpose_axis1 = gui_axis1,
|
||||
worldedit_gui_transpose_axis2 = gui_axis2,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_transpose", fields, cg)
|
||||
if fields.worldedit_gui_transpose_submit then
|
||||
gui_axis1[name] = axis_indices[fields.worldedit_gui_transpose_axis1]
|
||||
worldedit.show_page(name, "worldedit_gui_transpose")
|
||||
copy_changes(name, fields, cg)
|
||||
|
||||
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
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_flip", {
|
||||
@ -551,18 +634,18 @@ worldedit.register_gui_function("worldedit_gui_flip", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_flip", function(name, fields)
|
||||
local cg = {
|
||||
worldedit_gui_flip_axis = gui_axis1
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_flip", fields, cg)
|
||||
if fields.worldedit_gui_flip_submit then
|
||||
gui_axis1[name] = axis_indices[fields.worldedit_gui_flip_axis]
|
||||
copy_changes(name, fields, cg)
|
||||
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")
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_rotate", {
|
||||
@ -578,24 +661,19 @@ worldedit.register_gui_function("worldedit_gui_rotate", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_rotate", function(name, fields)
|
||||
local cg = {
|
||||
worldedit_gui_rotate_axis = gui_axis1,
|
||||
worldedit_gui_rotate_angle = gui_angle,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_rotate", fields, cg)
|
||||
if fields.worldedit_gui_rotate_submit then
|
||||
gui_axis1[name] = axis_indices[fields.worldedit_gui_rotate_axis]
|
||||
gui_angle[name] = angle_indices[fields.worldedit_gui_rotate_angle]
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_rotate")
|
||||
|
||||
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
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_orient", {
|
||||
@ -610,18 +688,18 @@ worldedit.register_gui_function("worldedit_gui_orient", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_orient", function(name, fields)
|
||||
local cg = {
|
||||
worldedit_gui_orient_angle = gui_angle,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_orient", fields, cg)
|
||||
if fields.worldedit_gui_orient_submit then
|
||||
gui_angle[name] = angle_indices[fields.worldedit_gui_orient_angle]
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_orient")
|
||||
|
||||
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
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_fixlight", {
|
||||
@ -648,6 +726,7 @@ worldedit.register_gui_function("worldedit_gui_suppress", {
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_suppress_node;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_suppress_search;Search]" ..
|
||||
formspec_node("5.5,1.1", nodename) ..
|
||||
"button_exit[0,2.5;3,0.8;worldedit_gui_suppress_submit;Suppress Nodes]"
|
||||
@ -655,18 +734,22 @@ worldedit.register_gui_function("worldedit_gui_suppress", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_suppress", function(name, fields)
|
||||
if fields.worldedit_gui_suppress_search or fields.worldedit_gui_suppress_submit then
|
||||
gui_nodename1[name] = tostring(fields.worldedit_gui_suppress_node)
|
||||
local cg = {
|
||||
worldedit_gui_suppress_search = true,
|
||||
worldedit_gui_suppress_node = gui_nodename1,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_suppress", fields, cg)
|
||||
if fields.worldedit_gui_suppress_submit then
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_suppress")
|
||||
if fields.worldedit_gui_suppress_submit then
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
minetest.chatcommands["/suppress"].func(name, n)
|
||||
end
|
||||
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
minetest.chatcommands["/suppress"].func(name, n)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_highlight", {
|
||||
@ -677,6 +760,7 @@ worldedit.register_gui_function("worldedit_gui_highlight", {
|
||||
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)) ..
|
||||
"field_close_on_enter[worldedit_gui_highlight_node;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_highlight_search;Search]" ..
|
||||
formspec_node("5.5,1.1", nodename) ..
|
||||
"button_exit[0,2.5;3,0.8;worldedit_gui_highlight_submit;Highlight Nodes]"
|
||||
@ -684,18 +768,22 @@ worldedit.register_gui_function("worldedit_gui_highlight", {
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_highlight", function(name, fields)
|
||||
if fields.worldedit_gui_highlight_search or fields.worldedit_gui_highlight_submit then
|
||||
gui_nodename1[name] = tostring(fields.worldedit_gui_highlight_node)
|
||||
local cg = {
|
||||
worldedit_gui_highlight_search = true,
|
||||
worldedit_gui_highlight_node = gui_nodename1,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_highlight", fields, cg)
|
||||
if fields.worldedit_gui_highlight_submit then
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_highlight")
|
||||
if fields.worldedit_gui_highlight_submit then
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
minetest.chatcommands["/highlight"].func(name, n)
|
||||
end
|
||||
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
minetest.chatcommands["/highlight"].func(name, n)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_restore", {
|
||||
@ -713,6 +801,7 @@ worldedit.register_gui_function("worldedit_gui_save_load", {
|
||||
local filename = gui_filename[name]
|
||||
return "size[6,4]" .. worldedit.get_formspec_header("worldedit_gui_save_load") ..
|
||||
string.format("field[0.5,1.5;4,0.8;worldedit_gui_save_filename;Filename;%s]", minetest.formspec_escape(filename)) ..
|
||||
"field_close_on_enter[worldedit_gui_save_filename;false]" ..
|
||||
"button_exit[0,2.5;3,0.8;worldedit_gui_save_load_submit_save;Save]" ..
|
||||
"button_exit[3,2.5;3,0.8;worldedit_gui_save_load_submit_allocate;Allocate]" ..
|
||||
"button_exit[0,3.5;3,0.8;worldedit_gui_save_load_submit_load;Load]"
|
||||
@ -723,6 +812,7 @@ 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])
|
||||
elseif fields.worldedit_gui_save_load_submit_allocate then
|
||||
@ -736,7 +826,7 @@ worldedit.register_gui_handler("worldedit_gui_save_load", function(name, fields)
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_cube", {
|
||||
name = "Cuboid", -- technically the command is misnamed, I know...
|
||||
name = "Cube",
|
||||
privs = combine_we_privs({"hollowcube", "cube"}),
|
||||
get_formspec = function(name)
|
||||
local width, height, length = gui_distance1[name], gui_distance2[name], gui_distance3[name]
|
||||
@ -744,41 +834,45 @@ worldedit.register_gui_function("worldedit_gui_cube", {
|
||||
local nodename = worldedit.normalize_nodename(node)
|
||||
return "size[6.5,4]" .. worldedit.get_formspec_header("worldedit_gui_cube") ..
|
||||
string.format("field[0.5,1.5;4,0.8;worldedit_gui_cube_node;Name;%s]", minetest.formspec_escape(node)) ..
|
||||
"field_close_on_enter[worldedit_gui_cube_node;false]" ..
|
||||
"button[4,1.18;1.5,0.8;worldedit_gui_cube_search;Search]" ..
|
||||
formspec_node("5.5,1.1", nodename) ..
|
||||
string.format("field[0.5,2.5;1,0.8;worldedit_gui_cube_width;Width;%s]", minetest.formspec_escape(width)) ..
|
||||
string.format("field[1.5,2.5;1,0.8;worldedit_gui_cube_height;Height;%s]", minetest.formspec_escape(height)) ..
|
||||
string.format("field[2.5,2.5;1,0.8;worldedit_gui_cube_length;Length;%s]", minetest.formspec_escape(length)) ..
|
||||
"field_close_on_enter[worldedit_gui_cube_width;false]" ..
|
||||
"field_close_on_enter[worldedit_gui_cube_height;false]" ..
|
||||
"field_close_on_enter[worldedit_gui_cube_length;false]" ..
|
||||
"button_exit[0,3.5;3,0.8;worldedit_gui_cube_submit_hollow;Hollow Cuboid]" ..
|
||||
"button_exit[3.5,3.5;3,0.8;worldedit_gui_cube_submit_solid;Solid Cuboid]"
|
||||
end,
|
||||
})
|
||||
|
||||
worldedit.register_gui_handler("worldedit_gui_cube", function(name, fields)
|
||||
if fields.worldedit_gui_cube_search
|
||||
or fields.worldedit_gui_cube_submit_hollow or fields.worldedit_gui_cube_submit_solid then
|
||||
gui_nodename1[name] = tostring(fields.worldedit_gui_cube_node)
|
||||
gui_distance1[name] = tostring(fields.worldedit_gui_cube_width)
|
||||
gui_distance2[name] = tostring(fields.worldedit_gui_cube_height)
|
||||
gui_distance3[name] = tostring(fields.worldedit_gui_cube_length)
|
||||
local cg = {
|
||||
worldedit_gui_cube_search = true,
|
||||
worldedit_gui_cube_node = gui_nodename1,
|
||||
worldedit_gui_cube_width = gui_distance1,
|
||||
worldedit_gui_cube_height = gui_distance2,
|
||||
worldedit_gui_cube_length = gui_distance3,
|
||||
}
|
||||
local ret = handle_changes(name, "worldedit_gui_cube", fields, cg)
|
||||
if fields.worldedit_gui_cube_submit_hollow or fields.worldedit_gui_cube_submit_solid then
|
||||
copy_changes(name, fields, cg)
|
||||
worldedit.show_page(name, "worldedit_gui_cube")
|
||||
|
||||
local submit = nil
|
||||
if fields.worldedit_gui_cube_submit_hollow then
|
||||
submit = "hollowcube"
|
||||
elseif fields.worldedit_gui_cube_submit_solid then
|
||||
local submit = "hollowcube"
|
||||
if fields.worldedit_gui_cube_submit_solid then
|
||||
submit = "cube"
|
||||
end
|
||||
if submit then
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
local args = string.format("%s %s %s %s", gui_distance1[name], gui_distance2[name], gui_distance3[name], n)
|
||||
minetest.chatcommands["/"..submit].func(name, args)
|
||||
end
|
||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||
if n then
|
||||
local args = string.format("%s %s %s %s", gui_distance1[name], gui_distance2[name], gui_distance3[name], n)
|
||||
minetest.chatcommands["/"..submit].func(name, args)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
return ret
|
||||
end)
|
||||
|
||||
worldedit.register_gui_function("worldedit_gui_clearobjects", {
|
||||
|
@ -70,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 rawget(_G, "unified_inventory") then --unified inventory installed
|
||||
if minetest.global_exists("unified_inventory") then -- unified inventory installed
|
||||
local old_func = worldedit.register_gui_function
|
||||
worldedit.register_gui_function = function(identifier, options)
|
||||
old_func(identifier, options)
|
||||
@ -103,7 +103,7 @@ if rawget(_G, "unified_inventory") then --unified inventory installed
|
||||
player:set_inventory_formspec(get_formspec(name, page))
|
||||
end
|
||||
end
|
||||
elseif rawget(_G, "inventory_plus") then --inventory++ installed
|
||||
elseif minetest.global_exists("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
|
||||
@ -134,7 +134,7 @@ elseif rawget(_G, "inventory_plus") then --inventory++ installed
|
||||
inventory_plus.set_inventory_formspec(player, get_formspec(name, page))
|
||||
end
|
||||
end
|
||||
elseif rawget(_G, "smart_inventory") then -- smart_inventory installed
|
||||
elseif minetest.global_exists("smart_inventory") then -- smart_inventory installed
|
||||
-- redefinition: Update the code element on inventory page to show the we-page
|
||||
function worldedit.show_page(name, page)
|
||||
local state = smart_inventory.get_page_state("worldedit_gui", name)
|
||||
@ -183,7 +183,7 @@ elseif rawget(_G, "smart_inventory") then -- smart_inventory installed
|
||||
smartfs_callback = smart_worldedit_gui_callback,
|
||||
sequence = 99
|
||||
})
|
||||
elseif rawget(_G, "sfinv") then --sfinv installed (part of minetest_game since 0.4.15)
|
||||
elseif minetest.global_exists("sfinv") then -- sfinv installed
|
||||
assert(sfinv.enabled)
|
||||
local orig_get = sfinv.pages["sfinv:crafting"].get
|
||||
sfinv.override_page("sfinv:crafting", {
|
||||
@ -194,21 +194,13 @@ elseif rawget(_G, "sfinv") then --sfinv installed (part of minetest_game since 0
|
||||
end
|
||||
})
|
||||
|
||||
--compatibility with pre-0.4.16 sfinv
|
||||
local set_page = sfinv.set_page or function(player, name)
|
||||
--assumptions: src pg has no leave callback, dst pg has no enter callback
|
||||
local ctx = {page=name}
|
||||
sfinv.contexts[player:get_player_name()] = ctx
|
||||
sfinv.set_player_inventory_formspec(player, ctx)
|
||||
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
|
||||
set_page(player, "sfinv:crafting")
|
||||
sfinv.set_page(player, "sfinv:crafting")
|
||||
return true
|
||||
end
|
||||
return false
|
||||
@ -222,11 +214,11 @@ elseif rawget(_G, "sfinv") then --sfinv installed (part of minetest_game since 0
|
||||
end
|
||||
else
|
||||
error(
|
||||
"worldedit_gui requires a supported \"gui management\" mod to be installed\n"..
|
||||
"To use the GUI you need to either\n"..
|
||||
"* Use minetest_game (at least 0.4.15) or a subgame with compatible sfinv\n"..
|
||||
"* Install Unified Inventory or Inventory++\n"..
|
||||
"If you do not want to use worldedit_gui, disable it by editing world.mt or from the Main Menu"
|
||||
"worldedit_gui requires a supported gui management mod to be installed.\n"..
|
||||
"To use the it you need to either:\n"..
|
||||
"* use minetest_game or another sfinv-compatible subgame\n"..
|
||||
"* install Unified Inventory, Inventory++ or Smart Inventory\n"..
|
||||
"If you don't want to use worldedit_gui, disable it by editing world.mt or from the main menu."
|
||||
)
|
||||
end
|
||||
|
||||
|
4
worldedit_gui/mod.conf
Normal file
4
worldedit_gui/mod.conf
Normal file
@ -0,0 +1,4 @@
|
||||
name = worldedit_gui
|
||||
description = WorldEdit GUI
|
||||
depends = worldedit, worldedit_commands
|
||||
optional_depends = unified_inventory, inventory_plus, sfinv, creative, smart_inventory
|
@ -1 +0,0 @@
|
||||
worldedit_commands
|
@ -1,52 +1,52 @@
|
||||
--provides shorter names for the commands in `worldedit_commands`
|
||||
|
||||
--returns true if command could not be aliased, false otherwise
|
||||
worldedit.alias_chatcommand = function(alias, original_command)
|
||||
if not minetest.chatcommands[original_command] then
|
||||
minetest.log("error", "worldedit_shortcommands: original command " .. original_command .. " does not exist")
|
||||
return true
|
||||
worldedit.alias_command = function(alias, original)
|
||||
if not worldedit.registered_commands[original] then
|
||||
minetest.log("error", "worldedit_shortcommands: original " .. original .. " does not exist")
|
||||
return
|
||||
end
|
||||
if minetest.chatcommands[alias] then
|
||||
if minetest.chatcommands["/" .. alias] then
|
||||
minetest.log("error", "worldedit_shortcommands: alias " .. alias .. " already exists")
|
||||
return true
|
||||
return
|
||||
end
|
||||
minetest.register_chatcommand(alias, minetest.chatcommands[original_command])
|
||||
return false
|
||||
|
||||
minetest.register_chatcommand("/" .. alias, minetest.chatcommands["/" .. original])
|
||||
worldedit.registered_commands[alias] = worldedit.registered_commands[original]
|
||||
end
|
||||
|
||||
worldedit.alias_chatcommand("/i", "/inspect")
|
||||
worldedit.alias_chatcommand("/rst", "/reset")
|
||||
worldedit.alias_chatcommand("/mk", "/mark")
|
||||
worldedit.alias_chatcommand("/umk", "/unmark")
|
||||
worldedit.alias_chatcommand("/1", "/pos1")
|
||||
worldedit.alias_chatcommand("/2", "/pos2")
|
||||
worldedit.alias_chatcommand("/fp", "/fixedpos")
|
||||
worldedit.alias_chatcommand("/v", "/volume")
|
||||
worldedit.alias_chatcommand("/s", "/set")
|
||||
worldedit.alias_chatcommand("/r", "/replace")
|
||||
worldedit.alias_chatcommand("/ri", "/replaceinverse")
|
||||
worldedit.alias_chatcommand("/hcube", "/hollowcube")
|
||||
worldedit.alias_chatcommand("/hspr", "/hollowsphere")
|
||||
worldedit.alias_chatcommand("/spr", "/sphere")
|
||||
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")
|
||||
worldedit.alias_chatcommand("/c", "/copy")
|
||||
worldedit.alias_chatcommand("/stk", "/stack")
|
||||
worldedit.alias_chatcommand("/sch", "/stretch")
|
||||
worldedit.alias_chatcommand("/tps", "/transpose")
|
||||
worldedit.alias_chatcommand("/fl", "/flip")
|
||||
worldedit.alias_chatcommand("/rot", "/rotate")
|
||||
worldedit.alias_chatcommand("/ort", "/orient")
|
||||
worldedit.alias_chatcommand("/hi", "/hide")
|
||||
worldedit.alias_chatcommand("/sup", "/suppress")
|
||||
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_command("i", "inspect")
|
||||
worldedit.alias_command("rst", "reset")
|
||||
worldedit.alias_command("mk", "mark")
|
||||
worldedit.alias_command("umk", "unmark")
|
||||
worldedit.alias_command("1", "pos1")
|
||||
worldedit.alias_command("2", "pos2")
|
||||
worldedit.alias_command("fp", "fixedpos")
|
||||
worldedit.alias_command("v", "volume")
|
||||
worldedit.alias_command("s", "set")
|
||||
worldedit.alias_command("r", "replace")
|
||||
worldedit.alias_command("ri", "replaceinverse")
|
||||
worldedit.alias_command("hcube", "hollowcube")
|
||||
worldedit.alias_command("hspr", "hollowsphere")
|
||||
worldedit.alias_command("spr", "sphere")
|
||||
worldedit.alias_command("hdo", "hollowdome")
|
||||
worldedit.alias_command("do", "dome")
|
||||
worldedit.alias_command("hcyl", "hollowcylinder")
|
||||
worldedit.alias_command("cyl", "cylinder")
|
||||
worldedit.alias_command("hpyr", "hollowpyramid")
|
||||
worldedit.alias_command("pyr", "pyramid")
|
||||
worldedit.alias_command("spl", "spiral")
|
||||
worldedit.alias_command("m", "move")
|
||||
worldedit.alias_command("c", "copy")
|
||||
worldedit.alias_command("stk", "stack")
|
||||
worldedit.alias_command("sch", "stretch")
|
||||
worldedit.alias_command("tps", "transpose")
|
||||
worldedit.alias_command("fl", "flip")
|
||||
worldedit.alias_command("rot", "rotate")
|
||||
worldedit.alias_command("ort", "orient")
|
||||
worldedit.alias_command("hi", "hide")
|
||||
worldedit.alias_command("sup", "suppress")
|
||||
worldedit.alias_command("hlt", "highlight")
|
||||
worldedit.alias_command("rsr", "restore")
|
||||
worldedit.alias_command("l", "lua")
|
||||
worldedit.alias_command("lt", "luatransform")
|
||||
worldedit.alias_command("clro", "clearobjects")
|
||||
|
3
worldedit_shortcommands/mod.conf
Normal file
3
worldedit_shortcommands/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = worldedit_shortcommands
|
||||
description = WorldEdit command short aliases
|
||||
depends = worldedit_commands
|
Reference in New Issue
Block a user