minertools: major code cleanup and optimisation.

Common code and variables moved to functions.lua, device
code updated.

Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
This commit is contained in:
Michal Cieslakiewicz 2018-10-07 14:00:13 +02:00
parent dc223e3516
commit 371639ecbb
7 changed files with 415 additions and 552 deletions

View File

@ -1,7 +1,7 @@
--[[
Advanced Mining Assistant aka AMA v1.0
Advanced Mining Assistant aka AMA v2.0
This one is an upgraded version of PMC. Adding one
more Mining Chip, gold circuitry and obsidian resonators
@ -9,6 +9,13 @@
increased.
Operational actions remain identical to PMC.
Technical differences to PMC:
* increased MineralFinder range
* increased MineralScanner range
* increased Geothermometer sensivity range
* MS signal info (low/medium/high) indicates distance to ore
* MF and MS settings are preserved during mode switch
Left click - scan and show results
Right click - change scan range/searched ore
Double right click - change device mode
@ -32,51 +39,23 @@ local scan_range_min = 1
local scan_range_max = 12
local scan_range = scan_range_max
local find_range = 8
local find_stone_idx = 1
local temp_range = 12
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 msg_high = minetest.get_color_escape_sequence("#52D017")
local msg_medium = minetest.get_color_escape_sequence("#EAC117")
local msg_low = minetest.get_color_escape_sequence("#E56717")
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"
local last_rclick_ts = 0
local find_ore_stones = { "default:stone_with_coal",
"default:stone_with_iron",
"default:stone_with_copper",
"default:stone_with_tin",
"default:stone_with_gold",
"default:stone_with_mese",
"default:stone_with_diamond" }
if minetest.get_modpath("moreores") then
find_ore_list["moreores:mineral_silver"] = "silver"
find_ore_list["moreores:mineral_mithril"] = "mithril"
find_ore_stones[#find_ore_stones + 1] = "moreores:mineral_silver"
find_ore_stones[#find_ore_stones + 1] = "moreores:mineral_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()
local scan_ore_stones = table.copy(find_ore_stones)
scan_ore_stones[#scan_ore_stones + 1] = "default:obsidian"
-- activate device function
function ama.use(itemstack, user, pointed_thing)
@ -85,71 +64,18 @@ function ama.use(itemstack, user, pointed_thing)
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 .. "[AMA:Geothermometer]" ..
msg_white ..
" Temperature gradient for this block is " ..
msg_val_clr ..
string.format("%+.4f", temp_scale * temp_var) ..
msg_white)
minertools.geothermometer_use("AMA:Geothermometer", player_name,
node_pos, temp_range, temp_scale)
elseif mode == MODE_OREFIND then
local head_pos = vector.add(vector.round(user:getpos()), head_vec)
local head_pos = vector.add(player_pos, minertools.head_vec)
local look_dir = user:get_look_dir()
local orecount, obsblock, oredepth =
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 oredepth > 0 then
oremsg = oremsg .. msg_white .. " (signal strength: "
if oredepth <= find_range / 3 then
oremsg = oremsg .. msg_high .. "HIGH"
elseif oredepth > find_range * 2 / 3 then
oremsg = oremsg .. msg_low .. "LOW"
else oremsg = oremsg .. msg_medium .. "MEDIUM" end
oremsg = oremsg .. msg_white .. ")"
end
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 .. "[AMA:MineralFinder]" .. msg_white ..
" Scan result for " .. msg_zero ..
find_ore_list[find_ore_stones[cur_stone_idx]] ..
msg_white .. " : " ..
oremsg .. msg_white)
minertools.mineralfinder_use("AMA:MineralFinder", player_name,
head_pos, look_dir, find_range,
find_ore_stones[find_stone_idx], 1)
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 .. "[AMA:MineralScanner]" .. msg_white ..
" Scan results for cubic range " .. scan_range ..
" : " .. oremsg .. msg_white)
minertools.mineralscanner_use("AMA:MineralScanner", player_name,
player_pos, scan_range,
scan_ore_stones)
end
return nil
end
@ -158,53 +84,32 @@ function ama.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
if rclick_ts - last_rclick_ts < minertools.dbl_click_us then
-- mode change
minertools.play_click(player_name)
mode = ((mode + 1) % 3) + 1
mode = ((mode + 1) % #mode_name) + 1
minetest.override_item("minertools:advanced_mining_assistant",
{range = tool_range[mode]})
minetest.chat_send_player(player_name,
msg_yellow .. "[AMA]" .. msg_white ..
" Switching mode to " .. msg_yellow ..
mode_name[mode] .. msg_white)
minertools.computer_mode_change_notify("AMA", player_name,
mode_name[mode])
if mode == MODE_OREFIND then
cur_stone_idx = def_stone_idx
minetest.chat_send_player(player_name,
msg_yellow .. "[AMA:MineralFinder]" .. msg_white ..
" Mineral type is now " .. msg_zero ..
find_ore_list[find_ore_stones[cur_stone_idx]] ..
msg_white)
-- AMA remembers settings, do not reset ore
minertools.print_mineral_type_is_now("AMA:MineralFinder",
player_name, find_ore_stones[find_stone_idx])
elseif mode == MODE_ORESCAN then
scan_range = scan_range_max
minetest.chat_send_player(player_name,
msg_yellow .. "[AMA:MineralScanner]" ..
msg_white .. " Scan range is now "
.. msg_zero .. scan_range .. msg_white)
-- AMA remembers settings, do not reset range
minertools.print_scan_range_is_now("AMA:MineralScanner",
player_name, scan_range)
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 .. "[AMA:MineralFinder]" .. msg_white ..
" Mineral type set to " .. msg_zero ..
find_ore_list[find_ore_stones[cur_stone_idx]] ..
msg_white)
find_stone_idx = minertools.mineralfinder_switch_ore(
"AMA:MineralFinder", player_name,
find_ore_stones, find_stone_idx)
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 .. "[AMA:MineralScanner]" .. msg_white ..
" Scan range set to " .. msg_zero .. scan_range ..
msg_white)
scan_range = minertools.mineralscanner_switch_range(
"AMA:MineralScanner", player_name,
scan_range_min, scan_range_max, scan_range)
end
end
last_rclick_ts = rclick_ts

View File

@ -7,53 +7,80 @@
minertools = {}
-- ******************
-- Play sound effects
-- ******************
-- *********
-- Constants
-- *********
function minertools.play_beep_ok(player_name)
-- colors
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 msg_high = minetest.get_color_escape_sequence("#52D017")
local msg_medium = minetest.get_color_escape_sequence("#EAC117")
local msg_low = minetest.get_color_escape_sequence("#E56717")
-- mineral labels (for display)
local mineral_label = {}
mineral_label["default:stone_with_coal"] = "coal"
mineral_label["default:stone_with_iron"] = "iron"
mineral_label["default:stone_with_copper"] = "copper"
mineral_label["default:stone_with_tin"] = "tin"
mineral_label["default:stone_with_gold"] = "gold"
mineral_label["default:stone_with_mese"] = "mese"
mineral_label["default:stone_with_diamond"] = "diamond"
mineral_label["default:obsidian"] = "obsidian"
if minetest.get_modpath("moreores") then
mineral_label["moreores:mineral_silver"] = "silver"
mineral_label["moreores:mineral_mithril"] = "mithril"
end
-- public constants
minertools.head_vec = vector.new({x = 0, y = 1, z = 0})
minertools.dbl_click_us = 300 * 1000
-- ****************
-- Helper functions
-- ****************
-- sounds
local function play_beep_ok(player_name)
minetest.sound_play("minertools_beep_ok", {
to_player = player_name,
gain = 0.8,
})
end
function minertools.play_beep_err(player_name)
local function play_beep_err(player_name)
minetest.sound_play("minertools_beep_err", {
to_player = player_name,
gain = 0.5,
})
end
function minertools.play_scan(player_name)
local function play_scan(player_name)
minetest.sound_play("minertools_scan", {
to_player = player_name,
gain = 0.8,
})
end
function minertools.play_click(player_name)
local function play_click(player_name)
minetest.sound_play("minertools_click", {
to_player = player_name,
gain = 0.6,
})
end
function minertools.play_pulse(player_name)
local function play_pulse(player_name)
minetest.sound_play("minertools_pulse", {
to_player = player_name,
gain = 0.8,
})
end
-- *******************
-- Node classification
-- *******************
-- check if node is of type that device can scan
-- (only nodes of natural origin can be analyzed properly)
function minertools.is_mineral(name)
local function is_mineral(name)
if name == nil then return false end
if minetest.get_item_group(name, "sand") > 0 then return true end
if minetest.get_item_group(name, "soil") > 0 then return true end
@ -70,7 +97,7 @@ function minertools.is_mineral(name)
end
-- check if node is made of obsidian
function minertools.has_obsidian(name)
local function has_obsidian(name)
if name == nil then return false end
if string.match(name, "^default:obsidian") then return true end
if minetest.get_modpath("stairs") then -- part of minetest game now
@ -88,7 +115,7 @@ end
-- calculate relative temperature (aka gradient based on thermal sources nearby)
-- return: temperature gradient
function minertools.calculate_rel_temp(pos, radius)
local function calculate_rel_temp(pos, radius)
local scan_vec = vector.new({x = radius, y = radius, z = radius})
local scan_pos1 = vector.subtract(pos, scan_vec)
local scan_pos2 = vector.add(pos, scan_vec)
@ -118,7 +145,7 @@ end
-- look_dir - direction of looking (normalized vector)
-- name - ore to search for (string)
-- return: mineral count, blocked by obsidian true/false, closest ore distance
function minertools.dir_mineral_scan(pos, range, look_dir, name)
local function dir_mineral_scan(pos, range, look_dir, name)
local node = {}
local pos_vec = {}
local last_vec = nil
@ -133,7 +160,7 @@ function minertools.dir_mineral_scan(pos, range, look_dir, name)
if node.name == name then
orecount = orecount + 1
if oredepth == 0 then oredepth = i end
elseif minertools.has_obsidian(node.name) then
elseif has_obsidian(node.name) then
obsblock = true
break
end
@ -149,7 +176,7 @@ end
-- range - scan max range (float)
-- nodes - node names to search for (array)
-- return: mineral table (keys - node names, values - node count)
function minertools.area_mineral_scan(pos, range, nodes)
local function area_mineral_scan(pos, range, nodes)
local scan_vec = vector.new({x = range, y = range, z = range})
local scan_pos1 = vector.subtract(pos, scan_vec)
local scan_pos2 = vector.add(pos, scan_vec)
@ -157,3 +184,197 @@ function minertools.area_mineral_scan(pos, range, nodes)
return minerals
end
-- ***************
-- Display helpers
-- ***************
function minertools.print_mineral_type_set_to(label, player_name, stone_name)
minetest.chat_send_player(player_name,
msg_yellow .. "[" .. label .. "]" .. msg_white ..
" Mineral type set to " .. msg_zero ..
mineral_label[stone_name] .. msg_white)
end
function minertools.print_scan_range_set_to(label, player_name, scan_range)
minetest.chat_send_player(player_name,
msg_yellow .. "[" .. label .. "]" ..
msg_white .. " Scan range set to "
.. msg_zero .. scan_range .. msg_white)
end
function minertools.print_mineral_type_is_now(label, player_name, stone_name)
minetest.chat_send_player(player_name,
msg_yellow .. "[" .. label .. "]" .. msg_white ..
" Mineral type is now " .. msg_zero ..
mineral_label[stone_name] .. msg_white)
end
function minertools.print_scan_range_is_now(label, player_name, scan_range)
minetest.chat_send_player(player_name,
msg_yellow .. "[" .. label .. "]" ..
msg_white .. " Scan range is now "
.. msg_zero .. scan_range .. msg_white)
end
-- *******
-- Modules
-- *******
-- geothermometer
-- parameters: label - device name in chat (string)
-- player_name - owner of device (string)
-- node_pos - pointed node position (vector)
-- radius - area of heat calculation (number)
-- scale - scaling factor (number)
-- temp_fmt - format of display (string, default "%+.4f")
function minertools.geothermometer_use(label, player_name, node_pos,
radius, scale, temp_fmt)
if not is_mineral(minetest.get_node(node_pos).name) then
play_beep_err(player_name)
return nil
end
local strfmt = "%+.4f"
if temp_fmt then strfmt = temp_fmt end
local temp_var = calculate_rel_temp(node_pos, radius)
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 .. "[" .. label .. "]" .. msg_white ..
" Temperature gradient for this block is " ..
msg_val_clr .. string.format(strfmt, scale * temp_var) ..
msg_white)
return nil
end
-- mineral finder
-- parameters: label - device name in chat (string)
-- player_name - owner of device (string)
-- head_pos - player head position (vector)
-- look_dir - player looking direction (vector)
-- range - depth of scanning (number)
-- stone_name - name of ore node to search for (string)
-- disp_detail - show ore distance (0-none, 1-H/M/L, 2-percentage)
function minertools.mineralfinder_use(label, player_name, head_pos, look_dir,
range, stone_name, disp_detail)
if not mineral_label[stone_name] then return nil end
local rangeshow = 0
if disp_detail then rangeshow = disp_detail end
local orecount, obsblock, oredepth = dir_mineral_scan(head_pos,
range, look_dir,
stone_name)
local oremsg = ""
if orecount > 0 then oremsg = msg_plus
else oremsg = msg_zero end
oremsg = oremsg .. orecount
if oredepth > 0 then
if rangeshow == 1 then
oremsg = oremsg .. msg_white .. " (signal strength: "
if oredepth <= find_range / 3 then
oremsg = oremsg .. msg_high .. "HIGH"
elseif oredepth > find_range * 2 / 3 then
oremsg = oremsg .. msg_low .. "LOW"
else oremsg = oremsg .. msg_medium .. "MEDIUM" end
oremsg = oremsg .. msg_white .. ")"
elseif rangeshow == 2 then
oremsg = oremsg .. msg_white .. " (signal strength: "
local sigpct = 100.0 * (find_range - oredepth + 1) / find_range
if sigpct >= 75 then oremsg = oremsg .. msg_high
elseif sigpct < 25 then oremsg = oremsg .. msg_low
else oremsg = oremsg .. msg_medium end
oremsg = oremsg .. string.format("%d%%", sigpct) ..
msg_white .. ")"
end
end
if obsblock then
oremsg = oremsg .. msg_warn ..
" (warning - scan incomplete, blocked by obsidian)"
end
play_pulse(player_name)
minetest.chat_send_player(player_name,
msg_yellow .. "[" .. label .. "]" .. msg_white ..
" Scan result for " .. msg_zero ..
mineral_label[stone_name] .. msg_white ..
" : " .. oremsg .. msg_white)
return nil
end
-- mineral scanner
-- parameters: label - device name in chat (string)
-- player_name - owner of device (string)
-- player_pos - player position (vector)
-- range - cubic range of scanning (number)
-- stones_list - minerals to scan for (table)
function minertools.mineralscanner_use(label, player_name, player_pos,
range, stones_list)
local minerals = area_mineral_scan(player_pos, range, stones_list)
local oremsg = ""
for orenode, orecount in pairs(minerals) do
if mineral_label[orenode] then
local oms = mineral_label[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
end
play_scan(player_name)
minetest.chat_send_player(player_name,
msg_yellow .. "[" .. label .. "]" .. msg_white ..
" Scan results for cubic range " .. range ..
" : " .. oremsg .. msg_white)
return nil
end
-- ************
-- Module modes
-- ************
-- mineral finder - change ore type
-- parameters: label - device name in chat (string)
-- player_name - owner of device (string)
-- stones_list - known minerals (table)
-- stone_index - current index in stones_list (number)
-- return: new ore index
function minertools.mineralfinder_switch_ore(label, player_name,
stones_list, stone_index)
play_click(player_name)
local new_stone_idx = (( stone_index + 1 ) % #stones_list) + 1
minertools.print_mineral_type_set_to(label, player_name,
stones_list[new_stone_idx])
return new_stone_idx
end
-- mineral scanner - change scan range
-- parameters: label - device name in chat (string)
-- player_name - owner of device (string)
-- player_pos - player position (vector)
-- min_range - minimal range of scanning (number)
-- max_range - maximal range of scanning (number)
-- range - current range of scanning (number)
-- return: new range
function minertools.mineralscanner_switch_range(label, player_name,
min_range, max_range, range)
play_click(player_name)
local new_range = range - 1
if new_range < min_range then
new_range = max_range
end
minertools.print_scan_range_set_to(label, player_name, new_range)
return new_range
end
-- ****************
-- Computer helpers
-- ****************
-- play click and display new mode
function minertools.computer_mode_change_notify(label, player_name, mode_name)
play_click(player_name)
minetest.chat_send_player(player_name,
msg_yellow .. "[" .. label .. "]" .. msg_white ..
" Switching mode to " .. msg_yellow ..
mode_name .. msg_white)
return nil
end

View File

@ -1,7 +1,7 @@
--[[
Geothermometer device v1.0
Geothermometer device v2.0
Principle of calculations:
heat energy dissipates with square distance from source (twice the distance
@ -27,31 +27,14 @@ local geothermometer = {}
local tool_range = 8
local scan_range = 10
local temp_scale = 50.0
local msg_white = minetest.get_color_escape_sequence("#FFFFFF")
local msg_hot = minetest.get_color_escape_sequence("#FFC0C0")
local msg_cold = minetest.get_color_escape_sequence("#C0C0FF")
local msg_yellow = minetest.get_color_escape_sequence("#FFFF00")
-- calculate and show relative temperature
function geothermometer.show_rel_temp(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then return nil end
local player_name = user:get_player_name()
local node_pos = vector.new(pointed_thing.under)
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, scan_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 .. "[Geothermometer]" .. msg_white ..
" Temperature gradient for this block is " ..
msg_val_clr .. string.format("%+.4f", temp_scale * temp_var) ..
msg_white)
minertools.geothermometer_use("Geothermometer", player_name,
node_pos, scan_range, temp_scale)
return nil
end

View File

@ -1,7 +1,7 @@
--[[
Portable Mineral Finder v1.0
Portable Mineral Finder v2.0
Short range directional radar that detects
presence of selected ore in front of device.
@ -26,70 +26,35 @@
local mineralfinder = {}
local tool_range = 4
local scan_range = 5
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 ore_list = {}
ore_list["default:stone_with_coal"] = "coal"
ore_list["default:stone_with_iron"] = "iron"
ore_list["default:stone_with_copper"] = "copper"
ore_list["default:stone_with_tin"] = "tin"
ore_list["default:stone_with_gold"] = "gold"
ore_list["default:stone_with_mese"] = "mese"
ore_list["default:stone_with_diamond"] = "diamond"
if minetest.get_modpath("moreores") then
ore_list["moreores:mineral_silver"] = "silver"
ore_list["moreores:mineral_mithril"] = "mithril"
end
local cur_stone_idx = 1
local ore_stones = {}
for i, _ in pairs(ore_list) do
ore_stones[#ore_stones + 1] = i
if i == "default:stone_with_coal" then
cur_stone_idx = #ore_stones
end
local ore_stones = { "default:stone_with_coal",
"default:stone_with_iron",
"default:stone_with_copper",
"default:stone_with_tin",
"default:stone_with_gold",
"default:stone_with_mese",
"default:stone_with_diamond" }
if minetest.get_modpath("moreores") then
ore_stones[#ore_stones + 1] = "moreores:mineral_silver"
ore_stones[#ore_stones + 1] = "moreores:mineral_mithril"
end
local head_vec = vector.new({x = 0, y = 1, z = 0})
-- scan for selected ore in front of device
function mineralfinder.scan_for_mineral(itemstack, user, pointed_thing)
local player_name = user:get_player_name()
local head_pos = vector.add(vector.round(user:getpos()), head_vec)
local head_pos = vector.add(vector.round(user:getpos()),
minertools.head_vec)
local look_dir = user:get_look_dir() -- normalized vec (x,y,z = -1..1)
local orecount, obsblock, _ = minertools.dir_mineral_scan(head_pos,
scan_range, look_dir,
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 .. "[MineralFinder]" .. msg_white ..
" Scan result for " .. msg_zero ..
ore_list[ore_stones[cur_stone_idx]] ..
msg_white .. " : " ..
oremsg .. msg_white)
minertools.mineralfinder_use("MineralFinder", player_name, head_pos,
look_dir, scan_range,
ore_stones[cur_stone_idx])
return nil
end
function mineralfinder.change_mineral_type(itemstack, user_placer, pointed_thing)
local player_name = user_placer:get_player_name()
minertools.play_click(player_name)
cur_stone_idx = cur_stone_idx + 1
if cur_stone_idx > #ore_stones then
cur_stone_idx = 1
end
minetest.chat_send_player(player_name,
msg_yellow .. "[MineralFinder]" .. msg_white ..
" Mineral type set to " .. msg_zero ..
ore_list[ore_stones[cur_stone_idx]] .. msg_white)
cur_stone_idx = minertools.mineralfinder_switch_ore("MineralFinder",
player_name, ore_stones, cur_stone_idx)
return nil
end

View File

@ -1,7 +1,7 @@
--[[
Portable Mineral Scanner v1.0
Portable Mineral Scanner v2.0
Scans cube around player with specified range and
provides feedback with ore quantity.
@ -21,63 +21,32 @@ local tool_range = 0
local scan_range_min = 1
local scan_range_max = 8
local scan_range = scan_range_max
local msg_white = minetest.get_color_escape_sequence("#FFFFFF")
local msg_yellow = minetest.get_color_escape_sequence("#FFFF00")
local msg_zero = minetest.get_color_escape_sequence("#00FFFF")
local msg_plus = minetest.get_color_escape_sequence("#FF00FF")
local ore_list = {}
ore_list["default:stone_with_coal"] = "coal"
ore_list["default:stone_with_iron"] = "iron"
ore_list["default:stone_with_copper"] = "copper"
ore_list["default:stone_with_tin"] = "tin"
ore_list["default:stone_with_gold"] = "gold"
ore_list["default:stone_with_mese"] = "mese"
ore_list["default:stone_with_diamond"] = "diamond"
ore_list["default:obsidian"] = "obsidian"
local ore_stones = { "default:stone_with_coal",
"default:stone_with_iron",
"default:stone_with_copper",
"default:stone_with_tin",
"default:stone_with_gold",
"default:stone_with_mese",
"default:stone_with_diamond",
"default:obsidian" }
if minetest.get_modpath("moreores") then
ore_list["moreores:mineral_silver"] = "silver"
ore_list["moreores:mineral_mithril"] = "mithril"
end
local ore_stones = {}
for i, _ in pairs(ore_list) do
ore_stones[#ore_stones + 1] = i
ore_stones[#ore_stones + 1] = "moreores:mineral_silver"
ore_stones[#ore_stones + 1] = "moreores:mineral_mithril"
end
-- scan for ores with center at current player position
function mineralscanner.scan_for_minerals(itemstack, user, pointed_thing)
local player_name = user:get_player_name()
local player_pos = vector.round(user:getpos())
local minerals = minertools.area_mineral_scan(player_pos, scan_range, ore_stones)
local oremsg = ""
for orenode, orecount in pairs(minerals) do
local oms = 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 .. "[MineralScanner]" .. msg_white ..
" Scan results for cubic range " .. scan_range ..
" : " .. oremsg .. msg_white)
minertools.mineralscanner_use("MineralScanner", player_name, player_pos,
scan_range, ore_stones)
return nil
end
function mineralscanner.change_scan_range(itemstack, user_placer, pointed_thing)
local player_name = user_placer:get_player_name()
minertools.play_click(player_name)
scan_range = scan_range - 1
if scan_range == 0 then
scan_range = scan_range_max
end
minetest.chat_send_player(player_name,
msg_yellow .. "[MineralScanner]" .. msg_white ..
" Scan range set to " .. msg_zero .. scan_range ..
msg_white)
scan_range = minertools.mineralscanner_switch_range("MineralScanner",
player_name, scan_range_min, scan_range_max, scan_range)
return nil
end

View File

@ -1,7 +1,7 @@
--[[
Portable Mineral Computer aka PMC v1.0
Portable Mineral Computer aka PMC v2.0
This is all-in-one device that provides functionality
of geothermometer, mineral scanner and mineral finder.
@ -9,6 +9,9 @@
by dedicated Mining Chip. Thanks to this, although
in one box, there is no signal loss or decreased range.
Technical info:
3 devices combined into one with no modifications
Left click - scan and show results
Right click - change scan range/searched ore
Double right click - change device mode
@ -32,48 +35,23 @@ local scan_range_min = 1
local scan_range_max = 8
local scan_range = scan_range_max
local find_range = 5
local find_stone_idx = 1
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"
local last_rclick_ts = 0
local find_ore_stones = { "default:stone_with_coal",
"default:stone_with_iron",
"default:stone_with_copper",
"default:stone_with_tin",
"default:stone_with_gold",
"default:stone_with_mese",
"default:stone_with_diamond" }
if minetest.get_modpath("moreores") then
find_ore_list["moreores:mineral_silver"] = "silver"
find_ore_list["moreores:mineral_mithril"] = "mithril"
find_ore_stones[#find_ore_stones + 1] = "moreores:mineral_silver"
find_ore_stones[#find_ore_stones + 1] = "moreores:mineral_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()
local scan_ore_stones = table.copy(find_ore_stones)
scan_ore_stones[#scan_ore_stones + 1] = "default:obsidian"
-- activate device function
function pmc.use(itemstack, user, pointed_thing)
@ -82,62 +60,18 @@ function pmc.use(itemstack, user, pointed_thing)
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)
minertools.geothermometer_use("PMC:Geothermometer", player_name,
node_pos, temp_range, temp_scale)
elseif mode == MODE_OREFIND then
local head_pos = vector.add(vector.round(user:getpos()), head_vec)
local head_pos = vector.add(player_pos, minertools.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)
minertools.mineralfinder_use("PMC:MineralFinder", player_name,
head_pos, look_dir, find_range,
find_ore_stones[find_stone_idx])
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)
minertools.mineralscanner_use("PMC:MineralScanner", player_name,
player_pos, scan_range,
scan_ore_stones)
end
return nil
end
@ -146,53 +80,32 @@ 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
if rclick_ts - last_rclick_ts < minertools.dbl_click_us then
-- mode change
minertools.play_click(player_name)
mode = ((mode + 1) % 3) + 1
mode = ((mode + 1) % #mode_name) + 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)
minertools.computer_mode_change_notify("PMC", player_name,
mode_name[mode])
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)
find_stone_idx = 1
minertools.print_mineral_type_set_to("PMC:MineralFinder",
player_name, find_ore_stones[find_stone_idx])
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)
minertools.print_scan_range_set_to("PMC:MineralScanner",
player_name, scan_range)
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)
find_stone_idx = minertools.mineralfinder_switch_ore(
"PMC:MineralFinder", player_name,
find_ore_stones, find_stone_idx)
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)
scan_range = minertools.mineralscanner_switch_range(
"PMC:MineralScanner", player_name,
scan_range_min, scan_range_max, scan_range)
end
end
last_rclick_ts = rclick_ts

View File

@ -1,7 +1,7 @@
--[[
Ultimate Mining Gizmo aka UMG v1.0
Ultimate Mining Gizmo aka UMG v2.0
This amazing device is an enhanced version of AMA.
Ranges and sensivity are increased again, now thanks
@ -10,6 +10,14 @@
Chip.
Operational actions remain identical to PMC and AMA.
Technical differences to AMA:
* increased tool range
* increased MineralFinder range
* increased MineralScanner range
* increased Geothermometer sensivity range
* increased Geothermometer display precision
* MS signal strength (in percent) indicates distance to ore
Left click - scan and show results
Right click - change scan range/searched ore
Double right click - change device mode
@ -33,51 +41,23 @@ local scan_range_min = 1
local scan_range_max = 16
local scan_range = scan_range_max
local find_range = 12
local find_stone_idx = 1
local temp_range = 16
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 msg_high = minetest.get_color_escape_sequence("#52D017")
local msg_medium = minetest.get_color_escape_sequence("#EAC117")
local msg_low = minetest.get_color_escape_sequence("#E56717")
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"
local last_rclick_ts = 0
local find_ore_stones = { "default:stone_with_coal",
"default:stone_with_iron",
"default:stone_with_copper",
"default:stone_with_tin",
"default:stone_with_gold",
"default:stone_with_mese",
"default:stone_with_diamond" }
if minetest.get_modpath("moreores") then
find_ore_list["moreores:mineral_silver"] = "silver"
find_ore_list["moreores:mineral_mithril"] = "mithril"
find_ore_stones[#find_ore_stones + 1] = "moreores:mineral_silver"
find_ore_stones[#find_ore_stones + 1] = "moreores:mineral_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()
local scan_ore_stones = table.copy(find_ore_stones)
scan_ore_stones[#scan_ore_stones + 1] = "default:obsidian"
-- activate device function
function umg.use(itemstack, user, pointed_thing)
@ -86,71 +66,19 @@ function umg.use(itemstack, user, pointed_thing)
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 .. "[UMG:Geothermometer]" ..
msg_white ..
" Temperature gradient for this block is " ..
msg_val_clr ..
string.format("%+.6f", temp_scale * temp_var) ..
msg_white)
minertools.geothermometer_use("UMG:Geothermometer", player_name,
node_pos, temp_range, temp_scale,
"%+.6f")
elseif mode == MODE_OREFIND then
local head_pos = vector.add(vector.round(user:getpos()), head_vec)
local head_pos = vector.add(player_pos, minertools.head_vec)
local look_dir = user:get_look_dir()
local orecount, obsblock, oredepth =
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 oredepth > 0 then
oremsg = oremsg .. msg_white .. " (signal strength: "
local sigpct = 100.0 * (find_range - oredepth + 1) / find_range
if sigpct >= 75 then oremsg = oremsg .. msg_high
elseif sigpct < 25 then oremsg = oremsg .. msg_low
else oremsg = oremsg .. msg_medium end
oremsg = oremsg .. string.format("%d%%", sigpct) ..
msg_white .. ")"
end
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 .. "[UMG:MineralFinder]" .. msg_white ..
" Scan result for " .. msg_zero ..
find_ore_list[find_ore_stones[cur_stone_idx]] ..
msg_white .. " : " ..
oremsg .. msg_white)
minertools.mineralfinder_use("UMG:MineralFinder", player_name,
head_pos, look_dir, find_range,
find_ore_stones[find_stone_idx], 2)
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 .. "[UMG:MineralScanner]" .. msg_white ..
" Scan results for cubic range " .. scan_range ..
" : " .. oremsg .. msg_white)
minertools.mineralscanner_use("UMG:MineralScanner", player_name,
player_pos, scan_range,
scan_ore_stones)
end
return nil
end
@ -159,53 +87,32 @@ function umg.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
if rclick_ts - last_rclick_ts < minertools.dbl_click_us then
-- mode change
minertools.play_click(player_name)
mode = ((mode + 1) % 3) + 1
mode = ((mode + 1) % #mode_name) + 1
minetest.override_item("minertools:ultimate_mining_gizmo",
{range = tool_range[mode]})
minetest.chat_send_player(player_name,
msg_yellow .. "[UMG]" .. msg_white ..
" Switching mode to " .. msg_yellow ..
mode_name[mode] .. msg_white)
minertools.computer_mode_change_notify("UMG", player_name,
mode_name[mode])
if mode == MODE_OREFIND then
cur_stone_idx = def_stone_idx
minetest.chat_send_player(player_name,
msg_yellow .. "[UMG:MineralFinder]" .. msg_white ..
" Mineral type is now " .. msg_zero ..
find_ore_list[find_ore_stones[cur_stone_idx]] ..
msg_white)
-- UMG remembers settings, do not reset ore
minertools.print_mineral_type_is_now("UMG:MineralFinder",
player_name, find_ore_stones[find_stone_idx])
elseif mode == MODE_ORESCAN then
scan_range = scan_range_max
minetest.chat_send_player(player_name,
msg_yellow .. "[UMG:MineralScanner]" ..
msg_white .. " Scan range is now "
.. msg_zero .. scan_range .. msg_white)
-- UMG remembers settings, do not reset range
minertools.print_scan_range_is_now("UMG:MineralScanner",
player_name, scan_range)
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 .. "[UMG:MineralFinder]" .. msg_white ..
" Mineral type set to " .. msg_zero ..
find_ore_list[find_ore_stones[cur_stone_idx]] ..
msg_white)
find_stone_idx = minertools.mineralfinder_switch_ore(
"UMG:MineralFinder", player_name,
find_ore_stones, find_stone_idx)
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 .. "[UMG:MineralScanner]" .. msg_white ..
" Scan range set to " .. msg_zero .. scan_range ..
msg_white)
scan_range = minertools.mineralscanner_switch_range(
"AMA:MineralScanner", player_name,
scan_range_min, scan_range_max, scan_range)
end
end
last_rclick_ts = rclick_ts