working beacon and radar

master
Thomas Rudin 2018-05-29 15:30:37 +02:00
parent d19fe98f98
commit 19c249ec5b
4 changed files with 275 additions and 0 deletions

114
beacon.lua Normal file
View File

@ -0,0 +1,114 @@
local update_formspec = function(meta)
local inv = meta:get_inventory()
local active = meta:get_int("active") == 1
local state = "Inactive"
if active then
state = "Active"
end
local name = meta:get_string("name")
meta:set_string("infotext", "Locator: " .. name .. " (" .. state .. ")")
meta:set_string("formspec", "size[8,3;]" ..
-- col 1
"field[0,1.5;4,1;name;Name;" .. name .. "]" ..
"button_exit[4,1;4,1;save;Save]" ..
"button_exit[0,2;8,1;toggle;Toggle]" ..
"")
end
-- base beacon
minetest.register_node("locator:beacon_base", {
description = "Locator beacon base",
tiles = {
"locator_beacon_base.png",
"locator_beacon_base.png",
"locator_beacon_base.png",
"locator_beacon_base.png",
"locator_beacon_base.png",
"locator_beacon_base.png",
},
groups = {cracky=3,oddly_breakable_by_hand=3},
sounds = default.node_sound_glass_defaults()
})
-- level/range register beacon
local register_beacon = function(level, range)
minetest.register_node("locator:beacon_" .. level, {
description = "Locator beacon, level: " .. level .. ", range: " .. range,
tiles = {
"locator_beacon_level" .. level .. ".png",
"locator_beacon_level" .. level .. ".png",
"locator_beacon_level" .. level .. ".png",
"locator_beacon_level" .. level .. ".png",
"locator_beacon_level" .. level .. ".png",
"locator_beacon_level" .. level .. ".png"
},
groups = {cracky=3,oddly_breakable_by_hand=3},
sounds = default.node_sound_glass_defaults(),
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
end,
on_dig = function(pos)
locator.remove_beacon(pos)
return true
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("name", "<unconfigured>")
meta:set_int("range", range)
meta:set_int("active", 0)
update_formspec(meta)
end,
on_receive_fields = function(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
local playername = sender:get_player_name()
if playername == meta:get_string("owner") then
-- owner
if fields.save then
local name = fields.name
meta:set_string("name", fields.name)
end
if fields.toggle then
if meta:get_int("active") == 1 then
meta:set_int("active", 0)
else
meta:set_int("active", 1)
end
end
else
-- non-owner
end
update_formspec(meta)
locator.update_beacon(pos, meta)
end
})
end
register_beacon(1, 500) -- short range
register_beacon(2, 5000) -- mid range
register_beacon(3, 30000) -- long range

61
functions.lua Normal file
View File

@ -0,0 +1,61 @@
local path = minetest.get_worldpath().."/locator_beacons.txt";
local load_beacons = function()
local file = io.open( path, "r" );
if( file ) then
local data = file:read("*all");
locator.beacons = minetest.deserialize( data );
file:close();
else
print("[Mod locator] Warning: Savefile '"..tostring( path ).."' not found.");
end
end
load_beacons()
local save_beacons = function()
local file = io.open( path, "w" );
if( file ) then
file:write( minetest.serialize(locator.beacons) );
file:close();
else
print("[Mod locator] Error: Savefile '"..tostring( path ).."' could not be written.");
end
end
locator.update_beacon = function(pos, meta)
local active = meta:get_int("active") == 1
local name = meta:get_string("name")
local range = meta:get_int("range")
local found = false
local data = { pos=pos, active=active, name=name, range=range }
for i,beacon in pairs(locator.beacons) do
if beacon.pos.x == pos.x and beacon.pos.y == pos.y and beacon.pos.z == pos.z then
-- found
locator.beacons[i] = data
found = true
end
end
if not found then
-- new entry
table.insert(locator.beacons, data)
end
save_beacons()
end
locator.remove_beacon = function(pos)
for i,beacon in pairs(locator.beacons) do
if beacon.pos.x == pos.x and beacon.pos.y == pos.y and beacon.pos.z == pos.z then
-- found
table.remove(locator.beacons, i)
save_beacons()
return
end
end
end

View File

@ -0,0 +1,12 @@
local MP = minetest.get_modpath("locator")
locator = {
beacons = {}
}
dofile(MP.."/beacon.lua")
dofile(MP.."/functions.lua")
dofile(MP.."/radar.lua")
print("[OK] Locator")

88
radar.lua Normal file
View File

@ -0,0 +1,88 @@
local update_formspec = function(meta)
local inv = meta:get_inventory()
meta:set_string("formspec", "size[8,3;]" ..
-- col 1
"button_exit[0,1;8,1;sweep;Radar sweep]" ..
"")
end
local hud = {} -- playername -> {}
local clear_radar = function(playername)
local hud_data = hud[playername]
local player = minetest.get_player_by_name(playername)
if not hud_data or not player or not player:is_player() then
return
end
for _,id in pairs(hud_data) do
player:hud_remove(id)
end
hud[playername] = nil
end
local show_radar = function(pos, player)
local name = player:get_player_name()
local hud_data = hud[name]
if hud_data then
-- already active hud
return
end
hud_data = {}
for i,beacon in pairs(locator.beacons) do
local distance = vector.distance(pos, beacon.pos)
if distance < beacon.range then
-- in range
local id = player:hud_add({
hud_elem_type = "waypoint",
name = "Beacon: " .. beacon.name,
text = "m",
number = 0x00FF00,
world_pos = beacon.pos
})
table.insert(hud_data, id)
end
end
hud[name] = hud_data;
minetest.after(10, function()
clear_radar(name)
end)
end
-- locator radar
minetest.register_node("locator:radar", {
description = "Locator radar",
tiles = {
"locator_radar.png",
"locator_radar.png",
"locator_radar.png",
"locator_radar.png",
"locator_radar.png",
"locator_radar.png"
},
groups = {cracky=3,oddly_breakable_by_hand=3},
sounds = default.node_sound_glass_defaults(),
on_construct = function(pos)
local meta = minetest.get_meta(pos)
update_formspec(meta)
end,
on_receive_fields = function(pos, formname, fields, sender)
if fields.sweep then
show_radar(pos, sender)
end
end
})