Rename mod: walls → hades_walls
[minetest_hades/hades_revisited.git] / mods / pipeworks / node_breaker.lua
blob4088feb2a63e2e539adc6da78ec8069d82edd8d1
2 --register aliases for when someone had technic installed, but then uninstalled it but not pipeworks
3 minetest.register_alias("technic:nodebreaker_off", "pipeworks:nodebreaker_off")
4 minetest.register_alias("technic:nodebreaker_on", "pipeworks:nodebreaker_on")
5 minetest.register_alias("technic:node_breaker_off", "pipeworks:nodebreaker_off") --old name
6 minetest.register_alias("technic:node_breaker_on", "pipeworks:nodebreaker_on") --old name
8 minetest.register_craft({
9 output = 'pipeworks:nodebreaker_off 1',
10 recipe = {
11 {'group:wood', 'hades_core:pick_mese','group:wood'},
12 {'hades_core:stone', 'hades_core:cobble','hades_core:stone'},
13 {'hades_core:stone', 'hades_core:mese_crystal_fragment','hades_core:stone'},
17 local function swap_node(pos, name)
18 local node = minetest.get_node(pos)
19 if node.name == name then
20 return
21 end
22 node.name = name
23 minetest.swap_node(pos, node)
24 end
26 --define the functions from https://github.com/minetest/minetest/pull/834 while waiting for the devs to notice it
27 local function dir_to_facedir(dir, is6d)
28 --account for y if requested
29 if is6d and math.abs(dir.y) > math.abs(dir.x) and math.abs(dir.y) > math.abs(dir.z) then
31 --from above
32 if dir.y < 0 then
33 if math.abs(dir.x) > math.abs(dir.z) then
34 if dir.x < 0 then
35 return 19
36 else
37 return 13
38 end
39 else
40 if dir.z < 0 then
41 return 10
42 else
43 return 4
44 end
45 end
47 --from below
48 else
49 if math.abs(dir.x) > math.abs(dir.z) then
50 if dir.x < 0 then
51 return 15
52 else
53 return 17
54 end
55 else
56 if dir.z < 0 then
57 return 6
58 else
59 return 8
60 end
61 end
62 end
64 --otherwise, place horizontally
65 elseif math.abs(dir.x) > math.abs(dir.z) then
66 if dir.x < 0 then
67 return 3
68 else
69 return 1
70 end
71 else
72 if dir.z < 0 then
73 return 2
74 else
75 return 0
76 end
77 end
78 end
80 local function delay(x)
81 return (function() return x end)
82 end
84 local function break_node (pos, facedir)
85 --locate the outgoing velocity, front, and back of the node via facedir_to_dir
86 if type(facedir) ~= "number" or facedir < 0 or facedir > 23 then return end
88 local vel = minetest.facedir_to_dir(facedir);
89 local front = {x=pos.x - vel.x, y=pos.y - vel.y, z=pos.z - vel.z}
91 local node = minetest.get_node(front)
92 if node.name == "air" or node.name == "ignore" then
93 return nil
94 elseif minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].liquidtype ~= "none" then
95 return nil
96 end
97 local meta = minetest.get_meta(pos)
98 local inv = meta:get_inventory()
99 inv:set_stack("pick", 1, ItemStack("hades_core:pick_mese"))
100 local pitch
101 local yaw
102 if vel.z < 0 then
103 yaw = 0
104 pitch = 0
105 elseif vel.z > 0 then
106 yaw = math.pi
107 pitch = 0
108 elseif vel.x < 0 then
109 yaw = 3*math.pi/2
110 pitch = 0
111 elseif vel.x > 0 then
112 yaw = math.pi/2
113 pitch = 0
114 elseif vel.y > 0 then
115 yaw = 0
116 pitch = -math.pi/2
117 else
118 yaw = 0
119 pitch = math.pi/2
121 local digger = {
122 get_inventory_formspec = delay(""),
123 get_look_dir = delay({x = -vel.x, y = -vel.y, z = -vel.z}),
124 get_look_pitch = delay(pitch),
125 get_look_yaw = delay(yaw),
126 get_player_control = delay({jump=false, right=false, left=false, LMB=false, RMB=false, sneak=false, aux1=false, down=false, up=false}),
127 get_player_control_bits = delay(0),
128 get_player_name = delay("node_breaker"),
129 is_player = delay(true),
130 set_inventory_formspec = delay(),
131 getpos = delay({x = pos.x, y = pos.y - 1.5, z = pos.z}), -- Player height
132 get_hp = delay(20),
133 get_inventory = delay(inv),
134 get_wielded_item = delay(ItemStack("hades_core:pick_mese")),
135 get_wield_index = delay(1),
136 get_wield_list = delay("pick"),
137 moveto = delay(),
138 punch = delay(),
139 remove = delay(),
140 right_click = delay(),
141 setpos = delay(),
142 set_hp = delay(),
143 set_properties = delay(),
144 set_wielded_item = delay(),
145 set_animation = delay(),
146 set_attach = delay(),
147 set_detach = delay(),
148 set_bone_position = delay(),
151 --check node to make sure it is diggable
152 local def = ItemStack({name=node.name}):get_definition()
153 if #def ~= 0 and not def.diggable or (def.can_dig and not def.can_dig(front, digger)) then --node is not diggable
154 return
157 --handle node drops
158 local drops = minetest.get_node_drops(node.name, "hades_core:pick_mese")
159 for _, dropped_item in ipairs(drops) do
160 local item1 = pipeworks.tube_item({x=pos.x, y=pos.y, z=pos.z}, dropped_item)
161 item1:get_luaentity().start_pos = {x=pos.x, y=pos.y, z=pos.z}
162 item1:set_velocity(vel)
163 item1:set_acceleration({x=0, y=0, z=0})
166 local oldmetadata = nil
167 if def.after_dig_node then
168 oldmetadata = minetest.get_meta(front):to_table()
171 minetest.remove_node(front)
173 --handle post-digging callback
174 if def.after_dig_node then
175 -- Copy pos and node because callback can modify them
176 local pos_copy = {x=front.x, y=front.y, z=front.z}
177 local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
178 def.after_dig_node(pos_copy, node_copy, oldmetadata, digger)
181 --run digging event callbacks
182 for _, callback in ipairs(minetest.registered_on_dignodes) do
183 -- Copy pos and node because callback can modify them
184 local pos_copy = {x=front.x, y=front.y, z=front.z}
185 local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
186 callback(pos_copy, node_copy, digger)
190 local node_breaker_on = function(pos, node)
191 if node.name == "pipeworks:nodebreaker_off" then
192 swap_node(pos, "pipeworks:nodebreaker_on")
193 break_node(pos, node.param2)
194 minetest.check_for_falling(pos)
198 local node_breaker_off = function(pos, node)
199 if node.name == "pipeworks:nodebreaker_on" then
200 swap_node(pos, "pipeworks:nodebreaker_off")
201 minetest.check_for_falling(pos)
205 minetest.register_node("pipeworks:nodebreaker_off", {
206 description = "Node Breaker",
207 tiles = {"pipeworks_nodebreaker_top_off.png","pipeworks_nodebreaker_bottom_off.png","pipeworks_nodebreaker_side2_off.png","pipeworks_nodebreaker_side1_off.png",
208 "pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_off.png"},
209 is_ground_content = true,
210 paramtype2 = "facedir",
211 groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1},
212 mesecons= {effector={rules=pipeworks.rules_all,action_on=node_breaker_on, action_off=node_breaker_off}},
213 sounds = hades_sounds.node_sound_stone_defaults(),
214 tube = {connect_sides={back=1}},
215 on_construct = function(pos)
216 local meta = minetest.get_meta(pos)
217 local inv = meta:get_inventory()
218 inv:set_size("pick", 1)
219 inv:set_stack("pick", 1, ItemStack("hades_core:pick_mese"))
220 end,
221 after_place_node = function (pos, placer)
222 pipeworks.scan_for_tube_objects(pos, placer)
223 local placer_pos = placer:get_pos()
225 --correct for the player's height
226 if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
228 --correct for 6d facedir
229 if placer_pos then
230 local dir = {
231 x = pos.x - placer_pos.x,
232 y = pos.y - placer_pos.y,
233 z = pos.z - placer_pos.z
235 local node = minetest.get_node(pos)
236 node.param2 = dir_to_facedir(dir, true)
237 minetest.set_node(pos, node)
238 minetest.log("action", "real (6d) facedir: " .. node.param2)
240 end,
241 after_dig_node = pipeworks.scan_for_tube_objects,
244 minetest.register_node("pipeworks:nodebreaker_on", {
245 description = "Node Breaker (on)",
246 tiles = {"pipeworks_nodebreaker_top_on.png","pipeworks_nodebreaker_bottom_on.png","pipeworks_nodebreaker_side2_on.png","pipeworks_nodebreaker_side1_on.png",
247 "pipeworks_nodebreaker_back.png","pipeworks_nodebreaker_front_on.png"},
248 mesecons= {effector={rules=pipeworks.rules_all,action_on=node_breaker_on, action_off=node_breaker_off}},
249 is_ground_content = true,
250 paramtype2 = "facedir",
251 groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2, mesecon = 2,tubedevice=1,not_in_creative_inventory=1},
252 sounds = hades_sounds.node_sound_stone_defaults(),
253 tube = {connect_sides={back=1}},
254 on_construct = function(pos)
255 local meta = minetest.get_meta(pos)
256 local inv = meta:get_inventory()
257 inv:set_size("pick", 1)
258 inv:set_stack("pick", 1, ItemStack("hades_core:pick_mese"))
259 end,
260 after_place_node = function (pos, placer)
261 pipeworks.scan_for_tube_objects(pos, placer)
262 local placer_pos = placer:get_pos()
264 --correct for the player's height
265 if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
267 --correct for 6d facedir
268 if placer_pos then
269 local dir = {
270 x = pos.x - placer_pos.x,
271 y = pos.y - placer_pos.y,
272 z = pos.z - placer_pos.z
274 local node = minetest.get_node(pos)
275 node.param2 = dir_to_facedir(dir, true)
276 minetest.set_node(pos, node)
277 minetest.log("action", "real (6d) facedir: " .. node.param2)
279 end,
280 after_dig_node = pipeworks.scan_for_tube_objects,