mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-23 03:55:01 +00:00
commit
7f6c8e146e
12 changed files with 198 additions and 6 deletions
|
@ -1,9 +1,13 @@
|
||||||
# WorldEditAdditions Changelog
|
# WorldEditAdditions Changelog
|
||||||
It's about time I started a changelog! This will serve from now on as the main changelog for WorldEditAdditions.
|
It's about time I started a changelog! This will serve from now on as the main changelog for WorldEditAdditions.
|
||||||
|
|
||||||
|
Note to self: See the bottom of this file for the release template text.
|
||||||
|
|
||||||
## v1.12 (unreleased)
|
## v1.12 (unreleased)
|
||||||
- Add `//srect` (_select rectangle_) - thanks, @VorTechnix!
|
- Add `//srect` (_select rectangle_) - thanks, @VorTechnix!
|
||||||
|
- Add `//spush`, `//spop`, and `//sstack`
|
||||||
|
- `//overlay`: Don't place nodes above water
|
||||||
|
|
||||||
|
|
||||||
## v1.11: The big data update (25th January 2021)
|
## v1.11: The big data update (25th January 2021)
|
||||||
- Add `//scale` (currently **experimental**)
|
- Add `//scale` (currently **experimental**)
|
||||||
|
|
|
@ -491,6 +491,30 @@ Short for _select rectangle_. Sets the pos2 at a set distance along 2 axes from
|
||||||
//srect -z y 25
|
//srect -z y 25
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `//sstack`
|
||||||
|
Displays the contents of your per-user selection stack. This stack can be pushed to and popped from rather like a stack of plates. See also `//spush` (for pushing to the selection stack) and `//spop` (for popping from the selection stack).
|
||||||
|
|
||||||
|
```
|
||||||
|
//sstack
|
||||||
|
```
|
||||||
|
|
||||||
|
## `//spush`
|
||||||
|
Pushes the currently defined region onto your per-user selection stack. Does not otherwise alter the defined region.
|
||||||
|
|
||||||
|
If the stack is full (currently the limit is set to 100 regions in the stack), then it will complain at you but otherwise will have no effect.
|
||||||
|
|
||||||
|
Note that pos2 does _not_ need to be defined in order to use this. if it isn't defined, then a pos2 of `nil` will be pushed onto the stack instead.
|
||||||
|
|
||||||
|
```
|
||||||
|
//spush
|
||||||
|
```
|
||||||
|
|
||||||
|
## `//spop`
|
||||||
|
Pops a selection off your per-user selection stack and applies it to the currently defined region. If pos2 from the item popped from the stack is nil, then pos2 is explicitly unset. If the stack is empty, this has no effect.
|
||||||
|
|
||||||
|
```
|
||||||
|
//spop
|
||||||
|
```
|
||||||
|
|
||||||
## `//y`
|
## `//y`
|
||||||
Confirms the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command.
|
Confirms the execution of a command if it could potentially affect a large number of nodes and take a while. This is a regular WorldEdit command.
|
||||||
|
|
|
@ -40,7 +40,6 @@ The detailed explanations have moved! Check them out [here](https://github.com/s
|
||||||
- [`//replacemix <target_node> [<chance>] <replace_node_a> [<chance_a>] [<replace_node_b> [<chance_b>]] [<replace_node_N> [<chance_N>]] ....`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#replacemix-target_node-chance-replace_node_a-chance_a-replace_node_b-chance_b-replace_node_n-chance_n-)
|
- [`//replacemix <target_node> [<chance>] <replace_node_a> [<chance_a>] [<replace_node_b> [<chance_b>]] [<replace_node_N> [<chance_N>]] ....`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#replacemix-target_node-chance-replace_node_a-chance_a-replace_node_b-chance_b-replace_node_n-chance_n-)
|
||||||
- [`//floodfill [<replace_node> [<radius>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#floodfill-replace_node-radius-floodfill)
|
- [`//floodfill [<replace_node> [<radius>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#floodfill-replace_node-radius-floodfill)
|
||||||
- [`//scale <axis> <scale_factor> | <factor_x> [<factor_y> <factor_z> [<anchor_x> <anchor_y> <anchor_z>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#scale-axis-scale_factor--factor_x-factor_y-factor_z-anchor_x-anchor_y-anchor_z) **experimental**
|
- [`//scale <axis> <scale_factor> | <factor_x> [<factor_y> <factor_z> [<anchor_x> <anchor_y> <anchor_z>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#scale-axis-scale_factor--factor_x-factor_y-factor_z-anchor_x-anchor_y-anchor_z) **experimental**
|
||||||
- [`//srect [<axis1> [<axis2>]] <length>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#srect-axis1-axis2-length)
|
|
||||||
|
|
||||||
### Terrain
|
### Terrain
|
||||||
- [`//overlay <node_name_a> [<chance_a>] <node_name_b> [<chance_b>] [<node_name_N> [<chance_N>]] ...`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-)
|
- [`//overlay <node_name_a> [<chance_a>] <node_name_b> [<chance_b>] [<node_name_N> [<chance_N>]] ...`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#overlay-node_name_a-chance_a-node_name_b-chance_b-node_name_n-chance_n-)
|
||||||
|
@ -57,6 +56,12 @@ The detailed explanations have moved! Check them out [here](https://github.com/s
|
||||||
### Statistics
|
### Statistics
|
||||||
- [`//count`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#count)
|
- [`//count`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#count)
|
||||||
|
|
||||||
|
### Selection
|
||||||
|
- [`//srect [<axis1> [<axis2>]] <length>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#srect-axis1-axis2-length)
|
||||||
|
- [`//sstack`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#sstack)
|
||||||
|
- [`//spush`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#spush)
|
||||||
|
- [`//spop`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#spop)
|
||||||
|
|
||||||
### Meta
|
### Meta
|
||||||
- [`//multi <command_a> <command_b> ....`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#multi-command_a-command_b-command_c-)
|
- [`//multi <command_a> <command_b> ....`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#multi-command_a-command_b-command_c-)
|
||||||
- [`//many <times> <command>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#many-times-command) _(new in v1.9)_
|
- [`//many <times> <command>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#many-times-command) _(new in v1.9)_
|
||||||
|
|
|
@ -45,3 +45,4 @@ dofile(worldeditadditions.modpath.."/lib/forest.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/ellipsoidapply.lua")
|
dofile(worldeditadditions.modpath.."/lib/ellipsoidapply.lua")
|
||||||
|
|
||||||
dofile(worldeditadditions.modpath.."/lib/subdivide.lua")
|
dofile(worldeditadditions.modpath.."/lib/subdivide.lua")
|
||||||
|
dofile(worldeditadditions.modpath.."/lib/selection/stack.lua")
|
||||||
|
|
|
@ -23,32 +23,38 @@ function worldeditadditions.overlay(pos1, pos2, node_weights)
|
||||||
for x = pos2.x, pos1.x, -1 do
|
for x = pos2.x, pos1.x, -1 do
|
||||||
local found_air = false
|
local found_air = false
|
||||||
local placed_node = false
|
local placed_node = false
|
||||||
|
-- print("\n\n[overlay] ****** column start ******")
|
||||||
for y = pos2.y, pos1.y, -1 do
|
for y = pos2.y, pos1.y, -1 do
|
||||||
local i = area:index(x, y, z)
|
local i = area:index(x, y, z)
|
||||||
|
-- print("[overlay] pos", x, y, z, "id", data[i], "name", minetest.get_name_from_content_id(data[i]), "is_liquid", worldeditadditions.is_liquidlike(data[i]))
|
||||||
|
|
||||||
local is_air = worldeditadditions.is_airlike(data[i])
|
local is_air = worldeditadditions.is_airlike(data[i])
|
||||||
|
local is_liquid = worldeditadditions.is_liquidlike(data[i])
|
||||||
-- wielded_light is now handled by worldeditadditions.is_airlike
|
-- wielded_light is now handled by worldeditadditions.is_airlike
|
||||||
|
|
||||||
local is_ignore = data[i] == node_id_ignore
|
local is_ignore = data[i] == node_id_ignore
|
||||||
|
|
||||||
if not is_air and not is_ignore then
|
if not is_air and not is_ignore then
|
||||||
if found_air then
|
local i_above = area:index(x, y + 1, z)
|
||||||
|
if found_air and not is_liquid then
|
||||||
local new_id = node_ids[math.random(node_ids_count)]
|
local new_id = node_ids[math.random(node_ids_count)]
|
||||||
-- We've found an air block previously, so it must be above us
|
-- We've found an air block previously, so it must be above us
|
||||||
-- Replace the node above us with the target block
|
-- Replace the node above us with the target block
|
||||||
data[area:index(x, y + 1, z)] = new_id
|
data[i_above] = new_id
|
||||||
changes.updated = changes.updated + 1
|
changes.updated = changes.updated + 1
|
||||||
placed_node = true
|
placed_node = true
|
||||||
if not changes.placed[new_id] then
|
if not changes.placed[new_id] then
|
||||||
changes.placed[new_id] = 0
|
changes.placed[new_id] = 0
|
||||||
end
|
end
|
||||||
changes.placed[new_id] = changes.placed[new_id] + 1
|
changes.placed[new_id] = changes.placed[new_id] + 1
|
||||||
|
-- print("[overlay] placed above ", x, y, z)
|
||||||
break -- Move on to the next column
|
break -- Move on to the next column
|
||||||
end
|
end
|
||||||
elseif not is_ignore then
|
elseif not is_ignore and not is_liquid then
|
||||||
|
-- print("[overlay] found air at", x, y, z)
|
||||||
found_air = true
|
found_air = true
|
||||||
end
|
end
|
||||||
|
if is_liquid then found_air = false end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not placed_node then
|
if not placed_node then
|
||||||
|
|
47
worldeditadditions/lib/selection/stack.lua
Normal file
47
worldeditadditions/lib/selection/stack.lua
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
--- Holds the per-user selection stacks.
|
||||||
|
worldeditadditions.sstack = {}
|
||||||
|
|
||||||
|
local sstack_max = 100
|
||||||
|
|
||||||
|
--- Calculates the height of the selection stack for the defined user.
|
||||||
|
-- If the defined user doesn't yet have a stack, a value of 0 is returned.
|
||||||
|
-- @param user string The name of the user to count the size of the selection stack for.
|
||||||
|
-- @return number The number of items on the stack for the given user.
|
||||||
|
function worldeditadditions.scount(name)
|
||||||
|
if not worldeditadditions.sstack[name] then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
return #worldeditadditions.sstack[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Inserts a selection region onto the stack for the user with the given name.
|
||||||
|
-- Stacks are per-user.
|
||||||
|
-- @param name string The name of the user to insert onto.
|
||||||
|
-- @param pos1 Vector Position 1
|
||||||
|
-- @param pos2 Vector Position 2
|
||||||
|
function worldeditadditions.spush(name, pos1, pos2)
|
||||||
|
if not worldeditadditions.sstack[name] then
|
||||||
|
worldeditadditions.sstack[name] = {}
|
||||||
|
end
|
||||||
|
-- Checck the stack height
|
||||||
|
if #worldeditadditions.sstack[name] > sstack_max then
|
||||||
|
return false, "Error: Selection stack height of "..sstack_max.." would be exceeded by pushing a new selection onto the stack now."
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(worldeditadditions.sstack[name], { pos1, pos2 })
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Pops a selection region off the stack for the given user.
|
||||||
|
-- Stacks are per-user.
|
||||||
|
-- @param name string The name of the user to remove a selection region off the stack for.
|
||||||
|
-- @return bool,Vector|string, Vector A bool true/false indicating success, followed by either a error message as a string if false or a pair of Vectors for the pos1 and pos2 from the item popped from the stack respectively.
|
||||||
|
function worldeditadditions.spop(name)
|
||||||
|
if not worldeditadditions.sstack[name] or #worldeditadditions.sstack[name] == 0 then
|
||||||
|
return false, "Error: The stack for user "..name.." is empty, so can't remove anything from it."
|
||||||
|
end
|
||||||
|
|
||||||
|
local item = table.remove(worldeditadditions.sstack[name])
|
||||||
|
return true, item[1], item[2]
|
||||||
|
end
|
|
@ -44,7 +44,7 @@ function worldeditadditions.is_liquidlike(id)
|
||||||
if node_name == nil or not minetest.registered_nodes[node_name] then return false end
|
if node_name == nil or not minetest.registered_nodes[node_name] then return false end
|
||||||
|
|
||||||
local liquidtype = minetest.registered_nodes[node_name].liquidtype
|
local liquidtype = minetest.registered_nodes[node_name].liquidtype
|
||||||
-- print("[is_liquidlike]", "id", id, "liquidtype", liquidtype)
|
-- print("[is_liquidlike]", "id", id, "name", node_name, "liquidtype", liquidtype)
|
||||||
|
|
||||||
if liquidtype == nil or liquidtype == "none" then return false end
|
if liquidtype == nil or liquidtype == "none" then return false end
|
||||||
-- If it's not none, then it has to be a liquid as the only other values are source and flowing
|
-- If it's not none, then it has to be a liquid as the only other values are source and flowing
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
worldeditadditions.vector = {}
|
worldeditadditions.vector = {}
|
||||||
|
|
||||||
function worldeditadditions.vector.tostring(v)
|
function worldeditadditions.vector.tostring(v)
|
||||||
|
if not v then return "(nil)" end
|
||||||
return "(" .. v.x ..", " .. v.y ..", " .. v.z ..")"
|
return "(" .. v.x ..", " .. v.y ..", " .. v.z ..")"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
33
worldeditadditions_commands/commands/selectors/spop.lua
Normal file
33
worldeditadditions_commands/commands/selectors/spop.lua
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
-- ███████ ██████ ██████ ██████
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ██████ ██ ██ ██████
|
||||||
|
-- ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ██ ██████ ██
|
||||||
|
worldedit.register_command("spop", {
|
||||||
|
params = "",
|
||||||
|
description = "Pops a region off your (per-user) selection stack.",
|
||||||
|
privs = { worldedit = true },
|
||||||
|
parse = function(params_text)
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
nodes_needed = function(name)
|
||||||
|
return 0
|
||||||
|
end,
|
||||||
|
func = function(name)
|
||||||
|
local success, pos1, pos2 = worldeditadditions.spop(name)
|
||||||
|
if not success then return success, pos1 end
|
||||||
|
|
||||||
|
worldedit.pos1[name] = pos1
|
||||||
|
worldedit.pos2[name] = pos2
|
||||||
|
worldedit.marker_update(name)
|
||||||
|
|
||||||
|
local new_count = worldeditadditions.scount(name)
|
||||||
|
local plural = "s are"
|
||||||
|
if new_count == 1 then plural = " is" end
|
||||||
|
|
||||||
|
local region_text = worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])
|
||||||
|
|
||||||
|
minetest.log("action", name .. " used //spush at "..region_text..". Stack height is now " .. new_count.." regions")
|
||||||
|
return true, "Region "..region_text.." pushed onto selection stack; "..new_count.." region"..plural.." now in the stack"
|
||||||
|
end
|
||||||
|
})
|
32
worldeditadditions_commands/commands/selectors/spush.lua
Normal file
32
worldeditadditions_commands/commands/selectors/spush.lua
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
-- ███████ ██████ ██ ██ ███████ ██ ██
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ██████ ██ ██ ███████ ███████
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ██ ██████ ███████ ██ ██
|
||||||
|
worldedit.register_command("spush", {
|
||||||
|
params = "",
|
||||||
|
description = "Pushes the currently defined region onto your (per-user) selection stack.",
|
||||||
|
privs = { worldedit = true },
|
||||||
|
require_pos = 1,
|
||||||
|
parse = function(params_text)
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
nodes_needed = function(name)
|
||||||
|
return 0
|
||||||
|
end,
|
||||||
|
func = function(name)
|
||||||
|
local success, msg = worldeditadditions.spush(name, worldedit.pos1[name], worldedit.pos2[name])
|
||||||
|
if not success then
|
||||||
|
return success, msg
|
||||||
|
end
|
||||||
|
|
||||||
|
local new_count = worldeditadditions.scount(name)
|
||||||
|
local plural = "s are"
|
||||||
|
if new_count == 1 then plural = " is" end
|
||||||
|
|
||||||
|
local region_text = worldeditadditions.vector.tostring(worldedit.pos1[name]).." - "..worldeditadditions.vector.tostring(worldedit.pos2[name])
|
||||||
|
|
||||||
|
minetest.log("action", name .. " used //spush at "..region_text..". Stack height is now " .. new_count.." regions")
|
||||||
|
return true, "Region "..region_text.." pushed onto selection stack; "..new_count.." region"..plural.." now in the stack"
|
||||||
|
end
|
||||||
|
})
|
36
worldeditadditions_commands/commands/selectors/sstack.lua
Normal file
36
worldeditadditions_commands/commands/selectors/sstack.lua
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
-- ███████ ███████ ████████ █████ ██████ ██ ██
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ███████ ██ ███████ ██ █████
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ███████ ██ ██ ██ ██████ ██ ██
|
||||||
|
worldedit.register_command("sstack", {
|
||||||
|
params = "",
|
||||||
|
description = "Displays the contents of your (per-user) selection stack.",
|
||||||
|
privs = { worldedit = true },
|
||||||
|
parse = function(params_text)
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
nodes_needed = function(name)
|
||||||
|
return 0
|
||||||
|
end,
|
||||||
|
func = function(name)
|
||||||
|
|
||||||
|
local result = {"Stack contents for user ", name, ":\n"}
|
||||||
|
if not worldeditadditions.sstack[name] then
|
||||||
|
table.insert(result, "(empty)")
|
||||||
|
else
|
||||||
|
for i,item in ipairs(worldeditadditions.sstack[name]) do
|
||||||
|
table.insert(result, i)
|
||||||
|
table.insert(result, ": ")
|
||||||
|
table.insert(result, worldeditadditions.vector.tostring(item[1]))
|
||||||
|
table.insert(result, " - ")
|
||||||
|
table.insert(result, worldeditadditions.vector.tostring(item[2]))
|
||||||
|
table.insert(result, "\n")
|
||||||
|
end
|
||||||
|
table.insert(result, "========================\nTotal ")
|
||||||
|
table.insert(result, #worldeditadditions.sstack[name])
|
||||||
|
table.insert(result, " items")
|
||||||
|
end
|
||||||
|
return true, table.concat(result, "")
|
||||||
|
end
|
||||||
|
})
|
|
@ -44,6 +44,9 @@ dofile(we_c.modpath.."/commands/meta/ellipsoidapply.lua")
|
||||||
-- dofile(we_c.modpath.."/commands/selectors/scol.lua")
|
-- dofile(we_c.modpath.."/commands/selectors/scol.lua")
|
||||||
dofile(we_c.modpath.."/commands/selectors/srect.lua")
|
dofile(we_c.modpath.."/commands/selectors/srect.lua")
|
||||||
-- dofile(we_c.modpath.."/commands/selectors/scube.lua")
|
-- dofile(we_c.modpath.."/commands/selectors/scube.lua")
|
||||||
|
dofile(we_c.modpath.."/commands/selectors/sstack.lua")
|
||||||
|
dofile(we_c.modpath.."/commands/selectors/spush.lua")
|
||||||
|
dofile(we_c.modpath.."/commands/selectors/spop.lua")
|
||||||
|
|
||||||
dofile(we_c.modpath.."/commands/extra/saplingaliases.lua")
|
dofile(we_c.modpath.."/commands/extra/saplingaliases.lua")
|
||||||
dofile(we_c.modpath.."/commands/extra/basename.lua")
|
dofile(we_c.modpath.."/commands/extra/basename.lua")
|
||||||
|
|
Loading…
Reference in a new issue