diff --git a/worldeditadditions_core/README.md b/worldeditadditions_core/README.md index 0f2350c..4deee17 100644 --- a/worldeditadditions_core/README.md +++ b/worldeditadditions_core/README.md @@ -1,3 +1,5 @@ # worldeditadditions_core This mod's purpose is to provide a solid base upon which the rest of WorldEditAdditions can function. Once it is complete, we will be able to mark our dependency on `worldedit` itself optional. To get to that point though will still require a significant effort in implementing enhanced versions of all existing WorldEdit commands. If you've got some free time and a great idea for a command, please do open a pull request! :D + +In short, `worldeditadditions_core` is a reimplementation of a number of underlying parts of the worldedit engine. Parts of `worldeditadditions_core` are likely to look very similar to parts of WorldEdit - this is because inspiration was taken from Uberi/WorldEdit when implementing `worldeditadditions_core`. diff --git a/worldeditadditions_core/core/lib/human_size.lua b/worldeditadditions_core/core/lib/human_size.lua new file mode 100644 index 0000000..fa8dce3 --- /dev/null +++ b/worldeditadditions_core/core/lib/human_size.lua @@ -0,0 +1,17 @@ + +-- TODO: This is duplicated from worldeditadditions/utils. We should consider moving worldeditadditions/utils to worldeditadditions_core. Perhaps also we could move the definition of the worldeditadditions namespace to worldeditadditions_core too? + +--- Formats (usually large) numbers as human-readable strings. +-- Ported from PHP: https://github.com/sbrl/Pepperminty-Wiki/blob/0a81c940c5803856db250b29f54658476bc81e21/core/05-functions.php#L67 +-- @param n number The number to format. +-- @param decimals number The number of decimal places to show. +-- @return string A formatted string that represents the given input number. +local function human_size(n, decimals) + local sizes = { "", "K", "M", "G", "T", "P", "E", "Y", "Z" } + local factor = math.floor((#tostring(n) - 1) / 3) + local multiplier = 10^(decimals or 0) + local result = math.floor(0.5 + (n / math.pow(1000, factor)) * multiplier) / multiplier + return result .. sizes[factor+1] +end + +return human_size diff --git a/worldeditadditions_core/core/register_command.lua b/worldeditadditions_core/core/register_command.lua index a503a7b..e29a1a2 100644 --- a/worldeditadditions_core/core/register_command.lua +++ b/worldeditadditions_core/core/register_command.lua @@ -54,7 +54,7 @@ local function register_command(cmdname, options) description = options.description, privs = options.privs, func = function(player_name, paramtext) - run_command(cmdname, player_name, paramtext) + run_command(cmdname, options, player_name, paramtext) end }) we_c.registered_commands[cmdname] = options diff --git a/worldeditadditions_core/core/run_command.lua b/worldeditadditions_core/core/run_command.lua index fcd7bf1..463da39 100644 --- a/worldeditadditions_core/core/run_command.lua +++ b/worldeditadditions_core/core/run_command.lua @@ -1,7 +1,53 @@ +local we_c = worldeditadditions_core +local human_size = dofile(we_c.modpath.."/core/lib/human_size.lua") -local function run_command(cmdname, func, paramtext) - -- TODO: Fill this in +-- TODO: Reimplement worldedit.player_notify(player_name, msg_text) + +local function run_command_stage2(player_name, func, parse_result) + local success, result_message = func(player_name, unpack(parse_result)) + if result_message then + -- TODO: If we were unsuccessfull, then colour the message red + worldedit.player_notify(player_name, result_message) + end +end + +local function run_command(cmdname, options, player_name, paramtext) + if options.require_pos > 0 and not worldedit.pos1[player_name] then + worldedit.player_notify(player_name, "Error: pos1 must be selected to use this command.") + return false + end + if options.require_pos > 1 and not worldedit.pos2[player_name] then + worldedit.player_notify(player_name, "Error: Both pos1 and pos2 must be selected (together making a region) to use this command.") + return false + end + + local parse_result = { options.parse(paramtext) } + local success = table.remove(parse_result, 1) + if not success then + worldedit.player_notify(player_name, parse_result[1] or "Invalid usage (no further error message was provided by the command. This is probably a bug.)") + return false + end + + if options.nodes_needed then + local potential_changes = options.nodes_needed(player_name, unpack(parse_result)) + + local limit = we_c.safe_region_limit_default + if we_c.safe_region_limits[player_name] then + limit = we_c.safe_region_limits[player_name] + end + + if potential_changes > limit then + worldedit.player_notify(player_name, "/"..cmdname.." "..paramtext.."' may affect up to "..human_size(potential_changes).." nodes. Type //y to continue, or //n to cancel (see the //saferegion command to control when this message appears).") + + -- TODO: Wrap run_command_stage2 in safe_region stuff + run_command_stage2(player_name, options.func, parse_result) + end + else + run_command_stage2(player_name, options.func, parse_result) + end + + end return run_command diff --git a/worldeditadditions_core/init.lua b/worldeditadditions_core/init.lua index b34c1d6..6446338 100644 --- a/worldeditadditions_core/init.lua +++ b/worldeditadditions_core/init.lua @@ -15,6 +15,11 @@ local modpath = minetest.get_modpath("worldeditadditions_core") worldeditadditions_core = { modpath = modpath, registered_commands = {}, + -- Storage for per-player node limits before safe_region kicks in. + -- TODO: Persist these to disk. + safe_region_limits = {}, + -- The default limit for new players on the number of potential nodes changed before safe_region kicks in. + safe_region_limit_default = 100000, register_command = dofile(modpath.."/core/register_command.lua") }