diff options
| author | Jeija <norrepli@gmail.com> | 2012-12-26 22:54:28 +0100 | 
|---|---|---|
| committer | Jeija <norrepli@gmail.com> | 2012-12-26 22:54:28 +0100 | 
| commit | d91e0b66cb7971ba54d071a0955f17d1a7b0162e (patch) | |
| tree | 11294026f6db9a7c49a5ab93ed9cc6d63b8db1a4 /mesecons_mvps | |
| parent | c508bfaea62156684ea90b04e8963fb9e30dfaf2 (diff) | |
Re-write pistons from scratch, propably fixes a lot of bugs and doesn't cause too many new ones.
Diffstat (limited to 'mesecons_mvps')
| -rw-r--r-- | mesecons_mvps/init.lua | 117 | 
1 files changed, 87 insertions, 30 deletions
| diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua index 3903910..57c538d 100644 --- a/mesecons_mvps/init.lua +++ b/mesecons_mvps/init.lua @@ -2,42 +2,99 @@  mesecon.mvps_stoppers={} -function mesecon:is_mvps_stopper(nodename) -	local i=1 -	repeat -		i=i+1 -		if mesecon.mvps_stoppers[i]==nodename then return true end -	until mesecon.mvps_stoppers[i]==nil -	return false +function mesecon:is_mvps_stopper(node, pushdir, stack, stackid) +	local get_stopper = mesecon.mvps_stoppers[node.name] +	if type (get_stopper) == "function" then +		get_stopper = get_stopper(node, pushdir, stack, stackid) +	end +	return get_stopper  end -function mesecon:register_mvps_stopper(nodename) -	local i=1 -	repeat -		i=i+1 -		if mesecon.mvps_stoppers[i]==nil then break end -	until false -	mesecon.mvps_stoppers[i]=nodename +function mesecon:register_mvps_stopper(nodename, get_stopper) +	if get_stopper == nil then +			get_stopper = true +	end +	mesecon.mvps_stoppers[nodename] = get_stopper  end -function mesecon:mvps_push(pos, direction) -- pos: pos of mvps; direction: direction of push -		pos.x=pos.x+direction.x -		pos.y=pos.y+direction.y -		pos.z=pos.z+direction.z +function mesecon:mvps_process_stack(stack) +	-- update mesecons for placed nodes ( has to be done after all nodes have been added ) +	for _, n in ipairs(stack) do +		mesecon.on_placenode(n.pos, n.node) +		mesecon:update_autoconnect(n.pos) +	end +end -		local lpos = {x=pos.x, y=pos.y, z=pos.z} -		local lnode = minetest.env:get_node(lpos) -		local newnode -		minetest.env:remove_node(lpos) -		while not(lnode.name == "ignore" or lnode.name == "air" or not(minetest.registered_nodes[lnode.name].liquidtype == "none")) do -			lpos.x=lpos.x+direction.x -			lpos.y=lpos.y+direction.y -			lpos.z=lpos.z+direction.z -			newnode = lnode -			lnode = minetest.env:get_node(lpos) -			minetest.env:add_node(lpos, newnode) -			nodeupdate(lpos) +function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed +	np = {x = pos.x, y = pos.y, z = pos.z} + +	-- determine the number of nodes to be pushed +	local nodes = {} +	while true do +		nn = minetest.env: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 +		end + +		if nn.name == "air" +		or minetest.registered_nodes[nn.name].liquidtype ~= "none" then --is liquid +			break +		end + +		table.insert (nodes, {node = nn, pos = np}) + +		np = mesecon:addPosRule(np, dir) +	end + +	-- determine if one of the nodes blocks the push +	for id, n in ipairs(nodes) do +		if mesecon:is_mvps_stopper(n.node, dir, nodes, id) then +			return  		end +	end + +	-- remove all nodes +	for _, n in ipairs(nodes) do +		minetest.env:remove_node(n.pos) +		nodeupdate(n.pos) +	end + +	-- update mesecons for removed nodes ( has to be done after all nodes have been removed ) +	for _, n in ipairs(nodes) do +		mesecon.on_dignode(n.pos, n.node) +		mesecon:update_autoconnect(n.pos) +	end + +	-- add nodes +	for _, n in ipairs(nodes) do +		np = mesecon:addPosRule(n.pos, dir) +		minetest.env:add_node(np, n.node) +		nodeupdate(np) +	end + +	for i in ipairs(nodes) do +		nodes[i].pos = mesecon:addPosRule(nodes[i].pos, dir) +	end + +	return true, nodes +end + +function mesecon:mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons) +	np = mesecon:addPosRule(pos, dir) +	nn = minetest.env:get_node(np) + +	if minetest.registered_nodes[nn.name].liquidtype == "none" +	and not mesecon:is_mvps_stopper(nn, {x = -dir.x, y = -dir.y, z = -dir.z}, {{pos = np, node = nn}}, 1) then +		minetest.env:remove_node(np) +		minetest.env:add_node(pos, nn) + +		nodeupdate(np) +		nodeupdate(pos) +		mesecon.on_dignode(np, nn) +		mesecon:update_autoconnect(np) +	end +	return {{pos = np, node = nn}}  end  function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull | 
