원본 프로젝트 : minetest-mods/mesecons
		
	Add support for sticky blocks for pistons and a a sample sticky block
This commit is contained in:
		| @@ -19,7 +19,6 @@ function mesecon.is_mvps_stopper(node, pushdir, stack, stackid) | ||||
| 	if type (get_stopper) == "function" then | ||||
| 		get_stopper = get_stopper(node, pushdir, stack, stackid) | ||||
| 	end | ||||
| 	if (get_stopper) then print(node.name) end | ||||
| 	return get_stopper | ||||
| end | ||||
|  | ||||
| @@ -48,27 +47,76 @@ function mesecon.mvps_process_stack(stack) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function mesecon.mvps_get_stack(pos, dir, maximum) | ||||
| function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky) | ||||
| 	-- determine the number of nodes to be pushed | ||||
| 	local np = {x = pos.x, y = pos.y, z = pos.z} | ||||
| 	local nodes = {} | ||||
| 	while true do | ||||
| 		local nn = minetest.get_node_or_nil(np) | ||||
| 		if not nn or #nodes > maximum then | ||||
| 			-- don't push at all, something is in the way (unloaded map or too many nodes) | ||||
| 			return nil | ||||
| 	local frontiers = {pos} | ||||
|  | ||||
| 	while #frontiers > 0 do | ||||
| 		local np = frontiers[1] | ||||
| 		local nn = minetest.get_node(np) | ||||
|  | ||||
| 		if nn.name ~= "air" | ||||
| 		and minetest.registered_nodes[nn.name] | ||||
| 		and minetest.registered_nodes[nn.name].liquidtype == "none" then | ||||
| 			table.insert(nodes, {node = nn, pos = np}) | ||||
| 			if #nodes > maximum then return nil end | ||||
|  | ||||
| 			-- add connected nodes to frontiers, connected is a vector list | ||||
| 			-- the vectors must be absolute positions | ||||
| 			local connected = {} | ||||
| 			if minetest.registered_nodes[nn.name] | ||||
| 			and minetest.registered_nodes[nn.name].mvps_sticky then | ||||
| 				connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn) | ||||
| 			end | ||||
|  | ||||
| 			table.insert(connected, vector.add(np, dir)) | ||||
|  | ||||
| 			-- If adjacent node is sticky block and connects add that | ||||
| 			-- position to the connected table | ||||
| 			for _, r in ipairs(mesecon.rules.alldirs) do | ||||
| 				local adjpos = vector.add(np, r) | ||||
| 				local adjnode = minetest.get_node(adjpos) | ||||
| 				if minetest.registered_nodes[adjnode.name] | ||||
| 				and minetest.registered_nodes[adjnode.name].mvps_sticky then | ||||
| 					local sticksto = minetest.registered_nodes[adjnode.name] | ||||
| 						.mvps_sticky(adjpos, adjnode) | ||||
|  | ||||
| 					-- connects to this position? | ||||
| 					for _, link in ipairs(sticksto) do | ||||
| 						if vector.equals(link, np) then | ||||
| 							table.insert(connected, adjpos) | ||||
| 						end | ||||
| 					end | ||||
| 				end | ||||
| 			end | ||||
|  | ||||
| 			if all_pull_sticky then | ||||
| 				table.insert(connected, vector.subtract(np, dir)) | ||||
| 			end | ||||
|  | ||||
| 			-- Make sure there are no duplicates in frontiers / nodes before | ||||
| 			-- adding nodes in "connected" to frontiers | ||||
| 			for _, cp in ipairs(connected) do | ||||
| 				local duplicate = false | ||||
| 				for _, rp in ipairs(nodes) do | ||||
| 					if vector.equals(cp, rp.pos) then | ||||
| 						duplicate = true | ||||
| 					end | ||||
| 				end | ||||
| 				for _, fp in ipairs(frontiers) do | ||||
| 					if vector.equals(cp, fp) then | ||||
| 						duplicate = true | ||||
| 					end | ||||
| 				end | ||||
| 				if not duplicate then | ||||
| 					table.insert(frontiers, cp) | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
|  | ||||
| 		if nn.name == "air" | ||||
| 		or (minetest.registered_nodes[nn.name] | ||||
| 		and minetest.registered_nodes[nn.name].liquidtype ~= "none") then --is liquid | ||||
| 			break | ||||
| 		end | ||||
|  | ||||
| 		table.insert (nodes, {node = nn, pos = np}) | ||||
|  | ||||
| 		np = mesecon.addPosRule(np, dir) | ||||
| 		table.remove(frontiers, 1) | ||||
| 	end | ||||
|  | ||||
| 	return nodes | ||||
| end | ||||
|  | ||||
| @@ -77,11 +125,19 @@ function mesecon.mvps_push(pos, dir, maximum) | ||||
| end | ||||
|  | ||||
| function mesecon.mvps_pull_all(pos, dir, maximum) | ||||
| 	return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, true) | ||||
| end | ||||
|  | ||||
| function mesecon.mvps_pull_single(pos, dir, maximum) | ||||
| 	return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum) | ||||
| end | ||||
|  | ||||
| function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum) -- pos: pos of mvps; stackdir: direction of building the stack; movedir: direction of actual movement; maximum: maximum nodes to be pushed | ||||
| 	local nodes = mesecon.mvps_get_stack(pos, stackdir, maximum) | ||||
| -- pos: pos of mvps; stackdir: direction of building the stack | ||||
| -- movedir: direction of actual movement | ||||
| -- maximum: maximum nodes to be pushed | ||||
| -- all_pull_sticky: All nodes are sticky in the direction that they are pulled from | ||||
| function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sticky) | ||||
| 	local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky) | ||||
|  | ||||
| 	if not nodes then return end | ||||
| 	-- determine if one of the nodes blocks the push / pull | ||||
| @@ -133,27 +189,6 @@ mesecon.register_on_mvps_move(function(moved_nodes) | ||||
| 	end | ||||
| end) | ||||
|  | ||||
| function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons) | ||||
| 	local np = mesecon.addPosRule(pos, dir) | ||||
| 	local nn = minetest.get_node(np) | ||||
|  | ||||
| 	if ((not minetest.registered_nodes[nn.name]) --unregistered node | ||||
| 	or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid node | ||||
| 	and not mesecon.is_mvps_stopper(nn, dir, {{pos = np, node = nn}}, 1) then --non-stopper node | ||||
| 		local meta = minetest.get_meta(np):to_table() | ||||
| 		minetest.remove_node(np) | ||||
| 		minetest.add_node(pos, nn) | ||||
| 		minetest.get_meta(pos):from_table(meta) | ||||
|  | ||||
| 		nodeupdate(np) | ||||
| 		nodeupdate(pos) | ||||
| 		mesecon.on_dignode(np, nn) | ||||
| 		mesecon.update_autoconnect(np) | ||||
| 		on_mvps_move({{pos = pos, oldpos = np, node = nn, meta = meta}}) | ||||
| 	end | ||||
| 	return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}} | ||||
| end | ||||
|  | ||||
| function mesecon.mvps_move_objects(pos, dir, nodestack) | ||||
| 	local objects_to_move = {} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user