Gábriel
2024-07-07 6731db14e580ddccace186f5a8ac03dad0661e0c
commit | author | age
636b0f 1 local S = technic.getter
Z 2
871ded 3 technic.register_power_tool("technic:prospector", 300000)
636b0f 4
a08ba2 5 -- Helper function to consolidate ItemStackMetaRef access and initialize
C 6 local function meta_to_table(meta)
7     local t = {}
8     local mt = meta:to_table()
9
10     t.charge = tonumber(mt.fields["technic:charge"]) or 0
11     t.target = mt.fields.target or ""
12     t.look_depth = tonumber(mt.fields.look_depth) or 7
13     t.look_radius = tonumber(mt.fields.look_radius) or 1
14     return t
636b0f 15 end
Z 16
17 minetest.register_tool("technic:prospector", {
18     description = S("Prospector"),
19     inventory_image = "technic_prospector.png",
20     wear_represents = "technic_RE_charge",
21     on_refill = technic.refill_RE_charge,
22     on_use = function(toolstack, user, pointed_thing)
23         if not user or not user:is_player() or user.is_fake_player then return end
24         if pointed_thing.type ~= "node" then return end
a08ba2 25         local meta = technic.get_stack_meta(toolstack)
C 26         local toolmeta = meta_to_table(meta)
636b0f 27         local look_diameter = toolmeta.look_radius * 2 + 1
Z 28         local charge_to_take = toolmeta.look_depth * (toolmeta.look_depth + 1) * look_diameter * look_diameter
29         if toolmeta.charge < charge_to_take then return end
30         if toolmeta.target == "" then
31             minetest.chat_send_player(user:get_player_name(), "Right-click to set target block type")
32             return
33         end
b8c902 34         if not technic.creative_mode then
M 35             toolmeta.charge = toolmeta.charge - charge_to_take
a08ba2 36             meta:set_int("technic:charge", toolmeta.charge)
b8c902 37             technic.set_RE_wear(toolstack, toolmeta.charge, technic.power_tools[toolstack:get_name()])
M 38         end
0f6bdb 39         -- What in the heaven's name is this evil sorcery ?
636b0f 40         local start_pos = pointed_thing.under
Z 41         local forward = minetest.facedir_to_dir(minetest.dir_to_facedir(user:get_look_dir(), true))
42         local right = forward.x ~= 0 and { x=0, y=1, z=0 } or (forward.y ~= 0 and { x=0, y=0, z=1 } or { x=1, y=0, z=0 })
43         local up = forward.x ~= 0 and { x=0, y=0, z=1 } or (forward.y ~= 0 and { x=1, y=0, z=0 } or { x=0, y=1, z=0 })
44         local base_pos = vector.add(start_pos, vector.multiply(vector.add(right, up), - toolmeta.look_radius))
45         local found = false
46         for f = 0, toolmeta.look_depth-1 do
47             for r = 0, look_diameter-1 do
48                 for u = 0, look_diameter-1 do
0f6bdb 49                     if minetest.get_node(
S 50                             vector.add(
51                                 vector.add(
52                                     vector.add(base_pos,
53                                         vector.multiply(forward, f)),
54                                     vector.multiply(right, r)),
55                                 vector.multiply(up, u))
56                             ).name == toolmeta.target then
57                         found = true
58                         break
59                     end
636b0f 60                 end
0f6bdb 61                 if found then break end
636b0f 62             end
0f6bdb 63             if found then break end
636b0f 64         end
0f6bdb 65         if math.random() < 0.02 then
S 66             found = not found
67         end
68
69         local ndef = minetest.registered_nodes[toolmeta.target]
70         minetest.chat_send_player(user:get_player_name(),
71             ndef.description.." is "..(found and "present" or "absent")..
72             " in "..look_diameter.."x"..look_diameter.."x"..toolmeta.look_depth.." region")
73
74         minetest.sound_play("technic_prospector_"..(found and "hit" or "miss"), {
75             pos = vector.add(user:get_pos(), { x = 0, y = 1, z = 0 }),
76             gain = 1.0,
77             max_hear_distance = 10
78         })
636b0f 79         return toolstack
Z 80     end,
81     on_place = function(toolstack, user, pointed_thing)
82         if not user or not user:is_player() or user.is_fake_player then return end
a08ba2 83         local meta = technic.get_stack_meta(toolstack)
C 84         local toolmeta = meta_to_table(meta)
636b0f 85         local pointed
Z 86         if pointed_thing.type == "node" then
87             local pname = minetest.get_node(pointed_thing.under).name
88             local pdef = minetest.registered_nodes[pname]
89             if pdef and (pdef.groups.not_in_creative_inventory or 0) == 0 and pname ~= toolmeta.target then
90                 pointed = pname
91             end
92         end
93         local look_diameter = toolmeta.look_radius * 2 + 1
94         minetest.show_formspec(user:get_player_name(), "technic:prospector_control",
95             "size[7,8.5]"..
96             "item_image[0,0;1,1;"..toolstack:get_name().."]"..
97             "label[1,0;"..minetest.formspec_escape(toolstack:get_definition().description).."]"..
98             (toolmeta.target ~= "" and
99                 "label[0,1.5;Current target:]"..
100                 "label[0,2;"..minetest.formspec_escape(minetest.registered_nodes[toolmeta.target].description).."]"..
101                 "item_image[0,2.5;1,1;"..toolmeta.target.."]" or
102                 "label[0,1.5;No target set]")..
103             (pointed and
104                 "label[3.5,1.5;May set new target:]"..
105                 "label[3.5,2;"..minetest.formspec_escape(minetest.registered_nodes[pointed].description).."]"..
106                 "item_image[3.5,2.5;1,1;"..pointed.."]"..
107                 "button_exit[3.5,3.65;2,0.5;target_"..pointed..";Set target]" or
108                 "label[3.5,1.5;No new target available]")..
109             "label[0,4.5;Region cross section:]"..
110             "label[0,5;"..look_diameter.."x"..look_diameter.."]"..
111             "label[3.5,4.5;Set region cross section:]"..
112             "button_exit[3.5,5.15;1,0.5;look_radius_0;1x1]"..
113             "button_exit[4.5,5.15;1,0.5;look_radius_1;3x3]"..
114             "button_exit[5.5,5.15;1,0.5;look_radius_3;7x7]"..
115             "label[0,6;Region depth:]"..
116             "label[0,6.5;"..toolmeta.look_depth.."]"..
117             "label[3.5,6;Set region depth:]"..
118             "button_exit[3.5,6.65;1,0.5;look_depth_7;7]"..
119             "button_exit[4.5,6.65;1,0.5;look_depth_14;14]"..
120             "button_exit[5.5,6.65;1,0.5;look_depth_21;21]"..
121             "label[0,7.5;Accuracy:]"..
122             "label[0,8;98%]")
123         return
4f78a6 124     end,
636b0f 125 })
Z 126
127 minetest.register_on_player_receive_fields(function(user, formname, fields)
128         if formname ~= "technic:prospector_control" then return false end
129     if not user or not user:is_player() or user.is_fake_player then return end
130     local toolstack = user:get_wielded_item()
131     if toolstack:get_name() ~= "technic:prospector" then return true end
a08ba2 132     local meta = technic.get_stack_meta(toolstack)
636b0f 133     for field, value in pairs(fields) do
Z 134         if field:sub(1, 7) == "target_" then
a08ba2 135             meta:set_string("target", field:sub(8))
C 136         elseif field:sub(1, 12) == "look_radius_" then
137             meta:set_string("look_radius", field:sub(13))
138         elseif field:sub(1, 11) == "look_depth_" then
139             meta:set_string("look_depth", field:sub(12))
636b0f 140         end
Z 141     end
142     user:set_wielded_item(toolstack)
143     return true
144 end)
4f78a6 145
636b0f 146 minetest.register_craft({
Z 147     output = "technic:prospector",
148     recipe = {
149         {"moreores:pick_silver", "moreores:mithril_block", "pipeworks:teleport_tube_1"},
44cb8d 150         {"basic_materials:brass_ingot", "technic:control_logic_unit", "basic_materials:brass_ingot"},
871ded 151         {"", "technic:blue_energy_crystal", ""},
636b0f 152     }
Z 153 })