Version 0.41.3
[MineClone/MineClone2/MineClone2-Fixes.git] / mods / ITEMS / REDSTONE / mcl_observers / init.lua
blob0017d461fafe47ca4df75c0a73a582dfd9005cff
1 local rules_flat = {
2 { x = 0, y = 0, z = -1, spread = true },
4 local get_rules_flat = function(node)
5 local rules = rules_flat
6 for i=1, node.param2 do
7 rules = mesecon.rotate_rules_left(rules)
8 end
9 return rules
10 end
12 local rules_down = {{ x = 0, y = 1, z = 0, spread = true }}
13 local rules_up = {{ x = 0, y = -1, z = 0, spread = true }}
15 -- Scan the node in front of the observer
16 -- and update the observer state if needed.
17 -- TODO: Also scan metadata changes.
18 -- TODO: Ignore some node changes.
19 local observer_scan = function(pos, initialize)
20 local node = minetest.get_node(pos)
21 local front
22 if node.name == "mcl_observers:observer_up_off" or node.name == "mcl_observers:observer_up_on" then
23 front = vector.add(pos, {x=0, y=1, z=0})
24 elseif node.name == "mcl_observers:observer_down_off" or node.name == "mcl_observers:observer_down_on" then
25 front = vector.add(pos, {x=0, y=-1, z=0})
26 else
27 front = vector.add(pos, minetest.facedir_to_dir(node.param2))
28 end
29 local frontnode = minetest.get_node(front)
30 local meta = minetest.get_meta(pos)
31 local oldnode = meta:get_string("node_name")
32 local oldparam2 = meta:get_string("node_param2")
33 local meta_needs_updating = false
34 if oldnode ~= "" and not initialize then
35 if not (frontnode.name == oldnode and frontnode.param2) then
36 -- Node state changed! Activate observer
37 if node.name == "mcl_observers:observer_off" then
38 minetest.set_node(pos, {name = "mcl_observers:observer_on", param2 = node.param2})
39 mesecon.receptor_on(pos, get_rules_flat(node))
40 elseif node.name == "mcl_observers:observer_down_off" then
41 minetest.set_node(pos, {name = "mcl_observers:observer_down_on"})
42 mesecon.receptor_on(pos, rules_down)
43 elseif node.name == "mcl_observers:observer_up_off" then
44 minetest.set_node(pos, {name = "mcl_observers:observer_up_on"})
45 mesecon.receptor_on(pos, rules_up)
46 end
47 meta_needs_updating = true
48 end
49 else
50 meta_needs_updating = true
51 end
52 if meta_needs_updating then
53 meta:set_string("node_name", frontnode.name)
54 meta:set_string("node_param2", frontnode.param2)
55 end
56 return frontnode
57 end
59 -- Vertical orientation (CURRENTLY DISABLED)
60 local observer_orientate = function(pos, placer)
61 -- Not placed by player
62 if not placer then return end
64 -- Placer pitch in degrees
65 local pitch = placer:get_look_vertical() * (180 / math.pi)
67 local node = minetest.get_node(pos)
68 if pitch > 55 then -- player looking upwards
69 -- Observer looking downwards
70 minetest.set_node(pos, {name="mcl_observers:observer_down_off"})
71 elseif pitch < -55 then -- player looking downwards
72 -- Observer looking upwards
73 minetest.set_node(pos, {name="mcl_observers:observer_up_off"})
74 end
75 end
77 mesecon.register_node("mcl_observers:observer",
79 is_ground_content = false,
80 sounds = mcl_sounds.node_sound_stone_defaults(),
81 paramtype2 = "facedir",
82 on_rotate = false,
83 _mcl_blast_resistance = 17.5,
84 _mcl_hardness = 3.5,
87 description = "Observer",
88 _doc_items_longdesc = "An observer is a redstone component which observes the block in front of it and sends a very short redstone pulse whenever this block changes.",
89 _doc_items_usagehelp = "Place the observer directly in front of the block you want to observe with the “face” looking at the block. The arrow shows you the side of the output, which is at the opposite side of the “face”. The arrow points to it. You need to place your redstone wire or any other component you want to power here.",
90 groups = {pickaxey=1, material_stone=1, not_opaque=1, },
91 tiles = {
92 "mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png",
93 "mcl_observers_observer_side.png", "mcl_observers_observer_side.png",
94 "mcl_observers_observer_front.png", "mcl_observers_observer_back.png",
96 mesecons = { receptor = {
97 state = mesecon.state.off,
98 rules = get_rules_flat,
99 }},
100 on_construct = function(pos)
101 observer_scan(pos, true)
102 end,
103 after_place_node = observer_orientate,
106 _doc_items_create_entry = false,
107 groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
108 tiles = {
109 "mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png",
110 "mcl_observers_observer_side.png", "mcl_observers_observer_side.png",
111 "mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png",
113 mesecons = { receptor = {
114 state = mesecon.state.on,
115 rules = get_rules_flat,
118 -- VERY quickly disable observer after construction
119 on_construct = function(pos)
120 local timer = minetest.get_node_timer(pos)
121 -- 1 redstone tick = 0.1 seconds
122 timer:start(0.1)
123 end,
124 on_timer = function(pos, elapsed)
125 local node = minetest.get_node(pos)
126 minetest.set_node(pos, {name = "mcl_observers:observer_off", param2 = node.param2})
127 mesecon.receptor_off(pos, get_rules_flat(node))
128 end,
132 mesecon.register_node("mcl_observers:observer_down",
134 is_ground_content = false,
135 sounds = mcl_sounds.node_sound_stone_defaults(),
136 groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
137 on_rotate = false,
138 _mcl_blast_resistance = 17.5,
139 _mcl_hardness = 3.5,
140 drop = "mcl_observers:observer_off",
143 tiles = {
144 "mcl_observers_observer_back.png", "mcl_observers_observer_front.png",
145 "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90",
146 "mcl_observers_observer_top.png", "mcl_observers_observer_top.png",
148 mesecons = { receptor = {
149 state = mesecon.state.off,
150 rules = rules_down,
152 on_construct = function(pos)
153 observer_scan(pos, true)
154 end,
157 _doc_items_create_entry = false,
158 tiles = {
159 "mcl_observers_observer_back_lit.png", "mcl_observers_observer_front.png",
160 "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90",
161 "mcl_observers_observer_top.png", "mcl_observers_observer_top.png",
163 mesecons = { receptor = {
164 state = mesecon.state.on,
165 rules = rules_down,
168 -- VERY quickly disable observer after construction
169 on_construct = function(pos)
170 local timer = minetest.get_node_timer(pos)
171 -- 1 redstone tick = 0.1 seconds
172 timer:start(0.1)
173 end,
174 on_timer = function(pos, elapsed)
175 local node = minetest.get_node(pos)
176 minetest.set_node(pos, {name = "mcl_observers:observer_down_off", param2 = node.param2})
177 mesecon.receptor_off(pos, rules_down)
178 end,
181 mesecon.register_node("mcl_observers:observer_up",
183 is_ground_content = false,
184 sounds = mcl_sounds.node_sound_stone_defaults(),
185 groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
186 on_rotate = false,
187 _mcl_blast_resistance = 17.5,
188 _mcl_hardness = 3.5,
189 drop = "mcl_observers:observer_off",
192 tiles = {
193 "mcl_observers_observer_front.png", "mcl_observers_observer_back.png",
194 "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270",
195 "mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180",
197 mesecons = { receptor = {
198 state = mesecon.state.off,
199 rules = rules_up,
201 on_construct = function(pos)
202 observer_scan(pos, true)
203 end,
206 _doc_items_create_entry = false,
207 tiles = {
208 "mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png",
209 "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270",
210 "mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180",
212 mesecons = { receptor = {
213 state = mesecon.state.on,
214 rules = rules_up,
217 -- VERY quickly disable observer after construction
218 on_construct = function(pos)
219 local timer = minetest.get_node_timer(pos)
220 -- 1 redstone tick = 0.1 seconds
221 timer:start(0.1)
222 end,
223 on_timer = function(pos, elapsed)
224 minetest.set_node(pos, {name = "mcl_observers:observer_up_off"})
225 mesecon.receptor_off(pos, rules_up)
226 end,
232 -- Regularily check the observer nodes.
233 -- TODO: This is rather slow and clunky. Find a more efficient way to do this.
234 minetest.register_abm({
235 nodenames = {"mcl_observers:observer_off", "mcl_observers:observer_down_off", "mcl_observers:observer_up_off"},
236 interval = 1,
237 chance = 1,
238 action = function(pos, node)
239 observer_scan(pos)
240 end,
244 minetest.register_craft({
245 output = "mcl_observers:observer_off",
246 recipe = {
247 { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
248 { "mcl_nether:quartz", "mesecons:redstone", "mesecons:redstone" },
249 { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
252 minetest.register_craft({
253 output = "mcl_observers:observer_off",
254 recipe = {
255 { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
256 { "mesecons:redstone", "mesecons:redstone", "mcl_nether:quartz" },
257 { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },