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