//dome+: add option to make the resulting dome hollow inside

This commit is contained in:
Starbeamrainbowlabs 2022-05-15 15:38:50 +01:00
parent 04e971e12d
commit 03fb033b70
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
3 changed files with 27 additions and 8 deletions

View file

@ -172,13 +172,15 @@ Generates both square and circular spiral shapes with the given `<replace_node>`
``` ```
### `//dome+ <radius> <replace_node> [<pointing_dir:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> ...]` ### `//dome+ <radius> <replace_node> [<pointing_dir:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> ...] [h[ollow]]`
Creates a dome shape (i.e. a hemisphere; half a sphere) with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction). Creates a dome shape (i.e. a hemisphere; half a sphere) with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction).
For example, `//dome+ 5 stone y` creates a dome shape pointing upwards, but `//dome+ 5 stone -y` creates a dome shape pointing downwards. For example, `//dome+ 5 stone y` creates a dome shape pointing upwards, but `//dome+ 5 stone -y` creates a dome shape pointing downwards.
Multiple pointing direction axes can be chained together to create multiple domes on top of each other. Multiple conflicting directions will cancel each other out. Multiple pointing direction axes can be chained together to create multiple domes on top of each other. Multiple conflicting directions will cancel each other out.
If `h` or `hollow` is specified at the end, then the resulting dome shape is made hollow.
``` ```
//dome+ 5 stone y //dome+ 5 stone y
//dome+ 10 diamond -x //dome+ 10 diamond -x

View file

@ -11,12 +11,16 @@ local Vector3 = wea.Vector3
-- @param pos Vector3 The central point to start drawing the dome from. -- @param pos Vector3 The central point to start drawing the dome from.
-- @param radius number The radius of the dome to create. -- @param radius number The radius of the dome to create.
-- @param replace_node string The fully qualified name of the node to use to make the dome with. -- @param replace_node string The fully qualified name of the node to use to make the dome with.
-- @parram pointing_dir Vector3 Optional. The direction the dome should point. Defaults to (0, 1, 0). See also wea.parse.axis_name. -- @param pointing_dir Vector3 Optional. The direction the dome should point. Defaults to (0, 1, 0). See also wea.parse.axis_name.
function worldeditadditions.dome(pos, radius, replace_node, pointing_dir) -- @param hollow boolean Whether to make the dome hollow or not. Defaults to false.
function worldeditadditions.dome(pos, radius, replace_node, pointing_dir, hollow)
pos = Vector3.clone(pos) pos = Vector3.clone(pos)
local pos1 = pos - radius local pos1 = pos - radius
local pos2 = pos + radius local pos2 = pos + radius
if not pointing_dir then pointing_dir = Vector3.new(0, 1, 0) end
if hollow == nil then hollow = false end
-- pos2 will always have the highest co-ordinates now -- pos2 will always have the highest co-ordinates now
-- Fetch the nodes in the specified area -- Fetch the nodes in the specified area
@ -25,6 +29,7 @@ function worldeditadditions.dome(pos, radius, replace_node, pointing_dir)
local node_id_replace = minetest.get_content_id(replace_node) local node_id_replace = minetest.get_content_id(replace_node)
local radius_sq = radius * radius local radius_sq = radius * radius
local radius_inner_sq = (radius-1) * (radius-1)
local centrepoint = Vector3.mean(pos1, pos2) local centrepoint = Vector3.mean(pos1, pos2)
@ -34,7 +39,13 @@ function worldeditadditions.dome(pos, radius, replace_node, pointing_dir)
for x = pos2.x, pos1.x, -1 do for x = pos2.x, pos1.x, -1 do
local distance_sq = (Vector3.new(x, y, z) - centrepoint):length_squared() local distance_sq = (Vector3.new(x, y, z) - centrepoint):length_squared()
if distance_sq < radius_sq then local is_in_range = distance_sq < radius_sq
if hollow and distance_sq < radius_inner_sq then
is_in_range = false
end
if is_in_range then
-- It's inside the radius, but we're still not sure given this is a dome and not a sphere -- It's inside the radius, but we're still not sure given this is a dome and not a sphere
local should_include = false local should_include = false
if x < centrepoint.x and pointing_dir.x < 0 then if x < centrepoint.x and pointing_dir.x < 0 then

View file

@ -26,7 +26,7 @@ end
-- ██ ██ ██ ██ ██ ██ ██ ██ -- ██ ██ ██ ██ ██ ██ ██ ██
-- ██████ ██████ ██ ██ ███████ -- ██████ ██████ ██ ██ ███████
worldedit.register_command("dome+", { -- TODO: Make this an override worldedit.register_command("dome+", { -- TODO: Make this an override
params = "<radius> <replace_node> [<pointing_dir:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> ...]", params = "<radius> <replace_node> [<pointing_dir:x|y|z|-x|-y|-z|?|front|back|left|right|up|down> ...] [h[ollow]]",
description = "Creates a dome shape with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction).", description = "Creates a dome shape with a specified radius of the defined node, optionally specifying the direction it should be pointing in (defaults to the positive y direction).",
privs = { worldedit = true }, privs = { worldedit = true },
require_pos = 1, require_pos = 1,
@ -40,6 +40,7 @@ worldedit.register_command("dome+", { -- TODO: Make this an override
end end
local radius = tonumber(parts[1]) local radius = tonumber(parts[1])
local replace_node = worldedit.normalize_nodename(parts[2]) local replace_node = worldedit.normalize_nodename(parts[2])
local hollow = false
if not radius then if not radius then
return false, "Error: Invalid radius '"..parts[1].."'. The radius must be a positive integer." return false, "Error: Invalid radius '"..parts[1].."'. The radius must be a positive integer."
@ -52,6 +53,10 @@ worldedit.register_command("dome+", { -- TODO: Make this an override
return false, "Error: Invalid replace_node '"..parts[1].."'." return false, "Error: Invalid replace_node '"..parts[1].."'."
end end
if #parts > 2 and (parts[#parts] == "h" or parts[#parts] == "hollow") then
hollow = true
table.remove(parts, #parts)
end
local axes = wea.table.shallowcopy(parts) local axes = wea.table.shallowcopy(parts)
table.remove(axes, 1) table.remove(axes, 1)
table.remove(axes, 1) table.remove(axes, 1)
@ -60,12 +65,12 @@ worldedit.register_command("dome+", { -- TODO: Make this an override
table.insert(axes, "+y") table.insert(axes, "+y")
end end
return true, radius, replace_node, axes return true, radius, replace_node, axes, hollow
end, end,
nodes_needed = function(name, radius) nodes_needed = function(name, radius)
return 4/3 * math.pi * radius * radius * radius return 4/3 * math.pi * radius * radius * radius
end, end,
func = function(name, radius, replace_node, axes) func = function(name, radius, replace_node, axes, hollow)
local start_time = wea.get_ms_time() local start_time = wea.get_ms_time()
local success_a, pointing_dir = parse_stage2(name, axes) local success_a, pointing_dir = parse_stage2(name, axes)
@ -77,7 +82,8 @@ worldedit.register_command("dome+", { -- TODO: Make this an override
pos, pos,
radius, radius,
replace_node, replace_node,
pointing_dir pointing_dir,
hollow
) )
if not success_b then return success_b, nodes_replaced end if not success_b then return success_b, nodes_replaced end