Merge pull request #64 from sbrl/selection-tools

sfactor and housekeeping
This commit is contained in:
Starbeamrainbowlabs 2021-06-28 01:08:10 +01:00 committed by GitHub
commit 643790dc07
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 138 additions and 33 deletions

3
.gitignore vendored
View file

@ -235,3 +235,6 @@ tmp/
temp/ temp/
# End of https://www.toptal.com/developers/gitignore/api/lua,node # End of https://www.toptal.com/developers/gitignore/api/lua,node
# VorTechnix stuff
.vdev/

View file

@ -3,6 +3,9 @@ It's about time I started a changelog! This will serve from now on as the main c
Note to self: See the bottom of this file for the release template text. Note to self: See the bottom of this file for the release template text.
## v1.13: Untitled update (unreleased)
- Add `//sfactor` (_selection factor_) - Selection Tools by @VorTechnix are finished for now.
## v1.12: The selection tools update (26th June 2021) ## v1.12: The selection tools update (26th June 2021)
- Add `//spush`, `//spop`, and `//sstack` - Add `//spush`, `//spop`, and `//sstack`
- Add `//srect` (_select rectangle_), `//scol` (_select column_), `//scube` (_select cube_) - thanks, @VorTechnix! - Add `//srect` (_select rectangle_), `//scol` (_select column_), `//scube` (_select cube_) - thanks, @VorTechnix!

View file

@ -641,7 +641,7 @@ Value | Description
----------------|-------------- ----------------|--------------
`grow` | Grow each axis specified in `<target>` to the nearest odd/even number to itself `grow` | Grow each axis specified in `<target>` to the nearest odd/even number to itself
`shrink` | Shrink each axis specified in `<target>` to the nearest odd/even number to itself `shrink` | Shrink each axis specified in `<target>` to the nearest odd/even number to itself
`average`|`avg` | Take the average of all axes specified in `<target>` and then for each specified axis grow or shrink it, depending on weather it is less than or greater than the average, to the nearest odd/even number to itself `average`/`avg` | Takes the average of all axes specified in `<target>` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest odd/even number to itself
#### *If `<operation>` == equal:* #### *If `<operation>` == equal:*
The `<mode>` argument can be omitted and will not be parsed if present if `<base>` is specified The `<mode>` argument can be omitted and will not be parsed if present if `<base>` is specified
@ -650,7 +650,8 @@ Value | Description
----------------|--------------- ----------------|---------------
`grow` | Grow each axis specified in `<target>` to the length of the longest specified axis `grow` | Grow each axis specified in `<target>` to the length of the longest specified axis
`shrink` | Shrink each axis specified in `<target>` to the length of the shortest specified axis `shrink` | Shrink each axis specified in `<target>` to the length of the shortest specified axis
`average`|`avg` | Set each axis specified in `<target>` to the average length of all the specified axes `average`/`avg` | Set each axis specified in `<target>` to the average length of all the specified axes
If `<base>` | `<mode>` becomes optional. If present it will be ignored.
### Additional arguments: ### Additional arguments:
@ -658,8 +659,25 @@ Name | Description
------------|------------------ ------------|------------------
`<target>` | Specify axes to perform operation on (default= xz)| `<target>` | Specify axes to perform operation on (default= xz)|
`<base>`: If `<operation>` == odd or even | Does nothing `<base>`: If `<operation>` == odd or even | Does nothing
`<base>`: If `<operation>` == equal | Overrides `<mode>`^[1] and sets all `<target>` axes equal to itself `<base>`: If `<operation>` == equal | Overrides `<mode>` and sets all `<target>` axes equal to itself
## `//sfactor <mode:grow|shrink|average> <factor> [<target=xz>]`
Short for _selection make_; alias: `//sfac`. Built specifically for use with `//maze`, this command sets targeted axes equal to the nearest multiple of `<factor>` based on the `<mode>`.
Usage examples:
```
//sfac grow 5
//sfac avg 3 xy
```
### `<mode>`: grow|shrink|average
Value | Description
--------|--------------
`grow` | Rounds the length of each target axis up to the nearest multiple of `<factor>`
`shrink` | Rounds the length of each target axis down to the nearest multiple of `<factor>`
`average`/`avg` | Takes the average of all axes specified in `<target>` and then for each specified axis grows or shrinks it, depending on whether it is less than or greater than the average, to the nearest multiple of `<factor>`
## `//sstack` ## `//sstack`
Displays the contents of your per-user selection stack. This stack can be pushed to and popped from rather like a stack of plates. See also `//spush` (for pushing to the selection stack) and `//spop` (for popping from the selection stack). Displays the contents of your per-user selection stack. This stack can be pushed to and popped from rather like a stack of plates. See also `//spush` (for pushing to the selection stack) and `//spop` (for popping from the selection stack).
@ -668,7 +686,6 @@ Displays the contents of your per-user selection stack. This stack can be pushed
//sstack //sstack
``` ```
## `//spush` ## `//spush`
Pushes the currently defined region onto your per-user selection stack. Does not otherwise alter the defined region. Pushes the currently defined region onto your per-user selection stack. Does not otherwise alter the defined region.

View file

@ -0,0 +1,22 @@
-- ███████ ███████ ██ ███████ ██████ ████████ ██████ ██████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ █████ ██ █████ ██ ██ ██ ██ ██████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ███████ ███████ ███████ ██████ ██ ██████ ██ ██ ███████
-- Chat commands that operate on selections.
local we_c = worldeditadditions_commands
we_c.modpath = minetest.get_modpath("worldeditadditions_commands")
dofile(we_c.modpath.."/commands/selectors/srel.lua")
dofile(we_c.modpath.."/commands/selectors/scentre.lua")
dofile(we_c.modpath.."/commands/selectors/scloud.lua")
dofile(we_c.modpath.."/commands/selectors/scol.lua")
dofile(we_c.modpath.."/commands/selectors/scube.lua")
dofile(we_c.modpath.."/commands/selectors/sfactor.lua")
dofile(we_c.modpath.."/commands/selectors/smake.lua")
dofile(we_c.modpath.."/commands/selectors/spop.lua")
dofile(we_c.modpath.."/commands/selectors/spush.lua")
dofile(we_c.modpath.."/commands/selectors/srect.lua")
dofile(we_c.modpath.."/commands/selectors/sstack.lua")

View file

@ -0,0 +1,83 @@
-- ███████ ███████ █████ ██████ ████████ ██████ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ █████ ███████ ██ ██ ██ ██ ██████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ██ ██ ██████ ██ ██████ ██ ██
local wea = worldeditadditions
worldedit.register_command("sfactor", {
params = "<mode> <factor> [<target=xz>]",
description = "Make the length of one or more target axes of the current selection to be multiple(s) of <factor>.",
privs = { worldedit = true },
require_pos = 2,
parse = function(params_text)
local parts = wea.split(params_text, "%s+", false)
if #parts < 2 then
return false, "Error: Not enough arguments. Expected \"<mode> <factor> [<target>]\"."
end
local mode, fac, targ = unpack(parts)
local modeSet = wea.makeset {"grow", "shrink", "avg"}
-- Mode parsing
if mode == "average" then -- If mode is average set to avg
mode = "avg"
elseif not modeSet[mode] then -- If mode is invalid throw error
return false, "Error: Invalid <mode> \""..mode.."\". Expected \"grow\", \"shrink\", or \"average\"/\"avg\"."
end
-- Factor parsing
local factest = tonumber(fac)
if not factest then
return false, "Error: Invalid <factor> \""..fac.."\". Expected a number."
elseif factest < 2 then
return false, "Error: <factor> is too low. Expected a number equal to or greater than 2."
else
fac = math.floor(factest+0.5)
end
-- Target parsing
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.tochars(targ:match("[xyz]+"),true,true))
else
return false, "Error: Invalid <target> \""..targ.."\". Expected \"x\" and or \"y\" and or \"z\"."
end
return true, mode, fac, targ
end,
func = function(name, mode, fac, targ)
local p1, p2 = vector.new(worldedit.pos1[name]), vector.new(worldedit.pos2[name])
local delta = vector.subtract(p2,p1) -- 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.tocharset(targ) -- Break up targ string into set table
local _m = 0 -- _m is the container to hold the average of the axes in targ
-- set _m to the max, min or mean of the target axes depending on mode (_tl is the length of targ) or base if it exists
if mode == "avg" then
for k,v in pairs(targ) do _m = _m + math.abs(delta[k]) end
_m = _m / _tl
end
-- Equasion: round(delta[<axis>] / factor) * factor
local eval = function(int,fac)
local tmp, abs, neg = int / fac, math.abs(int), int < 0
if mode == "avg" then
if int > _m then int = math.floor(abs / fac) * fac
else int = math.ceil(abs / fac) * fac end
elseif mode == "shrink" then int = math.floor(abs / fac) * fac
else int = math.ceil(abs / fac) * fac end
if int < fac then int = fac end -- Ensure selection doesn't collapse to 0
if neg then int = int * -1 end -- Ensure correct facing direction
return int
end
for k,v in pairs(targ) do delta[k] = eval(delta[k],fac) end
worldedit.pos2[name] = vector.add(p1,delta)
worldedit.mark_pos2(name)
return true, "position 2 set to " .. minetest.pos_to_string(p2)
end
})

View file

@ -61,9 +61,6 @@ worldedit.register_command("smake", {
return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"." return false, "Error: Invalid operator \""..oper.."\". Expected \"odd\", \"even\" or \"equal\"."
end end
if false then -- Argument test
return false, "<operator>: " .. oper .. ", <mode>: " .. tostring(mode) .. ", <target>: " .. tostring(targ) .. ", <base>: " .. tostring(base)
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)
@ -73,7 +70,7 @@ worldedit.register_command("smake", {
local delta = vector.subtract(p2,p1) -- local delta equation: Vd(a) = V2(a) - V1(a) local delta = vector.subtract(p2,p1) -- 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.tocharset(targ) -- Break up targ string into set table local targ = wea.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 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]
@ -99,7 +96,7 @@ worldedit.register_command("smake", {
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 -- Ensure correct facing direction
return int return int
end end
elseif oper == "odd" then elseif oper == "odd" then
@ -121,22 +118,8 @@ worldedit.register_command("smake", {
if int < 0 then return _m * -1 if int < 0 then return _m * -1
else return _m end else return _m end
end end
-- return false, "Case \"equal\" not handled."
end end
--- Test:
if false then
local brk = ""
for k,v in pairs(targ) do
brk = brk..k..": "..delta[k]..", "
delta[k] = eval(delta[k])
brk = brk..k..": "..delta[k]..", "
end
return false, brk
end
-- //multi //fp set1 589 2 -82 //fp set2 615 2 -53
-- //smake even shrink
for k,v in pairs(targ) do delta[k] = eval(delta[k]) end for k,v in pairs(targ) do delta[k] = eval(delta[k]) end
worldedit.pos2[name] = vector.add(p1,delta) worldedit.pos2[name] = vector.add(p1,delta)

View file

@ -41,16 +41,8 @@ dofile(we_c.modpath.."/commands/meta/many.lua")
dofile(we_c.modpath.."/commands/meta/subdivide.lua") dofile(we_c.modpath.."/commands/meta/subdivide.lua")
dofile(we_c.modpath.."/commands/meta/ellipsoidapply.lua") dofile(we_c.modpath.."/commands/meta/ellipsoidapply.lua")
dofile(we_c.modpath.."/commands/selectors/srel.lua") -- Selection Tools
dofile(we_c.modpath.."/commands/selectors/scentre.lua") dofile(we_c.modpath.."/commands/selectors/init.lua")
dofile(we_c.modpath.."/commands/selectors/scloud.lua")
dofile(we_c.modpath.."/commands/selectors/scol.lua")
dofile(we_c.modpath.."/commands/selectors/scube.lua")
dofile(we_c.modpath.."/commands/selectors/smake.lua")
dofile(we_c.modpath.."/commands/selectors/spop.lua")
dofile(we_c.modpath.."/commands/selectors/spush.lua")
dofile(we_c.modpath.."/commands/selectors/srect.lua")
dofile(we_c.modpath.."/commands/selectors/sstack.lua")
dofile(we_c.modpath.."/commands/extra/saplingaliases.lua") dofile(we_c.modpath.."/commands/extra/saplingaliases.lua")
dofile(we_c.modpath.."/commands/extra/basename.lua") dofile(we_c.modpath.."/commands/extra/basename.lua")
@ -85,3 +77,5 @@ worldedit.alias_command("naturalize", "layers")
worldedit.alias_command("flora", "bonemeal") worldedit.alias_command("flora", "bonemeal")
worldedit.alias_command("mcount", "count") worldedit.alias_command("mcount", "count")
worldedit.alias_command("sfac", "sfactor")