mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-22 07:23:00 +00:00
parent
0cfd651510
commit
4b2f2b0001
7 changed files with 122 additions and 0 deletions
|
@ -8,6 +8,7 @@ It's about time I started a changelog! This will serve from now on as the main c
|
||||||
- `//many`: Improve format of progress messages, add ETA
|
- `//many`: Improve format of progress messages, add ETA
|
||||||
- `//subdivide`: Make asynchronous, and use `minetest.emerge_area()` to ensure areas are loaded before executing on a subdivision chunk
|
- `//subdivide`: Make asynchronous, and use `minetest.emerge_area()` to ensure areas are loaded before executing on a subdivision chunk
|
||||||
- This will ensure that `//subdivide`ing enormous regions should now function as expected. Want to level an entire rainforest with `//subdivide` and `//clearcut`? Now you can! :D
|
- This will ensure that `//subdivide`ing enormous regions should now function as expected. Want to level an entire rainforest with `//subdivide` and `//clearcut`? Now you can! :D
|
||||||
|
- Add `//line` for drawing simple lines
|
||||||
|
|
||||||
|
|
||||||
## v1.9: The Nature Update (20th September 2020)
|
## v1.9: The Nature Update (20th September 2020)
|
||||||
|
|
|
@ -137,6 +137,20 @@ Creates a hollow torus at position 1 with the radius major and minor radii. Work
|
||||||
//hollowtorus 21 11 stone
|
//hollowtorus 21 11 stone
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `//line [<replace_node> [<radius>]]`
|
||||||
|
Draw a line from position 1 to position 2, optionally with a given thickness.
|
||||||
|
|
||||||
|
The radius can be tought fo as the thickness of the line, and is defined as the distance from a given node to an imaginary line from pos1 to pos2. Defaults to drawing with dirt and a radius of 1.
|
||||||
|
|
||||||
|
Floating-point values are fully supported for the radius.
|
||||||
|
|
||||||
|
```
|
||||||
|
//line
|
||||||
|
//line stone
|
||||||
|
//line sandstone 3
|
||||||
|
//line glass 0.5
|
||||||
|
```
|
||||||
|
|
||||||
### `//maze <replace_node> [<path_length> [<path_width> [<seed>]]]`
|
### `//maze <replace_node> [<path_length> [<path_width> [<seed>]]]`
|
||||||
Generates a maze using replace_node as the walls and air as the paths. Uses [an algorithm of my own devising](https://starbeamrainbowlabs.com/blog/article.php?article=posts/070-Language-Review-Lua.html). It is guaranteed that you can get from every point to every other point in generated mazes, and there are no loops.
|
Generates a maze using replace_node as the walls and air as the paths. Uses [an algorithm of my own devising](https://starbeamrainbowlabs.com/blog/article.php?article=posts/070-Language-Review-Lua.html). It is guaranteed that you can get from every point to every other point in generated mazes, and there are no loops.
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ The detailed explanations have moved! Check them out [here](https://github.com/s
|
||||||
- [`//torus <major_radius> <minor_radius> <node_name>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#torus-major_radius-minor_radius-node_name)
|
- [`//torus <major_radius> <minor_radius> <node_name>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#torus-major_radius-minor_radius-node_name)
|
||||||
- [`//hollowtorus <major_radius> <minor_radius> <node_name>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#hollowtorus-major_radius-minor_radius-node_name)
|
- [`//hollowtorus <major_radius> <minor_radius> <node_name>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#hollowtorus-major_radius-minor_radius-node_name)
|
||||||
- [`//walls <replace_node>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#walls-replace_node)
|
- [`//walls <replace_node>`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#walls-replace_node)
|
||||||
|
- [`//line [<replace_node> [<radius>]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#line-replace_node-radius)
|
||||||
- [`//maze <replace_node> [<path_length> [<path_width> [<seed>]]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#maze-replace_node-seed)
|
- [`//maze <replace_node> [<path_length> [<path_width> [<seed>]]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#maze-replace_node-seed)
|
||||||
- [`//maze3d <replace_node> [<path_length> [<path_width> [<path_depth> [<seed>]]]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#maze3d-replace_node-seed)
|
- [`//maze3d <replace_node> [<path_length> [<path_width> [<path_depth> [<seed>]]]]`](https://github.com/sbrl/Minetest-WorldEditAdditions/blob/master/Chat-Command-Reference.md#maze3d-replace_node-seed)
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ dofile(worldeditadditions.modpath.."/lib/layers.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/fillcaves.lua")
|
dofile(worldeditadditions.modpath.."/lib/fillcaves.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/ellipsoid.lua")
|
dofile(worldeditadditions.modpath.."/lib/ellipsoid.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/torus.lua")
|
dofile(worldeditadditions.modpath.."/lib/torus.lua")
|
||||||
|
dofile(worldeditadditions.modpath.."/lib/line.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/walls.lua")
|
dofile(worldeditadditions.modpath.."/lib/walls.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/replacemix.lua")
|
dofile(worldeditadditions.modpath.."/lib/replacemix.lua")
|
||||||
dofile(worldeditadditions.modpath.."/lib/maze2d.lua")
|
dofile(worldeditadditions.modpath.."/lib/maze2d.lua")
|
||||||
|
|
52
worldeditadditions/lib/line.lua
Normal file
52
worldeditadditions/lib/line.lua
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
--- Counts the nodes in a given area.
|
||||||
|
-- @module worldeditadditions.count
|
||||||
|
|
||||||
|
-- ██ ██ ███ ██ ███████
|
||||||
|
-- ██ ██ ████ ██ ██
|
||||||
|
-- ██ ██ ██ ██ ██ █████
|
||||||
|
-- ██ ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ██ ██ ████ ███████
|
||||||
|
function worldeditadditions.line(pos1, pos2, thickness, node_name)
|
||||||
|
local pos1_sorted, pos2_sorted = worldedit.sort_pos(pos1, pos2)
|
||||||
|
-- pos2 will always have the highest co-ordinates now
|
||||||
|
|
||||||
|
pos1 = vector.new(pos1)
|
||||||
|
pos2 = vector.new(pos2)
|
||||||
|
|
||||||
|
local node_id_replace = minetest.get_content_id(node_name)
|
||||||
|
print("thickness", thickness, "node_name", node_name, "node_id_replace", node_id_replace)
|
||||||
|
|
||||||
|
-- Fetch the nodes in the specified area
|
||||||
|
local manip, area = worldedit.manip_helpers.init(pos1, pos2)
|
||||||
|
local data = manip: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)
|
||||||
|
local counts = { replaced = 0 }
|
||||||
|
for z = pos2_sorted.z, pos1_sorted.z, -1 do
|
||||||
|
for x = pos2_sorted.x, pos1_sorted.x, -1 do
|
||||||
|
for y = pos2_sorted.y, pos1_sorted.y, -1 do
|
||||||
|
local here = vector.new(x, y, z)
|
||||||
|
local D = vector.normalize(
|
||||||
|
vector.subtract(pos2, pos1)
|
||||||
|
)
|
||||||
|
local d = vector.dot(vector.subtract(here, pos1), D)
|
||||||
|
local closest_on_line = vector.add(
|
||||||
|
pos1,
|
||||||
|
vector.multiply(D, d)
|
||||||
|
)
|
||||||
|
local distance = vector.length(vector.subtract(here, closest_on_line))
|
||||||
|
|
||||||
|
if distance < thickness then
|
||||||
|
print("[line] vector", closest_on_line.x, closest_on_line.y, closest_on_line.z, "length", distance)
|
||||||
|
data[area:index(x, y, z)] = node_id_replace
|
||||||
|
counts.replaced = counts.replaced + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Save the modified nodes back to disk & return
|
||||||
|
worldedit.manip_helpers.finish(manip, data)
|
||||||
|
|
||||||
|
return true, counts
|
||||||
|
end
|
52
worldeditadditions_commands/commands/line.lua
Normal file
52
worldeditadditions_commands/commands/line.lua
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
-- ██ ██ ███ ██ ███████
|
||||||
|
-- ██ ██ ████ ██ ██
|
||||||
|
-- ██ ██ ██ ██ ██ █████
|
||||||
|
-- ██ ██ ██ ██ ██ ██
|
||||||
|
-- ███████ ██ ██ ████ ███████
|
||||||
|
worldedit.register_command("line", {
|
||||||
|
params = "[<replace_node> [<radius>]]",
|
||||||
|
description = "Draws a line of a given radius (default: 1) from pos1 to pos2 in the given node (default: dirt).",
|
||||||
|
privs = { worldedit = true },
|
||||||
|
require_pos = 1,
|
||||||
|
parse = function(params_text)
|
||||||
|
if not params_text then params_text = "" end
|
||||||
|
local found, _, replace_node, radius = params_text:find("([a-z:_\\-]+)%s+([0-9.]+)")
|
||||||
|
|
||||||
|
if found == nil then
|
||||||
|
found, _, replace_node = params_text:find("([a-z:_\\-]+)")
|
||||||
|
radius = 1
|
||||||
|
end
|
||||||
|
if found == nil then
|
||||||
|
replace_node = "default:dirt"
|
||||||
|
end
|
||||||
|
radius = tonumber(radius)
|
||||||
|
|
||||||
|
replace_node = worldedit.normalize_nodename(replace_node)
|
||||||
|
|
||||||
|
if not replace_node then
|
||||||
|
worldedit.player_notify(name, "Error: Invalid node name.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, replace_node, radius
|
||||||
|
end,
|
||||||
|
nodes_needed = function(name, replace_node, radius)
|
||||||
|
-- Volume of a hemisphere
|
||||||
|
return math.ceil(math.pi
|
||||||
|
* radius * radius
|
||||||
|
* vector.distance(
|
||||||
|
vector.new(worldedit.pos1[name]),
|
||||||
|
vector.new(worldedit.pos2[name])
|
||||||
|
)) -- Volume of a cylinder
|
||||||
|
end,
|
||||||
|
func = function(name, replace_node, radius)
|
||||||
|
local start_time = worldeditadditions.get_ms_time()
|
||||||
|
local success, stats = worldeditadditions.line(worldedit.pos1[name], worldedit.pos2[name], radius, replace_node)
|
||||||
|
local time_taken = worldeditadditions.get_ms_time() - start_time
|
||||||
|
|
||||||
|
if success == false then return false, stats end
|
||||||
|
|
||||||
|
minetest.log("action", name .. " used //line at " .. worldeditadditions.vector.tostring(worldedit.pos1[name]) .. ", replacing " .. stats.replaced .. " nodes in " .. time_taken .. "s")
|
||||||
|
return true, stats.replaced .. " nodes replaced in " .. worldeditadditions.human_time(time_taken)
|
||||||
|
end
|
||||||
|
})
|
|
@ -25,6 +25,7 @@ dofile(we_c.modpath.."/commands/layers.lua")
|
||||||
dofile(we_c.modpath.."/commands/fillcaves.lua")
|
dofile(we_c.modpath.."/commands/fillcaves.lua")
|
||||||
dofile(we_c.modpath.."/commands/ellipsoid.lua")
|
dofile(we_c.modpath.."/commands/ellipsoid.lua")
|
||||||
dofile(we_c.modpath.."/commands/torus.lua")
|
dofile(we_c.modpath.."/commands/torus.lua")
|
||||||
|
dofile(we_c.modpath.."/commands/line.lua")
|
||||||
dofile(we_c.modpath.."/commands/walls.lua")
|
dofile(we_c.modpath.."/commands/walls.lua")
|
||||||
dofile(we_c.modpath.."/commands/maze.lua")
|
dofile(we_c.modpath.."/commands/maze.lua")
|
||||||
dofile(we_c.modpath.."/commands/replacemix.lua")
|
dofile(we_c.modpath.."/commands/replacemix.lua")
|
||||||
|
|
Loading…
Reference in a new issue