diff options
Diffstat (limited to 'callbuttons.lua')
| -rw-r--r-- | callbuttons.lua | 152 | 
1 files changed, 152 insertions, 0 deletions
| diff --git a/callbuttons.lua b/callbuttons.lua new file mode 100644 index 0000000..97d839f --- /dev/null +++ b/callbuttons.lua @@ -0,0 +1,152 @@ +local function makebuttontex(dir,upon,downon) +	local tex = "[combine:64x64:0,0=celevator_cabinet_sides.png:32,0=celevator_cabinet_sides.png:0,32=celevator_cabinet_sides.png:32,32=celevator_cabinet_sides.png:22,24=celevator_callbutton_panel.png" +	if dir == "up" then +		tex = tex..":24,35=celevator_callbutton_up.png" +		if upon then +			tex = tex..":33,36=celevator_callbutton_light.png" +		end +	elseif dir == "down" then +		tex = tex..":24,35=celevator_callbutton_down.png" +		if downon then +			tex = tex..":33,36=celevator_callbutton_light.png" +		end +	elseif dir == "both" then +		tex = tex..":24,28=celevator_callbutton_up.png:24,43=celevator_callbutton_down.png" +		if upon then +			tex = tex..":33,29=celevator_callbutton_light.png" +		end +		if downon then +			tex = tex..":33,44=celevator_callbutton_light.png" +		end +	end +	return(tex) +end + +local validstates = { +	{"up",false,false,"Up"}, +	{"up",true,false,"Up"}, +	{"down",false,false,"Down"}, +	{"down",false,true,"Down"}, +	{"both",false,false,"Up and Down"}, +	{"both",true,false,"Up and Down"}, +	{"both",false,true,"Up and Down"}, +	{"both",true,true,"Up and Down"}, +} + +local function setlight(pos,dir,newstate) +	local node = minetest.get_node(pos) +	if minetest.get_item_group(node.name,"_celevator_callbutton") ~= 1 then return end +	if dir == "up" then +		if minetest.get_item_group(node.name,"_celevator_callbutton_has_up") ~= 1 then return end +		local lit = minetest.get_item_group(node.name,"_celevator_callbutton_up_lit") == 1 +		if lit == newstate then return end +		local newname = "celevator:callbutton_" +		if minetest.get_item_group(node.name,"_celevator_callbutton_has_down") == 1 then +			newname = newname.."both" +		else +			newname = newname.."up" +		end +		if newstate then newname = newname.."_upon" end +		if minetest.get_item_group(node.name,"_celevator_callbutton_down_lit") == 1 then +			newname = newname.."_downon" +		end +		node.name = newname +		minetest.swap_node(pos,node) +	elseif dir == "down" then +		if minetest.get_item_group(node.name,"_celevator_callbutton_has_down") ~= 1 then return end +		local lit = minetest.get_item_group(node.name,"_celevator_callbutton_down_lit") == 1 +		if lit == newstate then return end +		local newname = "celevator:callbutton_" +		if minetest.get_item_group(node.name,"_celevator_callbutton_has_up") == 1 then +			newname = newname.."both" +		else +			newname = newname.."down" +		end +		if minetest.get_item_group(node.name,"_celevator_callbutton_up_lit") == 1 then +			newname = newname.."_upon" +		end +		if newstate then newname = newname.."_downon" end +		node.name = newname +		minetest.swap_node(pos,node) +	end +end + +local function disambiguatedir(pos,player) +	if player and not player.is_fake_player then +		local eyepos = vector.add(player:get_pos(),vector.add(player:get_eye_offset(),vector.new(0,1.5,0))) +		local lookdir = player:get_look_dir() +		local distance = vector.distance(eyepos,pos) +		local endpos = vector.add(eyepos,vector.multiply(lookdir,distance+1)) +		local ray = minetest.raycast(eyepos,endpos,true,false) +		local pointed,button,hitpos +		repeat +			pointed = ray:next() +			if pointed and pointed.type == "node" then +				local node = minetest.get_node(pointed.under) +				if node.name and (minetest.get_item_group(node.name,"_celevator_callbutton") == 1) then +					button = pointed.under +					hitpos = vector.subtract(pointed.intersection_point,button) +				end +			end +		until button or not pointed +		if not hitpos then return end +		hitpos.y = -1*hitpos.y +		hitpos.y = math.floor((hitpos.y+0.5)*64+0.5)+1 +		return hitpos.y >= 40 and "down" or "up" +	end +end + +for _,state in ipairs(validstates) do +	local boringside = "[combine:64x64:0,0=celevator_cabinet_sides.png:32,0=celevator_cabinet_sides.png:0,32=celevator_cabinet_sides.png:32,32=celevator_cabinet_sides.png" +	local nname = "celevator:callbutton_"..state[1] +	local dropname = nname +	if state[2] then nname = nname.."_upon" end +	if state[3] then nname = nname.."_downon" end +	local idle = not (state[2] or state[3]) +	local description = string.format("%s Call Button%s",state[4],(idle and "" or " (on state, you hacker you!)")) +	minetest.register_node(nname,{ +		description = description, +		groups = { +			dig_immediate = 2, +			not_in_creative_inventory = (idle and 0 or 1), +			_celevator_callbutton = 1, +			_celevator_callbutton_has_up = (state[1] == "down" and 0 or 1), +			_celevator_callbutton_has_down = (state[1] == "up" and 0 or 1), +			_celevator_callbutton_up_lit = (state[2] and 1 or 0), +			_celevator_callbutton_down_lit = (state[3] and 1 or 0), +		}, +		drop = dropname, +		tiles = { +			boringside, +			boringside, +			boringside, +			boringside, +			boringside, +			makebuttontex(state[1],state[2],state[3]) +		}, +		paramtype = "light", +		paramtype2 = "facedir", +		drawtype = "nodebox", +		node_box = { +			type = "fixed", +			fixed = { +				{-0.5,  -0.5, -0.5,  0.5,  0.5,  0.5 }, +				{-0.16, -0.37,-0.59, 0.17, 0.13,-0.5 }, +			}, +		}, +		on_rightclick = function(pos,_,clicker) +			if state[1] == "up" then +				setlight(pos,"up",not state[2]) +			elseif state[1] == "down" then +				setlight(pos,"down",not state[3]) +			elseif state[1] == "both" then +				local dir = disambiguatedir(pos,clicker) +				if dir == "up" then +					setlight(pos,"up",not state[2]) +				elseif dir == "down" then +					setlight(pos,"down",not state[3]) +				end +			end +		end, +	}) +end | 
