From 5121ffab8bb923ea6e8424b4ae62139172b6e79e Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 20 Sep 2025 14:01:29 +0200 Subject: [PATCH] Allow relative coordinate parsing for //fixedpos, since that's the only relevant command closes #260 --- ChatCommands.md | 2 ++ worldedit_commands/init.lua | 17 +++++++++++++++++ worldedit_commands/locale/template.txt | 1 + .../locale/worldedit_commands.de.tr | 1 + worldedit_commands/region.lua | 13 +++++++++---- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/ChatCommands.md b/ChatCommands.md index ebc2fae..c340b90 100644 --- a/ChatCommands.md +++ b/ChatCommands.md @@ -99,6 +99,8 @@ Set the WorldEdit region position 1 or 2 to the position (``, ``, ``). //fixedpos set1 -30 5 28 //fixedpos set2 1004 -200 432 +Note that the `~` syntax can be used here to indicate a coordinate relative to the player. + ### `//volume` Display the volume of the current WorldEdit region. diff --git a/worldedit_commands/init.lua b/worldedit_commands/init.lua index 4cecf19..510efda 100644 --- a/worldedit_commands/init.lua +++ b/worldedit_commands/init.lua @@ -199,6 +199,23 @@ function worldedit.player_axis(name) return "z", dir.z > 0 and 1 or -1 end +-- Wrapper for the engine's parse_coordinates +-- @return vector or nil +-- @note Not part of API +function worldedit.parse_coordinates(x, y, z, player_name) + local relpos + local player = minetest.get_player_by_name(player_name or "") + if player then + relpos = player:get_pos() + end + -- we don't bother to support ~ in the fallback path here + if not minetest.parse_coordinates then + x, y, z = tonumber(x), tonumber(y), tonumber(z) + return x and y and z and vector.new(x, y, z) + end + return minetest.parse_coordinates(x, y, z, relpos) +end + worldedit.register_command("about", { privs = {}, diff --git a/worldedit_commands/locale/template.txt b/worldedit_commands/locale/template.txt index 33433cb..a6aac63 100644 --- a/worldedit_commands/locale/template.txt +++ b/worldedit_commands/locale/template.txt @@ -51,6 +51,7 @@ select position @1 by punching a node= position @1: @2= position @1 not set= Set a WorldEdit region position to the position at (, , )= +invalid position= Display the volume of the current WorldEdit region= current region has a volume of @1 nodes (@2*@3*@4)= Remove all MapBlocks (16x16x16) containing the selected area from the map= diff --git a/worldedit_commands/locale/worldedit_commands.de.tr b/worldedit_commands/locale/worldedit_commands.de.tr index 61ffb90..9238876 100644 --- a/worldedit_commands/locale/worldedit_commands.de.tr +++ b/worldedit_commands/locale/worldedit_commands.de.tr @@ -62,6 +62,7 @@ select position @1 by punching a node=Wählen Sie Position @1 durch Hauen eines position @1: @2=Position @1: @2 position @1 not set=Position @1 ist nicht gesetzt Set a WorldEdit region position to the position at (, , )=Eine Position des WorldEdit-Gebiets auf (, , ) setzen +invalid position=Ungültige Position Display the volume of the current WorldEdit region=Volumen des aktuellen WorldEdit-Gebiets anzeigen current region has a volume of @1 nodes (@2*@3*@4)=Das aktuelle Gebiet hat ein Volumen von @1 Blöcken (@2×@3×@4) Remove all MapBlocks (16x16x16) containing the selected area from the map=Alle Kartenblöcke (16×16×16) entfernen, die das gewählte Gebiet enthalten diff --git a/worldedit_commands/region.lua b/worldedit_commands/region.lua index c380d49..43158e4 100644 --- a/worldedit_commands/region.lua +++ b/worldedit_commands/region.lua @@ -180,13 +180,18 @@ worldedit.register_command("fixedpos", { category = S("Region operations"), privs = {worldedit=true}, parse = function(param) - local found, _, flag, x, y, z = param:find("^(set[12])%s+([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)$") - if found == nil then + local found, _, flag, x, y, z = param:find("^(set[12])%s+(~?[+-]?%d+)%s+(~?[+-]?%d+)%s+(~?[+-]?%d+)$") + if not found then return false end - return true, flag, vector.new(tonumber(x), tonumber(y), tonumber(z)) + return true, flag, x, y, z end, - func = function(name, flag, pos) + func = function(name, flag, x, y, z) + -- Parse here, since player name isn't known in parse() + local pos = worldedit.parse_coordinates(x, y, z, name) + if not pos then + return false, S("invalid position") + end if flag == "set1" then set_pos1(name, pos) else --flag == "set2"