Fixed CLRF Issues (I hope)

This commit is contained in:
VorTechnix 2024-10-07 16:11:35 -07:00
parent 29bac504b0
commit 269a73be48
No known key found for this signature in database
GPG Key ID: 091E91A69545D5BA
11 changed files with 551 additions and 549 deletions

2
.gitattributes vendored Normal file

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

@ -1,78 +1,78 @@
local Vector3 = require("worldeditadditions_core.utils.vector3")
local facing_dirs = dofile("./.tests/parse/axes/include_facing_dirs.lua")
local parse = require("worldeditadditions_core.utils.parse.axes_parser")
local parse_keyword = parse.keyword
describe("parse_keyword", function()
-- Basic tests
it("should work on single axes", function()
local ktype, axis, sign = parse_keyword("x")
assert.are.equals("axis", ktype)
assert.are.same({"x"}, axis)
assert.are.equals(1, sign)
end)
it("should work with axis clumping", function()
local ktype, axis, sign = parse_keyword("zx")
assert.are.equals("axis", ktype)
assert.are.same({"x", "z"}, axis)
assert.are.equals(1, sign)
end)
it("should work with h and v", function()
local ktype, axis, sign = parse_keyword("hv")
assert.are.equals("axis", ktype)
assert.are.same(
{"x", "y", "z", rev={"x", "y", "z"}},
axis)
assert.are.equals(1, sign)
end)
it("should work with h and v in clumping", function()
local ktype, axis, sign = parse_keyword("hyxz")
assert.are.equals("axis", ktype)
assert.are.same(
{"x", "y", "z", rev={"x", "z"}},
axis)
assert.are.equals(1, sign)
end)
it("should work with negatives", function()
local ktype, axis, sign = parse_keyword("-xv")
assert.are.equals("axis", ktype)
assert.are.same({"x", "y", rev={"y"}}, axis)
assert.are.equals(-1, sign)
end)
it("should work with dirs", function()
local ktype, axis, sign = parse_keyword("left")
assert.are.equals("dir", ktype)
assert.are.equals("left", axis)
assert.are.equals(1, sign)
end)
it("should work with negative dirs", function()
local ktype, axis, sign = parse_keyword("-right")
assert.are.equals("dir", ktype)
assert.are.equals("right", axis)
assert.are.equals(-1, sign)
end)
it("should work with mirroring", function()
local ktype, axis, sign = parse_keyword("m")
assert.are.equals("rev", ktype)
assert.are.equals("mirroring", axis)
assert.are.equals(nil, sign)
end)
-- Error tests
it("should return error for bad axis", function()
local ktype, axis, sign = parse_keyword("-axv")
assert.are.equals("err", ktype)
end)
end)
local Vector3 = require("worldeditadditions_core.utils.vector3")
local facing_dirs = dofile("./.tests/parse/axes/include_facing_dirs.lua")
local parse = require("worldeditadditions_core.utils.parse.axes_parser")
local parse_keyword = parse.keyword
describe("parse_keyword", function()
-- Basic tests
it("should work on single axes", function()
local ktype, axis, sign = parse_keyword("x")
assert.are.equals("axis", ktype)
assert.are.same({"x"}, axis)
assert.are.equals(1, sign)
end)
it("should work with axis clumping", function()
local ktype, axis, sign = parse_keyword("zx")
assert.are.equals("axis", ktype)
assert.are.same({"x", "z"}, axis)
assert.are.equals(1, sign)
end)
it("should work with h and v", function()
local ktype, axis, sign = parse_keyword("hv")
assert.are.equals("axis", ktype)
assert.are.same(
{"x", "y", "z", rev={"x", "y", "z"}},
axis)
assert.are.equals(1, sign)
end)
it("should work with h and v in clumping", function()
local ktype, axis, sign = parse_keyword("hyxz")
assert.are.equals("axis", ktype)
assert.are.same(
{"x", "y", "z", rev={"x", "z"}},
axis)
assert.are.equals(1, sign)
end)
it("should work with negatives", function()
local ktype, axis, sign = parse_keyword("-xv")
assert.are.equals("axis", ktype)
assert.are.same({"x", "y", rev={"y"}}, axis)
assert.are.equals(-1, sign)
end)
it("should work with dirs", function()
local ktype, axis, sign = parse_keyword("left")
assert.are.equals("dir", ktype)
assert.are.equals("left", axis)
assert.are.equals(1, sign)
end)
it("should work with negative dirs", function()
local ktype, axis, sign = parse_keyword("-right")
assert.are.equals("dir", ktype)
assert.are.equals("right", axis)
assert.are.equals(-1, sign)
end)
it("should work with mirroring", function()
local ktype, axis, sign = parse_keyword("m")
assert.are.equals("rev", ktype)
assert.are.equals("mirroring", axis)
assert.are.equals(nil, sign)
end)
-- Error tests
it("should return error for bad axis", function()
local ktype, axis, sign = parse_keyword("-axv")
assert.are.equals("err", ktype)
end)
end)

@ -1,46 +1,46 @@
-- ███████ ███████ ██ ███████ ██████ ████████ ██████ ██████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ █████ ██ █████ ██ ██ ██ ██ ██████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ███████ ███████ ███████ ██████ ██ ██████ ██ ██ ███████
-- Chat commands that operate on selections.
local wea_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/"
local weac = worldeditadditions_core
dofile(wea_cmdpath.."scentre.lua")
dofile(wea_cmdpath.."scloud.lua")
dofile(wea_cmdpath.."sgrow.lua")
dofile(wea_cmdpath.."smake.lua")
dofile(wea_cmdpath.."spop.lua")
dofile(wea_cmdpath.."spush.lua")
dofile(wea_cmdpath.."srel.lua")
dofile(wea_cmdpath.."sshift.lua")
dofile(wea_cmdpath.."sshrink.lua")
dofile(wea_cmdpath.."sstack.lua")
--- DEPRECATED ---
dofile(wea_cmdpath.."scol.lua")
dofile(wea_cmdpath.."scube.lua")
dofile(wea_cmdpath.."srect.lua")
dofile(wea_cmdpath.."sfactor.lua")
--- END DEPRECATED ---
dofile(wea_cmdpath.."unmark.lua")
dofile(wea_cmdpath.."mark.lua")
dofile(wea_cmdpath.."pos1-2.lua")
dofile(wea_cmdpath.."reset.lua")
-- Aliases
weac.register_alias("sfac", "sfactor")
weac.register_alias("expand", "sgrow", true) -- true = override target
weac.register_alias("outset", "sgrow", true) -- true = override target
weac.register_alias("contract", "sshrink", true) -- true = override target
weac.register_alias("inset", "sshrink", true) -- true = override target
weac.register_alias("shift", "sshift", true) -- true = override target
weac.register_alias("1", "pos1", true) -- true = override target
weac.register_alias("2", "pos2", true) -- true = override target
-- ███████ ███████ ██ ███████ ██████ ████████ ██████ ██████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ █████ ██ █████ ██ ██ ██ ██ ██████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ███████ ███████ ███████ ██████ ██ ██████ ██ ██ ███████
-- Chat commands that operate on selections.
local wea_cmdpath = worldeditadditions_commands.modpath .. "/commands/selectors/"
local weac = worldeditadditions_core
dofile(wea_cmdpath.."scentre.lua")
dofile(wea_cmdpath.."scloud.lua")
dofile(wea_cmdpath.."sgrow.lua")
dofile(wea_cmdpath.."smake.lua")
dofile(wea_cmdpath.."spop.lua")
dofile(wea_cmdpath.."spush.lua")
dofile(wea_cmdpath.."srel.lua")
dofile(wea_cmdpath.."sshift.lua")
dofile(wea_cmdpath.."sshrink.lua")
dofile(wea_cmdpath.."sstack.lua")
--- DEPRECATED ---
dofile(wea_cmdpath.."scol.lua")
dofile(wea_cmdpath.."scube.lua")
dofile(wea_cmdpath.."srect.lua")
dofile(wea_cmdpath.."sfactor.lua")
--- END DEPRECATED ---
dofile(wea_cmdpath.."unmark.lua")
dofile(wea_cmdpath.."mark.lua")
dofile(wea_cmdpath.."pos1-2.lua")
dofile(wea_cmdpath.."reset.lua")
-- Aliases
weac.register_alias("sfac", "sfactor")
weac.register_alias("expand", "sgrow", true) -- true = override target
weac.register_alias("outset", "sgrow", true) -- true = override target
weac.register_alias("contract", "sshrink", true) -- true = override target
weac.register_alias("inset", "sshrink", true) -- true = override target
weac.register_alias("shift", "sshift", true) -- true = override target
weac.register_alias("1", "pos1", true) -- true = override target
weac.register_alias("2", "pos2", true) -- true = override target

@ -1,33 +1,33 @@
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ██████ ███████ ███ ██ ████████ ███████ ██████
-- ██ ██ ██ ████ ██ ██ ██ ██ ██
-- ███████ ██ █████ ██ ██ ██ ██ █████ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██████ ███████ ██ ████ ██ ███████ ██ ██
worldeditadditions_core.register_command("scentre", {
params = "",
description = "Set WorldEdit region positions 1 and 2 to the centre of the current selection.",
privs = {worldedit=true},
require_pos = 2,
parse = function(params_text)
return true
end,
func = function(name)
local mean = Vector3.mean(
Vector3.clone(wea_c.pos.get(name, 1)),
Vector3.clone(wea_c.pos.get(name, 2))
)
local pos1, pos2 = Vector3.clone(mean), Vector3.clone(mean)
pos1 = pos1:floor()
pos2 = pos2:ceil()
wea_c.pos.set_all(name, {pos1, pos2})
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
end,
})
-- lua print(vecs.mean.x..", "..vecs.mean.y..", "..vecs.mean.z)
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ██████ ███████ ███ ██ ████████ ███████ ██████
-- ██ ██ ██ ████ ██ ██ ██ ██ ██
-- ███████ ██ █████ ██ ██ ██ ██ █████ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██████ ███████ ██ ████ ██ ███████ ██ ██
worldeditadditions_core.register_command("scentre", {
params = "",
description = "Set WorldEdit region positions 1 and 2 to the centre of the current selection.",
privs = {worldedit=true},
require_pos = 2,
parse = function(params_text)
return true
end,
func = function(name)
local mean = Vector3.mean(
Vector3.clone(wea_c.pos.get(name, 1)),
Vector3.clone(wea_c.pos.get(name, 2))
)
local pos1, pos2 = Vector3.clone(mean), Vector3.clone(mean)
pos1 = pos1:floor()
pos2 = pos2:ceil()
wea_c.pos.set_all(name, {pos1, pos2})
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
end,
})
-- lua print(vecs.mean.x..", "..vecs.mean.y..", "..vecs.mean.z)

@ -1,22 +1,22 @@
local wea = worldeditadditions
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ███████ █████ ██████ ████████ ██████ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ █████ ███████ ██ ██ ██ ██ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██
worldeditadditions_core.register_command("sfactor", {
params = "None",
description = "DEPRECATED: please use //grow or //shrink instead.",
privs = { worldedit = true },
parse = function(params_text)
return params_text
end,
func = function(name, paramtext)
return false, "DEPRECATED: please use //grow or //shrink instead..."
end
})
local wea = worldeditadditions
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ███████ █████ ██████ ████████ ██████ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ █████ ███████ ██ ██ ██ ██ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██
worldeditadditions_core.register_command("sfactor", {
params = "None",
description = "DEPRECATED: please use //grow or //shrink instead.",
privs = { worldedit = true },
parse = function(params_text)
return params_text
end,
func = function(name, paramtext)
return false, "DEPRECATED: please use //grow or //shrink instead..."
end
})

@ -1,42 +1,42 @@
-- local wea = worldeditadditions
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ██████ ██████ ██████ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ███ ██████ ██ ██ ██ █ ██
-- ██ ██ ██ ██ ██ ██ ██ ██ ███ ██
-- ███████ ██████ ██ ██ ██████ ███ ███
worldeditadditions_core.register_command("sgrow", {
params = "<unified axis syntax>",
description = "Grow selection region",
privs = { worldedit = true },
require_pos = 0,
parse = function(params_text)
local ret = wea_c.split(params_text)
if #ret < 1 then return false, "SGROW: No params found!"
else return true, ret end
end,
func = function(name, params_text)
local facing = wea_c.player_dir(name)
local min, max = wea_c.parse.directions(params_text, facing)
if not min then return false, max end
local pos1 = wea_c.pos.get(name, 1)
local pos2 = wea_c.pos.get(name, 2)
if not pos2 then wea_c.pos.set(name, 2, pos1)
else pos1, pos2 = Vector3.sort(pos1, pos2) end
pos1, pos2 = pos1:add(min), pos2:add(max)
wea_c.pos.set_all(name, {pos1, pos2})
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
end,
})
-- Tests
-- //srel front 5 left 3 y 2
-- local wea = worldeditadditions
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ██████ ██████ ██████ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ███ ██████ ██ ██ ██ █ ██
-- ██ ██ ██ ██ ██ ██ ██ ██ ███ ██
-- ███████ ██████ ██ ██ ██████ ███ ███
worldeditadditions_core.register_command("sgrow", {
params = "<unified axis syntax>",
description = "Grow selection region",
privs = { worldedit = true },
require_pos = 0,
parse = function(params_text)
local ret = wea_c.split(params_text)
if #ret < 1 then return false, "SGROW: No params found!"
else return true, ret end
end,
func = function(name, params_text)
local facing = wea_c.player_dir(name)
local min, max = wea_c.parse.directions(params_text, facing)
if not min then return false, max end
local pos1 = wea_c.pos.get(name, 1)
local pos2 = wea_c.pos.get(name, 2)
if not pos2 then wea_c.pos.set(name, 2, pos1)
else pos1, pos2 = Vector3.sort(pos1, pos2) end
pos1, pos2 = pos1:add(min), pos2:add(max)
wea_c.pos.set_all(name, {pos1, pos2})
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
end,
})
-- Tests
-- //srel front 5 left 3 y 2

@ -1,131 +1,131 @@
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ███ ███ █████ ██ ██ ███████
-- ██ ████ ████ ██ ██ ██ ██ ██
-- ███████ ██ ████ ██ ███████ █████ █████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ██ ██ ██ ██ ██ ███████
worldeditadditions_core.register_command("smake", {
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.",
privs = { worldedit = true },
require_pos = 2,
parse = function(params_text)
-- Split params_text, check for missing arguments and fill in empty spots
local parts = wea_c.split(params_text, "%s+", false)
if #parts < 2 then
return false, "Error: Not enough arguments. Expected \"<operation> <mode> [<target=xyz> [<base>]]\"."
else
for i=3,4 do if not parts[i] then parts[i] = false end end
end
-- Initialize local variables and sets
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"}
-- Main Logic
-- Check base if base is present and if so valid.
if base then
if base:match("[xyz]") then -- ensure correct base syntax
base = base:match("[xyz]")
else
return false, "Error: Invalid base \""..base.."\". Expected \"x\", \"y\" or \"z\"."
end
end
-- Resolve target then mode (in that order incase mode is target).
if not targ then -- If no target set to default (xz)
targ = "xz"
elseif targ:match("[xyz]+") then -- ensure correct target syntax
targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true))
else
return false, "Error: Invalid <target> \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"."
end
if mode == "average" then -- If mode is average set to avg
mode = "avg"
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
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\"."
end
if base then
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
return false, "Error: <base> ("..base..") cannot be included in <target> ("..targ..")."
end
end
-- Check if operator is valid
if not operSet[oper] then
return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"."
end
return true, oper, mode, targ, base
end,
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 eval -- Declare eval placeholder function to edit later
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 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
-- 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]
elseif mode == "avg" then
for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end
_m = _m / _tl
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
else
-- 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.
_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
end
if oper == "even" then
eval = function(int)
local tmp, abs, neg = int / 2, math.abs(int), int < 0
if math.floor(tmp) ~= tmp then
if mode == "avg" then
if int > _m then int = abs - 1
else int = abs + 1 end
elseif mode == "shrink" and abs > 0 then int = abs - 1
else int = abs + 1 end
end
if neg then int = int * -1 end -- Ensure correct facing direction
return int
end
elseif oper == "odd" then
eval = function(int)
local tmp, abs, neg = int / 2, math.abs(int), int < 0
if math.floor(tmp) == tmp then
if mode == "avg" then
if int > _m then int = abs - 1
else int = abs + 1 end
elseif mode == "shrink" and abs > 0 then int = abs - 1
else int = abs + 1 end
end
if neg then int = int * -1 end
return int
end
else -- Case: oper == "equal"
eval = function(int)
-- Bug: shrink sets pos2 to pos1
if int < 0 then return _m * -1
else return _m end
end
end
for k,_ in pairs(targ) do delta[k] = eval(delta[k]) end
wea_c.pos.set(name, 2, pos1 + delta)
return true, "Position 2 to "..pos2
end
})
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ███ ███ █████ ██ ██ ███████
-- ██ ████ ████ ██ ██ ██ ██ ██
-- ███████ ██ ████ ██ ███████ █████ █████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ██ ██ ██ ██ ██ ███████
worldeditadditions_core.register_command("smake", {
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.",
privs = { worldedit = true },
require_pos = 2,
parse = function(params_text)
-- Split params_text, check for missing arguments and fill in empty spots
local parts = wea_c.split(params_text, "%s+", false)
if #parts < 2 then
return false, "Error: Not enough arguments. Expected \"<operation> <mode> [<target=xyz> [<base>]]\"."
else
for i=3,4 do if not parts[i] then parts[i] = false end end
end
-- Initialize local variables and sets
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"}
-- Main Logic
-- Check base if base is present and if so valid.
if base then
if base:match("[xyz]") then -- ensure correct base syntax
base = base:match("[xyz]")
else
return false, "Error: Invalid base \""..base.."\". Expected \"x\", \"y\" or \"z\"."
end
end
-- Resolve target then mode (in that order incase mode is target).
if not targ then -- If no target set to default (xz)
targ = "xz"
elseif targ:match("[xyz]+") then -- ensure correct target syntax
targ = table.concat(wea_c.tochars(targ:match("[xyz]+"),true,true))
else
return false, "Error: Invalid <target> \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"."
end
if mode == "average" then -- If mode is average set to avg
mode = "avg"
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
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\"."
end
if base then
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
return false, "Error: <base> ("..base..") cannot be included in <target> ("..targ..")."
end
end
-- Check if operator is valid
if not operSet[oper] then
return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"."
end
return true, oper, mode, targ, base
end,
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 eval -- Declare eval placeholder function to edit later
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 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
-- 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]
elseif mode == "avg" then
for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end
_m = _m / _tl
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
else
-- 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.
_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
end
if oper == "even" then
eval = function(int)
local tmp, abs, neg = int / 2, math.abs(int), int < 0
if math.floor(tmp) ~= tmp then
if mode == "avg" then
if int > _m then int = abs - 1
else int = abs + 1 end
elseif mode == "shrink" and abs > 0 then int = abs - 1
else int = abs + 1 end
end
if neg then int = int * -1 end -- Ensure correct facing direction
return int
end
elseif oper == "odd" then
eval = function(int)
local tmp, abs, neg = int / 2, math.abs(int), int < 0
if math.floor(tmp) == tmp then
if mode == "avg" then
if int > _m then int = abs - 1
else int = abs + 1 end
elseif mode == "shrink" and abs > 0 then int = abs - 1
else int = abs + 1 end
end
if neg then int = int * -1 end
return int
end
else -- Case: oper == "equal"
eval = function(int)
-- Bug: shrink sets pos2 to pos1
if int < 0 then return _m * -1
else return _m end
end
end
for k,_ in pairs(targ) do delta[k] = eval(delta[k]) end
wea_c.pos.set(name, 2, pos1 + delta)
return true, "Position 2 to "..pos2
end
})

@ -1,37 +1,37 @@
-- local wea = worldeditadditions
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ██████ ███████ ██
-- ██ ██ ██ ██ ██
-- ███████ ██████ █████ ██
-- ██ ██ ██ ██ ██
-- ███████ ██ ██ ███████ ███████
worldeditadditions_core.register_command("srel", {
params = "<unified axis syntax>",
description = "Set WorldEdit region position 2 relative to position 1 and player facing.",
privs = { worldedit = true },
require_pos = 0,
parse = function(params_text)
local ret = wea_c.split(params_text)
if #ret < 1 then return false, "SREL: No params found!"
else return true, ret end
end,
func = function(name, params_text)
local facing = wea_c.player_dir(name)
local vec, err = wea_c.parse.directions(params_text, facing, true)
if not vec then return false, err end
local pos1 = wea_c.pos.get(name, 1)
local pos2 = pos1:add(vec)
wea_c.pos.set_all(name, {pos1, pos2})
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
end,
})
-- Tests
-- //srel front 5 left 3 y 2
-- local wea = worldeditadditions
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ██████ ███████ ██
-- ██ ██ ██ ██ ██
-- ███████ ██████ █████ ██
-- ██ ██ ██ ██ ██
-- ███████ ██ ██ ███████ ███████
worldeditadditions_core.register_command("srel", {
params = "<unified axis syntax>",
description = "Set WorldEdit region position 2 relative to position 1 and player facing.",
privs = { worldedit = true },
require_pos = 0,
parse = function(params_text)
local ret = wea_c.split(params_text)
if #ret < 1 then return false, "SREL: No params found!"
else return true, ret end
end,
func = function(name, params_text)
local facing = wea_c.player_dir(name)
local vec, err = wea_c.parse.directions(params_text, facing, true)
if not vec then return false, err end
local pos1 = wea_c.pos.get(name, 1)
local pos2 = pos1:add(vec)
wea_c.pos.set_all(name, {pos1, pos2})
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
end,
})
-- Tests
-- //srel front 5 left 3 y 2

@ -1,42 +1,42 @@
-- local wea = worldeditadditions
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ███████ ██ ██ ██████ ██ ███ ██ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██
-- ███████ ███████ ███████ ██████ ██ ██ ██ ██ █████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ███████ ██ ██ ██ ██ ██ ██ ████ ██ ██
worldeditadditions_core.register_command("sshrink", {
params = "<unified axis syntax>",
description = "Shrink selection region",
privs = { worldedit = true },
require_pos = 0,
parse = function(params_text)
local ret = wea_c.split(params_text)
if #ret < 1 then return false, "Error: No params found!"
else return true, ret end
end,
func = function(name, params_text)
local facing = wea_c.player_dir(name)
local min, max = wea_c.parse.directions(params_text, facing)
if not min then return false, max end
local pos1 = wea_c.pos.get(name, 1)
local pos2 = wea_c.pos.get(name, 2)
if not pos2 then wea_c.pos.set(name, 2, pos1)
else pos1, pos2 = Vector3.sort(pos1, pos2) end
pos1, pos2 = pos1:add(max), pos2:add(min)
wea_c.pos.set_all(name, {pos1, pos2})
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
end,
})
-- Tests
-- //srel front 5 left 3 y 2
-- local wea = worldeditadditions
local wea_c = worldeditadditions_core
local Vector3 = wea_c.Vector3
-- ███████ ███████ ██ ██ ██████ ██ ███ ██ ██ ██
-- ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██
-- ███████ ███████ ███████ ██████ ██ ██ ██ ██ █████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ███████ ██ ██ ██ ██ ██ ██ ████ ██ ██
worldeditadditions_core.register_command("sshrink", {
params = "<unified axis syntax>",
description = "Shrink selection region",
privs = { worldedit = true },
require_pos = 0,
parse = function(params_text)
local ret = wea_c.split(params_text)
if #ret < 1 then return false, "Error: No params found!"
else return true, ret end
end,
func = function(name, params_text)
local facing = wea_c.player_dir(name)
local min, max = wea_c.parse.directions(params_text, facing)
if not min then return false, max end
local pos1 = wea_c.pos.get(name, 1)
local pos2 = wea_c.pos.get(name, 2)
if not pos2 then wea_c.pos.set(name, 2, pos1)
else pos1, pos2 = Vector3.sort(pos1, pos2) end
pos1, pos2 = pos1:add(max), pos2:add(min)
wea_c.pos.set_all(name, {pos1, pos2})
return true, "Position 1 to "..pos1..", Position 2 to "..pos2
end,
})
-- Tests
-- //srel front 5 left 3 y 2

@ -1,29 +1,29 @@
local wea_c = worldeditadditions_core
-- local Vector3 = wea_c.Vector3
-- ██ ██ █████ ███████ ██████ █████ ██████ ███████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ██ ███████ ███████ ██████ ███████ ██████ ███████ █████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██████ ██ ██ ███████ ██ ██ ██ ██ ██ ███████ ███████
worldeditadditions_core.register_command("uasparse", {
params = "<unified axis syntax>",
description = "Debug command. Returns min and max vectors for given inputs",
privs = { worldedit = true },
-- require_pos = 2,
parse = function(params_text)
local ret = wea_c.split(params_text)
if #ret < 1 then return false, "Error: No params found!"
else return true, ret end
end,
func = function(name, params_text)
local facing = wea_c.player_dir(name)
local min, max = wea_c.parse.directions(params_text, facing)
if not min then
return false, max
else
return true, "Min: "..min.." Max: "..max
end
end
})
local wea_c = worldeditadditions_core
-- local Vector3 = wea_c.Vector3
-- ██ ██ █████ ███████ ██████ █████ ██████ ███████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██ ██ ███████ ███████ ██████ ███████ ██████ ███████ █████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ██████ ██ ██ ███████ ██ ██ ██ ██ ██ ███████ ███████
worldeditadditions_core.register_command("uasparse", {
params = "<unified axis syntax>",
description = "Debug command. Returns min and max vectors for given inputs",
privs = { worldedit = true },
-- require_pos = 2,
parse = function(params_text)
local ret = wea_c.split(params_text)
if #ret < 1 then return false, "Error: No params found!"
else return true, ret end
end,
func = function(name, params_text)
local facing = wea_c.player_dir(name)
local min, max = wea_c.parse.directions(params_text, facing)
if not min then
return false, max
else
return true, "Min: "..min.." Max: "..max
end
end
})

@ -1,90 +1,90 @@
-- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here)
-- Source: https://stackoverflow.com/a/43582076/1460422
-- gsplit: iterate over substrings in a string separated by a pattern
--
-- Parameters:
-- text (string) - the string to iterate over
-- pattern (string) - the separator pattern
-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain
-- string, not a Lua pattern
--
-- Returns: iterator
--
-- Usage:
-- for substr in gsplit(text, pattern, plain) do
-- doSomething(substr)
-- end
local function gsplit(text, pattern, plain)
local splitStart, length = 1, #text
return function ()
if splitStart then
local sepStart, sepEnd = string.find(text, pattern, splitStart, plain)
local ret
if not sepStart then
ret = string.sub(text, splitStart)
splitStart = nil
elseif sepEnd < sepStart then
-- Empty separator!
ret = string.sub(text, splitStart, sepStart)
if sepStart < length then
splitStart = sepStart + 1
else
splitStart = nil
end
else
ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or ''
splitStart = sepEnd + 1
end
return ret
end
end
end
--- Split a string into substrings separated by a pattern. -- Deprecated
-- @param text string The string to iterate over
-- @param pattern string The separator pattern
-- @param plain boolean If true (or truthy), pattern is interpreted as a
-- plain string, not a Lua pattern
-- @returns table A sequence table containing the substrings
local function dsplit(text, pattern, plain)
local ret = {}
for match in gsplit(text, pattern, plain) do
table.insert(ret, match)
end
return ret
end
--- Split a string into substrings separated by a pattern.
-- @param str string The string to iterate over
-- @param dlm="%s+" string The delimiter (separator) pattern. If a falsey value is passed, then the default value is used.
-- @param plain boolean If true (or truthy), pattern is interpreted as a
-- plain string, not a Lua pattern
-- @returns table A sequence table containing the substrings
local function split(str,dlm,plain)
if not dlm then dlm = "%s+" end
local pos, ret = 0, {}
local ins, i = str:find(dlm,pos,plain)
-- "if plain" shaves off some time in the while statement
if plain then
while ins do
table.insert(ret,str:sub(pos,ins - 1))
pos = ins + #dlm
ins = str:find(dlm,pos,true)
end
else
while ins do
table.insert(ret,str:sub(pos,ins - 1))
pos = i + 1
ins, i = str:find(dlm,pos)
end
end
-- print(pos..","..#str)
if str:sub(pos,#str) ~= "" then
table.insert(ret,str:sub(pos,#str))
end
return ret
end
-- Licence: GPLv2 (MPL-2.0 is compatible, so we can use this here)
-- Source: https://stackoverflow.com/a/43582076/1460422
-- gsplit: iterate over substrings in a string separated by a pattern
--
-- Parameters:
-- text (string) - the string to iterate over
-- pattern (string) - the separator pattern
-- plain (boolean) - if true (or truthy), pattern is interpreted as a plain
-- string, not a Lua pattern
--
-- Returns: iterator
--
-- Usage:
-- for substr in gsplit(text, pattern, plain) do
-- doSomething(substr)
-- end
local function gsplit(text, pattern, plain)
local splitStart, length = 1, #text
return function ()
if splitStart then
local sepStart, sepEnd = string.find(text, pattern, splitStart, plain)
local ret
if not sepStart then
ret = string.sub(text, splitStart)
splitStart = nil
elseif sepEnd < sepStart then
-- Empty separator!
ret = string.sub(text, splitStart, sepStart)
if sepStart < length then
splitStart = sepStart + 1
else
splitStart = nil
end
else
ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or ''
splitStart = sepEnd + 1
end
return ret
end
end
end
--- Split a string into substrings separated by a pattern. -- Deprecated
-- @param text string The string to iterate over
-- @param pattern string The separator pattern
-- @param plain boolean If true (or truthy), pattern is interpreted as a
-- plain string, not a Lua pattern
-- @returns table A sequence table containing the substrings
local function dsplit(text, pattern, plain)
local ret = {}
for match in gsplit(text, pattern, plain) do
table.insert(ret, match)
end
return ret
end
--- Split a string into substrings separated by a pattern.
-- @param str string The string to iterate over
-- @param dlm="%s+" string The delimiter (separator) pattern. If a falsey value is passed, then the default value is used.
-- @param plain boolean If true (or truthy), pattern is interpreted as a
-- plain string, not a Lua pattern
-- @returns table A sequence table containing the substrings
local function split(str,dlm,plain)
if not dlm then dlm = "%s+" end
local pos, ret = 0, {}
local ins, i = str:find(dlm,pos,plain)
-- "if plain" shaves off some time in the while statement
if plain then
while ins do
table.insert(ret,str:sub(pos,ins - 1))
pos = ins + #dlm
ins = str:find(dlm,pos,true)
end
else
while ins do
table.insert(ret,str:sub(pos,ins - 1))
pos = i + 1
ins, i = str:find(dlm,pos)
end
end
-- print(pos..","..#str)
if str:sub(pos,#str) ~= "" then
table.insert(ret,str:sub(pos,#str))
end
return ret
end
return split