mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-22 15:33:00 +00: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
6 changed files with 179 additions and 0 deletions
|
@ -5,6 +5,7 @@ Note to self: See the bottom of this file for the release template text.
|
||||||
|
|
||||||
|
|
||||||
## v1.14: The untitled update (unreleased)
|
## 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`
|
- 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
|
## Misc
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -58,6 +58,7 @@ dofile(wea.modpath.."/lib/scale_down.lua")
|
||||||
dofile(wea.modpath.."/lib/scale.lua")
|
dofile(wea.modpath.."/lib/scale.lua")
|
||||||
dofile(wea.modpath.."/lib/spiral_square.lua")
|
dofile(wea.modpath.."/lib/spiral_square.lua")
|
||||||
dofile(wea.modpath.."/lib/spiral_circle.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/conv/conv.lua")
|
||||||
dofile(wea.modpath.."/lib/erode/erode.lua")
|
dofile(wea.modpath.."/lib/erode/erode.lua")
|
||||||
dofile(wea.modpath.."/lib/noise/init.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/spiral2.lua")
|
||||||
dofile(we_c.modpath.."/commands/copy.lua")
|
dofile(we_c.modpath.."/commands/copy.lua")
|
||||||
dofile(we_c.modpath.."/commands/move.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/count.lua")
|
||||||
dofile(we_c.modpath.."/commands/sculpt.lua")
|
dofile(we_c.modpath.."/commands/sculpt.lua")
|
||||||
|
|
Loading…
Reference in a new issue