283 lines
9.9 KiB
Lua
283 lines
9.9 KiB
Lua
-- Localize Hunger NG
|
|
local a = hunger_ng.attributes
|
|
local c = hunger_ng.configuration
|
|
local e = hunger_ng.effects
|
|
local f = hunger_ng.functions
|
|
local s = hunger_ng.settings
|
|
local S = hunger_ng.configuration.translator
|
|
|
|
-- Localize Luanti
|
|
local core_log = core.log
|
|
local get_player_by_name = core.get_player_by_name
|
|
local get_current_modname = core.get_current_modname
|
|
|
|
|
|
-- Gets and returns the given player-related data
|
|
--
|
|
-- To gain more flexibility this function is used wherever something from the
|
|
-- player has to be loaded either as custom player attribute or as planned
|
|
-- player meta data.
|
|
--
|
|
-- @param playername The name of the player to get the information from
|
|
-- @param field The field that has to be get.
|
|
-- @param as_string Optionally return the value of the field as string
|
|
-- @return bool|string|number
|
|
local get_data = function (playername, field, as_string)
|
|
local player = get_player_by_name(playername)
|
|
if not player then return false end
|
|
|
|
local player_meta = player:get_meta()
|
|
|
|
if as_string then
|
|
return tostring(player_meta:get(field) or 'invalid')
|
|
else
|
|
return tonumber(player_meta:get(field) or nil)
|
|
end
|
|
end
|
|
|
|
|
|
-- Sets a player-related attribute
|
|
--
|
|
-- To gain more flexibility on the player-related functions this function can
|
|
-- be used wherever a player-related attribute has to be set.
|
|
--
|
|
-- @param playername The name of the player to set the attribute to
|
|
-- @param field The field to set
|
|
-- @param value The value to set the field to
|
|
-- @return void
|
|
local set_data = function (playername, field, value)
|
|
local player = get_player_by_name(playername)
|
|
if not player then return false end
|
|
local player_meta = player:get_meta()
|
|
player_meta:set_string(field, value)
|
|
end
|
|
|
|
|
|
|
|
-- Print health and hunger changes
|
|
--
|
|
-- This function prints all health and hunger changes that are triggered by
|
|
-- this mod. The following information will be shown for every change.
|
|
--
|
|
-- t: Ingame time when the change was applied
|
|
-- p: player name affected by the change
|
|
-- w: Information on what was changes (hunger/health)
|
|
-- n: The new value as defined by the definition
|
|
-- d: definition (calculation) of the change (old + change = new)
|
|
--
|
|
-- @param playername Name of the player (p)
|
|
-- @param what Description on what was changed (w, hunger/health)
|
|
-- @param old The old value
|
|
-- @param new The new value
|
|
-- @param change The change amount
|
|
-- @param reason The given reason for the change
|
|
-- @return void
|
|
local debug_log = function (playername, what, old, new, change, reason)
|
|
if not c.debug_mode then return end
|
|
local timestamp = 24 * 60 * core.get_timeofday()
|
|
local h = tostring((math.floor(timestamp/60) % 60))
|
|
local m = tostring((math.floor(timestamp) % 60))
|
|
local text = ('t: +t, p: +p, w: +w, n: +n, d: +o + +c, r: +r'):gsub('+.', {
|
|
['+t'] = string.rep('0', 2-#h)..h..':'..string.rep('0', 2-#m)..m,
|
|
['+p'] = playername,
|
|
['+w'] = what,
|
|
['+o'] = old,
|
|
['+n'] = new,
|
|
['+c'] = change,
|
|
['+r'] = reason or 'n/a'
|
|
})
|
|
core_log('action', c.log_prefix..text)
|
|
end
|
|
|
|
|
|
-- Returns if hunger is disabled for the given player
|
|
--
|
|
-- When the player is no `interact` permission or has the `hunger_disabled`
|
|
-- parameter set then this function returns boolean true. Otherwise boolean
|
|
-- false will be returned.
|
|
--
|
|
-- @param playername The name of the player to check
|
|
-- @return bool
|
|
local hunger_disabled = function (playername)
|
|
local interact = core.check_player_privs(playername, { interact=true })
|
|
local disabled = get_data(playername, a.hunger_disabled)
|
|
if core.is_yes(disabled) or not interact then return true end
|
|
return false
|
|
end
|
|
|
|
|
|
-- Configures hunger effects for the player
|
|
--
|
|
-- The function can enable or disable hunger for a player. It is meant to be
|
|
-- used by other mods to disable or enable hunger effects for a specific
|
|
-- player. For example a magic item that prevents players from getting hungry.
|
|
--
|
|
-- The parameter `action` can be either `disable`, `enable`. The actions are
|
|
-- very self-explainatory.
|
|
--
|
|
-- @param playername The name of the player whose hunger is to be configured
|
|
-- @param action The action that will be taken as described
|
|
local configure_hunger = function (playername, action)
|
|
if not action then return end
|
|
|
|
if action == 'enable' then
|
|
set_data(playername, a.hunger_disabled, 0)
|
|
elseif action == 'disable' then
|
|
set_data(playername, a.hunger_disabled, 1)
|
|
end
|
|
end
|
|
|
|
|
|
-- Get the current hunger information
|
|
--
|
|
-- Gets (Returns) the current hunger information for the given player. See API
|
|
-- documentation for a detailled overview of the returned table.
|
|
--
|
|
-- @param playername The name of the player whose hunger value is to be get
|
|
-- @return table The table as described
|
|
hunger_ng.functions.get_hunger_information = function (playername)
|
|
local player = get_player_by_name(playername)
|
|
if not player then return { invalid = true, player_name = playername } end
|
|
|
|
local last_eaten = get_data(playername, a.eating_timestamp) or 0
|
|
local current_hunger = get_data(playername, a.hunger_value)
|
|
local player_properties = player:get_properties()
|
|
|
|
local e_heal = get_data(playername, a.effect_heal, true) == 'enabled'
|
|
local e_hunger = get_data(playername, a.effect_hunger, true) == 'enabled'
|
|
local e_starve = get_data(playername, a.effect_starve, true) == 'enabled'
|
|
|
|
return {
|
|
player_name = playername,
|
|
hunger = {
|
|
floored = math.floor(current_hunger),
|
|
ceiled = math.ceil(current_hunger),
|
|
disabled = hunger_disabled(playername),
|
|
exact = current_hunger,
|
|
enabled = e_heal
|
|
},
|
|
maximum = {
|
|
hunger = s.hunger.maximum,
|
|
health = player_properties.hp_max,
|
|
breath = player_properties.breath_max
|
|
},
|
|
effects = {
|
|
starving = {
|
|
enabled = e_starve,
|
|
status = current_hunger < e.starve.below
|
|
},
|
|
healing = {
|
|
enabled = e_heal,
|
|
status = current_hunger > e.heal.above
|
|
},
|
|
current_breath = player:get_breath(),
|
|
},
|
|
timestamps = {
|
|
last_eaten = tonumber(last_eaten),
|
|
request = tonumber(os.time())
|
|
}
|
|
}
|
|
end
|
|
|
|
|
|
-- Alter health by given value
|
|
--
|
|
-- @param playername The name of a player whose health value should be altered
|
|
-- @param change The health change (can be negative to damage the player)
|
|
hunger_ng.functions.alter_health = function (playername, change, reason)
|
|
local player = get_player_by_name(playername)
|
|
local hp_max = player:get_properties().hp_max
|
|
|
|
if player == nil then return end
|
|
if hunger_disabled(playername) then return end
|
|
|
|
local current_health = player:get_hp()
|
|
local new_health = current_health + change
|
|
|
|
if new_health > hp_max then new_health = hp_max end
|
|
if new_health < 0 then new_health = 0 end
|
|
|
|
player:set_hp(new_health, { hunger = reason })
|
|
debug_log(playername, 'health', current_health, new_health, change, reason)
|
|
end
|
|
|
|
|
|
-- Alter hunger by the given value
|
|
--
|
|
-- @param playername The name of a player whose hunger value should be altered
|
|
-- @param change The hunger change (can be negative to make player hungry)
|
|
hunger_ng.functions.alter_hunger = function (playername, change, reason)
|
|
local player = get_player_by_name(playername)
|
|
|
|
if player == nil then return end
|
|
if hunger_disabled(playername) then return end
|
|
|
|
local current_hunger = get_data(playername, a.hunger_value)
|
|
local new_hunger = current_hunger + change
|
|
local bar_id = get_data(playername, a.hunger_bar_id)
|
|
|
|
if new_hunger > s.hunger.maximum then new_hunger = s.hunger.maximum end
|
|
if new_hunger < 0 then new_hunger = 0 end
|
|
|
|
set_data(playername, a.hunger_value, new_hunger)
|
|
|
|
if s.hunger_bar.use then
|
|
player:hud_change(bar_id, 'number', math.ceil(new_hunger))
|
|
end
|
|
|
|
debug_log(playername, 'hunger', current_hunger, new_hunger, change, reason)
|
|
end
|
|
|
|
|
|
-- Set hunger effect metadata
|
|
--
|
|
-- The hunger effect meta data can be set by mods to temporary disable hunger
|
|
-- effects for the given player. Everything works normal but hunger effects
|
|
-- like hunger itself, starving and healing are not performed even if the
|
|
-- player is in a state where this would happen.
|
|
--
|
|
-- The effect is not persistent. When a player rejoins the setting is actively
|
|
-- removed during join time of that player. Mods need to actively track the
|
|
-- status if they want the setting persist between joins.
|
|
--
|
|
-- @see hunger_ng.alter_hunger
|
|
-- @see system/timers.lua
|
|
--
|
|
-- @param playername Name of the player to set the effect for
|
|
-- @param effect The effect name as described
|
|
-- @param setting Either `enabled` or `disabled`
|
|
-- @return void
|
|
hunger_ng.set_effect = function (playername, effect, setting)
|
|
local attribute = a['effect_'..effect] or false
|
|
local allowed_values = { enabled = true, disabled = true }
|
|
|
|
-- Warn in server log when a mod tries to configure an unknown effect
|
|
if attribute == false then
|
|
core_log('warning', ('+t +m tried to set +v for +p'):gsub('+.', {
|
|
['+t'] = '[hunger_ng]',
|
|
['+m'] = get_current_modname(),
|
|
['+v'] = 'unknown effect '..effect,
|
|
['+p'] = playername
|
|
}))
|
|
return
|
|
end
|
|
|
|
-- Set the attribute according to what the mod wants and log that setting
|
|
if allowed_values[setting] == true then
|
|
set_data(playername, attribute, setting)
|
|
core_log('verbose', ('+t +m sets +a to +v for +p'):gsub('+.', {
|
|
['+t'] = '[hunger_ng]',
|
|
['+m'] = get_current_modname(),
|
|
['+a'] = attribute,
|
|
['+v'] = setting,
|
|
['+p'] = playername
|
|
}))
|
|
end
|
|
end
|
|
|
|
|
|
-- Globalize the set and get function for player data for use in other files
|
|
hunger_ng.functions.get_data = get_data
|
|
hunger_ng.functions.set_data = set_data
|
|
hunger_ng.functions.hunger_disabled = hunger_disabled
|
|
hunger_ng.functions.configure_hunger = configure_hunger
|