2021-05-11 23:29:15 +02:00
local wea = worldeditadditions
2022-09-18 18:59:57 +02:00
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
2020-05-14 22:37:27 +02:00
-- ██████ ███████ ██████ ██ █████ ██████ ███████ ███ ███ ██ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ████ ██ ██ ██
-- ██████ █████ ██████ ██ ███████ ██ █████ ██ ████ ██ ██ ███
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ██ ███████ ██ ███████ ██ ██ ██████ ███████ ██ ██ ██ ██ ██
2022-09-18 18:59:57 +02:00
wea_c.register_command ( " replacemix " , {
2020-05-14 22:37:27 +02:00
params = " <target_node> [<chance>] <replace_node_a> [<chance_a>] [<replace_node_b> [<chance_b>]] [<replace_node_N> [<chance_N>]] ... " ,
description = " Replaces target_node with a mix of other nodes. Functions simmilarly to //mix. <chance> is optional and the chance to replace the target node at all. replace_node_a is the node to replace target_node with. If multiple nodes are specified in a space separated list, then when replacing an instance of target_node one is randomly chosen from the list. Just like with //mix, if a positive integer is present after a replace_node, that adds a weighting to that particular node making it more common. " ,
privs = { worldedit = true } ,
require_pos = 2 ,
parse = function ( params_text )
if not params_text or params_text == " " then
return false , " Error: No arguments specified "
end
2022-09-18 18:59:57 +02:00
local parts = wea_c.split_shell ( params_text )
2020-05-14 22:37:27 +02:00
local target_node = nil
local target_node_chance = 1
local replace_nodes = { }
local mode = " target_node "
local last_node_name = nil
for i , part in ipairs ( parts ) do
if mode == " target_node " then
target_node = worldedit.normalize_nodename ( part )
if not target_node then
return false , " Error: Invalid target_node name "
end
mode = " target_chance "
2022-09-18 18:59:57 +02:00
elseif mode == " target_chance " and wea_c.parse . chance ( part ) then
target_node_chance = wea_c.parse . chance ( part )
2020-05-14 22:37:27 +02:00
mode = " replace_node "
2022-09-18 18:59:57 +02:00
elseif ( mode == " target_chance " and not wea_c.parse . chance ( part , " weight " ) ) or mode == " replace_node " then
2020-05-14 22:37:27 +02:00
mode = " replace_node "
2022-09-18 18:59:57 +02:00
if wea_c.parse . chance ( part , " weight " ) then
2020-05-14 22:37:27 +02:00
if not last_node_name then
return false , " Error: No previous node name was found (this is a probably a bug). "
end
2022-09-18 18:59:57 +02:00
replace_nodes [ last_node_name ] = math.floor ( wea_c.parse . chance ( part , " weight " ) )
2020-05-14 22:37:27 +02:00
else
if last_node_name and not replace_nodes [ last_node_name ] then
replace_nodes [ last_node_name ] = 1
end
local node_name = worldedit.normalize_nodename ( part )
if not node_name then
return false , " Error: Invalid replace node name ' " .. part .. " '. "
end
last_node_name = node_name
end
end
end
2021-09-18 13:16:03 +02:00
if not target_node then return false , " Error: No target node specified. " end
if not last_node_name then return false , " Error: At least 1 replace node must be specified. " end
2020-05-14 22:37:27 +02:00
if not replace_nodes [ last_node_name ] then
replace_nodes [ last_node_name ] = 1
end
-- We unconditionally math.floor here because when we tried to test for it directly it was unreliable
return true , target_node , target_node_chance , replace_nodes
end ,
nodes_needed = function ( name ) -- target_node, target_node_chance, replace_nodes
return worldedit.volume ( worldedit.pos1 [ name ] , worldedit.pos2 [ name ] )
end ,
func = function ( name , target_node , target_node_chance , replace_nodes )
2022-09-18 18:59:57 +02:00
local start_time = wea_c.get_ms_time ( )
local pos1 , pos2 = Vector3.sort ( worldedit.pos1 [ name ] , worldedit.pos2 [ name ] )
local success , changed , candidates , distribution = wea.replacemix (
2020-05-14 22:37:27 +02:00
worldedit.pos1 [ name ] , worldedit.pos2 [ name ] ,
target_node ,
target_node_chance ,
replace_nodes
)
if not success then
return success , changed
end
2022-09-18 18:59:57 +02:00
local nodes_total = worldedit.volume ( pos1 , pos2 )
local percentage_replaced = wea_c.round ( ( changed / candidates ) * 100 , 2 )
local distribution_table = wea_c.format . node_distribution (
2021-03-20 02:48:56 +01:00
distribution ,
changed ,
true -- Add a grand total to the bottom
2020-05-14 22:37:27 +02:00
)
2022-09-18 18:59:57 +02:00
local time_taken = wea_c.get_ms_time ( ) - start_time
2020-05-14 22:37:27 +02:00
2022-09-18 18:59:57 +02:00
minetest.log ( " action " , name .. " used //replacemix at " .. pos1 .. " - " .. pos2 .. " , replacing " .. changed .. " nodes (out of " .. nodes_total .. " nodes) in " .. time_taken .. " s " )
2020-05-14 22:37:27 +02:00
2022-09-18 18:59:57 +02:00
return true , distribution_table .. changed .. " out of " .. candidates .. " (~ " .. percentage_replaced .. " %) candidates replaced in " .. wea_c.format . human_time ( time_taken )
2020-05-14 22:37:27 +02:00
end
} )