minertools: common code moved to functions.lua.
functions.lua file contains functions planned for reuse with coming all-in-one devices. Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
This commit is contained in:
parent
cc503d5663
commit
b6933064a9
157
minertools/functions.lua
Normal file
157
minertools/functions.lua
Normal file
@ -0,0 +1,157 @@
|
||||
|
||||
--[[
|
||||
|
||||
Common functions for devices in this mod.
|
||||
|
||||
]]--
|
||||
|
||||
minertools = {}
|
||||
|
||||
-- ******************
|
||||
-- Play sound effects
|
||||
-- ******************
|
||||
|
||||
function minertools.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)
|
||||
minetest.sound_play("minertools_beep_err", {
|
||||
to_player = player_name,
|
||||
gain = 0.5,
|
||||
})
|
||||
end
|
||||
|
||||
function minertools.play_scan(player_name)
|
||||
minetest.sound_play("minertools_scan", {
|
||||
to_player = player_name,
|
||||
gain = 0.8,
|
||||
})
|
||||
end
|
||||
|
||||
function minertools.play_click(player_name)
|
||||
minetest.sound_play("minertools_click", {
|
||||
to_player = player_name,
|
||||
gain = 0.6,
|
||||
})
|
||||
end
|
||||
|
||||
function minertools.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)
|
||||
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
|
||||
if minetest.get_item_group(name, "stone") > 0 then return true end
|
||||
if string.match(name, "^default:stone_with_") then return true end
|
||||
if name == "default:gravel"
|
||||
or name == "default:clay" then return true end
|
||||
if minetest.get_modpath("moreores") then
|
||||
if string.match(name, "^moreores:mineral_") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- check if node is made of obsidian
|
||||
function minertools.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
|
||||
if string.match(name, "^stairs:stair_obsidian") or
|
||||
string.match(name, "^stairs:slab_obsidian") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- ************
|
||||
-- Calculations
|
||||
-- ************
|
||||
|
||||
-- calculate relative temperature (aka gradient based on thermal sources nearby)
|
||||
-- return: temperature gradient
|
||||
function minertools.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)
|
||||
local water = minetest.find_nodes_in_area(scan_pos1, scan_pos2,
|
||||
{ "group:water" })
|
||||
local lava = minetest.find_nodes_in_area(scan_pos1, scan_pos2,
|
||||
{ "group:lava" })
|
||||
local temp_var = 0.0
|
||||
for _, v in ipairs(water) do
|
||||
local vd = vector.distance(pos, v)
|
||||
if vd <= radius then
|
||||
temp_var = temp_var - 1 / ( vd * vd )
|
||||
end
|
||||
end
|
||||
for _, v in ipairs(lava) do
|
||||
local vd = vector.distance(pos, v)
|
||||
if vd <= radius then
|
||||
temp_var = temp_var + 1 / ( vd * vd )
|
||||
end
|
||||
end
|
||||
return temp_var
|
||||
end
|
||||
|
||||
-- directional scan for specified mineral
|
||||
-- parameters: pos - device position (vector)
|
||||
-- range - scan depth (float)
|
||||
-- look_dir - direction of looking (normalized vector)
|
||||
-- name - ore to search for (string)
|
||||
-- return: mineral count, blocked by obsidian true/false
|
||||
function minertools.dir_mineral_scan(pos, range, look_dir, name)
|
||||
local node = {}
|
||||
local pos_vec = {}
|
||||
local last_vec = nil
|
||||
local orecount = 0
|
||||
local obsblock = false
|
||||
for i = 1, range, 1 do
|
||||
pos_vec = vector.add(pos, vector.round(vector.multiply(look_dir, i)))
|
||||
if not last_vec or not vector.equals(pos_vec, last_vec) then
|
||||
node = minetest.get_node_or_nil(pos_vec)
|
||||
if node then
|
||||
if node.name == name then
|
||||
orecount = orecount + 1
|
||||
elseif minertools.has_obsidian(node.name) then
|
||||
obsblock = true
|
||||
break
|
||||
end
|
||||
end
|
||||
last_vec = pos_vec -- protects against double count
|
||||
end
|
||||
end
|
||||
return orecount, obsblock
|
||||
end
|
||||
|
||||
-- scan for ores in cubic area
|
||||
-- parameters: pos - device position (vector)
|
||||
-- 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 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)
|
||||
local _, minerals = minetest.find_nodes_in_area(scan_pos1, scan_pos2, nodes)
|
||||
return minerals
|
||||
end
|
||||
|
@ -32,74 +32,17 @@ 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")
|
||||
|
||||
-- ****************
|
||||
-- Helper functions
|
||||
-- ****************
|
||||
|
||||
-- check if node is of type that device can scan
|
||||
-- (only nodes of natural origin can be analyzed properly)
|
||||
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
|
||||
if minetest.get_item_group(name, "stone") > 0 then return true end
|
||||
if string.match(name, "^default:stone_with_") then return true end
|
||||
if name == "default:gravel"
|
||||
or name == "default:clay" then return true end
|
||||
if minetest.get_modpath("moreores") then
|
||||
if string.match(name, "^moreores:mineral_") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- produce sounds
|
||||
local function beep_ok(player_name)
|
||||
minetest.sound_play("minertools_beep_ok", {
|
||||
to_player = player_name,
|
||||
gain = 0.8,
|
||||
})
|
||||
end
|
||||
|
||||
local function beep_err(player_name)
|
||||
minetest.sound_play("minertools_beep_err", {
|
||||
to_player = player_name,
|
||||
gain = 0.5,
|
||||
})
|
||||
end
|
||||
|
||||
-- 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 is_mineral(minetest.get_node(node_pos).name) then
|
||||
beep_err(player_name)
|
||||
if not minertools.is_mineral(minetest.get_node(node_pos).name) then
|
||||
minertools.play_beep_err(player_name)
|
||||
return nil
|
||||
end
|
||||
local scan_vec = vector.new({x = scan_range, y = scan_range,
|
||||
z = scan_range})
|
||||
local scan_pos1 = vector.subtract(node_pos, scan_vec)
|
||||
local scan_pos2 = vector.add(node_pos, scan_vec)
|
||||
local water = minetest.find_nodes_in_area(scan_pos1, scan_pos2,
|
||||
{ "group:water" })
|
||||
local lava = minetest.find_nodes_in_area(scan_pos1, scan_pos2,
|
||||
{ "group:lava" })
|
||||
local temp_var = 0.0
|
||||
for _, v in ipairs(water) do
|
||||
local vd = vector.distance(node_pos, v)
|
||||
if vd <= scan_range then
|
||||
temp_var = temp_var - 1 / ( vd * vd )
|
||||
end
|
||||
end
|
||||
for _, v in ipairs(lava) do
|
||||
local vd = vector.distance(node_pos, v)
|
||||
if vd <= scan_range then
|
||||
temp_var = temp_var + 1 / ( vd * vd )
|
||||
end
|
||||
end
|
||||
beep_ok(player_name)
|
||||
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
|
||||
|
@ -1,6 +1,7 @@
|
||||
-- This mod adds Miner's Electronic Tools
|
||||
-- (c) Micu 2018
|
||||
|
||||
dofile(minetest.get_modpath("minertools").."/functions.lua")
|
||||
dofile(minetest.get_modpath("minertools").."/mining_chip.lua")
|
||||
dofile(minetest.get_modpath("minertools").."/geothermometer.lua")
|
||||
dofile(minetest.get_modpath("minertools").."/mineralscanner.lua")
|
||||
|
@ -53,63 +53,14 @@ for i, _ in pairs(ore_list) do
|
||||
end
|
||||
local head_vec = vector.new({x = 0, y = 1, z = 0})
|
||||
|
||||
-- ****************
|
||||
-- Helper functions
|
||||
-- ****************
|
||||
|
||||
-- produce sound
|
||||
local function sound_pulse(player_name)
|
||||
minetest.sound_play("minertools_pulse", {
|
||||
to_player = player_name,
|
||||
gain = 0.8,
|
||||
})
|
||||
end
|
||||
|
||||
local function sound_click(player_name)
|
||||
minetest.sound_play("minertools_click", {
|
||||
to_player = player_name,
|
||||
gain = 0.6,
|
||||
})
|
||||
end
|
||||
|
||||
-- check if node includes obsidian
|
||||
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
|
||||
if string.match(name, "^stairs:stair_obsidian") or
|
||||
string.match(name, "^stairs:slab_obsidian") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- 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 look_dir = user:get_look_dir() -- normalized vec (x,y,z = -1..1)
|
||||
local node = {}
|
||||
local pos_vec = {}
|
||||
local last_vec = nil
|
||||
local orecount = 0
|
||||
local obsblock = false
|
||||
for i = 1, scan_range, 1 do
|
||||
pos_vec = vector.add(head_pos, vector.round(vector.multiply(look_dir, i)))
|
||||
if not last_vec or not vector.equals(pos_vec, last_vec) then
|
||||
node = minetest.get_node_or_nil(pos_vec)
|
||||
if node then
|
||||
if node.name == ore_stones[cur_stone_idx] then
|
||||
orecount = orecount + 1
|
||||
elseif has_obsidian(node.name) then
|
||||
obsblock = true
|
||||
break
|
||||
end
|
||||
end
|
||||
last_vec = pos_vec -- protects against double count
|
||||
end
|
||||
end
|
||||
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
|
||||
@ -118,7 +69,7 @@ function mineralfinder.scan_for_mineral(itemstack, user, pointed_thing)
|
||||
oremsg = oremsg .. msg_warn ..
|
||||
" (warning - scan incomplete, blocked by obsidian)"
|
||||
end
|
||||
sound_pulse(player_name)
|
||||
minertools.play_pulse(player_name)
|
||||
minetest.chat_send_player(player_name,
|
||||
msg_yellow .. "[MineralFinder]" .. msg_white ..
|
||||
" Scan result for " .. msg_zero ..
|
||||
@ -130,7 +81,7 @@ end
|
||||
|
||||
function mineralfinder.change_mineral_type(itemstack, user_placer, pointed_thing)
|
||||
local player_name = user_placer:get_player_name()
|
||||
sound_click(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
|
||||
|
@ -43,34 +43,11 @@ for i, _ in pairs(ore_list) do
|
||||
ore_stones[#ore_stones + 1] = i
|
||||
end
|
||||
|
||||
-- ****************
|
||||
-- Helper functions
|
||||
-- ****************
|
||||
|
||||
-- produce sound
|
||||
local function sound_scan(player_name)
|
||||
minetest.sound_play("minertools_scan", {
|
||||
to_player = player_name,
|
||||
gain = 0.8,
|
||||
})
|
||||
end
|
||||
|
||||
local function sound_range(player_name)
|
||||
minetest.sound_play("minertools_click", {
|
||||
to_player = player_name,
|
||||
gain = 0.6,
|
||||
})
|
||||
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 scan_vec = vector.new({x = scan_range, y = scan_range,
|
||||
z = scan_range})
|
||||
local scan_pos1 = vector.subtract(player_pos, scan_vec)
|
||||
local scan_pos2 = vector.add(player_pos, scan_vec)
|
||||
local _, minerals = minetest.find_nodes_in_area(scan_pos1, scan_pos2, ore_stones)
|
||||
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
|
||||
@ -82,7 +59,7 @@ function mineralscanner.scan_for_minerals(itemstack, user, pointed_thing)
|
||||
oremsg = oms
|
||||
end
|
||||
end
|
||||
sound_scan(player_name)
|
||||
minertools.play_scan(player_name)
|
||||
minetest.chat_send_player(player_name,
|
||||
msg_yellow .. "[MineralScanner]" .. msg_white ..
|
||||
" Scan results for cubic range " .. scan_range ..
|
||||
@ -92,7 +69,7 @@ end
|
||||
|
||||
function mineralscanner.change_scan_range(itemstack, user_placer, pointed_thing)
|
||||
local player_name = user_placer:get_player_name()
|
||||
sound_range(player_name)
|
||||
minertools.play_click(player_name)
|
||||
scan_range = scan_range - 1
|
||||
if scan_range == 0 then
|
||||
scan_range = scan_range_max
|
||||
|
Loading…
x
Reference in New Issue
Block a user