mirror of
https://github.com/Uberi/Minetest-WorldEdit.git
synced 2025-08-19 22:50:21 +02:00
Compare commits
17 Commits
116ae25ebd
...
2f535dd053
Author | SHA1 | Date | |
---|---|---|---|
2f535dd053 | |||
867cd6edc7 | |||
4918610c43 | |||
edd27636a6 | |||
7d0811fd47 | |||
4d08a1cc55 | |||
34844b2d38 | |||
0f5dcc790d | |||
37de177f72 | |||
f285a55dd5 | |||
9b26034aea | |||
963a9f6b96 | |||
5e8bfd5166 | |||
06a3b63578 | |||
5e47af8773 | |||
da51c688d2 | |||
ab93871877 |
140
ChatCommands.md
140
ChatCommands.md
@ -29,24 +29,26 @@ Many commands also have shorter names that can be typed faster. For example, if
|
|||||||
|
|
||||||
### `//about`
|
### `//about`
|
||||||
|
|
||||||
Get information about the mod.
|
Get information about the WorldEdit mod.
|
||||||
|
|
||||||
//about
|
//about
|
||||||
|
|
||||||
### `//inspect on/off/1/0/true/false/yes/no/enable/disable/<blank>`
|
### `//help [all/<cmd>]`
|
||||||
|
|
||||||
|
Get help for WorldEdit commands. `all` shows all WorldEdit commands, `<cmd>`
|
||||||
|
the help text for the given command.
|
||||||
|
|
||||||
|
//help
|
||||||
|
//help all
|
||||||
|
//help hollowpyramid
|
||||||
|
|
||||||
|
|
||||||
|
### `//inspect [on/off/1/0/true/false/yes/no/enable/disable]`
|
||||||
|
|
||||||
Enable or disable node inspection.
|
Enable or disable node inspection.
|
||||||
|
|
||||||
//inspect on
|
//inspect on
|
||||||
//inspect off
|
//inspect off
|
||||||
//inspect 1
|
|
||||||
//inspect 0
|
|
||||||
//inspect true
|
|
||||||
//inspect false
|
|
||||||
//inspect yes
|
|
||||||
//inspect no
|
|
||||||
//inspect enable
|
|
||||||
//inspect disable
|
|
||||||
//inspect
|
//inspect
|
||||||
|
|
||||||
### `//reset`
|
### `//reset`
|
||||||
@ -81,16 +83,17 @@ Set WorldEdit region position 2 to the player's location.
|
|||||||
|
|
||||||
### `//p set/set1/set2/get`
|
### `//p set/set1/set2/get`
|
||||||
|
|
||||||
Set WorldEdit region, WorldEdit position 1, or WorldEdit position 2 by punching nodes, or display the current WorldEdit region.
|
Set WorldEdit region, WorldEdit position 1, or WorldEdit position 2 by
|
||||||
|
punching nodes, or print the current WorldEdit region.
|
||||||
|
|
||||||
//p set
|
//p set
|
||||||
//p set1
|
//p set1
|
||||||
//p set2
|
//p set2
|
||||||
//p get
|
//p get
|
||||||
|
|
||||||
### `//fixedpos set1 x y z`
|
### `//fixedpos set1/set2 <x> <y> <z>`
|
||||||
|
|
||||||
Set a WorldEdit region position to the position at (`<x>`, `<y>`, `<z>`).
|
Set the WorldEdit region position 1 or 2 to the position (`<x>`, `<y>`, `<z>`).
|
||||||
|
|
||||||
//fixedpos set1 0 0 0
|
//fixedpos set1 0 0 0
|
||||||
//fixedpos set1 -30 5 28
|
//fixedpos set1 -30 5 28
|
||||||
@ -121,9 +124,12 @@ Set the current WorldEdit region to `<node>`.
|
|||||||
|
|
||||||
Set the param2 value of all nodes in the current WorldEdit region to `<param2>`.
|
Set the param2 value of all nodes in the current WorldEdit region to `<param2>`.
|
||||||
|
|
||||||
### `//mix <node1> [<count1>] <node2> [<count2>]...`
|
//param2 8
|
||||||
|
|
||||||
Fill the current WorldEdit region with a random mix of `<node1>`, `<node2>`, `...`. Weightings can be optionally specified via a number after a node name.
|
### `//mix <node1> [count1] <node2> [count2] ...`
|
||||||
|
|
||||||
|
Fill the current WorldEdit region with a random mix of `<node1>`, `<node2>`, `...`.
|
||||||
|
Weightings can be optionally specified via the `[count1]`, `[count2]`, `...` parameters after a node name.
|
||||||
|
|
||||||
//mix air
|
//mix air
|
||||||
//mix cactus stone glass sandstone
|
//mix cactus stone glass sandstone
|
||||||
@ -152,13 +158,15 @@ Replace all nodes other than `<search node>` with `<replace node>` in the curren
|
|||||||
|
|
||||||
### `//hollowcube <width> <height> <length> <node>`
|
### `//hollowcube <width> <height> <length> <node>`
|
||||||
|
|
||||||
Adds a hollow cube with its ground level centered at WorldEdit position 1 with dimensions `<width>` x `<height>` x `<length>`, composed of `<node>`.
|
Adds a hollow cube with its ground level centered at WorldEdit position 1 with
|
||||||
|
dimensions `<width>` x `<height>` x `<length>`, composed of `<node>`.
|
||||||
|
|
||||||
//hollowcube 6 5 6 Diamond Block
|
//hollowcube 6 5 6 Diamond Block
|
||||||
|
|
||||||
### `//cube <width> <height> <length> <node>`
|
### `//cube <width> <height> <length> <node>`
|
||||||
|
|
||||||
Adds a cube with its ground level centered at WorldEdit position 1 with dimensions `<width>` x `<height>` x `<length>`, composed of `<node>`.
|
Adds a cube with its ground level centered at WorldEdit position 1 with
|
||||||
|
dimensions `<width>` x `<height>` x `<length>`, composed of `<node>`.
|
||||||
|
|
||||||
//cube 6 5 6 Diamond Block
|
//cube 6 5 6 Diamond Block
|
||||||
//cube 7 2 1 default:cobble
|
//cube 7 2 1 default:cobble
|
||||||
@ -197,7 +205,8 @@ Add dome centered at WorldEdit position 1 with radius `<radius>`, composed of `<
|
|||||||
|
|
||||||
### `//hollowcylinder x/y/z/? <length> <radius1> [radius2] <node>`
|
### `//hollowcylinder x/y/z/? <length> <radius1> [radius2] <node>`
|
||||||
|
|
||||||
Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length `<length>`, base radius `<radius1>` (and top radius `[radius2]`), composed of `<node>`.
|
Add hollow cylinder at WorldEdit position 1 along the given axis with length `<length>`,
|
||||||
|
base radius `<radius1>` (and top radius `[radius2]`), composed of `<node>`.
|
||||||
|
|
||||||
Despite its name this command allows you to create cones (`radius2` = 0) as well as any shapes inbetween (0 < `radius2` < `radius1`).
|
Despite its name this command allows you to create cones (`radius2` = 0) as well as any shapes inbetween (0 < `radius2` < `radius1`).
|
||||||
Swapping `radius1` and `radius2` will create the same object but upside-down.
|
Swapping `radius1` and `radius2` will create the same object but upside-down.
|
||||||
@ -213,7 +222,8 @@ Swapping `radius1` and `radius2` will create the same object but upside-down.
|
|||||||
|
|
||||||
### `//cylinder x/y/z/? <length> <radius1> [radius2] <node>`
|
### `//cylinder x/y/z/? <length> <radius1> [radius2] <node>`
|
||||||
|
|
||||||
Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length `<length>`, base radius `<radius1>` (and top radius `[radius2]`), composed of `<node>`.
|
Add cylinder at WorldEdit position 1 along the given axis with length `<length>`,
|
||||||
|
base radius `<radius1>` (and top radius `[radius2]`), composed of `<node>`.
|
||||||
Can also create shapes other than cylinders, e.g. cones (see documentation above).
|
Can also create shapes other than cylinders, e.g. cones (see documentation above).
|
||||||
|
|
||||||
//cylinder x +5 8 Bronze Block
|
//cylinder x +5 8 Bronze Block
|
||||||
@ -225,18 +235,18 @@ Can also create shapes other than cylinders, e.g. cones (see documentation above
|
|||||||
//cylinder x 6 0 5 Dirt
|
//cylinder x 6 0 5 Dirt
|
||||||
//cylinder z 20 10 20 default:desert_stone
|
//cylinder z 20 10 20 default:desert_stone
|
||||||
|
|
||||||
### `//hollowpyramid x/y/z? <height> <node>`
|
### `//hollowpyramid x/y/z/? <height> <node>`
|
||||||
|
|
||||||
Add hollow pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height `<height>`, composed of `<node>`.
|
Add hollow pyramid centered at WorldEdit position 1 along the given axis with height `<height>` composed of `<node>`.
|
||||||
|
|
||||||
//hollowpyramid x 8 Diamond Block
|
//hollowpyramid x 8 Diamond Block
|
||||||
//hollowpyramid y -5 glass
|
//hollowpyramid y -5 glass
|
||||||
//hollowpyramid z 2 mesecons:wire_00000000_off
|
//hollowpyramid z 2 mesecons:wire_00000000_off
|
||||||
//hollowpyramid ? 12 mesecons:wire_00000000_off
|
//hollowpyramid ? 12 mesecons:wire_00000000_off
|
||||||
|
|
||||||
### `//pyramid x/y/z? <height> <node>`
|
### `//pyramid x/y/z/? <height> <node>`
|
||||||
|
|
||||||
Add pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height `<height>`, composed of `<node>`.
|
Add pyramid centered at WorldEdit position 1 along the given axis with height `<height>` composed of `<node>`.
|
||||||
|
|
||||||
//pyramid x 8 Diamond Block
|
//pyramid x 8 Diamond Block
|
||||||
//pyramid y -5 glass
|
//pyramid y -5 glass
|
||||||
@ -245,7 +255,8 @@ Add pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height
|
|||||||
|
|
||||||
### `//spiral <length> <height> <spacer> <node>`
|
### `//spiral <length> <height> <spacer> <node>`
|
||||||
|
|
||||||
Add spiral centered at WorldEdit position 1 with side length `<length>`, height `<height>`, space between walls `<spacer>`, composed of `<node>`.
|
Add spiral centered at WorldEdit position 1 with side length `<length>`,
|
||||||
|
height `<height>`, space between walls `<spacer>`, composed of `<node>`.
|
||||||
|
|
||||||
//spiral 20 5 3 Diamond Block
|
//spiral 20 5 3 Diamond Block
|
||||||
//spiral 5 2 1 glass
|
//spiral 5 2 1 glass
|
||||||
@ -253,7 +264,7 @@ Add spiral centered at WorldEdit position 1 with side length `<length>`, height
|
|||||||
|
|
||||||
### `//copy x/y/z/? <amount>`
|
### `//copy x/y/z/? <amount>`
|
||||||
|
|
||||||
Copy the current WorldEdit region along the x/y/z/? axis by `<amount>` nodes.
|
Copy the current WorldEdit region along the given axis by `<amount>` nodes.
|
||||||
|
|
||||||
//copy x 15
|
//copy x 15
|
||||||
//copy y -7
|
//copy y -7
|
||||||
@ -262,7 +273,7 @@ Copy the current WorldEdit region along the x/y/z/? axis by `<amount>` nodes.
|
|||||||
|
|
||||||
### `//move x/y/z/? <amount>`
|
### `//move x/y/z/? <amount>`
|
||||||
|
|
||||||
Move the current WorldEdit positions and region along the x/y/z/? axis by `<amount>` nodes.
|
Move the current WorldEdit positions and region along the given axis by `<amount>` nodes.
|
||||||
|
|
||||||
//move x 15
|
//move x 15
|
||||||
//move y -7
|
//move y -7
|
||||||
@ -271,7 +282,7 @@ Move the current WorldEdit positions and region along the x/y/z/? axis by `<amou
|
|||||||
|
|
||||||
### `//stack x/y/z/? <count>`
|
### `//stack x/y/z/? <count>`
|
||||||
|
|
||||||
Stack the current WorldEdit region along the x/y/z/? axis `<count>` times.
|
Stack the current WorldEdit region along the given axis `<count>` times.
|
||||||
|
|
||||||
//stack x 3
|
//stack x 3
|
||||||
//stack y -1
|
//stack y -1
|
||||||
@ -287,7 +298,9 @@ Stack the current WorldEdit region `<count>` times by offset `<x>`, `<y>`, `<z>`
|
|||||||
|
|
||||||
### `//stretch <stretchx> <stretchy> <stretchz>`
|
### `//stretch <stretchx> <stretchy> <stretchz>`
|
||||||
|
|
||||||
Scale the current WorldEdit positions and region by a factor of `<stretchx>`, `<stretchy>`, `<stretchz>` along the X, Y, and Z axes, repectively, with position 1 as the origin.
|
Scale the current WorldEdit positions and region by a factor of
|
||||||
|
`<stretchx>`, `<stretchy>`, `<stretchz>` along the X, Y, and Z axes,
|
||||||
|
respectively, with position 1 as the origin.
|
||||||
|
|
||||||
//stretch 2 2 2
|
//stretch 2 2 2
|
||||||
//stretch 1 2 1
|
//stretch 1 2 1
|
||||||
@ -295,25 +308,22 @@ Scale the current WorldEdit positions and region by a factor of `<stretchx>`, `<
|
|||||||
|
|
||||||
### `//transpose x/y/z/? x/y/z/?`
|
### `//transpose x/y/z/? x/y/z/?`
|
||||||
|
|
||||||
Transpose the current WorldEdit positions and region along the x/y/z/? and x/y/z/? axes.
|
Transpose the current WorldEdit positions and region along given axes.
|
||||||
|
|
||||||
//transpose x y
|
//transpose x y
|
||||||
//transpose x z
|
|
||||||
//transpose y z
|
//transpose y z
|
||||||
//transpose ? y
|
//transpose ? y
|
||||||
|
|
||||||
### `//flip x/y/z/?`
|
### `//flip x/y/z/?`
|
||||||
|
|
||||||
Flip the current WorldEdit region along the x/y/z/? axis.
|
Flip the current WorldEdit region along the given axis.
|
||||||
|
|
||||||
//flip x
|
//flip x
|
||||||
//flip y
|
|
||||||
//flip z
|
|
||||||
//flip ?
|
//flip ?
|
||||||
|
|
||||||
### `//rotate x/y/z/? <angle>`
|
### `//rotate x/y/z/? <angle>`
|
||||||
|
|
||||||
Rotate the current WorldEdit positions and region along the x/y/z/? axis by angle `<angle>` (90 degree increment).
|
Rotate the current WorldEdit positions and region along the given axis by angle `<angle>` (90 degree increment).
|
||||||
|
|
||||||
//rotate x 90
|
//rotate x 90
|
||||||
//rotate y 180
|
//rotate y 180
|
||||||
@ -341,6 +351,13 @@ Removes any fluid node within the current WorldEdit region.
|
|||||||
|
|
||||||
//drain
|
//drain
|
||||||
|
|
||||||
|
### `//clearcut`
|
||||||
|
|
||||||
|
Removes any plant, tree or foilage-like nodes in the selected region.
|
||||||
|
The idea is to remove anything that isn't part of the terrain, leaving a "natural" empty space ready for building.
|
||||||
|
|
||||||
|
//clearcut
|
||||||
|
|
||||||
### `//hide`
|
### `//hide`
|
||||||
|
|
||||||
Hide all nodes in the current WorldEdit region non-destructively.
|
Hide all nodes in the current WorldEdit region non-destructively.
|
||||||
@ -349,7 +366,7 @@ Hide all nodes in the current WorldEdit region non-destructively.
|
|||||||
|
|
||||||
### `//suppress <node>`
|
### `//suppress <node>`
|
||||||
|
|
||||||
Suppress all <node> in the current WorldEdit region non-destructively.
|
Suppress all `<node>` in the current WorldEdit region non-destructively.
|
||||||
|
|
||||||
//suppress Diamond Block
|
//suppress Diamond Block
|
||||||
//suppress glass
|
//suppress glass
|
||||||
@ -357,7 +374,7 @@ Suppress all <node> in the current WorldEdit region non-destructively.
|
|||||||
|
|
||||||
### `//highlight <node>`
|
### `//highlight <node>`
|
||||||
|
|
||||||
Highlight <node> in the current WorldEdit region by hiding everything else non-destructively.
|
Highlight `<node>` in the current WorldEdit region by hiding everything else non-destructively.
|
||||||
|
|
||||||
//highlight Diamond Block
|
//highlight Diamond Block
|
||||||
//highlight glass
|
//highlight glass
|
||||||
@ -401,8 +418,8 @@ Executes `<code>` as a Lua chunk in the global namespace.
|
|||||||
|
|
||||||
Executes `<code>` as a Lua chunk in the global namespace with the variable pos available, for each node in the current WorldEdit region.
|
Executes `<code>` as a Lua chunk in the global namespace with the variable pos available, for each node in the current WorldEdit region.
|
||||||
|
|
||||||
//luatransform minetest.add_node(pos, {name="default:stone"})
|
//luatransform minetest.swap_node(pos, {name="default:stone"})
|
||||||
//luatransform if minetest.get_node(pos).name == "air" then minetest.add_node(pos, {name="default:water_source"})
|
//luatransform if minetest.get_node(pos).name == "air" then minetest.add_node(pos, {name="default:water_source"}) end
|
||||||
|
|
||||||
### `//mtschemcreate <file>`
|
### `//mtschemcreate <file>`
|
||||||
|
|
||||||
@ -431,42 +448,44 @@ Clears all objects within the WorldEdit region.
|
|||||||
|
|
||||||
//clearobjects
|
//clearobjects
|
||||||
|
|
||||||
### `//shift x/y/z/?/up/down/left/right/front/back [+|-]<amount>`
|
### `//shift x/y/z/?/up/down/left/right/front/back [+/-]<amount>`
|
||||||
|
|
||||||
Shifts the selection area by `[+|-]<amount>` without touching its contents. The shifting axis can be absolute (`x/y/z`) or
|
Shifts the selection area by `[+|-]<amount>` without moving its contents.
|
||||||
relative (`up/down/left/right/front/back`).
|
The shifting axis can be absolute (`x/y/z`) or relative (`up/down/left/right/front/back`).
|
||||||
|
|
||||||
//shift left 5
|
//shift left 5
|
||||||
|
|
||||||
### `//expand [+|-]x/y/z/?/up/down/left/right/front/back <amount> [reverse-amount]`
|
### `//expand [+/-]x/y/z/?/up/down/left/right/front/back <amount> [reverse amount]`
|
||||||
|
|
||||||
Expands the selection by `<amount>` in the selected absolute or relative axis. If specified, the selection can be expanded in the
|
Expands the selection by `<amount>` in the selected absolute or relative axis.
|
||||||
opposite direction over the same axis by `[reverse-amount]`.
|
If specified, the selection can be expanded in the opposite direction over the same axis by `[reverse amount]`.
|
||||||
|
|
||||||
//expand right 7 5
|
//expand right 7 5
|
||||||
|
|
||||||
### `//contract [+|-]x/y/z/?/up/down/left/right/front/back <amount> [reverse-amount]`
|
### `//contract [+/-]x/y/z/?/up/down/left/right/front/back <amount> [reverse amount]`
|
||||||
|
|
||||||
Contracts the selection by `<amount>` in the selected absolute or relative axis. If specified, the selection can be contracted in the
|
Contracts the selection by `<amount>` in the selected absolute or relative axis.
|
||||||
opposite direction over the same axis by `[reverse-amount]`.
|
If specified, the selection can be contracted in the opposite direction over the same axis by `[reverse amount]`.
|
||||||
|
|
||||||
//expand right 7 5
|
//expand right 7 5
|
||||||
|
|
||||||
### `//outset [hv] <amount>`
|
### `//outset [h/v] <amount>`
|
||||||
|
|
||||||
Expands the selection in all directions by `<amount>`. If specified, the selection can be expanded horizontally in the x and z axes `[h]`
|
Expands the selection in all directions by `<amount>`. If specified,
|
||||||
or vertically in the y axis `[v]`.
|
the selection can be expanded horizontally in the x and z axes using `h`
|
||||||
|
or vertically in the y axis using `v`.
|
||||||
|
|
||||||
//outset v 5
|
//outset v 5
|
||||||
|
|
||||||
### `//inset [hv] <amount>`
|
### `//inset [h/v] <amount>`
|
||||||
|
|
||||||
Contracts the selection in all directions by `<amount>`. If specified, the selection can be contracted horizontally in the x and z axes `[h]`
|
Contracts the selection in all directions by `<amount>`. If specified,
|
||||||
or vertically in the y axis `[v]`.
|
the selection can be contracted horizontally in the x and z axes using `h`
|
||||||
|
or vertically in the y axis using `v`.
|
||||||
|
|
||||||
//outset v 5
|
//inset h 5
|
||||||
|
|
||||||
### `//brush none/<command> [parameters]`
|
### `//brush none/(<command> [parameters])`
|
||||||
|
|
||||||
Assigns the given `<command>` to the currently held brush item, it will be ran with the first pointed solid node (as determined via raycast) as
|
Assigns the given `<command>` to the currently held brush item, it will be ran with the first pointed solid node (as determined via raycast) as
|
||||||
WorldEdit position 1 when using that specific brush item.
|
WorldEdit position 1 when using that specific brush item.
|
||||||
@ -476,3 +495,14 @@ Note that this functionality requires the `worldedit_brush` mod enabled.
|
|||||||
//brush cube 8 8 8 Cobblestone
|
//brush cube 8 8 8 Cobblestone
|
||||||
//brush spr 12 glass
|
//brush spr 12 glass
|
||||||
//brush none
|
//brush none
|
||||||
|
|
||||||
|
### `//cubeapply <size>/(<sizex> <sizey> <sizez>) <command> [parameters]`
|
||||||
|
|
||||||
|
Selects a cube with side length of `<size>` around the WorldEdit position 1 and runs the given `<command>` on the newly selected region.
|
||||||
|
If `<sizex>`, `<sizey>` and `<sizez>` are given, they instead specify the length of the cuboid in X, Y, Z direction.
|
||||||
|
This is mostly useful for brushes since it allows commands such as `//replace` to be ran, but it can also be used standalone.
|
||||||
|
|
||||||
|
//cubeapply 10 replaceinverse air default:water_source
|
||||||
|
//brush cubeapply 15 drain
|
||||||
|
//brush cubeapply 12 3 12 drain
|
||||||
|
//brush cubeapply 1 deleteblocks
|
||||||
|
@ -46,6 +46,9 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function worldedit.keep_loaded(pos1, pos2)
|
function worldedit.keep_loaded(pos1, pos2)
|
||||||
|
-- Create a vmanip and read the area from map, this
|
||||||
|
-- causes all MapBlocks to be loaded into memory.
|
||||||
|
-- This doesn't actually *keep* them loaded, unlike the name implies.
|
||||||
local manip = minetest.get_voxel_manip()
|
local manip = minetest.get_voxel_manip()
|
||||||
manip:read_from_map(pos1, pos2)
|
manip:read_from_map(pos1, pos2)
|
||||||
end
|
end
|
||||||
|
@ -98,21 +98,6 @@ worldedit.marker_move = function(name, marker, deltavector)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Updates the location ingame of the markers
|
|
||||||
worldedit.marker_update = function(name, marker)
|
|
||||||
if marker == nil then
|
|
||||||
worldedit.mark_pos1(name)
|
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
elseif marker == 1 then
|
|
||||||
worldedit.mark_pos1(name)
|
|
||||||
elseif marker == 2 then
|
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
else
|
|
||||||
minetest.debug(
|
|
||||||
"worldedit: Invalid execution of function update_markers")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Returns two vectors with the directions for volumetric expansion
|
-- Returns two vectors with the directions for volumetric expansion
|
||||||
worldedit.get_expansion_directions = function(mark1, mark2)
|
worldedit.get_expansion_directions = function(mark1, mark2)
|
||||||
|
@ -114,16 +114,44 @@ function worldedit.serialize(pos1, pos2)
|
|||||||
return LATEST_SERIALIZATION_HEADER .. result, count
|
return LATEST_SERIALIZATION_HEADER .. result, count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Loads the schematic in `value` into a node list in the latest format.
|
|
||||||
-- Contains code based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile)
|
-- Contains code based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile)
|
||||||
-- by ChillCode, available under the MIT license.
|
-- by ChillCode, available under the MIT license.
|
||||||
|
local function deserialize_workaround(content)
|
||||||
|
local nodes
|
||||||
|
if not jit then
|
||||||
|
nodes = minetest.deserialize(content, true)
|
||||||
|
else
|
||||||
|
-- XXX: This is a filthy hack that works surprisingly well
|
||||||
|
-- in LuaJIT, `minetest.deserialize` will fail due to the register limit
|
||||||
|
nodes = {}
|
||||||
|
content = content:gsub("^%s*return%s*{", "", 1):gsub("}%s*$", "", 1) -- remove the starting and ending values to leave only the node data
|
||||||
|
-- remove string contents strings while preserving their length
|
||||||
|
local escaped = content:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end)
|
||||||
|
local startpos, startpos1 = 1, 1
|
||||||
|
local endpos
|
||||||
|
while true do -- go through each individual node entry (except the last)
|
||||||
|
startpos, endpos = escaped:find("},%s*{", startpos)
|
||||||
|
if not startpos then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local current = content:sub(startpos1, startpos)
|
||||||
|
local entry = minetest.deserialize("return " .. current, true)
|
||||||
|
table.insert(nodes, entry)
|
||||||
|
startpos, startpos1 = endpos, endpos
|
||||||
|
end
|
||||||
|
local entry = minetest.deserialize("return " .. content:sub(startpos1), true) -- process the last entry
|
||||||
|
table.insert(nodes, entry)
|
||||||
|
end
|
||||||
|
return nodes
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Loads the schematic in `value` into a node list in the latest format.
|
||||||
-- @return A node list in the latest format, or nil on failure.
|
-- @return A node list in the latest format, or nil on failure.
|
||||||
local function load_schematic(value)
|
local function load_schematic(value)
|
||||||
local version, header, content = worldedit.read_header(value)
|
local version, header, content = worldedit.read_header(value)
|
||||||
local nodes = {}
|
local nodes = {}
|
||||||
if version == 1 or version == 2 then -- Original flat table format
|
if version == 1 or version == 2 then -- Original flat table format
|
||||||
local tables = minetest.deserialize(content)
|
local tables = minetest.deserialize(content, true)
|
||||||
if not tables then return nil end
|
if not tables then return nil end
|
||||||
|
|
||||||
-- Transform the node table into an array of nodes
|
-- Transform the node table into an array of nodes
|
||||||
@ -161,28 +189,7 @@ local function load_schematic(value)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
elseif version == 4 or version == 5 then -- Nested table format
|
elseif version == 4 or version == 5 then -- Nested table format
|
||||||
if not jit then
|
nodes = deserialize_workaround(content)
|
||||||
-- This is broken for larger tables in the current version of LuaJIT
|
|
||||||
nodes = minetest.deserialize(content)
|
|
||||||
else
|
|
||||||
-- XXX: This is a filthy hack that works surprisingly well - in LuaJIT, `minetest.deserialize` will fail due to the register limit
|
|
||||||
nodes = {}
|
|
||||||
content = content:gsub("return%s*{", "", 1):gsub("}%s*$", "", 1) -- remove the starting and ending values to leave only the node data
|
|
||||||
local escaped = content:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end)
|
|
||||||
local startpos, startpos1, endpos = 1, 1
|
|
||||||
while true do -- go through each individual node entry (except the last)
|
|
||||||
startpos, endpos = escaped:find("},%s*{", startpos)
|
|
||||||
if not startpos then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
local current = content:sub(startpos1, startpos)
|
|
||||||
local entry = minetest.deserialize("return " .. current)
|
|
||||||
table.insert(nodes, entry)
|
|
||||||
startpos, startpos1 = endpos, endpos
|
|
||||||
end
|
|
||||||
local entry = minetest.deserialize("return " .. content:sub(startpos1)) -- process the last entry
|
|
||||||
table.insert(nodes, entry)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
@ -39,7 +39,7 @@ local brush_on_use = function(itemstack, placer)
|
|||||||
assert(pointed_thing.type == "node")
|
assert(pointed_thing.type == "node")
|
||||||
worldedit.pos1[name] = pointed_thing.under
|
worldedit.pos1[name] = pointed_thing.under
|
||||||
worldedit.pos2[name] = nil
|
worldedit.pos2[name] = nil
|
||||||
worldedit.mark_region(name)
|
worldedit.marker_update(name)
|
||||||
|
|
||||||
-- this isn't really clean...
|
-- this isn't really clean...
|
||||||
local player_notify_old = worldedit.player_notify
|
local player_notify_old = worldedit.player_notify
|
||||||
@ -101,7 +101,7 @@ worldedit.register_command("brush", {
|
|||||||
else
|
else
|
||||||
local cmddef = worldedit.registered_commands[cmd]
|
local cmddef = worldedit.registered_commands[cmd]
|
||||||
if cmddef == nil or cmddef.require_pos ~= 1 then
|
if cmddef == nil or cmddef.require_pos ~= 1 then
|
||||||
worldedit.player_notify(name, "Invalid command for brush use: //" .. cmd)
|
worldedit.player_notify(name, "//" .. cmd .. " cannot be used with brushes")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ worldedit.register_command("brush", {
|
|||||||
local ok, err = cmddef.parse(params)
|
local ok, err = cmddef.parse(params)
|
||||||
if not ok then
|
if not ok then
|
||||||
err = err or "invalid usage"
|
err = err or "invalid usage"
|
||||||
worldedit.player_notify(name, "Brush command: " .. err)
|
worldedit.player_notify(name, "Error with brush command: " .. err)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
worldedit.register_command("outset", {
|
worldedit.register_command("outset", {
|
||||||
params = "[h|v] <amount>",
|
params = "[h/v] <amount>",
|
||||||
description = "Outset the selected region.",
|
description = "Outset the selected region.",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
@ -38,7 +38,7 @@ worldedit.register_command("outset", {
|
|||||||
|
|
||||||
|
|
||||||
worldedit.register_command("inset", {
|
worldedit.register_command("inset", {
|
||||||
params = "[h|v] <amount>",
|
params = "[h/v] <amount>",
|
||||||
description = "Inset the selected region.",
|
description = "Inset the selected region.",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
@ -47,9 +47,7 @@ worldedit.register_command("inset", {
|
|||||||
if find == nil then
|
if find == nil then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
if dir:find("[^hv]") ~= nil then
|
||||||
local hv_test = dir:find("[^hv]+")
|
|
||||||
if hv_test ~= nil then
|
|
||||||
return false, "Invalid direction."
|
return false, "Invalid direction."
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -77,8 +75,8 @@ worldedit.register_command("inset", {
|
|||||||
|
|
||||||
|
|
||||||
worldedit.register_command("shift", {
|
worldedit.register_command("shift", {
|
||||||
params = "[x|y|z|?|up|down|left|right|front|back] [+|-]<amount>",
|
params = "x/y/z/?/up/down/left/right/front/back [+/-]<amount>",
|
||||||
description = "Moves the selection region. Does not move contents.",
|
description = "Shifts the selection area without moving its contents",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -112,8 +110,8 @@ worldedit.register_command("shift", {
|
|||||||
|
|
||||||
|
|
||||||
worldedit.register_command("expand", {
|
worldedit.register_command("expand", {
|
||||||
params = "[+|-]<x|y|z|?|up|down|left|right|front|back> <amount> [reverse-amount]",
|
params = "[+/-]x/y/z/?/up/down/left/right/front/back <amount> [reverse amount]",
|
||||||
description = "expand the selection in one or two directions at once",
|
description = "Expands the selection in the selected absolute or relative axis",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -161,8 +159,8 @@ worldedit.register_command("expand", {
|
|||||||
|
|
||||||
|
|
||||||
worldedit.register_command("contract", {
|
worldedit.register_command("contract", {
|
||||||
params = "[+|-]<x|y|z|?|up|down|left|right|front|back> <amount> [reverse-amount]",
|
params = "[+/-]x/y/z/?/up/down/left/right/front/back <amount> [reverse amount]",
|
||||||
description = "contract the selection in one or two directions at once",
|
description = "Contracts the selection in the selected absolute or relative axis",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -207,3 +205,62 @@ worldedit.register_command("contract", {
|
|||||||
return true, "Region contracted by " .. (amount + rev_amount) .. " nodes"
|
return true, "Region contracted by " .. (amount + rev_amount) .. " nodes"
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
worldedit.register_command("cubeapply", {
|
||||||
|
params = "<size>/(<sizex> <sizey> <sizez>) <command> [parameters]",
|
||||||
|
description = "Select a cube with side length <size> around position 1 and run <command> on region",
|
||||||
|
privs = {worldedit=true},
|
||||||
|
require_pos = 1,
|
||||||
|
parse = function(param)
|
||||||
|
local found, _, sidex, sidey, sidez, cmd, args =
|
||||||
|
param:find("^(%d+)%s+(%d+)%s+(%d+)%s+([^%s]+)%s*(.*)$")
|
||||||
|
if found == nil then
|
||||||
|
found, _, sidex, cmd, args = param:find("^(%d+)%s+([^%s]+)%s*(.*)$")
|
||||||
|
if found == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
sidey = sidex
|
||||||
|
sidez = sidex
|
||||||
|
end
|
||||||
|
sidex = tonumber(sidex)
|
||||||
|
sidey = tonumber(sidey)
|
||||||
|
sidez = tonumber(sidez)
|
||||||
|
if sidex < 1 or sidey < 1 or sidez < 1 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local cmddef = worldedit.registered_commands[cmd]
|
||||||
|
if cmddef == nil or cmddef.require_pos ~= 2 then
|
||||||
|
return false, "invalid usage: //" .. cmd .. " cannot be used with cubeapply"
|
||||||
|
end
|
||||||
|
-- run parsing of target command
|
||||||
|
local parsed = {cmddef.parse(args)}
|
||||||
|
if not table.remove(parsed, 1) then
|
||||||
|
return false, parsed[1]
|
||||||
|
end
|
||||||
|
return true, sidex, sidey, sidez, cmd, parsed
|
||||||
|
end,
|
||||||
|
nodes_needed = function(name, sidex, sidey, sidez, cmd, parsed)
|
||||||
|
-- its not possible to defer to the target command at this point
|
||||||
|
return sidex * sidey * sidez
|
||||||
|
end,
|
||||||
|
func = function(name, sidex, sidey, sidez, cmd, parsed)
|
||||||
|
local cmddef = assert(worldedit.registered_commands[cmd])
|
||||||
|
local success, missing_privs = minetest.check_player_privs(name, cmddef.privs)
|
||||||
|
if not success then
|
||||||
|
worldedit.player_notify(name, "Missing privileges: " ..
|
||||||
|
table.concat(missing_privs, ", "))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- update region to be the cuboid the user wanted
|
||||||
|
local half = vector.divide(vector.new(sidex, sidey, sidez), 2)
|
||||||
|
local sizea, sizeb = vector.apply(half, math.floor), vector.apply(half, math.ceil)
|
||||||
|
local center = worldedit.pos1[name]
|
||||||
|
worldedit.pos1[name] = vector.subtract(center, sizea)
|
||||||
|
worldedit.pos2[name] = vector.add(center, vector.subtract(sizeb, 1))
|
||||||
|
worldedit.marker_update(name)
|
||||||
|
|
||||||
|
-- actually run target command
|
||||||
|
return cmddef.func(name, unpack(parsed))
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
@ -122,8 +122,9 @@ local function check_region(name)
|
|||||||
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name])
|
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Strips any kind of escape codes (translation, colors) from a string
|
||||||
-- https://github.com/minetest/minetest/blob/53dd7819277c53954d1298dfffa5287c306db8d0/src/util/string.cpp#L777
|
-- https://github.com/minetest/minetest/blob/53dd7819277c53954d1298dfffa5287c306db8d0/src/util/string.cpp#L777
|
||||||
local function strip_translation_escapes(input)
|
local function strip_escapes(input)
|
||||||
local s = function(idx) return input:sub(idx, idx) end
|
local s = function(idx) return input:sub(idx, idx) end
|
||||||
local out = ""
|
local out = ""
|
||||||
local i = 1
|
local i = 1
|
||||||
@ -153,6 +154,8 @@ local function string_endswith(full, part)
|
|||||||
return full:find(part, 1, true) == #full - #part + 1
|
return full:find(part, 1, true) == #full - #part + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local description_cache = nil
|
||||||
|
|
||||||
-- normalizes node "description" `nodename`, returning a string (or nil)
|
-- normalizes node "description" `nodename`, returning a string (or nil)
|
||||||
worldedit.normalize_nodename = function(nodename)
|
worldedit.normalize_nodename = function(nodename)
|
||||||
nodename = nodename:gsub("^%s*(.-)%s*$", "%1") -- strip spaces
|
nodename = nodename:gsub("^%s*(.-)%s*$", "%1") -- strip spaces
|
||||||
@ -163,16 +166,30 @@ worldedit.normalize_nodename = function(nodename)
|
|||||||
return fullname
|
return fullname
|
||||||
end
|
end
|
||||||
nodename = nodename:lower()
|
nodename = nodename:lower()
|
||||||
for key, value in pairs(minetest.registered_nodes) do
|
|
||||||
if string_endswith(key, ":" .. nodename) then -- matches name (w/o mod part)
|
for key, _ in pairs(minetest.registered_nodes) do
|
||||||
|
if string_endswith(key:lower(), ":" .. nodename) then -- matches name (w/o mod part)
|
||||||
return key
|
return key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if description_cache == nil then
|
||||||
|
-- cache stripped descriptions
|
||||||
|
description_cache = {}
|
||||||
for key, value in pairs(minetest.registered_nodes) do
|
for key, value in pairs(minetest.registered_nodes) do
|
||||||
local desc = strip_translation_escapes(value.description):lower()
|
local desc = strip_escapes(value.description):gsub("\n.*", "", 1):lower()
|
||||||
|
if desc ~= "" then
|
||||||
|
description_cache[key] = desc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for key, desc in pairs(description_cache) do
|
||||||
if desc == nodename then -- matches description
|
if desc == nodename then -- matches description
|
||||||
return key
|
return key
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
for key, desc in pairs(description_cache) do
|
||||||
if desc == nodename .. " block" then
|
if desc == nodename .. " block" then
|
||||||
-- fuzzy description match (e.g. "Steel" == "Steel Block")
|
-- fuzzy description match (e.g. "Steel" == "Steel Block")
|
||||||
return key
|
return key
|
||||||
@ -180,8 +197,8 @@ worldedit.normalize_nodename = function(nodename)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local match = nil
|
local match = nil
|
||||||
for key, value in pairs(minetest.registered_nodes) do
|
for key, value in pairs(description_cache) do
|
||||||
if value.description:lower():find(nodename, 1, true) ~= nil then
|
if value:find(nodename, 1, true) ~= nil then
|
||||||
if match ~= nil then
|
if match ~= nil then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@ -215,7 +232,10 @@ worldedit.register_command("about", {
|
|||||||
params = "",
|
params = "",
|
||||||
description = "Get information about the WorldEdit mod",
|
description = "Get information about the WorldEdit mod",
|
||||||
func = function(name)
|
func = function(name)
|
||||||
worldedit.player_notify(name, "WorldEdit " .. worldedit.version_string .. " is available on this server. Type //help to get a list of commands, or get more information at https://github.com/Uberi/Minetest-WorldEdit")
|
worldedit.player_notify(name, "WorldEdit " .. worldedit.version_string..
|
||||||
|
" is available on this server. Type //help to get a list of "..
|
||||||
|
"commands, or get more information at "..
|
||||||
|
"https://github.com/Uberi/Minetest-WorldEdit")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -332,8 +352,7 @@ worldedit.register_command("reset", {
|
|||||||
func = function(name)
|
func = function(name)
|
||||||
worldedit.pos1[name] = nil
|
worldedit.pos1[name] = nil
|
||||||
worldedit.pos2[name] = nil
|
worldedit.pos2[name] = nil
|
||||||
worldedit.mark_pos1(name)
|
worldedit.marker_update(name)
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
worldedit.set_pos[name] = nil
|
worldedit.set_pos[name] = nil
|
||||||
--make sure the user does not try to confirm an operation after resetting pos:
|
--make sure the user does not try to confirm an operation after resetting pos:
|
||||||
reset_pending(name)
|
reset_pending(name)
|
||||||
@ -346,8 +365,7 @@ worldedit.register_command("mark", {
|
|||||||
description = "Show markers at the region positions",
|
description = "Show markers at the region positions",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
func = function(name)
|
func = function(name)
|
||||||
worldedit.mark_pos1(name)
|
worldedit.marker_update(name)
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
worldedit.player_notify(name, "region marked")
|
worldedit.player_notify(name, "region marked")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@ -360,8 +378,7 @@ worldedit.register_command("unmark", {
|
|||||||
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
||||||
worldedit.pos1[name] = nil
|
worldedit.pos1[name] = nil
|
||||||
worldedit.pos2[name] = nil
|
worldedit.pos2[name] = nil
|
||||||
worldedit.mark_pos1(name)
|
worldedit.marker_update(name)
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
worldedit.pos1[name] = pos1
|
worldedit.pos1[name] = pos1
|
||||||
worldedit.pos2[name] = pos2
|
worldedit.pos2[name] = pos2
|
||||||
worldedit.player_notify(name, "region unmarked")
|
worldedit.player_notify(name, "region unmarked")
|
||||||
@ -430,7 +447,7 @@ worldedit.register_command("p", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
worldedit.register_command("fixedpos", {
|
worldedit.register_command("fixedpos", {
|
||||||
params = "set1/set2 x y z",
|
params = "set1/set2 <x> <y> <z>",
|
||||||
description = "Set a WorldEdit region position to the position at (<x>, <y>, <z>)",
|
description = "Set a WorldEdit region position to the position at (<x>, <y>, <z>)",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -539,7 +556,7 @@ worldedit.register_command("param2", {
|
|||||||
parse = function(param)
|
parse = function(param)
|
||||||
local param2 = tonumber(param)
|
local param2 = tonumber(param)
|
||||||
if not param2 then
|
if not param2 then
|
||||||
return false, "Invalid or missing param2 argument"
|
return false
|
||||||
elseif param2 < 0 or param2 > 255 then
|
elseif param2 < 0 or param2 > 255 then
|
||||||
return false, "Param2 is out of range (must be between 0 and 255 inclusive!)"
|
return false, "Param2 is out of range (must be between 0 and 255 inclusive!)"
|
||||||
end
|
end
|
||||||
@ -553,7 +570,7 @@ worldedit.register_command("param2", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
worldedit.register_command("mix", {
|
worldedit.register_command("mix", {
|
||||||
params = "<node1> [<weighting1>] [<node2> [<weighting2>]] ...",
|
params = "<node1> [count1] <node2> [count2] ...",
|
||||||
description = "Fill the current WorldEdit region with a random mix of <node1>, ...",
|
description = "Fill the current WorldEdit region with a random mix of <node1>, ...",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
@ -573,6 +590,9 @@ worldedit.register_command("mix", {
|
|||||||
nodes[#nodes + 1] = node
|
nodes[#nodes + 1] = node
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if #nodes == 0 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
return true, nodes
|
return true, nodes
|
||||||
end,
|
end,
|
||||||
nodes_needed = check_region,
|
nodes_needed = check_region,
|
||||||
@ -773,7 +793,7 @@ end
|
|||||||
|
|
||||||
worldedit.register_command("hollowcylinder", {
|
worldedit.register_command("hollowcylinder", {
|
||||||
params = "x/y/z/? <length> <radius1> [radius2] <node>",
|
params = "x/y/z/? <length> <radius1> [radius2] <node>",
|
||||||
description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length>, base radius <radius1> (and top radius [radius2]), composed of <node>",
|
description = "Add hollow cylinder at WorldEdit position 1 along the given axis with length <length>, base radius <radius1> (and top radius [radius2]), composed of <node>",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 1,
|
require_pos = 1,
|
||||||
parse = check_cylinder,
|
parse = check_cylinder,
|
||||||
@ -794,7 +814,7 @@ worldedit.register_command("hollowcylinder", {
|
|||||||
|
|
||||||
worldedit.register_command("cylinder", {
|
worldedit.register_command("cylinder", {
|
||||||
params = "x/y/z/? <length> <radius1> [radius2] <node>",
|
params = "x/y/z/? <length> <radius1> [radius2] <node>",
|
||||||
description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length>, base radius <radius1> (and top radius [radius2]), composed of <node>",
|
description = "Add cylinder at WorldEdit position 1 along the given axis with length <length>, base radius <radius1> (and top radius [radius2]), composed of <node>",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 1,
|
require_pos = 1,
|
||||||
parse = check_cylinder,
|
parse = check_cylinder,
|
||||||
@ -827,7 +847,7 @@ end
|
|||||||
|
|
||||||
worldedit.register_command("hollowpyramid", {
|
worldedit.register_command("hollowpyramid", {
|
||||||
params = "x/y/z/? <height> <node>",
|
params = "x/y/z/? <height> <node>",
|
||||||
description = "Add hollow pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height <height>, composed of <node>",
|
description = "Add hollow pyramid centered at WorldEdit position 1 along the given axis with height <height>, composed of <node>",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 1,
|
require_pos = 1,
|
||||||
parse = check_pyramid,
|
parse = check_pyramid,
|
||||||
@ -847,7 +867,7 @@ worldedit.register_command("hollowpyramid", {
|
|||||||
|
|
||||||
worldedit.register_command("pyramid", {
|
worldedit.register_command("pyramid", {
|
||||||
params = "x/y/z/? <height> <node>",
|
params = "x/y/z/? <height> <node>",
|
||||||
description = "Add pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height <height>, composed of <node>",
|
description = "Add pyramid centered at WorldEdit position 1 along the given axis with height <height>, composed of <node>",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 1,
|
require_pos = 1,
|
||||||
parse = check_pyramid,
|
parse = check_pyramid,
|
||||||
@ -892,7 +912,7 @@ worldedit.register_command("spiral", {
|
|||||||
|
|
||||||
worldedit.register_command("copy", {
|
worldedit.register_command("copy", {
|
||||||
params = "x/y/z/? <amount>",
|
params = "x/y/z/? <amount>",
|
||||||
description = "Copy the current WorldEdit region along the x/y/z/? axis by <amount> nodes",
|
description = "Copy the current WorldEdit region along the given axis by <amount> nodes",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -919,7 +939,7 @@ worldedit.register_command("copy", {
|
|||||||
|
|
||||||
worldedit.register_command("move", {
|
worldedit.register_command("move", {
|
||||||
params = "x/y/z/? <amount>",
|
params = "x/y/z/? <amount>",
|
||||||
description = "Move the current WorldEdit region along the x/y/z/? axis by <amount> nodes",
|
description = "Move the current WorldEdit region along the given axis by <amount> nodes",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -944,15 +964,14 @@ worldedit.register_command("move", {
|
|||||||
|
|
||||||
pos1[axis] = pos1[axis] + amount
|
pos1[axis] = pos1[axis] + amount
|
||||||
pos2[axis] = pos2[axis] + amount
|
pos2[axis] = pos2[axis] + amount
|
||||||
worldedit.mark_pos1(name)
|
worldedit.marker_update(name)
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
worldedit.player_notify(name, count .. " nodes moved")
|
worldedit.player_notify(name, count .. " nodes moved")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
worldedit.register_command("stack", {
|
worldedit.register_command("stack", {
|
||||||
params = "x/y/z/? <count>",
|
params = "x/y/z/? <count>",
|
||||||
description = "Stack the current WorldEdit region along the x/y/z/? axis <count> times",
|
description = "Stack the current WorldEdit region along the given axis <count> times",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -1036,8 +1055,7 @@ worldedit.register_command("stretch", {
|
|||||||
--reset markers to scaled positions
|
--reset markers to scaled positions
|
||||||
worldedit.pos1[name] = pos1
|
worldedit.pos1[name] = pos1
|
||||||
worldedit.pos2[name] = pos2
|
worldedit.pos2[name] = pos2
|
||||||
worldedit.mark_pos1(name)
|
worldedit.marker_update(name)
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
|
|
||||||
worldedit.player_notify(name, count .. " nodes stretched")
|
worldedit.player_notify(name, count .. " nodes stretched")
|
||||||
end,
|
end,
|
||||||
@ -1045,7 +1063,7 @@ worldedit.register_command("stretch", {
|
|||||||
|
|
||||||
worldedit.register_command("transpose", {
|
worldedit.register_command("transpose", {
|
||||||
params = "x/y/z/? x/y/z/?",
|
params = "x/y/z/? x/y/z/?",
|
||||||
description = "Transpose the current WorldEdit region along the x/y/z/? and x/y/z/? axes",
|
description = "Transpose the current WorldEdit region along the given axes",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -1067,8 +1085,7 @@ worldedit.register_command("transpose", {
|
|||||||
--reset markers to transposed positions
|
--reset markers to transposed positions
|
||||||
worldedit.pos1[name] = pos1
|
worldedit.pos1[name] = pos1
|
||||||
worldedit.pos2[name] = pos2
|
worldedit.pos2[name] = pos2
|
||||||
worldedit.mark_pos1(name)
|
worldedit.marker_update(name)
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
|
|
||||||
worldedit.player_notify(name, count .. " nodes transposed")
|
worldedit.player_notify(name, count .. " nodes transposed")
|
||||||
end,
|
end,
|
||||||
@ -1076,7 +1093,7 @@ worldedit.register_command("transpose", {
|
|||||||
|
|
||||||
worldedit.register_command("flip", {
|
worldedit.register_command("flip", {
|
||||||
params = "x/y/z/?",
|
params = "x/y/z/?",
|
||||||
description = "Flip the current WorldEdit region along the x/y/z/? axis",
|
description = "Flip the current WorldEdit region along the given axis",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -1094,8 +1111,8 @@ worldedit.register_command("flip", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
worldedit.register_command("rotate", {
|
worldedit.register_command("rotate", {
|
||||||
params = "<axis> <angle>",
|
params = "x/y/z/? <angle>",
|
||||||
description = "Rotate the current WorldEdit region around the axis <axis> by angle <angle> (90 degree increment)",
|
description = "Rotate the current WorldEdit region around the given axis by angle <angle> (90 degree increment)",
|
||||||
privs = {worldedit=true},
|
privs = {worldedit=true},
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(param)
|
parse = function(param)
|
||||||
@ -1118,8 +1135,7 @@ worldedit.register_command("rotate", {
|
|||||||
--reset markers to rotated positions
|
--reset markers to rotated positions
|
||||||
worldedit.pos1[name] = pos1
|
worldedit.pos1[name] = pos1
|
||||||
worldedit.pos2[name] = pos2
|
worldedit.pos2[name] = pos2
|
||||||
worldedit.mark_pos1(name)
|
worldedit.marker_update(name)
|
||||||
worldedit.mark_pos2(name)
|
|
||||||
|
|
||||||
worldedit.player_notify(name, count .. " nodes rotated")
|
worldedit.player_notify(name, count .. " nodes rotated")
|
||||||
end,
|
end,
|
||||||
@ -1186,6 +1202,85 @@ worldedit.register_command("drain", {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local clearcut_cache
|
||||||
|
|
||||||
|
local function clearcut(pos1, pos2)
|
||||||
|
-- decide which nodes we consider plants
|
||||||
|
if clearcut_cache == nil then
|
||||||
|
clearcut_cache = {}
|
||||||
|
for name, def in pairs(minetest.registered_nodes) do
|
||||||
|
local groups = def.groups or {}
|
||||||
|
if (
|
||||||
|
-- the groups say so
|
||||||
|
groups.flower or groups.grass or groups.flora or groups.plant or
|
||||||
|
groups.leaves or groups.tree or groups.leafdecay or groups.sapling or
|
||||||
|
-- drawtype heuristic
|
||||||
|
(def.is_ground_content and def.buildable_to and
|
||||||
|
(def.sunlight_propagates or not def.walkable)
|
||||||
|
and def.drawtype == "plantlike") or
|
||||||
|
-- if it's flammable, it probably needs to go too
|
||||||
|
(def.is_ground_content and not def.walkable and groups.flammable)
|
||||||
|
) then
|
||||||
|
clearcut_cache[name] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local plants = clearcut_cache
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
local prev, any
|
||||||
|
|
||||||
|
for x = pos1.x, pos2.x do
|
||||||
|
for z = pos1.z, pos2.z do
|
||||||
|
prev = false
|
||||||
|
any = false
|
||||||
|
-- first pass: remove floating nodes that would be left over
|
||||||
|
for y = pos1.y, pos2.y do
|
||||||
|
local n = minetest.get_node({x=x, y=y, z=z}).name
|
||||||
|
if plants[n] then
|
||||||
|
prev = true
|
||||||
|
any = true
|
||||||
|
elseif prev then
|
||||||
|
local def = minetest.registered_nodes[n] or {}
|
||||||
|
local groups = def.groups or {}
|
||||||
|
if groups.attached_node or (def.buildable_to and groups.falling_node) then
|
||||||
|
minetest.remove_node({x=x, y=y, z=z})
|
||||||
|
count = count + 1
|
||||||
|
else
|
||||||
|
prev = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- second pass: remove plants, top-to-bottom to avoid item drops
|
||||||
|
if any then
|
||||||
|
for y = pos2.y, pos1.y, -1 do
|
||||||
|
local n = minetest.get_node({x=x, y=y, z=z}).name
|
||||||
|
if plants[n] then
|
||||||
|
minetest.remove_node({x=x, y=y, z=z})
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
|
worldedit.register_command("clearcut", {
|
||||||
|
params = "",
|
||||||
|
description = "Remove any plant, tree or foilage-like nodes in the selected region",
|
||||||
|
privs = {worldedit=true},
|
||||||
|
require_pos = 2,
|
||||||
|
nodes_needed = check_region,
|
||||||
|
func = function(name)
|
||||||
|
local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
|
||||||
|
local count = clearcut(pos1, pos2)
|
||||||
|
worldedit.player_notify(name, count .. " nodes removed")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
worldedit.register_command("hide", {
|
worldedit.register_command("hide", {
|
||||||
params = "",
|
params = "",
|
||||||
description = "Hide all nodes in the current WorldEdit region non-destructively",
|
description = "Hide all nodes in the current WorldEdit region non-destructively",
|
||||||
@ -1345,9 +1440,8 @@ worldedit.register_command("allocate", {
|
|||||||
end
|
end
|
||||||
|
|
||||||
worldedit.pos1[name] = nodepos1
|
worldedit.pos1[name] = nodepos1
|
||||||
worldedit.mark_pos1(name)
|
|
||||||
worldedit.pos2[name] = nodepos2
|
worldedit.pos2[name] = nodepos2
|
||||||
worldedit.mark_pos2(name)
|
worldedit.marker_update(name)
|
||||||
|
|
||||||
worldedit.player_notify(name, count .. " nodes allocated")
|
worldedit.player_notify(name, count .. " nodes allocated")
|
||||||
end,
|
end,
|
||||||
|
@ -2,57 +2,60 @@ worldedit.marker1 = {}
|
|||||||
worldedit.marker2 = {}
|
worldedit.marker2 = {}
|
||||||
worldedit.marker_region = {}
|
worldedit.marker_region = {}
|
||||||
|
|
||||||
|
local init_sentinel = "new" .. tostring(math.random(99999))
|
||||||
|
|
||||||
--marks worldedit region position 1
|
--marks worldedit region position 1
|
||||||
worldedit.mark_pos1 = function(name)
|
worldedit.mark_pos1 = function(name, region_too)
|
||||||
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
||||||
|
|
||||||
if pos1 ~= nil then
|
|
||||||
--make area stay loaded
|
|
||||||
local manip = minetest.get_voxel_manip()
|
|
||||||
manip:read_from_map(pos1, pos1)
|
|
||||||
end
|
|
||||||
if worldedit.marker1[name] ~= nil then --marker already exists
|
if worldedit.marker1[name] ~= nil then --marker already exists
|
||||||
worldedit.marker1[name]:remove() --remove marker
|
worldedit.marker1[name]:remove() --remove marker
|
||||||
worldedit.marker1[name] = nil
|
worldedit.marker1[name] = nil
|
||||||
end
|
end
|
||||||
if pos1 ~= nil then
|
if pos1 ~= nil then
|
||||||
|
--make area stay loaded
|
||||||
|
local manip = minetest.get_voxel_manip()
|
||||||
|
manip:read_from_map(pos1, pos1)
|
||||||
|
|
||||||
--add marker
|
--add marker
|
||||||
worldedit.marker1[name] = minetest.add_entity(pos1, "worldedit:pos1")
|
worldedit.marker1[name] = minetest.add_entity(pos1, "worldedit:pos1", init_sentinel)
|
||||||
if worldedit.marker1[name] ~= nil then
|
if worldedit.marker1[name] ~= nil then
|
||||||
worldedit.marker1[name]:get_luaentity().player_name = name
|
worldedit.marker1[name]:get_luaentity().player_name = name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if region_too == nil or region_too then
|
||||||
worldedit.mark_region(name)
|
worldedit.mark_region(name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--marks worldedit region position 2
|
--marks worldedit region position 2
|
||||||
worldedit.mark_pos2 = function(name)
|
worldedit.mark_pos2 = function(name, region_too)
|
||||||
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
||||||
|
|
||||||
if pos2 ~= nil then
|
|
||||||
--make area stay loaded
|
|
||||||
local manip = minetest.get_voxel_manip()
|
|
||||||
manip:read_from_map(pos2, pos2)
|
|
||||||
end
|
|
||||||
if worldedit.marker2[name] ~= nil then --marker already exists
|
if worldedit.marker2[name] ~= nil then --marker already exists
|
||||||
worldedit.marker2[name]:remove() --remove marker
|
worldedit.marker2[name]:remove() --remove marker
|
||||||
worldedit.marker2[name] = nil
|
worldedit.marker2[name] = nil
|
||||||
end
|
end
|
||||||
if pos2 ~= nil then
|
if pos2 ~= nil then
|
||||||
|
--make area stay loaded
|
||||||
|
local manip = minetest.get_voxel_manip()
|
||||||
|
manip:read_from_map(pos2, pos2)
|
||||||
|
|
||||||
--add marker
|
--add marker
|
||||||
worldedit.marker2[name] = minetest.add_entity(pos2, "worldedit:pos2")
|
worldedit.marker2[name] = minetest.add_entity(pos2, "worldedit:pos2", init_sentinel)
|
||||||
if worldedit.marker2[name] ~= nil then
|
if worldedit.marker2[name] ~= nil then
|
||||||
worldedit.marker2[name]:get_luaentity().player_name = name
|
worldedit.marker2[name]:get_luaentity().player_name = name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if region_too == nil or region_too then
|
||||||
worldedit.mark_region(name)
|
worldedit.mark_region(name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
worldedit.mark_region = function(name)
|
worldedit.mark_region = function(name)
|
||||||
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
|
||||||
|
|
||||||
if worldedit.marker_region[name] ~= nil then --marker already exists
|
if worldedit.marker_region[name] ~= nil then --marker already exists
|
||||||
--wip: make the area stay loaded somehow
|
|
||||||
for _, entity in ipairs(worldedit.marker_region[name]) do
|
for _, entity in ipairs(worldedit.marker_region[name]) do
|
||||||
entity:remove()
|
entity:remove()
|
||||||
end
|
end
|
||||||
@ -82,7 +85,8 @@ worldedit.mark_region = function(name)
|
|||||||
|
|
||||||
--XY plane markers
|
--XY plane markers
|
||||||
for _, z in ipairs({pos1.z - 0.5, pos2.z + 0.5}) do
|
for _, z in ipairs({pos1.z - 0.5, pos2.z + 0.5}) do
|
||||||
local marker = minetest.add_entity({x=pos1.x + sizex - 0.5, y=pos1.y + sizey - 0.5, z=z}, "worldedit:region_cube")
|
local entpos = {x=pos1.x + sizex - 0.5, y=pos1.y + sizey - 0.5, z=z}
|
||||||
|
local marker = minetest.add_entity(entpos, "worldedit:region_cube", init_sentinel)
|
||||||
if marker ~= nil then
|
if marker ~= nil then
|
||||||
marker:set_properties({
|
marker:set_properties({
|
||||||
visual_size={x=sizex * 2, y=sizey * 2},
|
visual_size={x=sizex * 2, y=sizey * 2},
|
||||||
@ -95,7 +99,8 @@ worldedit.mark_region = function(name)
|
|||||||
|
|
||||||
--YZ plane markers
|
--YZ plane markers
|
||||||
for _, x in ipairs({pos1.x - 0.5, pos2.x + 0.5}) do
|
for _, x in ipairs({pos1.x - 0.5, pos2.x + 0.5}) do
|
||||||
local marker = minetest.add_entity({x=x, y=pos1.y + sizey - 0.5, z=pos1.z + sizez - 0.5}, "worldedit:region_cube")
|
local entpos = {x=x, y=pos1.y + sizey - 0.5, z=pos1.z + sizez - 0.5}
|
||||||
|
local marker = minetest.add_entity(entpos, "worldedit:region_cube", init_sentinel)
|
||||||
if marker ~= nil then
|
if marker ~= nil then
|
||||||
marker:set_properties({
|
marker:set_properties({
|
||||||
visual_size={x=sizez * 2, y=sizey * 2},
|
visual_size={x=sizez * 2, y=sizey * 2},
|
||||||
@ -111,6 +116,13 @@ worldedit.mark_region = function(name)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--convenience function that calls everything
|
||||||
|
worldedit.marker_update = function(name)
|
||||||
|
worldedit.mark_pos1(name, false)
|
||||||
|
worldedit.mark_pos2(name, false)
|
||||||
|
worldedit.mark_region(name)
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_entity(":worldedit:pos1", {
|
minetest.register_entity(":worldedit:pos1", {
|
||||||
initial_properties = {
|
initial_properties = {
|
||||||
visual = "cube",
|
visual = "cube",
|
||||||
@ -120,9 +132,11 @@ minetest.register_entity(":worldedit:pos1", {
|
|||||||
"worldedit_pos1.png", "worldedit_pos1.png"},
|
"worldedit_pos1.png", "worldedit_pos1.png"},
|
||||||
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
||||||
physical = false,
|
physical = false,
|
||||||
|
static_save = false,
|
||||||
},
|
},
|
||||||
on_step = function(self, dtime)
|
on_activate = function(self, staticdata, dtime_s)
|
||||||
if worldedit.marker1[self.player_name] == nil then
|
if staticdata ~= init_sentinel then
|
||||||
|
-- we were loaded from before static_save = false was added
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
@ -130,6 +144,9 @@ minetest.register_entity(":worldedit:pos1", {
|
|||||||
self.object:remove()
|
self.object:remove()
|
||||||
worldedit.marker1[self.player_name] = nil
|
worldedit.marker1[self.player_name] = nil
|
||||||
end,
|
end,
|
||||||
|
on_blast = function(self, damage)
|
||||||
|
return false, false, {} -- don't damage or knockback
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_entity(":worldedit:pos2", {
|
minetest.register_entity(":worldedit:pos2", {
|
||||||
@ -141,9 +158,11 @@ minetest.register_entity(":worldedit:pos2", {
|
|||||||
"worldedit_pos2.png", "worldedit_pos2.png"},
|
"worldedit_pos2.png", "worldedit_pos2.png"},
|
||||||
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
|
||||||
physical = false,
|
physical = false,
|
||||||
|
static_save = false,
|
||||||
},
|
},
|
||||||
on_step = function(self, dtime)
|
on_activate = function(self, staticdata, dtime_s)
|
||||||
if worldedit.marker2[self.player_name] == nil then
|
if staticdata ~= init_sentinel then
|
||||||
|
-- we were loaded from before static_save = false was added
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
@ -151,6 +170,9 @@ minetest.register_entity(":worldedit:pos2", {
|
|||||||
self.object:remove()
|
self.object:remove()
|
||||||
worldedit.marker2[self.player_name] = nil
|
worldedit.marker2[self.player_name] = nil
|
||||||
end,
|
end,
|
||||||
|
on_blast = function(self, damage)
|
||||||
|
return false, false, {} -- don't damage or knockback
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_entity(":worldedit:region_cube", {
|
minetest.register_entity(":worldedit:region_cube", {
|
||||||
@ -159,11 +181,12 @@ minetest.register_entity(":worldedit:region_cube", {
|
|||||||
textures = {"worldedit_cube.png"},
|
textures = {"worldedit_cube.png"},
|
||||||
visual_size = {x=10, y=10},
|
visual_size = {x=10, y=10},
|
||||||
physical = false,
|
physical = false,
|
||||||
|
static_save = false,
|
||||||
},
|
},
|
||||||
on_step = function(self, dtime)
|
on_activate = function(self, staticdata, dtime_s)
|
||||||
if worldedit.marker_region[self.player_name] == nil then
|
if staticdata ~= init_sentinel then
|
||||||
|
-- we were loaded from before static_save = false was added
|
||||||
self.object:remove()
|
self.object:remove()
|
||||||
return
|
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_punch = function(self, hitter)
|
on_punch = function(self, hitter)
|
||||||
@ -176,5 +199,8 @@ minetest.register_entity(":worldedit:region_cube", {
|
|||||||
end
|
end
|
||||||
worldedit.marker_region[self.player_name] = nil
|
worldedit.marker_region[self.player_name] = nil
|
||||||
end,
|
end,
|
||||||
|
on_blast = function(self, damage)
|
||||||
|
return false, false, {} -- don't damage or knockback
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -132,11 +132,21 @@ local function handle_changes(name, identifier, fields, def)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- This has the same behaviour as the player invoking the chat command
|
||||||
|
local function execute_worldedit_command(command_name, player_name, params)
|
||||||
|
local chatcmd = minetest.registered_chatcommands["/" .. command_name]
|
||||||
|
assert(chatcmd, "unknown command: " .. command_name)
|
||||||
|
local _, msg = chatcmd.func(player_name, params)
|
||||||
|
if msg then
|
||||||
|
worldedit.player_notify(player_name, msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
worldedit.register_gui_function("worldedit_gui_about", {
|
worldedit.register_gui_function("worldedit_gui_about", {
|
||||||
name = "About",
|
name = "About",
|
||||||
privs = {interact=true},
|
privs = {interact=true},
|
||||||
on_select = function(name)
|
on_select = function(name)
|
||||||
minetest.chatcommands["/about"].func(name, "")
|
execute_worldedit_command("about", name, "")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -144,7 +154,8 @@ worldedit.register_gui_function("worldedit_gui_inspect", {
|
|||||||
name = "Toggle Inspect",
|
name = "Toggle Inspect",
|
||||||
privs = we_privs("inspect"),
|
privs = we_privs("inspect"),
|
||||||
on_select = function(name)
|
on_select = function(name)
|
||||||
minetest.chatcommands["/inspect"].func(name, worldedit.inspect[name] and "disable" or "enable")
|
execute_worldedit_command("inspect", name,
|
||||||
|
worldedit.inspect[name] and "disable" or "enable")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -178,47 +189,47 @@ worldedit.register_gui_function("worldedit_gui_region", {
|
|||||||
|
|
||||||
worldedit.register_gui_handler("worldedit_gui_region", function(name, fields)
|
worldedit.register_gui_handler("worldedit_gui_region", function(name, fields)
|
||||||
if fields.worldedit_gui_p_get then
|
if fields.worldedit_gui_p_get then
|
||||||
minetest.chatcommands["/p"].func(name, "get")
|
execute_worldedit_command("p", name, "get")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_p_set1 then
|
elseif fields.worldedit_gui_p_set1 then
|
||||||
minetest.chatcommands["/p"].func(name, "set1")
|
execute_worldedit_command("p", name, "set1")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_p_set2 then
|
elseif fields.worldedit_gui_p_set2 then
|
||||||
minetest.chatcommands["/p"].func(name, "set2")
|
execute_worldedit_command("p", name, "set2")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_pos1 then
|
elseif fields.worldedit_gui_pos1 then
|
||||||
minetest.chatcommands["/pos1"].func(name, "")
|
execute_worldedit_command("pos1", name, "")
|
||||||
worldedit.show_page(name, "worldedit_gui_region")
|
worldedit.show_page(name, "worldedit_gui_region")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_pos2 then
|
elseif fields.worldedit_gui_pos2 then
|
||||||
minetest.chatcommands["/pos2"].func(name, "")
|
execute_worldedit_command("pos2", name, "")
|
||||||
worldedit.show_page(name, "worldedit_gui_region")
|
worldedit.show_page(name, "worldedit_gui_region")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_reset then
|
elseif fields.worldedit_gui_reset then
|
||||||
minetest.chatcommands["/reset"].func(name, "")
|
execute_worldedit_command("reset", name, "")
|
||||||
worldedit.show_page(name, "worldedit_gui_region")
|
worldedit.show_page(name, "worldedit_gui_region")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_mark then
|
elseif fields.worldedit_gui_mark then
|
||||||
minetest.chatcommands["/mark"].func(name, "")
|
execute_worldedit_command("mark", name, "")
|
||||||
worldedit.show_page(name, "worldedit_gui_region")
|
worldedit.show_page(name, "worldedit_gui_region")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_unmark then
|
elseif fields.worldedit_gui_unmark then
|
||||||
minetest.chatcommands["/unmark"].func(name, "")
|
execute_worldedit_command("unmark", name, "")
|
||||||
worldedit.show_page(name, "worldedit_gui_region")
|
worldedit.show_page(name, "worldedit_gui_region")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_volume then
|
elseif fields.worldedit_gui_volume then
|
||||||
minetest.chatcommands["/volume"].func(name, "")
|
execute_worldedit_command("volume", name, "")
|
||||||
worldedit.show_page(name, "worldedit_gui_region")
|
worldedit.show_page(name, "worldedit_gui_region")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_fixedpos_pos1_submit then
|
elseif fields.worldedit_gui_fixedpos_pos1_submit then
|
||||||
minetest.chatcommands["/fixedpos"].func(name, string.format("set1 %s %s %s",
|
execute_worldedit_command("fixedpos", name, ("set1 %s %s %s"):format(
|
||||||
tostring(fields.worldedit_gui_fixedpos_pos1x),
|
tostring(fields.worldedit_gui_fixedpos_pos1x),
|
||||||
tostring(fields.worldedit_gui_fixedpos_pos1y),
|
tostring(fields.worldedit_gui_fixedpos_pos1y),
|
||||||
tostring(fields.worldedit_gui_fixedpos_pos1z)))
|
tostring(fields.worldedit_gui_fixedpos_pos1z)))
|
||||||
worldedit.show_page(name, "worldedit_gui_region")
|
worldedit.show_page(name, "worldedit_gui_region")
|
||||||
return true
|
return true
|
||||||
elseif fields.worldedit_gui_fixedpos_pos2_submit then
|
elseif fields.worldedit_gui_fixedpos_pos2_submit then
|
||||||
minetest.chatcommands["/fixedpos"].func(name, string.format("set2 %s %s %s",
|
execute_worldedit_command("fixedpos", name, ("set2 %s %s %s"):format(
|
||||||
tostring(fields.worldedit_gui_fixedpos_pos2x),
|
tostring(fields.worldedit_gui_fixedpos_pos2x),
|
||||||
tostring(fields.worldedit_gui_fixedpos_pos2y),
|
tostring(fields.worldedit_gui_fixedpos_pos2y),
|
||||||
tostring(fields.worldedit_gui_fixedpos_pos2z)))
|
tostring(fields.worldedit_gui_fixedpos_pos2z)))
|
||||||
@ -255,7 +266,7 @@ worldedit.register_gui_handler("worldedit_gui_set", function(name, fields)
|
|||||||
|
|
||||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
if n then
|
if n then
|
||||||
minetest.chatcommands["/set"].func(name, n)
|
execute_worldedit_command("set", name, n)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -301,7 +312,7 @@ worldedit.register_gui_handler("worldedit_gui_replace", function(name, fields)
|
|||||||
local n1 = worldedit.normalize_nodename(gui_nodename1[name])
|
local n1 = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
local n2 = worldedit.normalize_nodename(gui_nodename2[name])
|
local n2 = worldedit.normalize_nodename(gui_nodename2[name])
|
||||||
if n1 and n2 then
|
if n1 and n2 then
|
||||||
minetest.chatcommands["/"..submit].func(name, string.format("%s %s", n1, n2))
|
execute_worldedit_command(submit, name, n1 .. " " .. n2)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -350,7 +361,8 @@ worldedit.register_gui_handler("worldedit_gui_sphere_dome", function(name, field
|
|||||||
end
|
end
|
||||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
if n then
|
if n then
|
||||||
minetest.chatcommands["/"..submit].func(name, string.format("%s %s", gui_distance2[name], n))
|
execute_worldedit_command(submit, name,
|
||||||
|
gui_distance2[name] .. " " .. n)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -404,7 +416,7 @@ worldedit.register_gui_handler("worldedit_gui_cylinder", function(name, fields)
|
|||||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
if n then
|
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)
|
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)
|
execute_worldedit_command(submit, name, args)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -448,7 +460,9 @@ worldedit.register_gui_handler("worldedit_gui_pyramid", function(name, fields)
|
|||||||
end
|
end
|
||||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
if n then
|
if n then
|
||||||
minetest.chatcommands["/"..submit].func(name, string.format("%s %s %s", axis_values[gui_axis1[name]], gui_distance1[name], n))
|
execute_worldedit_command(submit, name,
|
||||||
|
string.format("%s %s %s", axis_values[gui_axis1[name]],
|
||||||
|
gui_distance1[name], n))
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -491,7 +505,9 @@ worldedit.register_gui_handler("worldedit_gui_spiral", function(name, fields)
|
|||||||
|
|
||||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
if n then
|
if n then
|
||||||
minetest.chatcommands["/spiral"].func(name, string.format("%s %s %s %s", gui_distance1[name], gui_distance2[name], gui_distance3[name], n))
|
execute_worldedit_command("spiral", name,
|
||||||
|
string.format("%s %s %s %s", gui_distance1[name],
|
||||||
|
gui_distance2[name], gui_distance3[name], n))
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -527,7 +543,8 @@ worldedit.register_gui_handler("worldedit_gui_copy_move", function(name, fields)
|
|||||||
if fields.worldedit_gui_copy_move_move then
|
if fields.worldedit_gui_copy_move_move then
|
||||||
submit = "move"
|
submit = "move"
|
||||||
end
|
end
|
||||||
minetest.chatcommands["/"..submit].func(name, string.format("%s %s", axis_values[gui_axis1[name]], gui_distance1[name]))
|
execute_worldedit_command(submit, name,
|
||||||
|
axis_values[gui_axis1[name]] .. " " .. gui_distance1[name])
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
@ -556,7 +573,8 @@ worldedit.register_gui_handler("worldedit_gui_stack", function(name, fields)
|
|||||||
copy_changes(name, fields, cg)
|
copy_changes(name, fields, cg)
|
||||||
worldedit.show_page(name, "worldedit_gui_stack")
|
worldedit.show_page(name, "worldedit_gui_stack")
|
||||||
|
|
||||||
minetest.chatcommands["/stack"].func(name, string.format("%s %s", axis_values[gui_axis1[name]], gui_count1[name]))
|
execute_worldedit_command("stack", name,
|
||||||
|
axis_values[gui_axis1[name]] .. " " .. gui_count1[name])
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
@ -589,7 +607,8 @@ worldedit.register_gui_handler("worldedit_gui_stretch", function(name, fields)
|
|||||||
copy_changes(name, fields, cg)
|
copy_changes(name, fields, cg)
|
||||||
worldedit.show_page(name, "worldedit_gui_stretch")
|
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]))
|
execute_worldedit_command("stretch", name, string.format("%s %s %s",
|
||||||
|
gui_count1[name], gui_count2[name], gui_count3[name]))
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
@ -616,7 +635,8 @@ worldedit.register_gui_handler("worldedit_gui_transpose", function(name, fields)
|
|||||||
if fields.worldedit_gui_transpose_submit then
|
if fields.worldedit_gui_transpose_submit then
|
||||||
copy_changes(name, fields, cg)
|
copy_changes(name, fields, cg)
|
||||||
|
|
||||||
minetest.chatcommands["/transpose"].func(name, string.format("%s %s", axis_values[gui_axis1[name]], axis_values[gui_axis2[name]]))
|
execute_worldedit_command("transpose", name,
|
||||||
|
axis_values[gui_axis1[name]] .. " " .. axis_values[gui_axis2[name]])
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
@ -642,7 +662,7 @@ worldedit.register_gui_handler("worldedit_gui_flip", function(name, fields)
|
|||||||
copy_changes(name, fields, cg)
|
copy_changes(name, fields, cg)
|
||||||
worldedit.show_page(name, "worldedit_gui_flip")
|
worldedit.show_page(name, "worldedit_gui_flip")
|
||||||
|
|
||||||
minetest.chatcommands["/flip"].func(name, axis_values[gui_axis1[name]])
|
execute_worldedit_command("flip", name, axis_values[gui_axis1[name]])
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
@ -670,7 +690,8 @@ worldedit.register_gui_handler("worldedit_gui_rotate", function(name, fields)
|
|||||||
copy_changes(name, fields, cg)
|
copy_changes(name, fields, cg)
|
||||||
worldedit.show_page(name, "worldedit_gui_rotate")
|
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]]))
|
execute_worldedit_command("rotate", name,
|
||||||
|
axis_values[gui_axis1[name]] .. " " .. angle_values[gui_angle[name]])
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
@ -696,7 +717,8 @@ worldedit.register_gui_handler("worldedit_gui_orient", function(name, fields)
|
|||||||
copy_changes(name, fields, cg)
|
copy_changes(name, fields, cg)
|
||||||
worldedit.show_page(name, "worldedit_gui_orient")
|
worldedit.show_page(name, "worldedit_gui_orient")
|
||||||
|
|
||||||
minetest.chatcommands["/orient"].func(name, tostring(angle_values[gui_angle[name]]))
|
execute_worldedit_command("orient", name,
|
||||||
|
tostring(angle_values[gui_angle[name]]))
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
@ -706,7 +728,7 @@ worldedit.register_gui_function("worldedit_gui_fixlight", {
|
|||||||
name = "Fix Lighting",
|
name = "Fix Lighting",
|
||||||
privs = we_privs("fixlight"),
|
privs = we_privs("fixlight"),
|
||||||
on_select = function(name)
|
on_select = function(name)
|
||||||
minetest.chatcommands["/fixlight"].func(name, "")
|
execute_worldedit_command("fixlight", name, "")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -714,7 +736,7 @@ worldedit.register_gui_function("worldedit_gui_hide", {
|
|||||||
name = "Hide Region",
|
name = "Hide Region",
|
||||||
privs = we_privs("hide"),
|
privs = we_privs("hide"),
|
||||||
on_select = function(name)
|
on_select = function(name)
|
||||||
minetest.chatcommands["/hide"].func(name, "")
|
execute_worldedit_command("hide", name, "")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -745,7 +767,7 @@ worldedit.register_gui_handler("worldedit_gui_suppress", function(name, fields)
|
|||||||
|
|
||||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
if n then
|
if n then
|
||||||
minetest.chatcommands["/suppress"].func(name, n)
|
execute_worldedit_command("suppress", name, n)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -779,7 +801,7 @@ worldedit.register_gui_handler("worldedit_gui_highlight", function(name, fields)
|
|||||||
|
|
||||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
if n then
|
if n then
|
||||||
minetest.chatcommands["/highlight"].func(name, n)
|
execute_worldedit_command("highlight", name, n)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -790,7 +812,7 @@ worldedit.register_gui_function("worldedit_gui_restore", {
|
|||||||
name = "Restore Region",
|
name = "Restore Region",
|
||||||
privs = we_privs("restore"),
|
privs = we_privs("restore"),
|
||||||
on_select = function(name)
|
on_select = function(name)
|
||||||
minetest.chatcommands["/restore"].func(name, "")
|
execute_worldedit_command("restore", name, "")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -814,11 +836,11 @@ worldedit.register_gui_handler("worldedit_gui_save_load", function(name, fields)
|
|||||||
worldedit.show_page(name, "worldedit_gui_save_load")
|
worldedit.show_page(name, "worldedit_gui_save_load")
|
||||||
|
|
||||||
if fields.worldedit_gui_save_load_submit_save then
|
if fields.worldedit_gui_save_load_submit_save then
|
||||||
minetest.chatcommands["/save"].func(name, gui_filename[name])
|
execute_worldedit_command("save", name, gui_filename[name])
|
||||||
elseif fields.worldedit_gui_save_load_submit_allocate then
|
elseif fields.worldedit_gui_save_load_submit_allocate then
|
||||||
minetest.chatcommands["/allocate"].func(name, gui_filename[name])
|
execute_worldedit_command("allocate", name, gui_filename[name])
|
||||||
else --fields.worldedit_gui_save_load_submit_load
|
else --fields.worldedit_gui_save_load_submit_load
|
||||||
minetest.chatcommands["/load"].func(name, gui_filename[name])
|
execute_worldedit_command("load", name, gui_filename[name])
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -868,7 +890,7 @@ worldedit.register_gui_handler("worldedit_gui_cube", function(name, fields)
|
|||||||
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
local n = worldedit.normalize_nodename(gui_nodename1[name])
|
||||||
if n then
|
if n then
|
||||||
local args = string.format("%s %s %s %s", gui_distance1[name], gui_distance2[name], gui_distance3[name], n)
|
local args = string.format("%s %s %s %s", gui_distance1[name], gui_distance2[name], gui_distance3[name], n)
|
||||||
minetest.chatcommands["/"..submit].func(name, args)
|
execute_worldedit_command(submit, name, args)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -879,6 +901,6 @@ worldedit.register_gui_function("worldedit_gui_clearobjects", {
|
|||||||
name = "Clear Objects",
|
name = "Clear Objects",
|
||||||
privs = we_privs("clearobjects"),
|
privs = we_privs("clearobjects"),
|
||||||
on_select = function(name)
|
on_select = function(name)
|
||||||
minetest.chatcommands["/clearobjects"].func(name, "")
|
execute_worldedit_command("clearobjects", name, "")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user