mirror of
				https://github.com/luanti-org/minetest_game.git
				synced 2025-10-30 15:15:34 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			194 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| xpanes = {}
 | |
| 
 | |
| local function rshift(x, by)
 | |
| 	return math.floor(x / 2 ^ by)
 | |
| end
 | |
| 
 | |
| local directions = {
 | |
| 	{x = 1, y = 0, z = 0},
 | |
| 	{x = 0, y = 0, z = 1},
 | |
| 	{x = -1, y = 0, z = 0},
 | |
| 	{x = 0, y = 0, z = -1},
 | |
| }
 | |
| 
 | |
| local function update_pane(pos, name)
 | |
| 	if not minetest.get_node(pos).name:find("^xpanes:"..name) then
 | |
| 		return
 | |
| 	end
 | |
| 	local sum = 0
 | |
| 	for i, dir in pairs(directions) do
 | |
| 		local node = minetest.get_node({
 | |
| 			x = pos.x + dir.x,
 | |
| 			y = pos.y + dir.y,
 | |
| 			z = pos.z + dir.z
 | |
| 		})
 | |
| 		local def = minetest.registered_nodes[node.name]
 | |
| 		local pane_num = def and def.groups.pane or 0
 | |
| 		if pane_num > 0 or not def or (def.walkable ~= false and
 | |
| 				def.drawtype ~= "nodebox") then
 | |
| 			sum = sum + 2 ^ (i - 1)
 | |
| 		end
 | |
| 	end
 | |
| 	if sum == 0 then
 | |
| 		sum = 15
 | |
| 	end
 | |
| 	minetest.set_node(pos, {name = "xpanes:"..name.."_"..sum})
 | |
| end
 | |
| 
 | |
| local function update_nearby(pos, node)
 | |
| 	node = node or minetest.get_node(pos)
 | |
| 	local name = node.name
 | |
| 	if not name or node.name:sub(1, 7) ~= "xpanes:" then
 | |
| 		return
 | |
| 	end
 | |
| 	local underscore_pos = string.find(name, "_[^_]*$") or 0
 | |
| 	local len = name:len()
 | |
| 	local num = tonumber(name:sub(underscore_pos+1, len))
 | |
| 	if not num or num < 1 or num > 15 then
 | |
| 		name = name:sub(8)
 | |
| 	else
 | |
| 		name = name:sub(8, underscore_pos - 1)
 | |
| 	end
 | |
| 	for i, dir in pairs(directions) do
 | |
| 		update_pane({
 | |
| 			x = pos.x + dir.x,
 | |
| 			y = pos.y + dir.y,
 | |
| 			z = pos.z + dir.z
 | |
| 		}, name)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local half_boxes = {
 | |
| 	{0,     -0.5, -1/32, 0.5,  0.5, 1/32},
 | |
| 	{-1/32, -0.5, 0,     1/32, 0.5, 0.5},
 | |
| 	{-0.5,  -0.5, -1/32, 0,    0.5, 1/32},
 | |
| 	{-1/32, -0.5, -0.5,  1/32, 0.5, 0}
 | |
| }
 | |
| 
 | |
| local full_boxes = {
 | |
| 	{-0.5,  -0.5, -1/32, 0.5,  0.5, 1/32},
 | |
| 	{-1/32, -0.5, -0.5,  1/32, 0.5, 0.5}
 | |
| }
 | |
| 
 | |
| local sb_half_boxes = {
 | |
| 	{0,     -0.5, -0.06, 0.5,  0.5, 0.06},
 | |
| 	{-0.06, -0.5, 0,     0.06, 0.5, 0.5},
 | |
| 	{-0.5,  -0.5, -0.06, 0,    0.5, 0.06},
 | |
| 	{-0.06, -0.5, -0.5,  0.06, 0.5, 0}
 | |
| }
 | |
| 
 | |
| local sb_full_boxes = {
 | |
| 	{-0.5,  -0.5, -0.06, 0.5,  0.5, 0.06},
 | |
| 	{-0.06, -0.5, -0.5,  0.06, 0.5, 0.5}
 | |
| }
 | |
| 
 | |
| function xpanes.register_pane(name, def)
 | |
| 	for i = 1, 15 do
 | |
| 		local need = {}
 | |
| 		local cnt = 0
 | |
| 		for j = 1, 4 do
 | |
| 			if rshift(i, j - 1) % 2 == 1 then
 | |
| 				need[j] = true
 | |
| 				cnt = cnt + 1
 | |
| 			end
 | |
| 		end
 | |
| 		local take = {}
 | |
| 		local take2 = {}
 | |
| 		if need[1] == true and need[3] == true then
 | |
| 			need[1] = nil
 | |
| 			need[3] = nil
 | |
| 			table.insert(take, full_boxes[1])
 | |
| 			table.insert(take2, sb_full_boxes[1])
 | |
| 		end
 | |
| 		if need[2] == true and need[4] == true then
 | |
| 			need[2] = nil
 | |
| 			need[4] = nil
 | |
| 			table.insert(take, full_boxes[2])
 | |
| 			table.insert(take2, sb_full_boxes[2])
 | |
| 		end
 | |
| 		for k in pairs(need) do
 | |
| 			table.insert(take, half_boxes[k])
 | |
| 			table.insert(take2, sb_half_boxes[k])
 | |
| 		end
 | |
| 		local texture = def.textures[1]
 | |
| 		if cnt == 1 then
 | |
| 			texture = def.textures[1].."^"..def.textures[2]
 | |
| 		end
 | |
| 		minetest.register_node(":xpanes:"..name.."_"..i, {
 | |
| 			drawtype = "nodebox",
 | |
| 			tiles = {def.textures[3], def.textures[3], texture},
 | |
| 			paramtype = "light",
 | |
| 			groups = def.groups,
 | |
| 			drop = "xpanes:"..name,
 | |
| 			sounds = def.sounds,
 | |
| 			node_box = {
 | |
| 				type = "fixed",
 | |
| 				fixed = take
 | |
| 			},
 | |
| 			selection_box = {
 | |
| 				type = "fixed",
 | |
| 				fixed = take2
 | |
| 			}
 | |
| 		})
 | |
| 	end
 | |
| 
 | |
| 	def.on_construct = function(pos)
 | |
| 		update_pane(pos, name)
 | |
| 	end
 | |
| 
 | |
| 	minetest.register_node(":xpanes:"..name, def)
 | |
| 
 | |
| 	minetest.register_craft({
 | |
| 		output = "xpanes:"..name.." 16",
 | |
| 		recipe = def.recipe
 | |
| 	})
 | |
| end
 | |
| 
 | |
| minetest.register_on_placenode(update_nearby)
 | |
| minetest.register_on_dignode(update_nearby)
 | |
| 
 | |
| xpanes.register_pane("pane", {
 | |
| 	description = "Glass Pane",
 | |
| 	tiles = {"xpanes_space.png"},
 | |
| 	drawtype = "airlike",
 | |
| 	paramtype = "light",
 | |
| 	sunlight_propagates = true,
 | |
| 	walkable = false,
 | |
| 	pointable = false,
 | |
| 	diggable = false,
 | |
| 	buildable_to = true,
 | |
| 	air_equivalent = true,
 | |
| 	textures = {"default_glass.png","xpanes_pane_half.png","xpanes_white.png"},
 | |
| 	inventory_image = "default_glass.png",
 | |
| 	wield_image = "default_glass.png",
 | |
| 	sounds = default.node_sound_glass_defaults(),
 | |
| 	groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
 | |
| 	recipe = {
 | |
| 		{'default:glass', 'default:glass', 'default:glass'},
 | |
| 		{'default:glass', 'default:glass', 'default:glass'}
 | |
| 	}
 | |
| })
 | |
| 
 | |
| xpanes.register_pane("bar", {
 | |
| 	description = "Iron bar",
 | |
| 	tiles = {"xpanes_space.png"},
 | |
| 	drawtype = "airlike",
 | |
| 	paramtype = "light",
 | |
| 	sunlight_propagates = true,
 | |
| 	walkable = false,
 | |
| 	pointable = false,
 | |
| 	diggable = false,
 | |
| 	buildable_to = true,
 | |
| 	air_equivalent = true,
 | |
| 	textures = {"xpanes_bar.png","xpanes_bar.png","xpanes_space.png"},
 | |
| 	inventory_image = "xpanes_bar.png",
 | |
| 	wield_image = "xpanes_bar.png",
 | |
| 	groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, pane=1},
 | |
| 	sounds = default.node_sound_stone_defaults(),
 | |
| 	recipe = {
 | |
| 		{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
 | |
| 		{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}
 | |
| 	}
 | |
| })
 | |
| 
 |