mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-24 14:42:24 +01:00
Add //dome+
Improvements oveer //dome: - Allow customising the direction it points in - Allow multiple pointing directions at once to give the effect of creating multiple domes on top of each other in a single command (it's actually implemented as an implicit union, and doesn't actually call wea.dome more than once).
This commit is contained in:
parent
a99cef7bf9
commit
04e971e12d
@ -5,6 +5,7 @@ Note to self: See the bottom of this file for the release template text.
|
||||
|
||||
|
||||
## v1.14: The untitled update (unreleased)
|
||||
- Add `//dome+`, which allows you to change the direction the dome is pointing in, and also create multiple domes at once
|
||||
- Migrate from `depends.txt` to `mod.conf`
|
||||
|
||||
|
||||
|
@ -172,6 +172,20 @@ 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> ...]`
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
//dome+ 5 stone y
|
||||
//dome+ 10 diamond -x
|
||||
//dome+ 25 cactus y z
|
||||
//dome+ 9 dirt x y z
|
||||
```
|
||||
|
||||
|
||||
## Misc
|
||||
<!--
|
||||
|
@ -58,6 +58,7 @@ dofile(wea.modpath.."/lib/scale_down.lua")
|
||||
dofile(wea.modpath.."/lib/scale.lua")
|
||||
dofile(wea.modpath.."/lib/spiral_square.lua")
|
||||
dofile(wea.modpath.."/lib/spiral_circle.lua")
|
||||
dofile(wea.modpath.."/lib/dome.lua")
|
||||
dofile(wea.modpath.."/lib/conv/conv.lua")
|
||||
dofile(wea.modpath.."/lib/erode/erode.lua")
|
||||
dofile(wea.modpath.."/lib/noise/init.lua")
|
||||
|
72
worldeditadditions/lib/dome.lua
Normal file
72
worldeditadditions/lib/dome.lua
Normal file
@ -0,0 +1,72 @@
|
||||
local wea = worldeditadditions
|
||||
local Vector3 = wea.Vector3
|
||||
|
||||
-- ██████ ██████ ███ ███ ███████
|
||||
-- ██ ██ ██ ██ ████ ████ ██
|
||||
-- ██ ██ ██ ██ ██ ████ ██ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ ██████ ██ ██ ███████
|
||||
--- Creates a dome shape with the given node, optionally specifying the
|
||||
-- direction the point should point.
|
||||
-- @param pos Vector3 The central point to start drawing the dome from.
|
||||
-- @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.
|
||||
-- @parram 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)
|
||||
pos = Vector3.clone(pos)
|
||||
local pos1 = pos - radius
|
||||
local pos2 = pos + radius
|
||||
|
||||
-- pos2 will always have the highest co-ordinates now
|
||||
|
||||
-- Fetch the nodes in the specified area
|
||||
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
||||
local data = manip:get_data()
|
||||
|
||||
local node_id_replace = minetest.get_content_id(replace_node)
|
||||
local radius_sq = radius * radius
|
||||
local centrepoint = Vector3.mean(pos1, pos2)
|
||||
|
||||
|
||||
local replaced = 0
|
||||
for z = pos2.z, pos1.z, -1 do
|
||||
for y = pos2.y, pos1.y, -1 do
|
||||
for x = pos2.x, pos1.x, -1 do
|
||||
local distance_sq = (Vector3.new(x, y, z) - centrepoint):length_squared()
|
||||
|
||||
if distance_sq < radius_sq then
|
||||
-- It's inside the radius, but we're still not sure given this is a dome and not a sphere
|
||||
local should_include = false
|
||||
if x < centrepoint.x and pointing_dir.x < 0 then
|
||||
should_include = true
|
||||
end
|
||||
if x > centrepoint.x and pointing_dir.x > 0 then
|
||||
should_include = true
|
||||
end
|
||||
if y < centrepoint.y and pointing_dir.y < 0 then
|
||||
should_include = true
|
||||
end
|
||||
if y > centrepoint.y and pointing_dir.y > 0 then
|
||||
should_include = true
|
||||
end
|
||||
if z < centrepoint.z and pointing_dir.z < 0 then
|
||||
should_include = true
|
||||
end
|
||||
if z > centrepoint.z and pointing_dir.z > 0 then
|
||||
should_include = true
|
||||
end
|
||||
|
||||
if should_include then
|
||||
data[area:index(x, y, z)] = node_id_replace
|
||||
replaced = replaced + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Save the modified nodes back to disk & return
|
||||
worldedit.manip_helpers.finish(manip, data)
|
||||
|
||||
return true, replaced
|
||||
end
|
90
worldeditadditions_commands/commands/dome.lua
Normal file
90
worldeditadditions_commands/commands/dome.lua
Normal file
@ -0,0 +1,90 @@
|
||||
local wea = worldeditadditions
|
||||
local Vector3 = wea.Vector3
|
||||
|
||||
local function parse_stage2(name, parts)
|
||||
local result = Vector3.new()
|
||||
for i,axis_name in ipairs(parts) do
|
||||
local success, result_this = wea.parse.axis_name(axis_name, wea.player_dir(name))
|
||||
if not success then return success, result_this end
|
||||
|
||||
result = result + result_this
|
||||
end
|
||||
|
||||
result = result:clamp(Vector3.new(-1, -1, -1), Vector3.new(1, 1, 1))
|
||||
|
||||
|
||||
if result.length == 0 then
|
||||
return false, "Refusing to create a dome with no distinct pointing direction."
|
||||
end
|
||||
|
||||
return true, result
|
||||
end
|
||||
|
||||
-- ██████ ██████ ███ ███ ███████
|
||||
-- ██ ██ ██ ██ ████ ████ ██
|
||||
-- ██ ██ ██ ██ ██ ████ ██ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ ██████ ██ ██ ███████
|
||||
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> ...]",
|
||||
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 },
|
||||
require_pos = 1,
|
||||
parse = function(params_text)
|
||||
if not params_text then params_text = "" end
|
||||
|
||||
local parts = wea.split_shell(params_text)
|
||||
|
||||
if #parts < 2 then
|
||||
return false, "Error: Not enough arguments (see /help /dome for usage information)."
|
||||
end
|
||||
local radius = tonumber(parts[1])
|
||||
local replace_node = worldedit.normalize_nodename(parts[2])
|
||||
|
||||
if not radius then
|
||||
return false, "Error: Invalid radius '"..parts[1].."'. The radius must be a positive integer."
|
||||
end
|
||||
if radius < 1 then
|
||||
return false, "Error: The minimum radius size is 1, but you entered"..tostring(radius).."."
|
||||
end
|
||||
|
||||
if not replace_node then
|
||||
return false, "Error: Invalid replace_node '"..parts[1].."'."
|
||||
end
|
||||
|
||||
local axes = wea.table.shallowcopy(parts)
|
||||
table.remove(axes, 1)
|
||||
table.remove(axes, 1)
|
||||
|
||||
if #axes == 0 then
|
||||
table.insert(axes, "+y")
|
||||
end
|
||||
|
||||
return true, radius, replace_node, axes
|
||||
end,
|
||||
nodes_needed = function(name, radius)
|
||||
return 4/3 * math.pi * radius * radius * radius
|
||||
end,
|
||||
func = function(name, radius, replace_node, axes)
|
||||
local start_time = wea.get_ms_time()
|
||||
|
||||
local success_a, pointing_dir = parse_stage2(name, axes)
|
||||
if not success_a then return success_a, pointing_dir end
|
||||
|
||||
local pos = Vector3.clone(worldedit.pos1[name])
|
||||
|
||||
local success_b, nodes_replaced = wea.dome(
|
||||
pos,
|
||||
radius,
|
||||
replace_node,
|
||||
pointing_dir
|
||||
)
|
||||
if not success_b then return success_b, nodes_replaced end
|
||||
|
||||
local time_taken = wea.get_ms_time() - start_time
|
||||
|
||||
|
||||
minetest.log("action", name.." used //dome+ at "..pos.." with a radius of "..tostring(radius)..", modifying "..nodes_replaced.." nodes in "..wea.format.human_time(time_taken))
|
||||
return true, nodes_replaced.." nodes replaced "..wea.format.human_time(time_taken)
|
||||
end
|
||||
})
|
@ -38,6 +38,7 @@ dofile(we_c.modpath.."/commands/walls.lua")
|
||||
dofile(we_c.modpath.."/commands/spiral2.lua")
|
||||
dofile(we_c.modpath.."/commands/copy.lua")
|
||||
dofile(we_c.modpath.."/commands/move.lua")
|
||||
dofile(we_c.modpath.."/commands/dome.lua")
|
||||
|
||||
dofile(we_c.modpath.."/commands/count.lua")
|
||||
dofile(we_c.modpath.."/commands/sculpt.lua")
|
||||
|
Loading…
Reference in New Issue
Block a user