minetest-game-adventuretest/mods/hunger/functions.lua

188 lines
4.7 KiB
Lua

function hunger.update_hunger(player, new_lvl)
local name = player:get_player_name() or nil
if not name then
return false
end
if minetest.setting_getbool("enable_damage") == false then
pd.set(name,"hunger_lvl",20)
return
end
local lvl = pd.get(name,"hunger_lvl")
if new_lvl then
lvl = new_lvl
end
if lvl > HUNGER_MAX then
lvl = HUNGER_MAX
end
pd.set(name,"hunger_lvl",lvl)
if lvl > 20 then
lvl = 20
end
hud.change_item(player, "hunger", {number = lvl})
end
local update_hunger = hunger.update_hunger
-- player-action based hunger changes
function hunger.handle_node_actions(pos, oldnode, player, ext)
if not player or not player:is_player() then
return
end
local name = player:get_player_name()
local exhaus = pd.get_number(name,"hunger_exhaus")
local lvl = pd.get_number(name,"hunger_lvl")
if not exhaus then
exhaus = 0
--return
end
local new = HUNGER_EXHAUST_PLACE
-- placenode event
if not ext then
new = HUNGER_EXHAUST_DIG
end
-- assume its send by action_timer(globalstep)
if not pos and not oldnode then
new = HUNGER_EXHAUST_MOVE
end
exhaus = exhaus + new
if exhaus > HUNGER_EXHAUST_LVL then
exhaus = 0
local h = lvl
if h > 0 then
update_hunger(player, h - 1)
end
end
pd.set(name,"hunger_exhaus",exhaus)
end
function hunger_move(player,name,dtime)
local controls = player:get_player_control()
-- Determine if the player is walking
if controls.up or controls.down or controls.left or controls.right then
hunger.handle_node_actions(nil, nil, player)
end
end
adventuretest.register_pl_hook(hunger_move,HUNGER_MOVE_TICK)
function do_hunger_tick(player,name,dtime)
local name = player:get_player_name()
if minetest.check_player_privs(name, {immortal=true}) then
update_hunger(player,20)
return
end
local hunger = pd.get_number(name,"hunger_lvl")
if hunger > 0 then
pd.increment(name,"hunger_lvl",-1)
update_hunger(player, hunger - 1)
end
end
adventuretest.register_pl_hook(do_hunger_tick,HUNGER_TICK)
function do_health_tick(player,name,dtime)
local name = player:get_player_name()
local lvl = pd.get_number(name,"hunger_lvl")
local air = player:get_breath() or 0
local hp = player:get_hp()
-- heal player by 1 hp if not dead and saturation is > 15 (of 30)
if lvl > HUNGER_HEAL_LVL and air > 0 then
if hp < pd.get_number(name,"max_hp") then
player:set_hp(hp + HUNGER_HEAL)
end
end
-- or damage player by 1 hp if saturation is < 2 (of 30)
if lvl < HUNGER_STARVE_LVL then
player:set_hp(hp - HUNGER_STARVE)
end
end
adventuretest.register_pl_hook(do_health_tick,HUNGER_HEALTH_TICK)
-- food functions
local food = hunger.food
function hunger.register_food(name, hunger_change, replace_with_item, poisen, heal, sound)
food[name] = {}
food[name].saturation = hunger_change -- hunger points added
food[name].replace = replace_with_item -- what item is given back after eating
food[name].poisen = poisen -- time its poisening
food[name].healing = heal -- amount of HP
food[name].sound = sound -- special sound that is played when eating
end
-- Poison player
local function poisenp(tick, time, time_left, player)
time_left = time_left + tick
if time_left < time then
minetest.after(tick, poisenp, tick, time, time_left, player)
else
hud.change_item(player, "hunger", {text = "hud_hunger_fg.png"})
end
local hp = player:get_hp() -1 or 0
if hp > 0 then
player:set_hp(hp)
end
end
function hunger.eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
local item = itemstack:get_name()
local def = food[item]
if not def then
def = {}
def.saturation = hp_change * 1.3
def.replace = replace_with_item
end
local func = hunger.item_eat(def.saturation, def.replace, def.poisen, def.healing, def.sound)
return func(itemstack, user, pointed_thing)
end
function hunger.item_eat(hunger_change, replace_with_item, poisen, heal, sound)
return function(itemstack, user, pointed_thing)
if itemstack:take_item() ~= nil and user ~= nil then
local name = user:get_player_name()
local sat = pd.get_number(name,"hunger_lvl")
local hp = user:get_hp()
local max_hp = pd.get_number(name,"max_hp")
-- Saturation
if sat < HUNGER_MAX and hunger_change then
sat = sat + hunger_change
hunger.update_hunger(user, sat)
if sat >= HUNGER_MAX then
minetest.chat_send_player(name, "You feel full.");
end
end
-- Healing
if hp < max_hp and heal then
hp = hp + heal
if hp > max_hp then
hp = max_hp
end
user:set_hp(hp)
end
-- Poison
if poisen then
hud.change_item(user, "hunger", {text = "hunger_statbar_poisen.png"})
poisenp(1.0, poisen, 0, user)
end
-- eating sound
if not sound then
sound = "hunger_eat"
end
minetest.sound_play(sound, {to_player = name, gain = 0.7})
itemstack:add_item(replace_with_item)
end
return itemstack
end
end