Update smake.lua

This commit is contained in:
VorTechnix 2024-09-15 17:04:57 -07:00
parent 38b55712cc
commit 4c4fab189e
No known key found for this signature in database
GPG Key ID: 091E91A69545D5BA

@ -1,133 +1,131 @@
local wea = worldeditadditions local wea_c = worldeditadditions_core
local wea_c = worldeditadditions_core local Vector3 = wea_c.Vector3
local Vector3 = wea_c.Vector3
-- ███████ ███ ███ █████ ██ ██ ███████
-- ███████ ███ ███ █████ ██ ██ ███████ -- ██ ████ ████ ██ ██ ██ ██ ██
-- ██ ████ ████ ██ ██ ██ ██ ██ -- ███████ ██ ████ ██ ███████ █████ █████
-- ███████ ██ ████ ██ ███████ █████ █████ -- ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ -- ███████ ██ ██ ██ ██ ██ ██ ███████
-- ███████ ██ ██ ██ ██ ██ ██ ███████ worldeditadditions_core.register_command("smake", {
worldeditadditions_core.register_command("smake", { params = "<operation:odd|even|equal> <mode:grow|shrink|average> [<target=xyz> [<base>]]",
params = "<operation:odd|even|equal> <mode:grow|shrink|average> [<target=xyz> [<base>]]", description = "Make one or more axes of the current selection odd, even, or equal to another.",
description = "Make one or more axes of the current selection odd, even, or equal to another.", privs = { worldedit = true },
privs = { worldedit = true }, require_pos = 2,
require_pos = 2, parse = function(params_text)
parse = function(params_text) -- Split params_text, check for missing arguments and fill in empty spots
-- Split params_text, check for missing arguments and fill in empty spots local parts = wea_c.split(params_text, "%s+", false)
local parts = wea_c.split(params_text, "%s+", false) if #parts < 2 then
if #parts < 2 then return false, "Error: Not enough arguments. Expected \"<operation> <mode> [<target=xyz> [<base>]]\"."
return false, "Error: Not enough arguments. Expected \"<operation> <mode> [<target=xyz> [<base>]]\"." else
else for i=3,4 do if not parts[i] then parts[i] = false end end
for i=3,4 do if not parts[i] then parts[i] = false end end end
end
-- Initialize local variables and sets
-- Initialize local variables and sets local oper, mode, targ, base = wea_c.table.unpack(parts)
local oper, mode, targ, base = wea_c.table.unpack(parts) local operSet, modeSet = wea_c.table.makeset {"equal", "odd", "even"}, wea_c.table.makeset {"grow", "shrink", "avg"}
local operSet, modeSet = wea_c.table.makeset {"equal", "odd", "even"}, wea_c.table.makeset {"grow", "shrink", "avg"}
-- Main Logic
-- Main Logic -- Check base if base is present and if so valid.
-- Check base if base is present and if so valid. if base then
if base then if base:match("[xyz]") then -- ensure correct base syntax
if base:match("[xyz]") then -- ensure correct base syntax base = base:match("[xyz]")
base = base:match("[xyz]") else
else return false, "Error: Invalid base \""..base.."\". Expected \"x\", \"y\" or \"z\"."
return false, "Error: Invalid base \""..base.."\". Expected \"x\", \"y\" or \"z\"." end
end end
end
-- Resolve target then mode (in that order incase mode is target).
-- Resolve target then mode (in that order incase mode is target). if not targ then -- If no target set to default (xz)
if not targ then -- If no target set to default (xz) targ = "xz"
targ = "xz" elseif targ:match("[xyz]+") then -- ensure correct target syntax
elseif targ:match("[xyz]+") then -- ensure correct target syntax targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true))
targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true)) else
else return false, "Error: Invalid <target> \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"."
return false, "Error: Invalid <target> \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"." end
end
if mode == "average" then -- If mode is average set to avg
if mode == "average" then -- If mode is average set to avg mode = "avg"
mode = "avg" elseif mode:match("[xyz]+") then -- If target is actually base set vars to correct values.
elseif mode:match("[xyz]+") then -- If target is actually base set vars to correct values. base, targ, mode = targ:sub(1,1), table.concat(wea_c.tochars(mode:match("[xyz]+"),true,true)), false
base, targ, mode = targ:sub(1,1), table.concat(wea_c.tochars(mode:match("[xyz]+"),true,true)), false elseif not modeSet[mode] and not base then -- If mode is invalid and base isn't present throw error
elseif not modeSet[mode] and not base then -- If mode is invalid and base isn't present throw error return false, "Error: Invalid <mode> \""..mode.."\". Expected \"grow\", \"shrink\", or \"average\"/\"avg\"."
return false, "Error: Invalid <mode> \""..mode.."\". Expected \"grow\", \"shrink\", or \"average\"/\"avg\"." end
end
if base then
if base then if oper ~= "equal" then base = false -- If operation isn't equalize we don't need <base>
if oper ~= "equal" then base = false -- If operation isn't equalize we don't need <base> elseif targ:match(base) then -- Else check that base is not in target and return error if it is
elseif targ:match(base) then -- Else check that base is not in target and return error if it is return false, "Error: <base> ("..base..") cannot be included in <target> ("..targ..")."
return false, "Error: <base> ("..base..") cannot be included in <target> ("..targ..")." end
end end
end
-- Check if operator is valid
-- Check if operator is valid if not operSet[oper] then
if not operSet[oper] then return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"."
return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"." end
end
return true, oper, mode, targ, base
return true, oper, mode, targ, base end,
end, func = function(name, oper, mode, targ, base)
func = function(name, oper, mode, targ, base) local pos1, pos2 = Vector3.clone(wea_c.pos.get(name, 1)), Vector3.clone(wea_c.pos.get(name, 2))
local pos1, pos2 = Vector3.clone(worldedit.pos1[name]), Vector3.clone(worldedit.pos2[name]) local eval -- Declare eval placeholder function to edit later
local eval -- Declare eval placeholder function to edit later
local delta = pos2 - pos1 -- local delta equation: Vd(a) = V2(a) - V1(a)
local delta = pos2 - pos1 -- local delta equation: Vd(a) = V2(a) - V1(a) local _tl = #targ -- Get targ length as a variable incase mode is "average"/"avg"
local _tl = #targ -- Get targ length as a variable incase mode is "average"/"avg" local targ = wea_c.tocharset(targ) -- Break up targ string into set table
local targ = wea_c.tocharset(targ) -- Break up targ string into set table local _m = 0 -- _m is the container to hold the max, min or average (depending on the mode) of the axes in targ
local _m = 0 -- _m is the container to hold the max, min or average (depending on the mode) of the axes in targ
-- set _m to the max, min or mean of the target axes depending on mode or base if it exists
-- set _m to the max, min or mean of the target axes depending on mode or base if it exists if base then _m = delta[base]
if base then _m = delta[base] elseif mode == "avg" then
elseif mode == "avg" then for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end
for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end _m = _m / _tl
_m = _m / _tl elseif mode == "grow" then
elseif mode == "grow" then for k,v in pairs(targ) do if math.abs(delta[k]) > _m then _m = math.abs(delta[k]) end end
for k,v in pairs(targ) do if math.abs(delta[k]) > _m then _m = math.abs(delta[k]) end end else
else -- Take output of next(targ), put it in a table, wrap the table in brackets to force evlauation so that
-- Take output of next(targ), put it in a table, wrap the table in brackets to force evlauation so that -- we can call the first element of that table to serve as the key for a call to delta.
-- we can call the first element of that table to serve as the key for a call to delta. _m = delta[({next(targ)})[1]]
_m = delta[({next(targ)})[1]] for k,v in pairs(targ) do if math.abs(delta[k]) < _m then _m = math.abs(delta[k]) end end
for k,v in pairs(targ) do if math.abs(delta[k]) < _m then _m = math.abs(delta[k]) end end end
end
if oper == "even" then
if oper == "even" then eval = function(int)
eval = function(int) local tmp, abs, neg = int / 2, math.abs(int), int < 0
local tmp, abs, neg = int / 2, math.abs(int), int < 0 if math.floor(tmp) ~= tmp then
if math.floor(tmp) ~= tmp then if mode == "avg" then
if mode == "avg" then if int > _m then int = abs - 1
if int > _m then int = abs - 1 else int = abs + 1 end
else int = abs + 1 end elseif mode == "shrink" and abs > 0 then int = abs - 1
elseif mode == "shrink" and abs > 0 then int = abs - 1 else int = abs + 1 end
else int = abs + 1 end end
end if neg then int = int * -1 end -- Ensure correct facing direction
if neg then int = int * -1 end -- Ensure correct facing direction return int
return int end
end elseif oper == "odd" then
elseif oper == "odd" then eval = function(int)
eval = function(int) local tmp, abs, neg = int / 2, math.abs(int), int < 0
local tmp, abs, neg = int / 2, math.abs(int), int < 0 if math.floor(tmp) == tmp then
if math.floor(tmp) == tmp then if mode == "avg" then
if mode == "avg" then if int > _m then int = abs - 1
if int > _m then int = abs - 1 else int = abs + 1 end
else int = abs + 1 end elseif mode == "shrink" and abs > 0 then int = abs - 1
elseif mode == "shrink" and abs > 0 then int = abs - 1 else int = abs + 1 end
else int = abs + 1 end end
end if neg then int = int * -1 end
if neg then int = int * -1 end return int
return int end
end else -- Case: oper == "equal"
else -- Case: oper == "equal" eval = function(int)
eval = function(int) -- Bug: shrink sets pos2 to pos1
-- Bug: shrink sets pos2 to pos1 if int < 0 then return _m * -1
if int < 0 then return _m * -1 else return _m end
else return _m end end
end end
end
for k,_ in pairs(targ) do delta[k] = eval(delta[k]) end
for k,v in pairs(targ) do delta[k] = eval(delta[k]) end
wea_c.pos.set(name, 2, pos1 + delta)
worldedit.pos2[name] = pos1 + delta return true, "Pos2 set to "..pos2
worldedit.mark_pos2(name) end
return true, "position 2 set to "..pos2 })
end
})