OreTracker/init.lua

164 lines
6.5 KiB
Lua
Raw Normal View History

2021-10-07 21:05:59 +02:00
-- https://rubenwardy.com/minetest_modding_book/en/map/environment.html#finding-nodes
-- A public API
oretracker = {}
oretracker.S = minetest.get_translator("oretracker")
oretracker.modpath = minetest.get_modpath("oretracker")
oretracker.store = minetest.get_mod_storage()
-- Settings
-- Do not set detect_range to a very high number it may cause extreme loads when there are multiple players with this range
-- Recommended range is 8 blocks
oretracker.detect_range = 8 -- Range in blocks
-- The prefered fastest is 1 second, 0 or negative is instantanious updates (Which greatly impacts the server/client)
-- Recommended default is 3 seconds.
oretracker.scan_frequency = 3 -- Frequency in seconds
-- This attempts to detect the gamemode
if not minetest.registered_nodes["default:stone"] then
if not minetest.registered_nodes["mcl_core:stone"] then
oretracker.gamemode = "N/A"
else
oretracker.gamemode = "MCL"
-- Attempt to determine if it's MCL5 or MCL2
if not minetest.registered_nodes["mcl_nether:ancient_debris"] then
oretracker.gamemode = "MCL2"
else
oretracker.gamemode = "MCL5"
end
end
else
oretracker.gamemode = "MTG"
end
minetest.log("action", "[oretracker] Detected game "..oretracker.gamemode..".")
-- Form a container to track what ores we want to follow
oretracker.ores = {}
dofile(oretracker.modpath .. "/api.lua")
-- Use api to assign ores we know/should be caring about
if oretracker.gamemode == "MCL2" or oretracker.gamemode == "MCL5" then
oretracker.add_ore("mcl_core:stone_with_coal")
oretracker.add_ore("mcl_core:stone_with_iron")
oretracker.add_ore("mcl_core:stone_with_gold")
oretracker.add_ore("mcl_core:stone_with_redstone")
oretracker.add_ore("mcl_core:stone_with_redstone_lit")
oretracker.add_ore("mcl_core:stone_with_lapis")
oretracker.add_ore("mcl_core:stone_with_emerald")
oretracker.add_ore("mcl_core:stone_with_diamond")
oretracker.add_ore("mcl_nether:quartz_ore") -- This fails on MCL2 :S
-- oretracker.add_ore("mcl_nether:glowstone") -- Same here, though by default this is disabled as glowstone isn't a "ore"
end
if oretracker.gamemode == "MCL5" then
oretracker.add_ore("mcl_copper:stone_with_copper")
oretracker.add_ore("mcl_nether:ancient_debris")
oretracker.add_ore("mcl_nether_gold:nether_gold_ore")
end
if oretracker.gamemode == "MTG" then
oretracker.add_ore("default:stone_with_coal")
oretracker.add_ore("default:stone_with_iron")
oretracker.add_ore("default:stone_with_gold")
oretracker.add_ore("default:stone_with_copper")
oretracker.add_ore("default:stone_with_tin")
oretracker.add_ore("default:stone_with_mese")
oretracker.add_ore("default:stone_with_diamond")
end
local size = 0
local result = "Ores: "
for i, v in ipairs(oretracker.ores) do
result = result..v.." "
size = size + 1
end
minetest.log("action", "[oretracker] Found "..size.." ores configured.")
minetest.log("action", "[oretracker] "..result)
-- Now to add the tracker notification system
oretracker.check_player = function(player)
local p = player
if not minetest.is_player(p) then
p = minetest.get_player_by_name(p)
end
local pos = p:get_pos()
local pname = p:get_player_name()
-- I need to clean up the player's ore waypoints added by the latter code
oretracker.clear_pos(pname)
local p1 = vector.subtract(pos, {x = oretracker.detect_range, y = oretracker.detect_range, z = oretracker.detect_range})
local p2 = vector.add(pos, {x = oretracker.detect_range, y = oretracker.detect_range, z = oretracker.detect_range})
local area = minetest.find_nodes_in_area(p1, p2, oretracker.ores)
for i=1, #area do
local node = minetest.get_node_or_nil(area[i])
if node == nil then
minetest.log("action", "[oretracker] Failed to obtain node at "..minetest.pos_to_string(area[1], 1)..".")
else
local delta = vector.subtract(area[i], pos)
local distance = (delta.x*delta.x) + (delta.y*delta.y) + (delta.z*delta.z)
if distance <= oretracker.detect_range*oretracker.detect_range then
distance = string.format("%.0f", math.sqrt(distance))
local block = "?"
local color = 0xffffff
if string.find(node.name, "coal") then
block = "Coa"
color = 0xc8c8c8
elseif string.find(node.name, "iron") then
block = "Iro"
color = 0xaf644b
elseif string.find(node.name, "gold") then
block = "Gol"
color = 0xc8c84b
elseif string.find(node.name, "mese") then
block = "Mes"
color = 0xffff4b
elseif string.find(node.name, "diamond") then
block = "Dia"
color = 0x4bfafa
elseif string.find(node.name, "quartz") then
block = "Qua"
color = 0xc8c8c8
elseif string.find(node.name, "copper") then
block = "Cop"
color = 0xc86400
elseif string.find(node.name, "tin") then
block = "Tin"
color = 0xc8c8c8
elseif string.find(node.name, "debris") then
block = "Deb"
color = 0xaa644b
elseif string.find(node.name, "lapis") then
block = "Lap"
color = 0x4b4bc8
elseif string.find(node.name, "redstone") then
block = "Red"
color = 0xc81919
elseif string.find(node.name, "glowstone") then
block = "Glo"
color = 0xffff4b
end
if block == "?" then
minetest.log("action", "[oretracker] Found '"..node.name.."' at "..minetest.pos_to_string(area[i], 1).." which is "..distance.." away from '"..pname..".")
block = node.name
end
-- Make a waypoint with the nodes name
oretracker.add_pos(pname, area[i], block, color)
end
end
end
end
local interval = 0
minetest.register_globalstep(function(dtime)
interval = interval - dtime
if interval <= 0 then
for _, player in ipairs(minetest.get_connected_players()) do
oretracker.check_player(player)
end
interval = oretracker.scan_frequency
end
end)