summaryrefslogtreecommitdiff
path: root/mesecons_doors/init.lua
blob: 0938889503fbf5001c68c62ba2834e9d95f95d90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
local other_state_node = {}
for _, material in ipairs({
	{ id = "wood", desc = "Wooden", color = "brown" },
	{ id = "steel", desc = "Steel", color = "grey" },
}) do
	doors:register_door("mesecons_doors:op_door_"..material.id, {
		description = "Mesecon-operated "..material.desc.." Door",
		inventory_image = minetest.registered_items["doors:door_"..material.id].inventory_image,
		groups = minetest.registered_nodes["doors:door_"..material.id.."_b_1"].groups,
		tiles_bottom = {"door_"..material.id.."_b.png", "door_"..material.color..".png"},
		tiles_top = {"door_"..material.id.."_a.png", "door_"..material.color..".png"},
	})
	local groups_plus_mesecon = { mesecon = 2 }
	for k, v in pairs(minetest.registered_nodes["doors:door_"..material.id.."_b_1"].groups) do
		groups_plus_mesecon[k] = v
	end
	doors:register_door("mesecons_doors:sig_door_"..material.id, {
		description = "Mesecon-signalling "..material.desc.." Door",
		inventory_image = minetest.registered_items["doors:door_"..material.id].inventory_image,
		groups = groups_plus_mesecon,
		tiles_bottom = {"door_"..material.id.."_b.png", "door_"..material.color..".png"},
		tiles_top = {"door_"..material.id.."_a.png", "door_"..material.color..".png"},
	})
	for _, thishalf in ipairs({ "t", "b" }) do
		local otherhalf = thishalf == "t" and "b" or "t"
		local otherdir = thishalf == "t" and -1 or 1
		for orientation = 1, 2 do
			local thissuffix = material.id.."_"..thishalf.."_"..orientation
			local othersuffix = material.id.."_"..otherhalf.."_"..orientation
			local thisopname = "mesecons_doors:op_door_"..thissuffix
			local otheropname = "mesecons_doors:op_door_"..othersuffix
			local oponr = minetest.registered_nodes[thisopname].on_rightclick
			local function handle_mesecon_signal (thispos, thisnode, signal)
				local thismeta = minetest.get_meta(thispos)
				if signal == thismeta:get_int("sigstate") then return end
				thismeta:set_int("sigstate", signal)
				local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z }
				if minetest.get_node(otherpos).name ~= otheropname then return end
				local othermeta = minetest.get_meta(otherpos)
				local newdoorstate = math.max(thismeta:get_int("sigstate"), othermeta:get_int("sigstate"))
				if newdoorstate == thismeta:get_int("doorstate") then return end
				oponr(thispos, thisnode, nil)
				thismeta:set_int("doorstate", newdoorstate)
				othermeta:set_int("doorstate", newdoorstate)
			end
			minetest.override_item(thisopname, {
				on_construct = function (pos)
					if mesecon:is_powered(pos) then
						local node = minetest.get_node(pos)
						mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on", 1)
						mesecon:activate(pos, node, nil, 1)
					end
				end,
				on_rightclick = function (pos, node, clicker) end,
				mesecons = {
					effector = {
						action_on = function (pos, node)
							handle_mesecon_signal(pos, node, 1)
						end,
						action_off = function (pos, node)
							handle_mesecon_signal(pos, node, 0)
						end,
					},
				},
			})
			local thissigname = "mesecons_doors:sig_door_"..thissuffix
			local othersigname = "mesecons_doors:sig_door_"..othersuffix
			local sigonr = minetest.registered_nodes[thissigname].on_rightclick
			minetest.override_item(thissigname, {
				on_rightclick = function (thispos, thisnode, clicker)
					local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z }
					print("open: otherpos.name="..minetest.get_node(otherpos).name..", othersigname="..othersigname)
					if minetest.get_node(otherpos).name ~= othersigname then return end
					sigonr(thispos, thisnode, clicker)
					for _, pos in ipairs({ thispos, otherpos }) do
						local node = minetest.get_node(pos)
						node.name = other_state_node[node.name]
						minetest.swap_node(pos, node)
						mesecon:receptor_on(pos)
					end
				end,
				mesecons = { receptor = { state = mesecon.state.off } },
			})
			other_state_node[thissigname] = thissigname.."_on"
			local ondef = {}
			for k, v in pairs(minetest.registered_nodes[thissigname]) do
				ondef[k] = v
			end
			ondef.on_rightclick = function (thispos, thisnode, clicker)
				local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z }
				print("close: otherpos.name="..minetest.get_node(otherpos).name..", othersigname="..othersigname)
				if minetest.get_node(otherpos).name ~= othersigname.."_on" then return end
				for _, pos in ipairs({ thispos, otherpos }) do
					local node = minetest.get_node(pos)
					node.name = other_state_node[node.name]
					minetest.swap_node(pos, node)
					mesecon:receptor_off(pos)
				end
				sigonr(thispos, thisnode, clicker)
			end
			ondef.mesecons = { receptor = { state = mesecon.state.on } }
			ondef.after_destruct = function (thispos, thisnode)
				local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z }
				if minetest.get_node(otherpos).name == othersigname.."_on" then
					minetest.remove_node(otherpos)
					mesecon:receptor_off(otherpos)
				end
			end
			other_state_node[thissigname.."_on"] = thissigname
			ondef.mesecon_other_state_node = thissigname
			minetest.register_node(thissigname.."_on", ondef)
		end
	end
	minetest.register_craft({
		output = "mesecons_doors:op_door_"..material.id,
		recipe = {
			{ "group:mesecon_conductor_craftable", "", "" },
			{ "", "doors:door_"..material.id, "group:mesecon_conductor_craftable" },
			{ "group:mesecon_conductor_craftable", "", "" },
		},
	})
	minetest.register_craft({
		output = "mesecons_doors:sig_door_"..material.id,
		recipe = {
			{ "", "", "group:mesecon_conductor_craftable" },
			{ "group:mesecon_conductor_craftable", "doors:door_"..material.id, "" },
			{ "", "", "group:mesecon_conductor_craftable" },
		},
	})
end