This repository has been archived on 2020-05-24. You can view files and clone it, but cannot push or open issues or pull requests.
minetest-mod-sparktech/sparktool/lua/scanner.lua

196 lines
5.0 KiB
Lua

local NAME = minetest.get_current_modname()
local players_scanning = {}
local players_hud = {}
local RADIUS = 7
local USAGE = 2
local SPEED = 0.4
local CAPACITY = 500
-- Returns an iterator over the sorted keys
-- or if the ord_fun is given, ordered by the ord_fun
-- ord_fun takes a table and two keys a and b
-- and should return a boolean whether a < b
local function sorted_pairs(tab, ord_fun)
local sorted_keys = {}
for k, _ in pairs(tab) do
sorted_keys[#sorted_keys + 1] = k
end
if ord_fun then
table.sort(sorted_keys, function (a, b)
return ord_fun(tab, a, b)
end)
else
table.sort(sorted_keys)
end
local i = 0
return function()
i = i + 1
return sorted_keys[i], tab[sorted_keys[i]]
end
end
local function scan(pos, radius)
local found = {}
local low = math.floor(radius / 2)
for x_d = -low,radius-low-1 do
for y_d = -low,radius-low-1 do
for z_d = -low,radius-low-1 do
local name = minetest.get_node({
x = pos.x + x_d,
y = pos.y + y_d,
z = pos.z + z_d
}).name
found[name] = (found[name] or 0) + 1
end
end
end
found.air = nil
found.ignore = nil
return found
end
local function use_fun(itemstack, user, pointed_thing)
local name = user:get_player_name()
if players_scanning[name] ~= nil then
players_scanning[name] = nil
local hud_num = players_hud[name]
if hud_num then
user:hud_change(hud_num, "text", "")
end
--minetest.chat_send_player(name, "Disabled scanner.")
else
players_scanning[name] = {}
--minetest.chat_send_player(name, "Enabled scanner.")
end
return itemstack
end
local total_time = 0
minetest.register_globalstep(function (dtime)
total_time = total_time + dtime
if total_time >= SPEED then
total_time = 0
for name, last in pairs(players_scanning) do
if last ~= nil then
local player = minetest.get_player_by_name(name)
if player == nil then
players_scanning[name] = nil
players_hud[name] = nil
return
end
local inv = player:get_inventory()
local index
for i, e in ipairs(inv:get_list("main")) do
if e:get_name() == NAME .. ":scanner" and e:get_meta():get_int("energy") >= USAGE then
index = i
break
end
end
local hud_num = players_hud[name]
if index == nil then
--minetest.chat_send_player(name, "Scanner disabled due to lack of energy or Scanner.")
player:hud_change(hud_num, "text", "")
players_scanning[name] = nil
return
end
local stack = inv:get_stack("main", index, ItemStack(NAME .. ":scanner"))
local meta = stack:get_meta()
local energy = meta:get_int("energy")
meta:set_int("energy", energy - USAGE)
inv:set_stack("main", index, stack:get_definition()._sparktech_update_energy(stack))
local new = scan(player:get_pos(), RADIUS)
local hud_s = ""
-- for oname, ocount in pairs(last) do
-- if new[oname] == nil then
-- minetest.chat_send_player(name, "Lost " .. oname)
-- end
-- end
for nname, ncount in sorted_pairs(new, function (t, a, b)
if t[a] == t[b] then
return a > b
else
return t[a] > t[b]
end
end) do
local desc = minetest.registered_nodes[nname].description
if desc == "" then
desc = nname
end
hud_s = hud_s .. "\n" .. ncount .. " " .. desc
-- if last[nname] ~= ncount then
-- minetest.chat_send_player(name, "Found " .. nname .. " count: " .. tostring(ncount))
-- end
end
if hud_num then
player:hud_change(hud_num, "text", hud_s)
end
players_scanning[name] = new
end
end
end
end)
minetest.register_on_joinplayer(function(player)
players_hud[player:get_player_name()] = player:hud_add({
hud_elem_type = "text",
scale = {
x = 100,
y = 100
},
text = "",
number = 0xFFFFFF,
alignment = -1,
position = {
x = 0.1,
y = 0.9
}
})
end)
minetest.register_tool(NAME .. ":scanner", {
description = "Scanner",
inventory_image = "scanner.png",
stack_max = 1,
on_place = use_fun,
on_secondary_use = use_fun,
groups = {
sparktech_chargable = CAPACITY
},
_sparktech_update_energy = function (itemstack)
local meta = itemstack:get_meta()
local c = meta:get_int("energy") or 0
if c <= 0 then
itemstack:set_wear(65535)
return itemstack
end
itemstack:set_wear(65535 - math.ceil(c / CAPACITY * 65535))
return itemstack
end
})
minetest.register_craft({
output = NAME .. ":scanner",
recipe = {
{ "default:gold_ingot", "default:copper_ingot", "default:mese_crystal" },
{ "group:steel_plate", "xpanes:obsidian_pane_flat", "group:steel_plate" },
{ "", "group:steel_plate", "" }
}
})