acef5d8283
This device is 3-in-1, it combines geothermometer, mineral scanner and mineral finder in one compartment while retaining each device's characteristics. Double right-click to change device mode. Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
232 lines
7.6 KiB
Lua
232 lines
7.6 KiB
Lua
|
|
--[[
|
|
|
|
Portable Mineral Computer aka PMC v1.0
|
|
|
|
This is all-in-one device that provides functionality
|
|
of geothermometer, mineral scanner and mineral finder.
|
|
These basic components are all connected and managed
|
|
by dedicated Mining Chip. Thanks to this, although
|
|
in one box, there is no signal loss or decreased range.
|
|
|
|
Left click - scan and show results
|
|
Right click - change scan range/searched ore
|
|
Double right click - change device mode
|
|
|
|
]]--
|
|
|
|
-- ************************
|
|
-- Namespaces and variables
|
|
-- ************************
|
|
|
|
local pmc = {}
|
|
local MODE_GEOTHERM = 1
|
|
local MODE_OREFIND = 2
|
|
local MODE_ORESCAN = 3
|
|
local mode = MODE_GEOTHERM
|
|
local mode_name = { [MODE_GEOTHERM] = "Geothermometer",
|
|
[MODE_OREFIND] = "Mineral Finder",
|
|
[MODE_ORESCAN] = "Mineral Scanner", }
|
|
local tool_range = { [MODE_GEOTHERM] = 8, [MODE_OREFIND] = 5, [MODE_ORESCAN] = 0 }
|
|
local scan_range_min = 1
|
|
local scan_range_max = 8
|
|
local scan_range = scan_range_max
|
|
local find_range = 5
|
|
local temp_range = 10
|
|
local temp_scale = 50.0
|
|
local head_vec = vector.new({x = 0, y = 1, z = 0})
|
|
local msg_white = minetest.get_color_escape_sequence("#FFFFFF")
|
|
local msg_yellow = minetest.get_color_escape_sequence("#FFFF00")
|
|
local msg_warn = minetest.get_color_escape_sequence("#FF8080")
|
|
local msg_zero = minetest.get_color_escape_sequence("#00FFFF")
|
|
local msg_plus = minetest.get_color_escape_sequence("#FF00FF")
|
|
local msg_hot = minetest.get_color_escape_sequence("#FFC0C0")
|
|
local msg_cold = minetest.get_color_escape_sequence("#C0C0FF")
|
|
local find_ore_list = {}
|
|
find_ore_list["default:stone_with_coal"] = "coal"
|
|
find_ore_list["default:stone_with_iron"] = "iron"
|
|
find_ore_list["default:stone_with_copper"] = "copper"
|
|
find_ore_list["default:stone_with_tin"] = "tin"
|
|
find_ore_list["default:stone_with_gold"] = "gold"
|
|
find_ore_list["default:stone_with_mese"] = "mese"
|
|
find_ore_list["default:stone_with_diamond"] = "diamond"
|
|
if minetest.get_modpath("moreores") then
|
|
find_ore_list["moreores:mineral_silver"] = "silver"
|
|
find_ore_list["moreores:mineral_mithril"] = "mithril"
|
|
end
|
|
local def_stone_idx = 1
|
|
local find_ore_stones = {}
|
|
for i, _ in pairs(find_ore_list) do
|
|
find_ore_stones[#find_ore_stones + 1] = i
|
|
if i == "default:stone_with_coal" then
|
|
def_stone_idx = #find_ore_stones
|
|
end
|
|
end
|
|
local cur_stone_idx = def_stone_idx
|
|
local scan_ore_list = {}
|
|
for i, n in pairs(find_ore_list) do
|
|
scan_ore_list[i] = n
|
|
end
|
|
scan_ore_list["default:obsidian"] = "obsidian"
|
|
local scan_ore_stones = {}
|
|
for i, _ in pairs(scan_ore_list) do
|
|
scan_ore_stones[#scan_ore_stones + 1] = i
|
|
end
|
|
local dbl_click_ms = 400
|
|
local last_rclick_ts = minetest.get_us_time()
|
|
|
|
-- activate device function
|
|
function pmc.use(itemstack, user, pointed_thing)
|
|
local player_name = user:get_player_name()
|
|
local player_pos = vector.round(user:getpos())
|
|
local node_pos = vector.new(pointed_thing.under)
|
|
if mode == MODE_GEOTHERM then
|
|
if pointed_thing.type ~= "node" then return nil end
|
|
if not minertools.is_mineral(minetest.get_node(node_pos).name) then
|
|
minertools.play_beep_err(player_name)
|
|
return nil
|
|
end
|
|
local temp_var = minertools.calculate_rel_temp(node_pos, temp_range)
|
|
minertools.play_beep_ok(player_name)
|
|
local msg_val_clr = msg_white
|
|
if temp_var < 0 then msg_val_clr = msg_cold
|
|
elseif temp_var > 0 then msg_val_clr = msg_hot end
|
|
minetest.chat_send_player(player_name,
|
|
msg_yellow .. "[PMC:Geothermometer]" ..
|
|
msg_white ..
|
|
" Temperature gradient for this block is " ..
|
|
msg_val_clr ..
|
|
string.format("%+.4f", temp_scale * temp_var) ..
|
|
msg_white)
|
|
elseif mode == MODE_OREFIND then
|
|
local head_pos = vector.add(vector.round(user:getpos()), head_vec)
|
|
local look_dir = user:get_look_dir()
|
|
local orecount, obsblock = minertools.dir_mineral_scan(head_pos,
|
|
find_range, look_dir,
|
|
find_ore_stones[cur_stone_idx])
|
|
local oremsg = ""
|
|
if orecount > 0 then oremsg = msg_plus
|
|
else oremsg = msg_zero end
|
|
oremsg = oremsg .. orecount
|
|
if obsblock then
|
|
oremsg = oremsg .. msg_warn ..
|
|
" (warning - scan incomplete, blocked by obsidian)"
|
|
end
|
|
minertools.play_pulse(player_name)
|
|
minetest.chat_send_player(player_name,
|
|
msg_yellow .. "[PMC:MineralFinder]" .. msg_white ..
|
|
" Scan result for " .. msg_zero ..
|
|
find_ore_list[find_ore_stones[cur_stone_idx]] ..
|
|
msg_white .. " : " ..
|
|
oremsg .. msg_white)
|
|
elseif mode == MODE_ORESCAN then
|
|
local minerals = minertools.area_mineral_scan(player_pos,
|
|
scan_range, scan_ore_stones)
|
|
local oremsg = ""
|
|
for orenode, orecount in pairs(minerals) do
|
|
local oms = scan_ore_list[orenode] .. " = " .. orecount
|
|
if orecount == 0 then oms = msg_zero .. oms
|
|
else oms = msg_plus .. oms end
|
|
if oremsg ~= "" then
|
|
oremsg = oremsg .. msg_white .. ", " .. oms
|
|
else
|
|
oremsg = oms
|
|
end
|
|
end
|
|
minertools.play_scan(player_name)
|
|
minetest.chat_send_player(player_name,
|
|
msg_yellow .. "[PMC:MineralScanner]" .. msg_white ..
|
|
" Scan results for cubic range " .. scan_range ..
|
|
" : " .. oremsg .. msg_white)
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function pmc.change_mode(itemstack, user_placer, pointed_thing)
|
|
local player_name = user_placer:get_player_name()
|
|
local rclick_ts = minetest.get_us_time()
|
|
-- detect right double-click
|
|
if rclick_ts - last_rclick_ts < dbl_click_ms * 1000 then
|
|
-- mode change
|
|
minertools.play_click(player_name)
|
|
mode = ((mode + 1) % 3) + 1
|
|
minetest.override_item("minertools:portable_mining_computer",
|
|
{range = tool_range[mode]})
|
|
minetest.chat_send_player(player_name,
|
|
msg_yellow .. "[PMC]" .. msg_white ..
|
|
" Switching mode to " .. msg_yellow ..
|
|
mode_name[mode] .. msg_white)
|
|
if mode == MODE_OREFIND then
|
|
cur_stone_idx = def_stone_idx
|
|
minetest.chat_send_player(player_name,
|
|
msg_yellow .. "[PMC:MineralFinder]" .. msg_white ..
|
|
" Mineral type set to " .. msg_zero ..
|
|
find_ore_list[find_ore_stones[cur_stone_idx]] ..
|
|
msg_white)
|
|
elseif mode == MODE_ORESCAN then
|
|
scan_range = scan_range_max
|
|
minetest.chat_send_player(player_name,
|
|
msg_yellow .. "[PMC:MineralScanner]" ..
|
|
msg_white .. " Scan range set to "
|
|
.. msg_zero .. scan_range .. msg_white)
|
|
end
|
|
else
|
|
-- option change
|
|
if mode == MODE_OREFIND then
|
|
cur_stone_idx = cur_stone_idx + 1
|
|
if cur_stone_idx > #find_ore_stones then
|
|
cur_stone_idx = 1
|
|
end
|
|
minertools.play_click(player_name)
|
|
minetest.chat_send_player(player_name,
|
|
msg_yellow .. "[PMC:MineralFinder]" .. msg_white ..
|
|
" Mineral type set to " .. msg_zero ..
|
|
find_ore_list[find_ore_stones[cur_stone_idx]] ..
|
|
msg_white)
|
|
elseif mode == MODE_ORESCAN then
|
|
scan_range = scan_range - 1
|
|
if scan_range == 0 then
|
|
scan_range = scan_range_max
|
|
end
|
|
minertools.play_click(player_name)
|
|
minetest.chat_send_player(player_name,
|
|
msg_yellow .. "[PMC:MineralScanner]" .. msg_white ..
|
|
" Scan range set to " .. msg_zero .. scan_range ..
|
|
msg_white)
|
|
end
|
|
end
|
|
last_rclick_ts = rclick_ts
|
|
return nil
|
|
end
|
|
|
|
-- *************
|
|
-- Register Tool
|
|
-- *************
|
|
|
|
minetest.register_tool("minertools:portable_mining_computer", {
|
|
description = "Portable Mining Computer",
|
|
wield_image = "minertools_pmc_hand.png",
|
|
wield_scale = { x = 1, y = 1, z = 1 },
|
|
inventory_image = "minertools_pmc_inv.png",
|
|
stack_max = 1,
|
|
range = tool_range[mode],
|
|
on_use = pmc.use,
|
|
on_place = pmc.change_mode,
|
|
on_secondary_use = pmc.change_mode,
|
|
})
|
|
|
|
-- ************
|
|
-- Craft Recipe
|
|
-- ************
|
|
|
|
minetest.register_craft({
|
|
output = "minertools:portable_mining_computer",
|
|
type = "shaped",
|
|
recipe = {
|
|
{ "default:steel_ingot", "minertools:geothermometer", "default:steel_ingot" },
|
|
{ "minertools:mineral_finder", "minertools:mining_chip", "minertools:mineral_scanner" },
|
|
{ "default:steel_ingot", "default:mese_crystal", "default:steel_ingot" },
|
|
},
|
|
})
|
|
|