diff options
| author | Jeija <norrepli@gmail.com> | 2015-02-28 13:42:39 +0100 | 
|---|---|---|
| committer | Jeija <norrepli@gmail.com> | 2015-02-28 13:42:39 +0100 | 
| commit | a6d0a523ba896762ac8b0d327863e523ab86dc47 (patch) | |
| tree | faf6b15af9ae1b056ee45651b12ce2ed6e28e6fe /mesecons_mvps | |
| parent | aa5538a7348f56b654b9204bf0644c11ee5f8b1d (diff) | |
Add support for sticky blocks for pistons and a a sample sticky blockorigin/sticky_blocks
Diffstat (limited to 'mesecons_mvps')
| -rw-r--r-- | mesecons_mvps/init.lua | 113 | 
1 files changed, 74 insertions, 39 deletions
| diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua index e7c9d5a..beec94b 100644 --- a/mesecons_mvps/init.lua +++ b/mesecons_mvps/init.lua @@ -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 -		end +	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 -		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(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 -		table.insert (nodes, {node = nn, pos = np}) +			if all_pull_sticky then +				table.insert(connected, vector.subtract(np, dir)) +			end -		np = mesecon.addPosRule(np, dir) +			-- 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 +		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 = {} | 
