mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-27 17:43:53 +01:00
Merge branch 'main' into VorTechnix
This commit is contained in:
commit
b20c8f9af1
62
.github/workflows/test.yml
vendored
Normal file
62
.github/workflows/test.yml
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
name: "CI Tests"
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
Syntax-Check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# Checkout the git repo
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install apt dependencies
|
||||||
|
run: sudo apt-get --quiet install lua5.1
|
||||||
|
|
||||||
|
- name: uname -a
|
||||||
|
run: uname -a
|
||||||
|
|
||||||
|
- name: Lua version
|
||||||
|
run: lua -v
|
||||||
|
|
||||||
|
- name: Perform Check
|
||||||
|
run: find . -type f -name '*.lua' -not -path '*luarocks*' -not -path '*.git/*' -print0 | xargs -0 -n1 -P "$(nproc)" luac -p;
|
||||||
|
Busted:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# Checkout the git repo
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install apt dependencies
|
||||||
|
run: sudo apt-get --quiet install lua5.1 luarocks
|
||||||
|
|
||||||
|
- name: uname -a
|
||||||
|
run: uname -a
|
||||||
|
|
||||||
|
- name: Lua version
|
||||||
|
run: lua -v
|
||||||
|
|
||||||
|
- name: Set up tests
|
||||||
|
run: ./tests.sh run
|
||||||
|
|
||||||
|
- name: Run Tests
|
||||||
|
run: ./tests.sh run
|
||||||
|
LuaCheck:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# Checkout the git repo
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install apt dependencies
|
||||||
|
run: sudo apt-get --quiet install lua5.1 lua-check
|
||||||
|
|
||||||
|
- name: uname -a
|
||||||
|
run: uname -a
|
||||||
|
|
||||||
|
- name: Lua version
|
||||||
|
run: lua -v
|
||||||
|
|
||||||
|
# luacheck throws lots of errors at the moment, so don't fail the build
|
||||||
|
- name: Run luacheck
|
||||||
|
run: luacheck . || true
|
||||||
|
|
36
.luacheckrc
Normal file
36
.luacheckrc
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
quiet = 1
|
||||||
|
codes = true
|
||||||
|
|
||||||
|
exclude_files = {
|
||||||
|
".luarocks/*",
|
||||||
|
"worldeditadditions/utils/bit.lua"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ignore = {
|
||||||
|
"631", "61[124]",
|
||||||
|
"542",
|
||||||
|
"412",
|
||||||
|
"321/bit",
|
||||||
|
"21[123]"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Read-write globals (i.e. they can be defined)
|
||||||
|
globals = {
|
||||||
|
"worldedit",
|
||||||
|
"worldeditadditions",
|
||||||
|
"worldeditadditions_commands",
|
||||||
|
"worldeditadditions_core"
|
||||||
|
}
|
||||||
|
-- Read-only globals
|
||||||
|
read_globals = {
|
||||||
|
"minetest",
|
||||||
|
"vector",
|
||||||
|
"assert",
|
||||||
|
"bit",
|
||||||
|
"it",
|
||||||
|
"describe",
|
||||||
|
"bonemeal",
|
||||||
|
"dofile"
|
||||||
|
}
|
||||||
|
std = "max"
|
@ -10,6 +10,9 @@ Note to self: See the bottom of this file for the release template text.
|
|||||||
- Add `//wcorner` (_wireframe corners_), `//wbox` (_wireframe box_), `//compass` (_wireframe compass_) - Wireframes implemented by @VorTechnix.
|
- Add `//wcorner` (_wireframe corners_), `//wbox` (_wireframe box_), `//compass` (_wireframe compass_) - Wireframes implemented by @VorTechnix.
|
||||||
- Add `//for` for executing commands while changing their arguments - Implemented by @VorTechnix.
|
- Add `//for` for executing commands while changing their arguments - Implemented by @VorTechnix.
|
||||||
- Add `//sshift` (_selection shift_) - WorldEdit cuboid manipulator replacements implemented by @VorTechnix.
|
- Add `//sshift` (_selection shift_) - WorldEdit cuboid manipulator replacements implemented by @VorTechnix.
|
||||||
|
- Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues
|
||||||
|
- Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting
|
||||||
|
|
||||||
|
|
||||||
## 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`
|
||||||
|
11
tests.sh
11
tests.sh
@ -2,6 +2,12 @@
|
|||||||
# Make sure the current directory is the location of this script to simplify matters
|
# Make sure the current directory is the location of this script to simplify matters
|
||||||
cd "$(dirname "$(readlink -f "$0")")" || { echo "Error: Failed to cd to script directory" >&2; exit 1; };
|
cd "$(dirname "$(readlink -f "$0")")" || { echo "Error: Failed to cd to script directory" >&2; exit 1; };
|
||||||
|
|
||||||
|
# To run Luacheck:
|
||||||
|
#
|
||||||
|
# luacheck . --ignore 631 61[124] 412 21[123] --globals minetest worldedit worldeditadditions worldeditadditions_commands worldeditadditions_core vector assert bit it describe bonemeal --codes -j "$(nproc)" --quiet --exclude-files .luarocks/*
|
||||||
|
#
|
||||||
|
# This is a work-in-progress, as it currently throws an *enormous* number of warnings.
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log_msg() {
|
log_msg() {
|
||||||
@ -35,6 +41,10 @@ run_setup() {
|
|||||||
luarocks --tree "${luarocks_root}" install busted;
|
luarocks --tree "${luarocks_root}" install busted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_syntax_check() {
|
||||||
|
find . -type f -name '*.lua' -not -path '*luarocks*' -not -path '*.git/*' -print0 | xargs -0 -n1 -P "$(nproc)" luac -p;
|
||||||
|
}
|
||||||
|
|
||||||
run_test() {
|
run_test() {
|
||||||
.luarocks/bin/busted --no-auto-insulate --pattern ".test.lua" .tests;
|
.luarocks/bin/busted --no-auto-insulate --pattern ".test.lua" .tests;
|
||||||
}
|
}
|
||||||
@ -48,6 +58,7 @@ case "${mode}" in
|
|||||||
if [[ ! -d "${luarocks_root}" ]]; then
|
if [[ ! -d "${luarocks_root}" ]]; then
|
||||||
run_setup;
|
run_setup;
|
||||||
fi
|
fi
|
||||||
|
run_syntax_check;
|
||||||
run_test;
|
run_test;
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ function worldeditadditions.erode.river(heightmap_initial, heightmap, heightmap_
|
|||||||
local height_up = heightmap[hi]
|
local height_up = heightmap[hi]
|
||||||
local height_down = heightmap[hi]
|
local height_down = heightmap[hi]
|
||||||
local height_left = heightmap[hi]
|
local height_left = heightmap[hi]
|
||||||
local height_down = heightmap[hi]
|
local height_right = heightmap[hi]
|
||||||
|
|
||||||
if x > 0 then height_left = heightmap[z*heightmap_size.x + x-1] end
|
if x > 0 then height_left = heightmap[z*heightmap_size.x + x-1] end
|
||||||
if x < heightmap_size.x - 1 then height_right = heightmap[z*heightmap_size.x + x+1] end
|
if x < heightmap_size.x - 1 then height_right = heightmap[z*heightmap_size.x + x+1] end
|
||||||
@ -80,14 +80,14 @@ function worldeditadditions.erode.river(heightmap_initial, heightmap, heightmap_
|
|||||||
local action = "none"
|
local action = "none"
|
||||||
if not isedge then
|
if not isedge then
|
||||||
if sides_higher > sides_lower then
|
if sides_higher > sides_lower then
|
||||||
for i,sidecount in ipairs(params.raise_sides) do
|
for _,sidecount in ipairs(params.raise_sides) do
|
||||||
if sidecount == sides_higher then
|
if sidecount == sides_higher then
|
||||||
action = "fill"
|
action = "fill"
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
for i,sidecount in ipairs(params.lower_sides) do
|
for _i,sidecount in ipairs(params.lower_sides) do
|
||||||
if sidecount == sides_lower then
|
if sidecount == sides_lower then
|
||||||
action = "remove"
|
action = "remove"
|
||||||
break
|
break
|
||||||
@ -109,10 +109,10 @@ function worldeditadditions.erode.river(heightmap_initial, heightmap, heightmap_
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for i,hi in ipairs(fill) do
|
for _i,hi in ipairs(fill) do
|
||||||
heightmap[hi] = heightmap[hi] + 1
|
heightmap[hi] = heightmap[hi] + 1
|
||||||
end
|
end
|
||||||
for i,hi in ipairs(remove) do
|
for _i,hi in ipairs(remove) do
|
||||||
heightmap[hi] = heightmap[hi] - 1
|
heightmap[hi] = heightmap[hi] - 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ function worldeditadditions.forest(pos1, pos2, density_multiplier, sapling_weigh
|
|||||||
local did_grow = false
|
local did_grow = false
|
||||||
local new_id_at_pos
|
local new_id_at_pos
|
||||||
local new_name_at_pos
|
local new_name_at_pos
|
||||||
for i=1,100 do
|
for attempt_number=1,100 do
|
||||||
bonemeal:on_use(
|
bonemeal:on_use(
|
||||||
{ x = x, y = y, z = z },
|
{ x = x, y = y, z = z },
|
||||||
4,
|
4,
|
||||||
@ -55,7 +55,7 @@ function worldeditadditions.forest(pos1, pos2, density_multiplier, sapling_weigh
|
|||||||
if not group_cache[new_id_at_pos] then
|
if not group_cache[new_id_at_pos] then
|
||||||
did_grow = true
|
did_grow = true
|
||||||
-- Log the number of attempts it took to grow
|
-- Log the number of attempts it took to grow
|
||||||
table.insert(stats.attempts, i)
|
table.insert(stats.attempts, attempt_number)
|
||||||
-- Update the running total of saplings that grew
|
-- Update the running total of saplings that grew
|
||||||
if not stats.placed[node_id] then
|
if not stats.placed[node_id] then
|
||||||
stats.placed[node_id] = 0
|
stats.placed[node_id] = 0
|
||||||
|
@ -17,7 +17,7 @@ local function printspace(space, w, h)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function generate_maze(seed, width, height, path_length, path_width)
|
local function generate_maze(seed, width, height, path_length, path_width)
|
||||||
start_time = worldeditadditions.get_ms_time()
|
local start_time = worldeditadditions.get_ms_time()
|
||||||
|
|
||||||
if not path_length then path_length = 2 end
|
if not path_length then path_length = 2 end
|
||||||
if not path_width then path_width = 1 end
|
if not path_width then path_width = 1 end
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
----------------------------------
|
----------------------------------
|
||||||
-- function to print out the world
|
-- function to print out the world
|
||||||
----------------------------------
|
----------------------------------
|
||||||
function printspace3d(space, w, h, d)
|
local function printspace3d(space, w, h, d)
|
||||||
for z = 0, d - 1, 1 do
|
for z = 0, d - 1, 1 do
|
||||||
for y = 0, h - 1, 1 do
|
for y = 0, h - 1, 1 do
|
||||||
local line = ""
|
local line = ""
|
||||||
@ -18,9 +18,6 @@ function printspace3d(space, w, h, d)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Initialise the world
|
|
||||||
start_time = worldeditadditions.get_ms_time()
|
|
||||||
|
|
||||||
local function generate_maze3d(seed, width, height, depth, path_length, path_width, path_depth)
|
local function generate_maze3d(seed, width, height, depth, path_length, path_width, path_depth)
|
||||||
|
|
||||||
if not path_length then path_length = 2 end
|
if not path_length then path_length = 2 end
|
||||||
|
@ -37,7 +37,7 @@ function worldeditadditions.noise.params_apply_default(params)
|
|||||||
local default_copy = wea.table.shallowcopy(params_default)
|
local default_copy = wea.table.shallowcopy(params_default)
|
||||||
|
|
||||||
-- Keyword support
|
-- Keyword support
|
||||||
for i, keyword in ipairs(wea.noise.engines.available) do
|
for _i, keyword in ipairs(wea.noise.engines.available) do
|
||||||
if params_el[keyword] ~= nil then
|
if params_el[keyword] ~= nil then
|
||||||
params_el.algorithm = keyword
|
params_el.algorithm = keyword
|
||||||
end
|
end
|
||||||
|
@ -48,8 +48,8 @@ function worldeditadditions.noise.run2d(pos1, pos2, noise_params)
|
|||||||
)
|
)
|
||||||
if not success then return success, message end
|
if not success then return success, message end
|
||||||
|
|
||||||
|
local stats
|
||||||
local success, stats = wea.apply_heightmap_changes(
|
success, stats = wea.apply_heightmap_changes(
|
||||||
pos1, pos2,
|
pos1, pos2,
|
||||||
area, data,
|
area, data,
|
||||||
heightmap_old, heightmap_new,
|
heightmap_old, heightmap_new,
|
||||||
|
@ -80,7 +80,7 @@ function worldeditadditions.scale_down(pos1, pos2, scale, anchor)
|
|||||||
if anchor.y < 0 then posi_copy.y = size.y - posi_copy.y end
|
if anchor.y < 0 then posi_copy.y = size.y - posi_copy.y end
|
||||||
if anchor.z < 0 then posi_copy.z = size.z - posi_copy.z end
|
if anchor.z < 0 then posi_copy.z = size.z - posi_copy.z end
|
||||||
|
|
||||||
local posi_copy = vector.add(pos1, posi_copy)
|
posi_copy = vector.add(pos1, posi_copy)
|
||||||
|
|
||||||
local i_source = area:index(x, y, z)
|
local i_source = area:index(x, y, z)
|
||||||
local i_target = area:index(posi_copy.x, posi_copy.y, posi_copy.z)
|
local i_target = area:index(posi_copy.x, posi_copy.y, posi_copy.z)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
-- @param decimals number The number of decimal places to show.
|
-- @param decimals number The number of decimal places to show.
|
||||||
-- @return string A formatted string that represents the given input number.
|
-- @return string A formatted string that represents the given input number.
|
||||||
function worldeditadditions.format.human_size(n, decimals)
|
function worldeditadditions.format.human_size(n, decimals)
|
||||||
sizes = { "", "K", "M", "G", "T", "P", "E", "Y", "Z" }
|
local sizes = { "", "K", "M", "G", "T", "P", "E", "Y", "Z" }
|
||||||
local factor = math.floor((#tostring(n) - 1) / 3)
|
local factor = math.floor((#tostring(n) - 1) / 3)
|
||||||
local multiplier = 10^(decimals or 0)
|
local multiplier = 10^(decimals or 0)
|
||||||
local result = math.floor(0.5 + (n / math.pow(1000, factor)) * multiplier) / multiplier
|
local result = math.floor(0.5 + (n / math.pow(1000, factor)) * multiplier) / multiplier
|
||||||
|
@ -16,7 +16,7 @@ local values = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- From http://lua-users.org/wiki/SimpleRound
|
-- From http://lua-users.org/wiki/SimpleRound
|
||||||
function round(num, numDecimalPlaces)
|
local function round(num, numDecimalPlaces)
|
||||||
local mult = 10^(numDecimalPlaces or 0)
|
local mult = 10^(numDecimalPlaces or 0)
|
||||||
return math.floor(num * mult + 0.5) / mult
|
return math.floor(num * mult + 0.5) / mult
|
||||||
end
|
end
|
||||||
@ -37,7 +37,7 @@ end
|
|||||||
|
|
||||||
local values_count = #values
|
local values_count = #values
|
||||||
|
|
||||||
function test(size)
|
local function test(size)
|
||||||
local cpu_start = os.clock()
|
local cpu_start = os.clock()
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ function worldeditadditions.is_airlike(id)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
-- Just in case
|
-- Just in case
|
||||||
if worldeditadditions.str_starts(this_node_name, "wielded_light") then
|
if worldeditadditions.str_starts(name, "wielded_light") then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
-- Just in case
|
-- Just in case
|
||||||
|
@ -21,7 +21,7 @@ function worldeditadditions.unwind_node_list(list)
|
|||||||
local result = {}
|
local result = {}
|
||||||
for i,item in ipairs(list) do
|
for i,item in ipairs(list) do
|
||||||
local node_id = minetest.get_content_id(item.node)
|
local node_id = minetest.get_content_id(item.node)
|
||||||
for i = 1, item.weight do
|
for _i = 1, item.weight do
|
||||||
table.insert(result, node_id)
|
table.insert(result, node_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -21,7 +21,7 @@ function worldeditadditions.parse.map(params_text, keywords)
|
|||||||
-- Look for bools
|
-- Look for bools
|
||||||
if part_converted == "true" then part_converted = true end
|
if part_converted == "true" then part_converted = true end
|
||||||
if part_converted == "false" then part_converted = false end
|
if part_converted == "false" then part_converted = false end
|
||||||
result[last_key] = part
|
result[last_key] = part_converted
|
||||||
mode = "KEY"
|
mode = "KEY"
|
||||||
else
|
else
|
||||||
last_key = part
|
last_key = part
|
||||||
|
@ -40,7 +40,7 @@ local function tokenise(str)
|
|||||||
-- Decrease the nested depth
|
-- Decrease the nested depth
|
||||||
nested_depth = nested_depth - 1
|
nested_depth = nested_depth - 1
|
||||||
-- Pop the start of this block off the stack and find this block's contents
|
-- Pop the start of this block off the stack and find this block's contents
|
||||||
block_start = table.remove(nested_stack, #nested_stack)
|
local block_start = table.remove(nested_stack, #nested_stack)
|
||||||
local substr = str:sub(block_start, nextpos - 1)
|
local substr = str:sub(block_start, nextpos - 1)
|
||||||
if #substr > 0 and nested_depth == 0 then table.insert(result, substr) end
|
if #substr > 0 and nested_depth == 0 then table.insert(result, substr) end
|
||||||
elseif char == "{" then
|
elseif char == "{" then
|
||||||
|
@ -6,7 +6,7 @@ local Queue = {}
|
|||||||
Queue.__index = Queue
|
Queue.__index = Queue
|
||||||
|
|
||||||
function Queue.new()
|
function Queue.new()
|
||||||
result = { first = 0, last = -1, items = {} }
|
local result = { first = 0, last = -1, items = {} }
|
||||||
setmetatable(result, Queue)
|
setmetatable(result, Queue)
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
dofile(worldeditadditions.modpath.."/utils/strings/split.lua")
|
local wea = worldeditadditions
|
||||||
dofile(worldeditadditions.modpath.."/utils/strings/polyfill.lua")
|
|
||||||
dofile(worldeditadditions.modpath.."/utils/strings/tochars.lua")
|
dofile(wea.modpath.."/utils/strings/split.lua")
|
||||||
|
dofile(wea.modpath.."/utils/strings/polyfill.lua")
|
||||||
|
dofile(wea.modpath.."/utils/strings/tochars.lua")
|
||||||
|
wea.split_shell = dofile(wea.modpath.."/utils/strings/split_shell.lua")
|
||||||
|
92
worldeditadditions/utils/strings/split_shell.lua
Normal file
92
worldeditadditions/utils/strings/split_shell.lua
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
-- worldeditadditions = { modpath="/home/sbrl/.minetest/worlds/Mod-Sandbox/worldmods/WorldEditAdditions/worldeditadditions/" }
|
||||||
|
local table_map = dofile(worldeditadditions.modpath.."/utils/tables/table_map.lua")
|
||||||
|
|
||||||
|
local function is_whitespace(char)
|
||||||
|
return char:match("%s")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function split_shell(text)
|
||||||
|
local text_length = #text
|
||||||
|
local scan_pos = 1
|
||||||
|
local result = { }
|
||||||
|
local acc = {}
|
||||||
|
local mode = "NORMAL" -- NORMAL, INSIDE_QUOTES_SINGLE, INSIDE_QUOTES_DOUBLE
|
||||||
|
|
||||||
|
|
||||||
|
for i=1,text_length do
|
||||||
|
local prevchar = ""
|
||||||
|
local curchar = text:sub(i,i)
|
||||||
|
local nextchar = ""
|
||||||
|
local nextnextchar = ""
|
||||||
|
if i > 1 then prevchar = text:sub(i-1, i-1) end
|
||||||
|
if i < text_length then nextchar = text:sub(i+1, i+1) end
|
||||||
|
if i+1 < text_length then nextnextchar = text:sub(i+2, i+2) end
|
||||||
|
|
||||||
|
-- print("mode", mode, "prevchar", prevchar, "curchar", curchar, "nextchar", nextchar)
|
||||||
|
|
||||||
|
if mode == "NORMAL" then
|
||||||
|
if is_whitespace(curchar) and #acc > 0 then
|
||||||
|
table.insert(result, table.concat(acc, ""))
|
||||||
|
acc = {}
|
||||||
|
elseif (curchar == "\"" or curchar == "'") and #acc == 0 and prevchar ~= "\\" then
|
||||||
|
if curchar == "\"" then
|
||||||
|
mode = "INSIDE_QUOTES_DOUBLE"
|
||||||
|
else
|
||||||
|
mode = "INSIDE_QUOTES_SINGLE"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
table.insert(acc, curchar)
|
||||||
|
end
|
||||||
|
elseif mode == "INSIDE_QUOTES_DOUBLE" then
|
||||||
|
if curchar == "\"" and prevchar ~= "\\" and (is_whitespace(nextchar) or #nextchar == 0) then
|
||||||
|
-- It's the end of a quote!
|
||||||
|
mode = "NORMAL"
|
||||||
|
|
||||||
|
elseif (curchar == "\\" and (
|
||||||
|
nextchar ~= "\""
|
||||||
|
or (nextchar == "\"" and not is_whitespace(nextnextchar))
|
||||||
|
)) or curchar ~= "\\" then
|
||||||
|
-- It's a regular character
|
||||||
|
table.insert(acc, curchar)
|
||||||
|
end
|
||||||
|
elseif mode == "INSIDE_QUOTES_SINGLE" then
|
||||||
|
if curchar == "'" and prevchar ~= "\\" and is_whitespace(nextchar) then
|
||||||
|
-- It's the end of a quote!
|
||||||
|
mode = "NORMAL"
|
||||||
|
elseif (curchar == "\\" and (
|
||||||
|
nextchar ~= "'"
|
||||||
|
or (nextchar == "'" and not is_whitespace(nextnextchar))
|
||||||
|
)) or curchar ~= "\\" then
|
||||||
|
-- It's a regular character
|
||||||
|
table.insert(acc, curchar)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #acc > 0 then
|
||||||
|
table.insert(result, table.concat(acc, ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Unwind all escapes by 1 level
|
||||||
|
return table_map(result, function(str)
|
||||||
|
return str:gsub("\\([\"'\\])", "%1")
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
return split_shell
|
||||||
|
|
||||||
|
-- local function test(text)
|
||||||
|
-- print("Source", text)
|
||||||
|
-- for i,value in ipairs(split_shell(text)) do
|
||||||
|
-- print("i", i, "→", value)
|
||||||
|
-- end
|
||||||
|
-- print("************")
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- test("yay yay yay")
|
||||||
|
-- test("dirt \"snow block\"")
|
||||||
|
-- test("yay \"yay yay\" yay")
|
||||||
|
-- test("yay \"yay\\\" yay\" yay")
|
||||||
|
-- test("yay \"yay 'inside quotes' yay\\\"\" yay")
|
||||||
|
-- test("yay 'inside quotes' another")
|
||||||
|
-- test("y\"ay \"yay 'in\\\"side quotes' yay\" y\\\"ay")
|
@ -15,7 +15,7 @@ worldedit.register_command("bonemeal", {
|
|||||||
params_text = "1"
|
params_text = "1"
|
||||||
end
|
end
|
||||||
|
|
||||||
local parts = worldeditadditions.split(params_text, "%s+", false)
|
local parts = worldeditadditions.split_shell(params_text, "%s+", false)
|
||||||
|
|
||||||
local strength = 1
|
local strength = 1
|
||||||
local chance = 1
|
local chance = 1
|
||||||
|
@ -11,7 +11,8 @@ worldedit.register_command("convolve", {
|
|||||||
parse = function(params_text)
|
parse = function(params_text)
|
||||||
if not params_text then params_text = "" end
|
if not params_text then params_text = "" end
|
||||||
|
|
||||||
local parts = worldeditadditions.split(params_text, "%s+", false)
|
-- local parts = worldeditadditions.split(params_text, "%s+", false)
|
||||||
|
local parts = worldeditadditions.split_shell(params_text)
|
||||||
|
|
||||||
local kernel_name = "gaussian"
|
local kernel_name = "gaussian"
|
||||||
local width = 5
|
local width = 5
|
||||||
@ -58,10 +59,12 @@ worldedit.register_command("convolve", {
|
|||||||
kernel_size[0] = kernel_height
|
kernel_size[0] = kernel_height
|
||||||
kernel_size[1] = kernel_width
|
kernel_size[1] = kernel_width
|
||||||
|
|
||||||
local success, stats = worldeditadditions.convolve(
|
local stats
|
||||||
|
success, stats = worldeditadditions.convolve(
|
||||||
worldedit.pos1[name], worldedit.pos2[name],
|
worldedit.pos1[name], worldedit.pos2[name],
|
||||||
kernel, kernel_size
|
kernel, kernel_size
|
||||||
)
|
)
|
||||||
|
if not success then return success, stats end
|
||||||
|
|
||||||
local time_taken = worldeditadditions.get_ms_time() - start_time
|
local time_taken = worldeditadditions.get_ms_time() - start_time
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
-- ███████ ███████ ███████ ██ ██ ███████ ██████ ██ ██████
|
-- ███████ ███████ ███████ ██ ██ ███████ ██████ ██ ██████
|
||||||
local wea = worldeditadditions
|
local wea = worldeditadditions
|
||||||
local function parse_params_ellipsoid(params_text)
|
local function parse_params_ellipsoid(params_text)
|
||||||
local parts = wea.split(params_text, "%s+", false)
|
local parts = wea.split_shell(params_text)
|
||||||
|
|
||||||
if #parts < 4 then
|
if #parts < 4 then
|
||||||
return false, "Error: Not enough arguments. Expected \"<rx> <ry> <rz> <replace_node> [h[ollow]]\"."
|
return false, "Error: Not enough arguments. Expected \"<rx> <ry> <rz> <replace_node> [h[ollow]]\"."
|
||||||
|
@ -18,7 +18,7 @@ worldedit.register_command("forest", {
|
|||||||
end
|
end
|
||||||
|
|
||||||
local success, sapling_list = worldeditadditions.parse.weighted_nodes(
|
local success, sapling_list = worldeditadditions.parse.weighted_nodes(
|
||||||
worldeditadditions.split(params_text, "%s+", false),
|
worldeditadditions.split_shell(params_text),
|
||||||
false,
|
false,
|
||||||
function(name)
|
function(name)
|
||||||
return worldedit.normalize_nodename(
|
return worldedit.normalize_nodename(
|
||||||
|
@ -14,7 +14,7 @@ worldedit.register_command("layers", {
|
|||||||
end
|
end
|
||||||
|
|
||||||
local success, node_list = worldeditadditions.parse.weighted_nodes(
|
local success, node_list = worldeditadditions.parse.weighted_nodes(
|
||||||
worldeditadditions.split(params_text, "%s+", false),
|
worldeditadditions.split_shell(params_text),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
return success, node_list
|
return success, node_list
|
||||||
|
@ -24,8 +24,7 @@ worldedit.register_command("line", {
|
|||||||
replace_node = worldedit.normalize_nodename(replace_node)
|
replace_node = worldedit.normalize_nodename(replace_node)
|
||||||
|
|
||||||
if not replace_node then
|
if not replace_node then
|
||||||
worldedit.player_notify(name, "Error: Invalid node name.")
|
return false, "Error: Invalid node name '"..replace_node.."'."
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return true, replace_node, radius
|
return true, replace_node, radius
|
||||||
|
@ -5,7 +5,7 @@ local function parse_params_maze(params_text, is_3d)
|
|||||||
return false, "No arguments specified"
|
return false, "No arguments specified"
|
||||||
end
|
end
|
||||||
|
|
||||||
local parts = worldeditadditions.split(params_text, "%s+", false)
|
local parts = worldeditadditions.split_shell(params_text)
|
||||||
|
|
||||||
local replace_node = parts[1]
|
local replace_node = parts[1]
|
||||||
local seed = os.time()
|
local seed = os.time()
|
||||||
|
@ -43,7 +43,7 @@ worldedit.register_command("airapply", {
|
|||||||
end,
|
end,
|
||||||
func = function(name, cmd, args_parsed)
|
func = function(name, cmd, args_parsed)
|
||||||
if not minetest.check_player_privs(name, cmd.privs) then
|
if not minetest.check_player_privs(name, cmd.privs) then
|
||||||
return false, "Your privileges are insufficient to execute the command '"..cmd_name.."'."
|
return false, "Your privileges are insufficient to execute the command '"..cmd.."'."
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos1, pos2 = worldeditadditions.Vector3.sort(
|
local pos1, pos2 = worldeditadditions.Vector3.sort(
|
||||||
@ -56,7 +56,7 @@ worldedit.register_command("airapply", {
|
|||||||
pos1, pos2,
|
pos1, pos2,
|
||||||
function()
|
function()
|
||||||
cmd.func(name, worldeditadditions.table.unpack(args_parsed))
|
cmd.func(name, worldeditadditions.table.unpack(args_parsed))
|
||||||
end, args
|
end, args_parsed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,14 +45,14 @@ worldedit.register_command("ellipsoidapply", {
|
|||||||
end,
|
end,
|
||||||
func = function(name, cmd, args_parsed)
|
func = function(name, cmd, args_parsed)
|
||||||
if not minetest.check_player_privs(name, cmd.privs) then
|
if not minetest.check_player_privs(name, cmd.privs) then
|
||||||
return false, "Your privileges are insufficient to execute the command '"..cmd_name.."'."
|
return false, "Your privileges are insufficient to execute the command '"..cmd.."'."
|
||||||
end
|
end
|
||||||
|
|
||||||
local success, stats_time = worldeditadditions.ellipsoidapply(
|
local success, stats_time = worldeditadditions.ellipsoidapply(
|
||||||
worldedit.pos1[name], worldedit.pos2[name],
|
worldedit.pos1[name], worldedit.pos2[name],
|
||||||
function()
|
function()
|
||||||
cmd.func(name, worldeditadditions.table.unpack(args_parsed))
|
cmd.func(name, worldeditadditions.table.unpack(args_parsed))
|
||||||
end, args
|
end, args_parsed
|
||||||
)
|
)
|
||||||
local time_overhead = 100 - worldeditadditions.round((stats_time.fn / stats_time.all) * 100, 3)
|
local time_overhead = 100 - worldeditadditions.round((stats_time.fn / stats_time.all) * 100, 3)
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
-- explode(separator, string)
|
-- explode(separator, string)
|
||||||
-- From http://lua-users.org/wiki/SplitJoin
|
-- From http://lua-users.org/wiki/SplitJoin
|
||||||
|
-- TODO: Refactor this to use wea.split instead
|
||||||
local function explode(delim, str)
|
local function explode(delim, str)
|
||||||
local ll, is_done
|
local ll, is_done
|
||||||
local delim_length = string.len(delim)
|
local delim_length = string.len(delim)
|
||||||
@ -12,7 +13,7 @@ local function explode(delim, str)
|
|||||||
return function()
|
return function()
|
||||||
if is_done then return end
|
if is_done then return end
|
||||||
|
|
||||||
local result = nil
|
local result
|
||||||
local loc = string.find(str, delim, ll, true) -- find the next d in the string
|
local loc = string.find(str, delim, ll, true) -- find the next d in the string
|
||||||
if loc ~= nil then -- if "not not" found then..
|
if loc ~= nil then -- if "not not" found then..
|
||||||
result = string.sub(str, ll, loc - 1) -- Save it in our array.
|
result = string.sub(str, ll, loc - 1) -- Save it in our array.
|
||||||
|
@ -12,7 +12,7 @@ local function explode(delim, str)
|
|||||||
return function()
|
return function()
|
||||||
if is_done then return end
|
if is_done then return end
|
||||||
|
|
||||||
local result = nil
|
local result
|
||||||
local loc = string.find(str, delim, ll, true) -- find the next d in the string
|
local loc = string.find(str, delim, ll, true) -- find the next d in the string
|
||||||
if loc ~= nil then -- if "not not" found then..
|
if loc ~= nil then -- if "not not" found then..
|
||||||
result = string.sub(str, ll, loc - 1) -- Save it in our array.
|
result = string.sub(str, ll, loc - 1) -- Save it in our array.
|
||||||
@ -35,8 +35,6 @@ minetest.register_chatcommand("/multi", {
|
|||||||
params_text = worldeditadditions.trim(params_text)
|
params_text = worldeditadditions.trim(params_text)
|
||||||
if #params_text == 0 then return false, "Error: No commands specified, so there's nothing to do." end
|
if #params_text == 0 then return false, "Error: No commands specified, so there's nothing to do." end
|
||||||
|
|
||||||
|
|
||||||
local i = 1 -- For feedback only
|
|
||||||
local master_start_time = worldeditadditions.get_ms_time()
|
local master_start_time = worldeditadditions.get_ms_time()
|
||||||
local times = {}
|
local times = {}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ worldedit.register_command("subdivide", {
|
|||||||
local cmd_args_parsed = {cmd.parse(args)}
|
local cmd_args_parsed = {cmd.parse(args)}
|
||||||
local success = table.remove(cmd_args_parsed, 1)
|
local success = table.remove(cmd_args_parsed, 1)
|
||||||
if not success then
|
if not success then
|
||||||
return false, cmd_name..": "..(parsed[1] or "invalid usage")
|
return false, cmd_name..": "..(cmd_args_parsed[1] or "invalid usage")
|
||||||
end
|
end
|
||||||
|
|
||||||
wea.subdivide(pos1, pos2, chunk_size, function(cpos1, cpos2, stats)
|
wea.subdivide(pos1, pos2, chunk_size, function(cpos1, cpos2, stats)
|
||||||
|
@ -10,7 +10,7 @@ worldedit.register_command("overlay", {
|
|||||||
require_pos = 2,
|
require_pos = 2,
|
||||||
parse = function(params_text)
|
parse = function(params_text)
|
||||||
local success, node_list = worldeditadditions.parse.weighted_nodes(
|
local success, node_list = worldeditadditions.parse.weighted_nodes(
|
||||||
worldeditadditions.split(params_text, "%s+", false)
|
worldeditadditions.split_shell(params_text)
|
||||||
)
|
)
|
||||||
return success, node_list
|
return success, node_list
|
||||||
end,
|
end,
|
||||||
|
@ -15,7 +15,7 @@ worldedit.register_command("replacemix", {
|
|||||||
return false, "Error: No arguments specified"
|
return false, "Error: No arguments specified"
|
||||||
end
|
end
|
||||||
|
|
||||||
local parts = wea.split(params_text, "%s+", false)
|
local parts = wea.split_shell(params_text)
|
||||||
|
|
||||||
local target_node = nil
|
local target_node = nil
|
||||||
local target_node_chance = 1
|
local target_node_chance = 1
|
||||||
|
@ -30,14 +30,14 @@ worldedit.register_command("scale", {
|
|||||||
parse = function(params_text)
|
parse = function(params_text)
|
||||||
if not params_text then params_text = "" end
|
if not params_text then params_text = "" end
|
||||||
|
|
||||||
local parts = worldeditadditions.split(params_text, "%s+", false)
|
local parts = worldeditadditions.split_shell(params_text)
|
||||||
|
|
||||||
local scale = vector.new(1, 1, 1)
|
local scale = vector.new(1, 1, 1)
|
||||||
local anchor = vector.new(1, 1, 1)
|
local anchor = vector.new(1, 1, 1)
|
||||||
|
|
||||||
if #parts == 2 then
|
if #parts == 2 then
|
||||||
if not (parts[1] == "x" or parts[1] == "y" or parts[1] == "z"
|
if not (parts[1] == "x" or parts[1] == "y" or parts[1] == "z"
|
||||||
or parts[1] == "-x" or parts[1] == "-y" or parts[1] == "-z") then
|
or parts[1] == "-x" or parts[1] == "-y" or parts[1] == "-z") then
|
||||||
return false, "Error: Got 2 arguments, but the first doesn't look like the name of an axis."
|
return false, "Error: Got 2 arguments, but the first doesn't look like the name of an axis."
|
||||||
end
|
end
|
||||||
local axis = parts[1]
|
local axis = parts[1]
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||||
-- ██ ██████ ██ ██ ██████ ███████
|
-- ██ ██████ ██ ██ ██████ ███████
|
||||||
local function parse_params_torus(params_text)
|
local function parse_params_torus(params_text)
|
||||||
local parts = worldeditadditions.split(params_text, "%s+", false)
|
local parts = worldeditadditions.split_shell(params_text)
|
||||||
|
|
||||||
if #parts < 1 then
|
if #parts < 1 then
|
||||||
return false, "Error: No replace_node specified."
|
return false, "Error: No replace_node specified."
|
||||||
|
@ -37,7 +37,7 @@ function worldeditadditions.doc.parse_reference()
|
|||||||
function(item, i) return item.level ~= 2 end
|
function(item, i) return item.level ~= 2 end
|
||||||
)
|
)
|
||||||
for i,value in ipairs(headings) do
|
for i,value in ipairs(headings) do
|
||||||
print(i, "level", level, "heading", heading, "text", text)
|
print(i, "level", value.level, "heading", value.heading, "text", value.text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user