286 lines
8.7 KiB
Lua
286 lines
8.7 KiB
Lua
local S = minetest.get_translator("sf_resources")
|
|
|
|
sf_resources = {}
|
|
|
|
-- Legacy support: Name of the HUD type field for 'hud_add'.
|
|
local hud_type_field_name
|
|
if minetest.features.hud_def_type_field then
|
|
-- Minetest 5.9.0 and later
|
|
hud_type_field_name = "type"
|
|
else
|
|
-- All Minetest versions before 5.9.0
|
|
hud_type_field_name = "hud_elem_type"
|
|
end
|
|
|
|
local GRAVITY = 9.81
|
|
local LIFE_TIMER = 300
|
|
local MAGNET_RANGE = 0.8
|
|
local HUD_SHOW_TIME = 5000000
|
|
local MAX_RESOURCES = 999
|
|
|
|
sf_resources.registered_resources = {}
|
|
local registered_resource_entities = {}
|
|
|
|
local registered_on_resource_changes = {}
|
|
|
|
local player_huds = {}
|
|
|
|
sf_resources.register_on_resource_change = function(func)
|
|
table.insert(registered_on_resource_changes, func)
|
|
end
|
|
|
|
local function report_resource_change(player, resource, count)
|
|
for i=1, #registered_on_resource_changes do
|
|
registered_on_resource_changes[i](player, resource, count)
|
|
end
|
|
end
|
|
|
|
sf_resources.register_resource = function(id, def)
|
|
sf_resources.registered_resources["sf_resources:"..id] = {
|
|
description = def.description,
|
|
texture = def.texture,
|
|
icon = def.icon or def.texture,
|
|
}
|
|
minetest.register_entity("sf_resources:"..id, {
|
|
initial_properties = {
|
|
pointable = false,
|
|
physical = true,
|
|
collide_with_objects = false,
|
|
visual = "sprite",
|
|
vertical = true,
|
|
textures = { def.texture },
|
|
use_texture_alpha = true,
|
|
visual_size = { x = 0.3, y = 0.3, z = 0.3 },
|
|
collisionbox = { -0.15, -0.15, -0.15, 0.15, 0.15, 0.15 },
|
|
selectionnbox = { -0.15, -0.15, -0.15, 0.15, 0.15, 0.15 },
|
|
},
|
|
_life_timer = 0,
|
|
_count = 1,
|
|
get_staticdata = function(self)
|
|
local tabl = {
|
|
life_timer = self._life_timer,
|
|
count = self._count,
|
|
}
|
|
return minetest.serialize(tabl)
|
|
end,
|
|
on_activate = function(self, staticdata)
|
|
local tabl = minetest.deserialize(staticdata)
|
|
if type(tabl) == "table" then
|
|
self._life_timer = tabl._life_timer or 0
|
|
self._count = tabl._count or 1
|
|
end
|
|
self.object:set_armor_groups({immortal=1})
|
|
self.object:set_acceleration({x=0,y=-GRAVITY,z=0})
|
|
end,
|
|
on_step = function(self, dtime, moveresult)
|
|
if moveresult and moveresult.collides then
|
|
if moveresult.touching_ground then
|
|
local vel = self.object:get_velocity()
|
|
vel.x = 0
|
|
vel.z = 0
|
|
self.object:set_velocity(vel)
|
|
end
|
|
end
|
|
if not def.never_despawns then
|
|
self._life_timer = self._life_timer + dtime
|
|
if self._life_timer > LIFE_TIMER then
|
|
self.object:remove()
|
|
return
|
|
end
|
|
end
|
|
end,
|
|
})
|
|
end
|
|
|
|
local collect_resource = function(player, resource_object)
|
|
local pmeta = player:get_meta()
|
|
local rname = resource_object:get_luaentity().name
|
|
local rcount_player = sf_resources.get_resource_count(player, rname)
|
|
local rcount_res = resource_object:get_luaentity()._count or 1
|
|
local newcount = rcount_player + rcount_res
|
|
sf_resources.set_resource_count(player, rname, newcount)
|
|
local rdesc = sf_resources.registered_resources[rname].description
|
|
minetest.sound_play({name="sf_resources_collect", gain=0.9}, {to_player=player:get_player_name()}, true)
|
|
resource_object:remove()
|
|
end
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
local players = minetest.get_connected_players()
|
|
for p=1, #players do
|
|
local player = players[p]
|
|
local objs = minetest.get_objects_inside_radius(player:get_pos(), MAGNET_RANGE)
|
|
for o=1, #objs do
|
|
local obj = objs[o]
|
|
local lua = obj:get_luaentity()
|
|
if lua and sf_resources.registered_resources[lua.name] then
|
|
collect_resource(player, obj)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
function sf_resources.spawn_resource(pos, rname, count)
|
|
if not count then
|
|
count = 1
|
|
end
|
|
local obj = minetest.add_entity(pos, rname)
|
|
if obj then
|
|
local lua = obj:get_luaentity()
|
|
if lua then
|
|
lua._count = count
|
|
end
|
|
end
|
|
return obj
|
|
end
|
|
|
|
minetest.register_chatcommand("resource", {
|
|
privs = { server = true },
|
|
params = S("((<resource name> | all) [<count>]) | list"),
|
|
description = S("Show or set your resources"),
|
|
func = function(name, param)
|
|
local player = minetest.get_player_by_name(name)
|
|
if player == nil or not player:is_player() then
|
|
return false, S("Player does not exist.")
|
|
end
|
|
if param == "" then
|
|
return false
|
|
end
|
|
if param == "list" then
|
|
local list = {}
|
|
for k,_ in pairs(sf_resources.registered_resources) do
|
|
table.insert(list, k)
|
|
end
|
|
local out = table.concat(list, "\n")
|
|
return true, out
|
|
end
|
|
local rname, rcount = string.match(param, "([a-z0-9_:]+) ([-~%d.]+)")
|
|
if rname and rcount then
|
|
if rname == "all" then
|
|
for k,_ in pairs(sf_resources.registered_resources) do
|
|
local rcount_player = sf_resources.get_resource_count(player, k)
|
|
local rrcount = minetest.parse_relative_number(rcount, rcount_player)
|
|
rrcount = math.floor(rrcount)
|
|
sf_resources.set_resource_count(player, k, rrcount)
|
|
end
|
|
return true, S("All resources set!")
|
|
else
|
|
if not sf_resources.registered_resources[rname] then
|
|
return false, S("Unknown resource.")
|
|
end
|
|
local rcount_player = sf_resources.get_resource_count(player, rname)
|
|
rcount = minetest.parse_relative_number(rcount, rcount_player)
|
|
rcount = math.floor(rcount)
|
|
sf_resources.set_resource_count(player, rname, rcount)
|
|
local newrcount = sf_resources.get_resource_count(player, rname)
|
|
return true, S("@1: @2", sf_resources.registered_resources[rname].description, newrcount)
|
|
end
|
|
else
|
|
rname = param
|
|
if sf_resources.registered_resources[rname] then
|
|
local rcount_player = sf_resources.get_resource_count(player, rname)
|
|
return true, S("@1: @2", sf_resources.registered_resources[rname].description, rcount_player)
|
|
else
|
|
return false, S("Not a valid resource name.")
|
|
end
|
|
end
|
|
end,
|
|
})
|
|
|
|
sf_resources.get_resource_count = function(player, resourcename)
|
|
local pmeta = player:get_meta()
|
|
local rcount = pmeta:get_int(resourcename)
|
|
return rcount
|
|
end
|
|
|
|
sf_resources.set_resource_count = function(player, resourcename, count)
|
|
local pmeta = player:get_meta()
|
|
if count > MAX_RESOURCES then
|
|
count = MAX_RESOURCES
|
|
end
|
|
if count < 0 then
|
|
count = 0
|
|
end
|
|
pmeta:set_int(resourcename, count)
|
|
report_resource_change(player, resourcename, count)
|
|
end
|
|
|
|
|
|
local init_hud = function(player)
|
|
local pname = player:get_player_name()
|
|
local id_icon = player:hud_add({
|
|
[hud_type_field_name] = "image",
|
|
position = { x = 0, y = 1 },
|
|
scale = { x = 4, y = 4 },
|
|
text = "blank.png",
|
|
offset = { x = 20, y = -100 },
|
|
alignment = { x = 1, y = -1 },
|
|
z_index = 101,
|
|
})
|
|
local id_num = player:hud_add({
|
|
[hud_type_field_name] = "text",
|
|
position = { x = 0, y = 1 },
|
|
scale = { x = 100, y = 100 },
|
|
text = "",
|
|
number = 0xFFFFFF,
|
|
alignment = { x = 1, y = -1 },
|
|
size = { x = 2, y = 2 },
|
|
style = 0,
|
|
offset = { x = 100, y = -118 },
|
|
z_index = 102,
|
|
})
|
|
player_huds[pname] = {
|
|
icon = id_icon,
|
|
num = id_num,
|
|
shown = false,
|
|
}
|
|
end
|
|
|
|
sf_resources.register_on_resource_change(function(player, resource, count)
|
|
local pname = player:get_player_name()
|
|
if not player_huds[pname] then
|
|
return
|
|
end
|
|
local icon = sf_resources.registered_resources[resource].icon
|
|
player:hud_change(player_huds[pname].icon, "text", icon)
|
|
player:hud_change(player_huds[pname].num, "text", tostring(count))
|
|
player_huds[pname].shown = true
|
|
player_huds[pname].shown_at = minetest.get_us_time()
|
|
end)
|
|
|
|
sf_resources.register_on_resource_change(function(player, rname, count)
|
|
if rname == "sf_resources:shadow_fragement" then
|
|
sf_dialog.show_dialog(player, "shadow_fragment", true)
|
|
elseif rname == "sf_resources:healing_essence" then
|
|
sf_dialog.show_dialog(player, "healing_essence", true)
|
|
elseif rname == "sf_resources:light_crystal" then
|
|
sf_dialog.show_dialog(player, "first_light_crystal", true)
|
|
end
|
|
end)
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
local now = minetest.get_us_time()
|
|
for playername, hudinfo in pairs(player_huds) do
|
|
local player = minetest.get_player_by_name(playername)
|
|
if player then
|
|
if player_huds[playername].shown and now - player_huds[playername].shown_at > HUD_SHOW_TIME then
|
|
player:hud_change(player_huds[playername].icon, "text", "blank.png")
|
|
player:hud_change(player_huds[playername].num, "text", "")
|
|
player_huds[playername].shown = false
|
|
player_huds[playername].shown_at = nil
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
init_hud(player)
|
|
end)
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
player_huds[player:get_player_name()] = nil
|
|
end)
|
|
|
|
sf_resources.register_resource("shadow_fragment", { description = S("Shadow Fragment"), texture = "sf_resources_shadow_fragment.png", icon = "sf_resources_shadow_fragment_icon.png" })
|
|
sf_resources.register_resource("light_crystal", { description = S("Light Crystal"), texture = "sf_resources_light_crystal.png", never_despawns = true })
|
|
sf_resources.register_resource("healing_essence", { description = S("Healing Essence"), texture = "sf_resources_healing_essence.png", icon = "sf_resources_healing_essence_icon.png", never_despawns = true })
|