mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-26 00:53:00 +00:00
//bonmeal: add optional node list constraint
This commit is contained in:
parent
3338a3fddf
commit
87f84e2482
4 changed files with 48 additions and 15 deletions
|
@ -9,7 +9,8 @@ Note to self: See the bottom of this file for the release template text.
|
||||||
- Add `//airapply` for applying commands only to air nodes in the defined region
|
- Add `//airapply` for applying commands only to air nodes in the defined region
|
||||||
- Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues
|
- Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues
|
||||||
- Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting
|
- Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting
|
||||||
- Add optional slope constraint to `//layers` (inspired by [WorldPainter](https://worldpainter.net/))
|
- `//layers`: Add optional slope constraint (inspired by [WorldPainter](https://worldpainter.net/))
|
||||||
|
- `//bonemeal`: Add optional node list contraint
|
||||||
|
|
||||||
|
|
||||||
## v1.12: The selection tools update (26th June 2021)
|
## v1.12: The selection tools update (26th June 2021)
|
||||||
|
|
|
@ -225,7 +225,7 @@ Additional examples:
|
||||||
//maze3d stone 6 3 3 54321
|
//maze3d stone 6 3 3 54321
|
||||||
```
|
```
|
||||||
|
|
||||||
## `//bonemeal [<strength> [<chance>]]`
|
## `//bonemeal [<strength> [<chance> [<node_name> [<node_name> ...]]]]`
|
||||||
Requires the [`bonemeal`](https://content.minetest.net/packages/TenPlus1/bonemeal/) ([repo](https://notabug.org/TenPlus1/bonemeal/)) mod (otherwise _WorldEditAdditions_ will not register this command and output a message to the server log). Alias: `//flora`.
|
Requires the [`bonemeal`](https://content.minetest.net/packages/TenPlus1/bonemeal/) ([repo](https://notabug.org/TenPlus1/bonemeal/)) mod (otherwise _WorldEditAdditions_ will not register this command and output a message to the server log). Alias: `//flora`.
|
||||||
|
|
||||||
Bonemeals all eligible nodes in the current region. An eligible node is one that has an air node directly above it - note that just because a node is eligible doesn't mean to say that something will actually happen when the `bonemeal` mod bonemeals it.
|
Bonemeals all eligible nodes in the current region. An eligible node is one that has an air node directly above it - note that just because a node is eligible doesn't mean to say that something will actually happen when the `bonemeal` mod bonemeals it.
|
||||||
|
@ -240,6 +240,9 @@ For example, a chance number of 2 would mean a 50% chance that any given eligibl
|
||||||
|
|
||||||
Since WorldEditAdditions v1.12, a percentage chance is also supported. This is denoted by suffixing a number with a percent sign (e.g. `//bonemeal 1 25%`).
|
Since WorldEditAdditions v1.12, a percentage chance is also supported. This is denoted by suffixing a number with a percent sign (e.g. `//bonemeal 1 25%`).
|
||||||
|
|
||||||
|
Since WorldEditAdditions v1.13, a list of node names is also optionally supported. This will constrain bonemeal operations to be performed only on the node names listed.
|
||||||
|
|
||||||
|
|
||||||
```weacmd
|
```weacmd
|
||||||
//bonemeal
|
//bonemeal
|
||||||
//bonemeal 3 25
|
//bonemeal 3 25
|
||||||
|
@ -247,6 +250,8 @@ Since WorldEditAdditions v1.12, a percentage chance is also supported. This is d
|
||||||
//bonemeal 1 10
|
//bonemeal 1 10
|
||||||
//bonemeal 2 15
|
//bonemeal 2 15
|
||||||
//bonemeal 2 10%
|
//bonemeal 2 10%
|
||||||
|
//bonemeal 2 10% dirt
|
||||||
|
//bonemeal 4 50 ethereal:grove_dirt
|
||||||
```
|
```
|
||||||
|
|
||||||
## `//walls <replace_node>`
|
## `//walls <replace_node>`
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
-- strength The strength to apply - see bonemeal:on_use
|
-- strength The strength to apply - see bonemeal:on_use
|
||||||
-- chance Positive integer that represents the chance bonemealing will occur
|
-- chance Positive integer that represents the chance bonemealing will occur
|
||||||
function worldeditadditions.bonemeal(pos1, pos2, strength, chance)
|
function worldeditadditions.bonemeal(pos1, pos2, strength, chance, nodename_list)
|
||||||
|
if not nodename_list then nodename_list = {} end
|
||||||
pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||||
-- pos2 will always have the highest co-ordinates now
|
-- pos2 will always have the highest co-ordinates now
|
||||||
|
|
||||||
|
@ -14,6 +15,12 @@ function worldeditadditions.bonemeal(pos1, pos2, strength, chance)
|
||||||
return false, "Bonemeal mod not loaded"
|
return false, "Bonemeal mod not loaded"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local node_list = worldeditadditions.table.map(nodename_list, function(nodename)
|
||||||
|
return minetest.get_content_id(nodename)
|
||||||
|
end)
|
||||||
|
local node_list_count = #nodename_list
|
||||||
|
|
||||||
|
|
||||||
-- Fetch the nodes in the specified area
|
-- Fetch the nodes in the specified area
|
||||||
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
||||||
local data = manip:get_data()
|
local data = manip:get_data()
|
||||||
|
@ -26,10 +33,17 @@ function worldeditadditions.bonemeal(pos1, pos2, strength, chance)
|
||||||
for z = pos2.z, pos1.z, -1 do
|
for z = pos2.z, pos1.z, -1 do
|
||||||
for x = pos2.x, pos1.x, -1 do
|
for x = pos2.x, pos1.x, -1 do
|
||||||
for y = pos2.y, pos1.y, -1 do
|
for y = pos2.y, pos1.y, -1 do
|
||||||
if not worldeditadditions.is_airlike(data[area:index(x, y, z)]) then
|
local i = area:index(x, y, z)
|
||||||
|
if not worldeditadditions.is_airlike(data[i]) then
|
||||||
|
local should_bonemeal = true
|
||||||
|
if node_list_count > 0 and not worldeditadditions.table.contains(node_list, data[i]) then
|
||||||
|
should_bonemeal = false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- It's not an air node, so let's try to bonemeal it
|
-- It's not an air node, so let's try to bonemeal it
|
||||||
|
|
||||||
if math.random(0, chance - 1) == 0 then
|
if should_bonemeal and math.random(0, chance - 1) == 0 then
|
||||||
bonemeal:on_use(
|
bonemeal:on_use(
|
||||||
{ x = x, y = y, z = z },
|
{ x = x, y = y, z = z },
|
||||||
strength,
|
strength,
|
||||||
|
|
|
@ -6,7 +6,7 @@ local we_c = worldeditadditions_commands
|
||||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██████ ██████ ██ ████ ███████ ██ ██ ███████ ██ ██ ███████
|
-- ██████ ██████ ██ ████ ███████ ██ ██ ███████ ██ ██ ███████
|
||||||
worldedit.register_command("bonemeal", {
|
worldedit.register_command("bonemeal", {
|
||||||
params = "[<strength> [<chance>]]",
|
params = "[<strength> [<chance> [<node_name> [<node_name> ...]]]]",
|
||||||
description = "Bonemeals everything that's bonemeal-able that has an air node directly above it. Optionally takes a strength value to use (default: 1, maximum: 4), and a chance to actually bonemeal an eligible node (positive integer; nodes have a 1-in-<chance> chance to be bonemealed; higher values mean a lower chance; default: 1 - 100% chance).",
|
description = "Bonemeals everything that's bonemeal-able that has an air node directly above it. Optionally takes a strength value to use (default: 1, maximum: 4), and a chance to actually bonemeal an eligible node (positive integer; nodes have a 1-in-<chance> chance to be bonemealed; higher values mean a lower chance; default: 1 - 100% chance).",
|
||||||
privs = { worldedit = true },
|
privs = { worldedit = true },
|
||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
|
@ -19,15 +19,16 @@ worldedit.register_command("bonemeal", {
|
||||||
|
|
||||||
local strength = 1
|
local strength = 1
|
||||||
local chance = 1
|
local chance = 1
|
||||||
|
local node_names = {} -- An empty table means all nodes
|
||||||
|
|
||||||
if #parts >= 1 then
|
if #parts >= 1 then
|
||||||
strength = tonumber(parts[1])
|
strength = tonumber(table.remove(parts, 1))
|
||||||
if not strength then
|
if not strength then
|
||||||
return false, "Invalid strength value (value must be an integer)"
|
return false, "Invalid strength value (value must be an integer)"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #parts >= 2 then
|
if #parts >= 2 then
|
||||||
chance = worldeditadditions.parse.chance(parts[2])
|
chance = worldeditadditions.parse.chance(table.remove(parts, 1))
|
||||||
if not chance then
|
if not chance then
|
||||||
return false, "Invalid chance value (must be a positive integer)"
|
return false, "Invalid chance value (must be a positive integer)"
|
||||||
end
|
end
|
||||||
|
@ -37,21 +38,33 @@ worldedit.register_command("bonemeal", {
|
||||||
return false, "Error: strength value out of bounds (value must be an integer between 1 and 4 inclusive)"
|
return false, "Error: strength value out of bounds (value must be an integer between 1 and 4 inclusive)"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if #parts > 0 then
|
||||||
|
for _,nodename in pairs(parts) do
|
||||||
|
local normalised = worldedit.normalize_nodename(nodename)
|
||||||
|
if not normalised then return false, "Error: Unknown node name '"..nodename.."'." end
|
||||||
|
table.insert(node_names, normalised)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- We unconditionally math.floor here because when we tried to test for it directly it was unreliable
|
-- We unconditionally math.floor here because when we tried to test for it directly it was unreliable
|
||||||
return true, math.floor(strength), math.floor(chance)
|
return true, math.floor(strength), math.floor(chance), node_names
|
||||||
end,
|
end,
|
||||||
nodes_needed = function(name) -- strength, chance
|
nodes_needed = function(name) -- strength, chance
|
||||||
-- Since every node has to have an air block, in the best-case scenario
|
-- Since every node has to have an air block, in the best-case scenario
|
||||||
-- edit only half the nodes in the selected area
|
-- edit only half the nodes in the selected area
|
||||||
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) / 2
|
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) / 2
|
||||||
end,
|
end,
|
||||||
func = function(name, strength, chance)
|
func = function(name, strength, chance, node_names)
|
||||||
local start_time = worldeditadditions.get_ms_time()
|
local start_time = worldeditadditions.get_ms_time()
|
||||||
local success, nodes_bonemealed, candidates = worldeditadditions.bonemeal(worldedit.pos1[name], worldedit.pos2[name], strength, chance)
|
local success, nodes_bonemealed, candidates = worldeditadditions.bonemeal(
|
||||||
if not success then
|
worldedit.pos1[name], worldedit.pos2[name],
|
||||||
-- nodes_bonemealed is an error message here because success == false
|
strength, chance,
|
||||||
return success, nodes_bonemealed
|
node_names
|
||||||
end
|
)
|
||||||
|
-- nodes_bonemealed is an error message here if success == false
|
||||||
|
if not success then return success, nodes_bonemealed end
|
||||||
|
|
||||||
local percentage = worldeditadditions.round((nodes_bonemealed / candidates)*100, 2)
|
local percentage = worldeditadditions.round((nodes_bonemealed / candidates)*100, 2)
|
||||||
local time_taken = worldeditadditions.get_ms_time() - start_time
|
local time_taken = worldeditadditions.get_ms_time() - start_time
|
||||||
-- Avoid nan% - since if there aren't any candidates then nodes_bonemealed will be 0 too
|
-- Avoid nan% - since if there aren't any candidates then nodes_bonemealed will be 0 too
|
||||||
|
|
Loading…
Reference in a new issue