diff options
author | Zefram <zefram@fysh.org> | 2014-07-03 19:42:29 +0100 |
---|---|---|
committer | Novatux <nathanael.courant@laposte.net> | 2014-07-07 15:15:30 +0200 |
commit | 9004ab3322f8c4288c1197a963c887be8e14ec92 (patch) | |
tree | 9bddda9402b7373c42cc881d4ec4367b16f8e48f | |
parent | 01b475c7cc7821489ad1fbe2db5ad85bcfcc10f9 (diff) |
Handheld prospecting toolorigin/recipes_rework
The new tool will say whether a target block type is present in a
specified region, to allow for more targeted digging. It is deliberately
quite weak, with several limitations: only stores enough charge for a
small number of shots; target can only be set by pointing at an example
node; range is limited; accuracy is less than 100%. Some of these
limitations should probably be ameliorated, but not entirely eliminated,
in the future when we have a better idea of game balance.
The inventory image is only a placeholder.
-rw-r--r-- | technic/sounds/technic_prospector_hit.ogg | bin | 0 -> 4698 bytes | |||
-rw-r--r-- | technic/sounds/technic_prospector_miss.ogg | bin | 0 -> 4481 bytes | |||
-rw-r--r-- | technic/textures/technic_prospector.png | bin | 0 -> 367 bytes | |||
-rw-r--r-- | technic/tools/init.lua | 1 | ||||
-rw-r--r-- | technic/tools/prospector.lua | 126 |
5 files changed, 127 insertions, 0 deletions
diff --git a/technic/sounds/technic_prospector_hit.ogg b/technic/sounds/technic_prospector_hit.ogg Binary files differnew file mode 100644 index 0000000..3a8ad2d --- /dev/null +++ b/technic/sounds/technic_prospector_hit.ogg diff --git a/technic/sounds/technic_prospector_miss.ogg b/technic/sounds/technic_prospector_miss.ogg Binary files differnew file mode 100644 index 0000000..0f050d0 --- /dev/null +++ b/technic/sounds/technic_prospector_miss.ogg diff --git a/technic/textures/technic_prospector.png b/technic/textures/technic_prospector.png Binary files differnew file mode 100644 index 0000000..2f9ee6c --- /dev/null +++ b/technic/textures/technic_prospector.png diff --git a/technic/tools/init.lua b/technic/tools/init.lua index 60327a5..b8d9127 100644 --- a/technic/tools/init.lua +++ b/technic/tools/init.lua @@ -13,6 +13,7 @@ dofile(path.."/cans.lua") dofile(path.."/chainsaw.lua") dofile(path.."/tree_tap.lua") dofile(path.."/sonic_screwdriver.lua") +dofile(path.."/prospector.lua") if minetest.get_modpath("screwdriver") then -- compatibility alias diff --git a/technic/tools/prospector.lua b/technic/tools/prospector.lua new file mode 100644 index 0000000..686e0a7 --- /dev/null +++ b/technic/tools/prospector.lua @@ -0,0 +1,126 @@ +local S = technic.getter + +technic.register_power_tool("technic:prospector", 15000) + +local function get_metadata(toolstack) + local m = minetest.deserialize(toolstack:get_metadata()) + if not m then m = {} end + if not m.charge then m.charge = 0 end + if not m.target then m.target = "" end + if not m.look_depth then m.look_depth = 7 end + if not m.look_radius then m.look_radius = 1 end + return m +end + +minetest.register_tool("technic:prospector", { + description = S("Prospector"), + inventory_image = "technic_prospector.png", + wear_represents = "technic_RE_charge", + on_refill = technic.refill_RE_charge, + on_use = function(toolstack, user, pointed_thing) + if not user or not user:is_player() or user.is_fake_player then return end + if pointed_thing.type ~= "node" then return end + local toolmeta = get_metadata(toolstack) + local look_diameter = toolmeta.look_radius * 2 + 1 + local charge_to_take = toolmeta.look_depth * (toolmeta.look_depth + 1) * look_diameter * look_diameter + if toolmeta.charge < charge_to_take then return end + if toolmeta.target == "" then + minetest.chat_send_player(user:get_player_name(), "Right-click to set target block type") + return + end + toolmeta.charge = toolmeta.charge - charge_to_take + toolstack:set_metadata(minetest.serialize(toolmeta)) + technic.set_RE_wear(toolstack, toolmeta.charge, technic.power_tools[toolstack:get_name()]) + local start_pos = pointed_thing.under + local forward = minetest.facedir_to_dir(minetest.dir_to_facedir(user:get_look_dir(), true)) + 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 }) + 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 }) + local base_pos = vector.add(start_pos, vector.multiply(vector.add(right, up), - toolmeta.look_radius)) + local found = false + for f = 0, toolmeta.look_depth-1 do + for r = 0, look_diameter-1 do + for u = 0, look_diameter-1 do + if minetest.get_node(vector.add(vector.add(vector.add(base_pos, vector.multiply(forward, f)), vector.multiply(right, r)), vector.multiply(up, u))).name == toolmeta.target then found = true end + end + end + end + if math.random() < 0.02 then found = not found end + minetest.chat_send_player(user:get_player_name(), minetest.registered_nodes[toolmeta.target].description.." is "..(found and "present" or "absent").." in "..look_diameter.."x"..look_diameter.."x"..toolmeta.look_depth.." region") + minetest.sound_play("technic_prospector_"..(found and "hit" or "miss"), { pos = vector.add(user:getpos(), { x = 0, y = 1, z = 0 }), gain = 1.0, max_hear_distance = 10 }) + return toolstack + end, + on_place = function(toolstack, user, pointed_thing) + if not user or not user:is_player() or user.is_fake_player then return end + local toolmeta = get_metadata(toolstack) + local pointed + if pointed_thing.type == "node" then + local pname = minetest.get_node(pointed_thing.under).name + local pdef = minetest.registered_nodes[pname] + if pdef and (pdef.groups.not_in_creative_inventory or 0) == 0 and pname ~= toolmeta.target then + pointed = pname + end + end + local look_diameter = toolmeta.look_radius * 2 + 1 + minetest.show_formspec(user:get_player_name(), "technic:prospector_control", + "size[7,8.5]".. + "item_image[0,0;1,1;"..toolstack:get_name().."]".. + "label[1,0;"..minetest.formspec_escape(toolstack:get_definition().description).."]".. + (toolmeta.target ~= "" and + "label[0,1.5;Current target:]".. + "label[0,2;"..minetest.formspec_escape(minetest.registered_nodes[toolmeta.target].description).."]".. + "item_image[0,2.5;1,1;"..toolmeta.target.."]" or + "label[0,1.5;No target set]").. + (pointed and + "label[3.5,1.5;May set new target:]".. + "label[3.5,2;"..minetest.formspec_escape(minetest.registered_nodes[pointed].description).."]".. + "item_image[3.5,2.5;1,1;"..pointed.."]".. + "button_exit[3.5,3.65;2,0.5;target_"..pointed..";Set target]" or + "label[3.5,1.5;No new target available]").. + "label[0,4.5;Region cross section:]".. + "label[0,5;"..look_diameter.."x"..look_diameter.."]".. + "label[3.5,4.5;Set region cross section:]".. + "button_exit[3.5,5.15;1,0.5;look_radius_0;1x1]".. + "button_exit[4.5,5.15;1,0.5;look_radius_1;3x3]".. + "button_exit[5.5,5.15;1,0.5;look_radius_3;7x7]".. + "label[0,6;Region depth:]".. + "label[0,6.5;"..toolmeta.look_depth.."]".. + "label[3.5,6;Set region depth:]".. + "button_exit[3.5,6.65;1,0.5;look_depth_7;7]".. + "button_exit[4.5,6.65;1,0.5;look_depth_14;14]".. + "button_exit[5.5,6.65;1,0.5;look_depth_21;21]".. + "label[0,7.5;Accuracy:]".. + "label[0,8;98%]") + return + end, +}) + +minetest.register_on_player_receive_fields(function(user, formname, fields) + if formname ~= "technic:prospector_control" then return false end + if not user or not user:is_player() or user.is_fake_player then return end + local toolstack = user:get_wielded_item() + if toolstack:get_name() ~= "technic:prospector" then return true end + local toolmeta = get_metadata(toolstack) + for field, value in pairs(fields) do + if field:sub(1, 7) == "target_" then + toolmeta.target = field:sub(8) + end + if field:sub(1, 12) == "look_radius_" then + toolmeta.look_radius = field:sub(13) + end + if field:sub(1, 11) == "look_depth_" then + toolmeta.look_depth = field:sub(12) + end + end + toolstack:set_metadata(minetest.serialize(toolmeta)) + user:set_wielded_item(toolstack) + return true +end) + +minetest.register_craft({ + output = "technic:prospector", + recipe = { + {"moreores:pick_silver", "moreores:mithril_block", "pipeworks:teleport_tube_1"}, + {"technic:brass_ingot", "technic:control_logic_unit", "technic:brass_ingot"}, + {"", "technic:brass_ingot", ""}, + } +}) |