mirror of
				https://github.com/sbrl/Minetest-WorldEditAdditions
				synced 2025-11-04 05:53:07 +01:00 
			
		
		
		
	
							parent
							
								
									0cfd651510
								
							
						
					
					
						commit
						4b2f2b0001
					
				@ -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
 | 
			
		||||
 - `//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
 | 
			
		||||
 - Add `//line` for drawing simple lines
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 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
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### `//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>]]]`
 | 
			
		||||
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)
 | 
			
		||||
 - [`//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)
 | 
			
		||||
 - [`//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)
 | 
			
		||||
 - [`//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/ellipsoid.lua")
 | 
			
		||||
dofile(worldeditadditions.modpath.."/lib/torus.lua")
 | 
			
		||||
dofile(worldeditadditions.modpath.."/lib/line.lua")
 | 
			
		||||
dofile(worldeditadditions.modpath.."/lib/walls.lua")
 | 
			
		||||
dofile(worldeditadditions.modpath.."/lib/replacemix.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/ellipsoid.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/maze.lua")
 | 
			
		||||
dofile(we_c.modpath.."/commands/replacemix.lua")
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user