mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-26 00:53:00 +00:00
Start working on //copy, but it's not finished yet.
We need to merge @VorTechnix's branch in first to gain access to advanced axis parsing functions before we can complete it. For this reason, the command registration for //copy is currently commented out.
This commit is contained in:
parent
8044a9059c
commit
653864be99
5 changed files with 157 additions and 1 deletions
|
@ -53,6 +53,8 @@ dofile(wea.modpath.."/lib/conv/conv.lua")
|
|||
dofile(wea.modpath.."/lib/erode/erode.lua")
|
||||
dofile(wea.modpath.."/lib/noise/init.lua")
|
||||
|
||||
dofile(wea.modpath.."/lib/copy.lua")
|
||||
|
||||
dofile(wea.modpath.."/lib/count.lua")
|
||||
|
||||
dofile(wea.modpath.."/lib/bonemeal.lua")
|
||||
|
|
47
worldeditadditions/lib/copy.lua
Normal file
47
worldeditadditions/lib/copy.lua
Normal file
|
@ -0,0 +1,47 @@
|
|||
--- Copies a region to another location, potentially overwriting the exiting region.
|
||||
-- @module worldeditadditions.copy
|
||||
|
||||
local wea = worldeditadditions
|
||||
local Vector3 = wea.Vector3
|
||||
|
||||
-- ██████ ██████ ██████ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ██ ██████ ████
|
||||
-- ██ ██ ██ ██ ██
|
||||
-- ██████ ██████ ██ ██
|
||||
|
||||
function worldeditadditions.count(source_pos1, source_pos2, target_pos1, target_pos2)
|
||||
source_pos1, source_pos2 = Vector3.sort(source_pos1, source_pos2)
|
||||
target_pos1, target_pos2 = Vector3.sort(target_pos1, target_pos2)
|
||||
|
||||
local offset = source_pos1:subtract(target_pos1)
|
||||
-- {source,target}_pos2 will always have the highest co-ordinates now
|
||||
|
||||
-- Fetch the nodes in the source area
|
||||
local manip_source, area_source = worldedit.manip_helpers.init(source_pos1, source_pos2)
|
||||
local data_source = manip_source:get_data()
|
||||
|
||||
-- Fetch a manip for the target area
|
||||
local manip_target, area_target = worldedit.manip_helpers.init(target_pos1, target_pos2)
|
||||
local data_target = manip_target:get_data()
|
||||
|
||||
-- z y x is the preferred loop order (because CPU cache I'd guess, since then we're iterating linearly through the data array)
|
||||
|
||||
for z = source_pos2.z, source_pos1.z, -1 do
|
||||
for y = source_pos2.y, source_pos1.y, -1 do
|
||||
for x = source_pos2.x, source_pos1.x, -1 do
|
||||
local source = Vector3.new(x, y, z)
|
||||
local source_i = area_source:index(x, y, z)
|
||||
local target = source:subtract(offset)
|
||||
local target_i = area_target:index(target.x, target.y, target.z)
|
||||
|
||||
data_target[target_i] = data_source[source_i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Save the modified nodes back to disk & return
|
||||
worldedit.manip_helpers.finish(manip_target, data_target)
|
||||
|
||||
return true, worldedit.volume(target_pos1, target_pos2)
|
||||
end
|
55
worldeditadditions/utils/parse/axes.lua
Normal file
55
worldeditadditions/utils/parse/axes.lua
Normal file
|
@ -0,0 +1,55 @@
|
|||
local wea = worldeditadditions
|
||||
local Vector3 = dofile(wea.modpath.."/utils/vector3.lua")
|
||||
-- BUG: This does not exist yet - need to merge @VorTechnix's branch first to get it
|
||||
-- TODO: Uncomment then once it's implemented
|
||||
-- local parse_axis = dofile(wea.modpath.."/utils/axis.lua")
|
||||
|
||||
--- Parses a token list of axes and counts into a Vector3.
|
||||
-- For example, "x 4" would become { x = 4, y = 0, z = 0 }, and "? 4 -z 10"
|
||||
-- might become { x = 4, y = 0, z = -10 }.
|
||||
-- Note that the input here needs to be *pre split*. wea.split_shell is
|
||||
-- recommended for this purpose.
|
||||
-- Uses wea.parse.axis for parsing axis names.
|
||||
-- @param token_list string[] A list of tokens to parse
|
||||
-- @returns Vector3 A Vector3 generated from parsing out the input token list.
|
||||
local function parse_axes(token_list)
|
||||
local vector_result = wea.Vector3.new()
|
||||
|
||||
if #token_list < 2 then
|
||||
return false, "Error: Not enough arguments (at least 2 are required)"
|
||||
end
|
||||
|
||||
local state = "AXIS"
|
||||
local current_axis = nil
|
||||
local success
|
||||
|
||||
for i,token in ipairs(token_list) do
|
||||
if state == "AXIS" then
|
||||
success, current_axis = parse_axis(token)
|
||||
if not success then return success, current_axis end
|
||||
state = "VALUE"
|
||||
elseif state == "VALUE" then
|
||||
|
||||
local offset_this = tonumber(token)
|
||||
if not offset_this then
|
||||
return false, "Error: Invalid count value for axis '"..current_axis.."'. Values may only be positive or negative integers."
|
||||
end
|
||||
|
||||
-- Handle negative axes
|
||||
if current_axis:sub(1, 1) == "-" then
|
||||
offset_this = -offset_this
|
||||
current_axis = current_axis:sub(2, 2)
|
||||
end
|
||||
|
||||
vector_result[current_axis] = vector_result[current_axis] + offset_this
|
||||
|
||||
state = "AXIS"
|
||||
else
|
||||
return false, "Error: Failed to parse input due to unknown state '"..tostring(state).."' (this is probably a bug - please report it!)"
|
||||
end
|
||||
end
|
||||
|
||||
return vector_result
|
||||
end
|
||||
|
||||
return parse_axes
|
|
@ -4,7 +4,9 @@
|
|||
-- ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ███████ ███████
|
||||
|
||||
worldeditadditions.parse = {}
|
||||
worldeditadditions.parse = {
|
||||
axes = dofile(worldeditadditions.modpath.."/utils/parse/axes.lua")
|
||||
}
|
||||
|
||||
dofile(worldeditadditions.modpath.."/utils/parse/chance.lua")
|
||||
dofile(worldeditadditions.modpath.."/utils/parse/map.lua")
|
||||
|
|
50
worldeditadditions_commands/commands/copy.lua
Normal file
50
worldeditadditions_commands/commands/copy.lua
Normal file
|
@ -0,0 +1,50 @@
|
|||
local wea = worldeditadditions
|
||||
-- ██████ ██████ ██████ ██ ██
|
||||
-- ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ██ ██████ ████
|
||||
-- ██ ██ ██ ██ ██
|
||||
-- ██████ ██████ ██ ██
|
||||
worldedit.register_command("copy", { -- TODO: Make this an override
|
||||
params = "<axis:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> <count> [<axis> <count> [...]]",
|
||||
description = "Copies the defined region to another location - potentially on multiple axes at once.",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 2,
|
||||
parse = function(params_text)
|
||||
if not params_text then params_text = "" end
|
||||
|
||||
local parts = wea.split_shell(params_text)
|
||||
|
||||
local copy_offset = wea.parse.axes(parts)
|
||||
|
||||
if copy_offset == wea.Vector3.new() then
|
||||
return false, "Refusing to copy region a distance of 0 nodes"
|
||||
end
|
||||
|
||||
return true, copy_offset:floor()
|
||||
end,
|
||||
nodes_needed = function(name)
|
||||
-- We don't actually modify anything, but without returning a
|
||||
-- number here safe_region doesn't work
|
||||
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name])
|
||||
end,
|
||||
func = function(name, copy_offset)
|
||||
local start_time = wea.get_ms_time()
|
||||
|
||||
local source_pos1 = wea.Vector3.clone(worldedit.pos1[name])
|
||||
local source_pos2 = wea.Vector3.clone(worldedit.pos2[name])
|
||||
|
||||
local target_pos1 = source_pos1:add(copy_offset)
|
||||
local target_pos2 = source_pos2:add(copy_offset)
|
||||
|
||||
local success, nodes_modified = wea.copy(
|
||||
source_pos1, source_pos2,
|
||||
target_pos1, target_pos2
|
||||
)
|
||||
|
||||
local time_taken = wea.get_ms_time() - start_time
|
||||
|
||||
|
||||
minetest.log("action", name.." used //copy from "..source_pos1.." - "..source_pos2.." to "..target_pos1.." - "..target_pos2..", modifying "..nodes_modified.." nodes in "..wea.format.human_time(time_taken))
|
||||
return true, nodes_modified.." nodes copied using offset "..copy_offset.." in "..wea.format.human_time(time_taken)
|
||||
end
|
||||
})
|
Loading…
Reference in a new issue