mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-22 15:33:00 +00:00
Fix a ton of bugs but there are lots more to go.....
This commit is contained in:
parent
cdba38d37d
commit
acb288b984
9 changed files with 202 additions and 77 deletions
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
worldeditadditions = {}
|
worldeditadditions = {}
|
||||||
worldeditadditions.modpath = minetest.get_modpath("worldeditadditions")
|
worldeditadditions.modpath = minetest.get_modpath("worldeditadditions")
|
||||||
|
dofile(worldeditadditions.modpath.."/utils/vector.lua")
|
||||||
dofile(worldeditadditions.modpath.."/utils/strings.lua")
|
dofile(worldeditadditions.modpath.."/utils/strings.lua")
|
||||||
dofile(worldeditadditions.modpath.."/utils/numbers.lua")
|
dofile(worldeditadditions.modpath.."/utils/numbers.lua")
|
||||||
dofile(worldeditadditions.modpath.."/utils/nodes.lua")
|
dofile(worldeditadditions.modpath.."/utils/nodes.lua")
|
||||||
|
@ -14,7 +15,6 @@ dofile(worldeditadditions.modpath.."/utils/tables.lua")
|
||||||
dofile(worldeditadditions.modpath.."/utils/terrain.lua")
|
dofile(worldeditadditions.modpath.."/utils/terrain.lua")
|
||||||
dofile(worldeditadditions.modpath.."/utils/raycast_adv.lua") -- For the farwand
|
dofile(worldeditadditions.modpath.."/utils/raycast_adv.lua") -- For the farwand
|
||||||
|
|
||||||
dofile(worldeditadditions.modpath.."/utils.lua")
|
|
||||||
dofile(worldeditadditions.modpath.."/lib/floodfill.lua")
|
dofile(worldeditadditions.modpath.."/lib/floodfill.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/overlay.lua")
|
dofile(worldeditadditions.modpath.."/lib/overlay.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/layers.lua")
|
dofile(worldeditadditions.modpath.."/lib/layers.lua")
|
||||||
|
@ -25,6 +25,7 @@ dofile(worldeditadditions.modpath.."/lib/replacemix.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/maze2d.lua")
|
dofile(worldeditadditions.modpath.."/lib/maze2d.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/maze3d.lua")
|
dofile(worldeditadditions.modpath.."/lib/maze3d.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/conv/conv.lua")
|
dofile(worldeditadditions.modpath.."/lib/conv/conv.lua")
|
||||||
|
dofile(worldeditadditions.modpath.."/lib/erode/erode.lua")
|
||||||
|
|
||||||
dofile(worldeditadditions.modpath.."/lib/count.lua")
|
dofile(worldeditadditions.modpath.."/lib/count.lua")
|
||||||
|
|
||||||
|
|
|
@ -75,45 +75,11 @@ function worldeditadditions.convolve(pos1, pos2, kernel, kernel_size)
|
||||||
-- worldeditadditions.print_2d(heightmap, (pos2.z - pos1.z) + 1)
|
-- worldeditadditions.print_2d(heightmap, (pos2.z - pos1.z) + 1)
|
||||||
-- print("transformed")
|
-- print("transformed")
|
||||||
-- worldeditadditions.print_2d(heightmap_conv, (pos2.z - pos1.z) + 1)
|
-- worldeditadditions.print_2d(heightmap_conv, (pos2.z - pos1.z) + 1)
|
||||||
-- It seems to be convolving as intended, but something's probably getting lost in translation below
|
|
||||||
|
|
||||||
for z = heightmap_size[0], 0, -1 do
|
worldeditadditions.apply_heightmap_changes(
|
||||||
for x = heightmap_size[1], 0, -1 do
|
pos1, pos2, area, data,
|
||||||
local hi = z*heightmap_size[1] + x
|
heightmap, heightmap_conv, heightmap_size
|
||||||
|
)
|
||||||
|
|
||||||
local height_old = heightmap[hi]
|
|
||||||
local height_new = heightmap_conv[hi]
|
|
||||||
-- print("[conv/save] hi", hi, "height_old", heightmap[hi], "height_new", heightmap_conv[hi], "z", z, "x", x, "pos1.y", pos1.y)
|
|
||||||
|
|
||||||
-- Lua doesn't have a continue statement :-/
|
|
||||||
if height_old == height_new then
|
|
||||||
-- noop
|
|
||||||
elseif height_new < height_old then
|
|
||||||
stats.removed = stats.removed + (height_old - height_new)
|
|
||||||
local y = height_new
|
|
||||||
while y < height_old do
|
|
||||||
local ci = area:index(pos1.x + x, pos1.y + y, pos1.z + z)
|
|
||||||
-- print("[conv/save] remove at y", y, "→", pos1.y + y, "current:", minetest.get_name_from_content_id(data[ci]))
|
|
||||||
data[ci] = node_id_air
|
|
||||||
y = y + 1
|
|
||||||
end
|
|
||||||
else -- height_new > height_old
|
|
||||||
-- We subtract one because the heightmap starts at 1 (i.e. 1 = 1 node in the column), but the selected region is inclusive
|
|
||||||
local node_id = data[area:index(pos1.x + x, pos1.y + (height_old - 1), pos1.z + z)]
|
|
||||||
-- print("[conv/save] filling with ", node_id, "→", minetest.get_name_from_content_id(node_id))
|
|
||||||
|
|
||||||
stats.added = stats.added + (height_new - height_old)
|
|
||||||
local y = height_old
|
|
||||||
while y < height_new do
|
|
||||||
local ci = area:index(pos1.x + x, pos1.y + y, pos1.z + z)
|
|
||||||
-- print("[conv/save] add at y", y, "→", pos1.y + y, "current:", minetest.get_name_from_content_id(data[ci]))
|
|
||||||
data[ci] = node_id
|
|
||||||
y = y + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
worldedit.manip_helpers.finish(manip, data)
|
worldedit.manip_helpers.finish(manip, data)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,39 @@
|
||||||
worldeditadditions.erode = {}
|
worldeditadditions.erode = {}
|
||||||
|
|
||||||
dofile(worldeditadditions.modpath.."/lib/erode/snowballs.lua")
|
dofile(worldeditadditions.modpath.."/lib/erode/snowballs.lua")
|
||||||
|
|
||||||
|
|
||||||
|
function worldeditadditions.erode.run(pos1, pos2, algorithm, params)
|
||||||
|
pos1, pos2 = worldedit.sort_pos(pos1, pos2)
|
||||||
|
|
||||||
|
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
||||||
|
local data = manip:get_data()
|
||||||
|
|
||||||
|
local heightmap_size = {}
|
||||||
|
heightmap_size[0] = (pos2.z - pos1.z) + 1
|
||||||
|
heightmap_size[1] = (pos2.x - pos1.x) + 1
|
||||||
|
|
||||||
|
local heightmap = worldeditadditions.make_heightmap(pos1, pos2, manip, area, data)
|
||||||
|
local heightmap_eroded = worldeditadditions.shallowcopy(heightmap)
|
||||||
|
|
||||||
|
print("[erode.run] algorithm: "..algorithm..", params:");
|
||||||
|
print(worldeditadditions.map_stringify(params))
|
||||||
|
worldeditadditions.print_2d(heightmap, heightmap_size[1])
|
||||||
|
|
||||||
|
if algorithm == "snowballs" then
|
||||||
|
local success, msg = worldeditadditions.erode.snowballs(heightmap_eroded, heightmap_size, params)
|
||||||
|
if not success then return success, msg end
|
||||||
|
else
|
||||||
|
return false, "Error: Unknown algorithm '"..algorithm.."'. Currently implemented algorithms: snowballs (2d; hydraulic-like). Ideas for algorithms to implement are welcome!"
|
||||||
|
end
|
||||||
|
|
||||||
|
local success, msg = worldeditadditions.apply_heightmap_changes(
|
||||||
|
pos1, pos2, area, data,
|
||||||
|
heightmap, heightmap_eroded, heightmap_size
|
||||||
|
)
|
||||||
|
if not success then return success, msg end
|
||||||
|
|
||||||
|
worldedit.manip_helpers.finish(manip, data)
|
||||||
|
|
||||||
|
return true, stats
|
||||||
|
end
|
||||||
|
|
|
@ -1,32 +1,3 @@
|
||||||
--[[
|
|
||||||
2D erosion algorithm based on snowballs
|
|
||||||
Note that this *mutates* the given heightmap.
|
|
||||||
@source https://jobtalle.com/simulating_hydraulic_erosion.html
|
|
||||||
|
|
||||||
]]--
|
|
||||||
function worldeditadditions.erode.snowballs(heightmap, heightmap_size, params)
|
|
||||||
-- Apply the default settings
|
|
||||||
worldeditadditions.table_apply({
|
|
||||||
rate_deposit = 0.03,
|
|
||||||
rate_erosion = 0.04,
|
|
||||||
friction = 0.07,
|
|
||||||
speed = 0.15,
|
|
||||||
radius = 0.8,
|
|
||||||
snowball_max_steps = 80,
|
|
||||||
scale_iterations = 0.04,
|
|
||||||
drops_per_cell = 0.4,
|
|
||||||
snowball_count = 50000
|
|
||||||
}, params)
|
|
||||||
|
|
||||||
local normals = worldeditadditions.calculate_normals(heightmap, heightmap_size)
|
|
||||||
|
|
||||||
for i = 1, params.snowball_count do
|
|
||||||
snowball(
|
|
||||||
heightmap, normals, heightmap_size,
|
|
||||||
{ x = math.random() }
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function snowball(heightmap, normalmap, heightmap_size, startpos, params)
|
local function snowball(heightmap, normalmap, heightmap_size, startpos, params)
|
||||||
local offset = { -- Random jitter - apparently helps to avoid snowballs from entrenching too much
|
local offset = { -- Random jitter - apparently helps to avoid snowballs from entrenching too much
|
||||||
|
@ -72,3 +43,33 @@ local function snowball(heightmap, normalmap, heightmap_size, startpos, params)
|
||||||
heightmap[i] = math.floor(heightmap[i] + 0.5)
|
heightmap[i] = math.floor(heightmap[i] + 0.5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
2D erosion algorithm based on snowballs
|
||||||
|
Note that this *mutates* the given heightmap.
|
||||||
|
@source https://jobtalle.com/simulating_hydraulic_erosion.html
|
||||||
|
|
||||||
|
]]--
|
||||||
|
function worldeditadditions.erode.snowballs(heightmap, heightmap_size, params)
|
||||||
|
-- Apply the default settings
|
||||||
|
worldeditadditions.table_apply({
|
||||||
|
rate_deposit = 0.03,
|
||||||
|
rate_erosion = 0.04,
|
||||||
|
friction = 0.07,
|
||||||
|
speed = 0.15,
|
||||||
|
radius = 0.8,
|
||||||
|
snowball_max_steps = 80,
|
||||||
|
scale_iterations = 0.04,
|
||||||
|
drops_per_cell = 0.4,
|
||||||
|
snowball_count = 50000
|
||||||
|
}, params)
|
||||||
|
|
||||||
|
local normals = worldeditadditions.calculate_normals(heightmap, heightmap_size)
|
||||||
|
|
||||||
|
for i = 1, params.snowball_count do
|
||||||
|
snowball(
|
||||||
|
heightmap, normals, heightmap_size,
|
||||||
|
{ x = math.random() }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -86,6 +86,7 @@ end
|
||||||
-- @param tbl number[] The ZERO-indexed list of numbers
|
-- @param tbl number[] The ZERO-indexed list of numbers
|
||||||
-- @param width number The width of 2D array.
|
-- @param width number The width of 2D array.
|
||||||
function worldeditadditions.print_2d(tbl, width)
|
function worldeditadditions.print_2d(tbl, width)
|
||||||
|
print("==== count: "..#tbl..", width:"..width.." ====")
|
||||||
local display_width = 1
|
local display_width = 1
|
||||||
for _i,value in pairs(tbl) do
|
for _i,value in pairs(tbl) do
|
||||||
display_width = math.max(display_width, #tostring(value))
|
display_width = math.max(display_width, #tostring(value))
|
||||||
|
@ -209,6 +210,32 @@ function worldeditadditions.parse_weighted_nodes(parts, as_list)
|
||||||
return true, result
|
return true, result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function worldeditadditions.parse_map(params_text)
|
||||||
|
local result = {}
|
||||||
|
local parts = worldeditadditions.split(params_text, "%s+", false)
|
||||||
|
|
||||||
|
local last_key = nil
|
||||||
|
for i, part in ipairs(parts) do
|
||||||
|
if i % 2 == 1 then
|
||||||
|
-- Try converting to a number to see if it works
|
||||||
|
local part_converted = tonumber(part)
|
||||||
|
if as_number == nil then part_converted = part end
|
||||||
|
result[last_key] = part
|
||||||
|
else
|
||||||
|
last_key = part
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true, result
|
||||||
|
end
|
||||||
|
|
||||||
|
function worldeditadditions.map_stringify(map)
|
||||||
|
local result = {}
|
||||||
|
for key, value in pairs(map) do
|
||||||
|
table.insert(key.."\t"..value)
|
||||||
|
end
|
||||||
|
return table.concat(result, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
--- Converts a float milliseconds into a human-readable string.
|
--- Converts a float milliseconds into a human-readable string.
|
||||||
-- Ported from PHP human_time from Pepperminty Wiki: https://github.com/sbrl/Pepperminty-Wiki/blob/fa81f0d/core/05-functions.php#L82-L104
|
-- Ported from PHP human_time from Pepperminty Wiki: https://github.com/sbrl/Pepperminty-Wiki/blob/fa81f0d/core/05-functions.php#L82-L104
|
||||||
-- @param ms float The number of milliseconds to convert.
|
-- @param ms float The number of milliseconds to convert.
|
||||||
|
|
|
@ -45,9 +45,10 @@ end
|
||||||
-- @param heightmap_size int[] The size of the heightmap in the form [ z, x ]
|
-- @param heightmap_size int[] The size of the heightmap in the form [ z, x ]
|
||||||
-- @return Vector[] The calculated normal map, in the same form as the input heightmap. Each element of the array is a 3D Vector (i.e. { x, y, z }) representing a normal.
|
-- @return Vector[] The calculated normal map, in the same form as the input heightmap. Each element of the array is a 3D Vector (i.e. { x, y, z }) representing a normal.
|
||||||
function worldeditadditions.calculate_normals(heightmap, heightmap_size)
|
function worldeditadditions.calculate_normals(heightmap, heightmap_size)
|
||||||
|
print("heightmap_size: "..heightmap_size[1].."x"..heightmap_size[0])
|
||||||
local result = {}
|
local result = {}
|
||||||
for z = heightmap_size[0], 0, -1 do
|
for z = heightmap_size[0]-1, 0, -1 do
|
||||||
for x = heightmap_size[1], 0, -1 do
|
for x = heightmap_size[1]-1, 0, -1 do
|
||||||
-- Algorithm ref https://stackoverflow.com/a/13983431/1460422
|
-- Algorithm ref https://stackoverflow.com/a/13983431/1460422
|
||||||
-- Also ref Vector.mjs, which I implemented myself (available upon request)
|
-- Also ref Vector.mjs, which I implemented myself (available upon request)
|
||||||
local hi = z*heightmap_size[1] + x
|
local hi = z*heightmap_size[1] + x
|
||||||
|
@ -57,9 +58,14 @@ function worldeditadditions.calculate_normals(heightmap, heightmap_size)
|
||||||
local left = heightmap[hi]
|
local left = heightmap[hi]
|
||||||
local right = heightmap[hi]
|
local right = heightmap[hi]
|
||||||
if z - 1 > 0 then up = heightmap[(z-1)*heightmap_size[1] + x] end
|
if z - 1 > 0 then up = heightmap[(z-1)*heightmap_size[1] + x] end
|
||||||
if z + 1 < heightmap_size[1] then down = heightmap[(z+1)*heightmap_size[1] + x] end
|
if z + 1 < heightmap_size[0]-1 then down = heightmap[(z+1)*heightmap_size[1] + x] end
|
||||||
if x - 1 > 0 then left = heightmap[z*heightmap_size[1] + (x-1)] end
|
if x - 1 > 0 then left = heightmap[z*heightmap_size[1] + (x-1)] end
|
||||||
if x + 1 < heightmap_size[0] then right = heightmap[z*heightmap_size[1] + (x+1)] end
|
if x + 1 < heightmap_size[1]-1 then right = heightmap[z*heightmap_size[1] + (x+1)] end
|
||||||
|
|
||||||
|
print("[normals] UP | index", (z-1)*heightmap_size[1] + x, "z", z, "z-1", z - 1, "up", up, "limit", 0)
|
||||||
|
print("[normals] DOWN | index", (z+1)*heightmap_size[1] + x, "z", z, "z+1", z + 1, "down", down, "limit", heightmap_size[1]-1)
|
||||||
|
print("[normals] LEFT | index", z*heightmap_size[1] + (x-1), "x", x, "x-1", x - 1, "left", left, "limit", 0)
|
||||||
|
print("[normals] RIGHT | index", z*heightmap_size[1] + (x+1), "x", x, "x+1", x + 1, "right", right, "limit", heightmap_size[1]-1)
|
||||||
|
|
||||||
result[hi] = worldeditadditions.vector.normalize({
|
result[hi] = worldeditadditions.vector.normalize({
|
||||||
x = left - right,
|
x = left - right,
|
||||||
|
@ -70,3 +76,47 @@ function worldeditadditions.calculate_normals(heightmap, heightmap_size)
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function worldeditadditions.apply_heightmap_changes(pos1, pos2, area, data, heightmap_old, heightmap_new, heightmap_size)
|
||||||
|
local stats = { added = 0, removed = 0 }
|
||||||
|
local node_id_air = minetest.get_content_id("air")
|
||||||
|
|
||||||
|
for z = heightmap_size[0], 0, -1 do
|
||||||
|
for x = heightmap_size[1], 0, -1 do
|
||||||
|
local hi = z*heightmap_size[1] + x
|
||||||
|
|
||||||
|
local height_old = heightmap[hi]
|
||||||
|
local height_new = heightmap_new[hi]
|
||||||
|
-- print("[conv/save] hi", hi, "height_old", heightmap[hi], "height_new", heightmap_new[hi], "z", z, "x", x, "pos1.y", pos1.y)
|
||||||
|
|
||||||
|
-- Lua doesn't have a continue statement :-/
|
||||||
|
if height_old == height_new then
|
||||||
|
-- noop
|
||||||
|
elseif height_new < height_old then
|
||||||
|
stats.removed = stats.removed + (height_old - height_new)
|
||||||
|
local y = height_new
|
||||||
|
while y < height_old do
|
||||||
|
local ci = area:index(pos1.x + x, pos1.y + y, pos1.z + z)
|
||||||
|
-- print("[conv/save] remove at y", y, "→", pos1.y + y, "current:", minetest.get_name_from_content_id(data[ci]))
|
||||||
|
data[ci] = node_id_air
|
||||||
|
y = y + 1
|
||||||
|
end
|
||||||
|
else -- height_new > height_old
|
||||||
|
-- We subtract one because the heightmap starts at 1 (i.e. 1 = 1 node in the column), but the selected region is inclusive
|
||||||
|
local node_id = data[area:index(pos1.x + x, pos1.y + (height_old - 1), pos1.z + z)]
|
||||||
|
-- print("[conv/save] filling with ", node_id, "→", minetest.get_name_from_content_id(node_id))
|
||||||
|
|
||||||
|
stats.added = stats.added + (height_new - height_old)
|
||||||
|
local y = height_old
|
||||||
|
while y < height_new do
|
||||||
|
local ci = area:index(pos1.x + x, pos1.y + y, pos1.z + z)
|
||||||
|
-- print("[conv/save] add at y", y, "→", pos1.y + y, "current:", minetest.get_name_from_content_id(data[ci]))
|
||||||
|
data[ci] = node_id
|
||||||
|
y = y + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, stats
|
||||||
|
end
|
||||||
|
|
|
@ -16,12 +16,12 @@ end
|
||||||
-- This method does *not* mutate.
|
-- This method does *not* mutate.
|
||||||
-- @param v Vector The vector to calculate from.
|
-- @param v Vector The vector to calculate from.
|
||||||
-- @return Vector A new normalised vector.
|
-- @return Vector A new normalised vector.
|
||||||
function worldeditadditions.vector.normalise(v)
|
function worldeditadditions.vector.normalize(v)
|
||||||
local length = math.sqrt(worldeditadditions.lengthsquared(v))
|
local length = math.sqrt(worldeditadditions.vector.lengthsquared(v))
|
||||||
return {
|
return {
|
||||||
x = x / length,
|
x = v.x / length,
|
||||||
y = y / length,
|
y = v.y / length,
|
||||||
z = z / length
|
z = v.z / length
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
43
worldeditadditions_commands/commands/erode.lua
Normal file
43
worldeditadditions_commands/commands/erode.lua
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
-- ██████ ██ ██ ███████ ██████ ██ █████ ██ ██
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ██ ██ ██ ██ █████ ██████ ██ ███████ ████
|
||||||
|
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
|
-- ██████ ████ ███████ ██ ██ ███████ ██ ██ ██
|
||||||
|
worldedit.register_command("erode", {
|
||||||
|
params = "[<snowballs|...> [<key_1> [<vaue_1>]] [<key_2> [<value_2>]] ...]",
|
||||||
|
description = "Runs the specified erosion algorithm over the given defined region. This may occur in 2d or 3d. Currently implemented algorithms: snowballs (default;2d hydraulic-like). Also optionally takes an arbitrary set of key - value pairs representing parameters to pass to the algorithm. See the full documentation for details.",
|
||||||
|
privs = { worldedit = true },
|
||||||
|
require_pos = 2,
|
||||||
|
parse = function(params_text)
|
||||||
|
if not params_text or params_text == "" then
|
||||||
|
return true, "snowballs", {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if params_text:find("%s") == nil then
|
||||||
|
return true, params_text, {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local algorithm, params = params_text:match("([^%s]+)%s(.+)")
|
||||||
|
if algorithm == nil then
|
||||||
|
return false, "Failed to split params_text into 2 parts (this is probably a bug)"
|
||||||
|
end
|
||||||
|
|
||||||
|
local success, map = worldeditadditions.parse_map(params)
|
||||||
|
if not success then return success, map end
|
||||||
|
return true, algorithm, map
|
||||||
|
end,
|
||||||
|
nodes_needed = function(name)
|
||||||
|
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name])
|
||||||
|
end,
|
||||||
|
func = function(name, algorithm, params)
|
||||||
|
local start_time = worldeditadditions.get_ms_time()
|
||||||
|
local success, stats = worldeditadditions.erode.run(
|
||||||
|
worldedit.pos1[name], worldedit.pos2[name],
|
||||||
|
algorithm, params
|
||||||
|
)
|
||||||
|
local time_taken = worldeditadditions.get_ms_time() - start_time
|
||||||
|
|
||||||
|
minetest.log("action", name .. " used //erode "..algorithm.." at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. changes.replaced .. " nodes and skipping " .. changes.skipped_columns .. " columns in " .. time_taken .. "s")
|
||||||
|
return true, changes.replaced .. " nodes replaced and " .. changes.skipped_columns .. " columns skipped in " .. worldeditadditions.human_time(time_taken)
|
||||||
|
end
|
||||||
|
})
|
|
@ -30,6 +30,7 @@ dofile(we_c.modpath.."/commands/walls.lua")
|
||||||
dofile(we_c.modpath.."/commands/maze.lua")
|
dofile(we_c.modpath.."/commands/maze.lua")
|
||||||
dofile(we_c.modpath.."/commands/replacemix.lua")
|
dofile(we_c.modpath.."/commands/replacemix.lua")
|
||||||
dofile(we_c.modpath.."/commands/convolve.lua")
|
dofile(we_c.modpath.."/commands/convolve.lua")
|
||||||
|
dofile(we_c.modpath.."/commands/erode.lua")
|
||||||
|
|
||||||
dofile(we_c.modpath.."/commands/count.lua")
|
dofile(we_c.modpath.."/commands/count.lua")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue