256 lines
6.5 KiB
Lua
256 lines
6.5 KiB
Lua
|
--
|
||
|
-- Hunger mod
|
||
|
-- For nodetest
|
||
|
-- Tweaked by Kaadmy, for Pixture
|
||
|
--
|
||
|
|
||
|
hunger = {}
|
||
|
|
||
|
hunger.hunger = {} -- the hunger level for each player
|
||
|
hunger.active = {} -- how a player has been active recently
|
||
|
hunger.moving = {} -- how much the player is moving
|
||
|
hunger.saturation = {} -- how saturated with food the player is
|
||
|
|
||
|
local player_step = {}
|
||
|
local player_health_step = {}
|
||
|
local player_bar = {}
|
||
|
local base_interval = 1
|
||
|
local file = minetest.get_worldpath() .. "/hunger"
|
||
|
|
||
|
function hunger.save_hunger()
|
||
|
local output = io.open(file, "w")
|
||
|
for name, v in pairs(hunger.hunger) do
|
||
|
output:write(hunger.hunger[name].." "..hunger.saturation[name].." "..name.."\n")
|
||
|
end
|
||
|
io.close(output)
|
||
|
end
|
||
|
|
||
|
local function load_hunger()
|
||
|
local input = io.open(file, "r")
|
||
|
if input then
|
||
|
repeat
|
||
|
local hnger = input:read("*n")
|
||
|
local sat = input:read("*n")
|
||
|
local name = input:read("*l")
|
||
|
|
||
|
if name == nil or sat == nil then break end
|
||
|
|
||
|
name = name:sub(2)
|
||
|
|
||
|
if not hnger then hnger = 20 end
|
||
|
if not sat then say = 0 end
|
||
|
|
||
|
hunger.hunger[name] = hnger
|
||
|
hunger.saturation[name] = sat
|
||
|
|
||
|
print("[hunger] '"..name.."' has "..hnger.." hunger and is saturated to "..sat.."%")
|
||
|
until input:read(0) == nil
|
||
|
io.close(input)
|
||
|
else
|
||
|
hunger.save_hunger()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
load_hunger()
|
||
|
|
||
|
function hunger.update_bar(player)
|
||
|
if not player then return end
|
||
|
local name = player:get_player_name()
|
||
|
if player_bar[name] then
|
||
|
player:hud_change(player_bar[name], "number", hunger.hunger[name])
|
||
|
else
|
||
|
player_bar[name] = player:hud_add(
|
||
|
{
|
||
|
hud_elem_type = "statbar",
|
||
|
position = {x=0.5,y=1.0},
|
||
|
text = "hunger.png",
|
||
|
number = hunger.hunger[name],
|
||
|
dir = 0,
|
||
|
size = {x=16, y=16},
|
||
|
offset = {x=64, y=-(48+24+16)},
|
||
|
})
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if minetest.setting_getbool("enable_damage") == true then
|
||
|
|
||
|
-- Prevent players from starving while afk (<--joke)
|
||
|
minetest.register_on_dignode(
|
||
|
function(pos, oldnode, player)
|
||
|
if not player then return end
|
||
|
local name = player:get_player_name()
|
||
|
hunger.active[name] = hunger.active[name]+ 2
|
||
|
end)
|
||
|
|
||
|
minetest.register_on_placenode(
|
||
|
function(pos, node, player)
|
||
|
if not player then return end
|
||
|
local name = player:get_player_name()
|
||
|
hunger.active[name] = hunger.active[name]+ 2
|
||
|
end)
|
||
|
|
||
|
minetest.register_on_joinplayer(
|
||
|
function(player)
|
||
|
local name = player:get_player_name()
|
||
|
if not hunger.hunger[name] then hunger.hunger[name] = 20 end
|
||
|
player:hud_add(
|
||
|
{
|
||
|
hud_elem_type = "statbar",
|
||
|
position = {x=0.5,y=1.0},
|
||
|
text = "hunger.png^[colorize:#666666:255",
|
||
|
number = 20,
|
||
|
dir = 0,
|
||
|
size = {x=16, y=16},
|
||
|
offset = {x=64, y=-(48+24+16)},
|
||
|
})
|
||
|
|
||
|
hunger.update_bar(player)
|
||
|
end)
|
||
|
|
||
|
minetest.register_on_leaveplayer(
|
||
|
function(player)
|
||
|
local name = player:get_player_name()
|
||
|
player_bar[name] = nil
|
||
|
end)
|
||
|
|
||
|
minetest.register_on_respawnplayer(
|
||
|
function(player)
|
||
|
local name = player:get_player_name()
|
||
|
hunger.hunger[name] = 20
|
||
|
hunger.update_bar(player)
|
||
|
hunger.save_hunger()
|
||
|
end)
|
||
|
|
||
|
minetest.register_on_item_eat(
|
||
|
function(hpdata, replace_with_item, itemstack, player, pointed_thing)
|
||
|
if not player then return end
|
||
|
if not hpdata then return end
|
||
|
|
||
|
local hp_change = 0
|
||
|
local saturation = 2
|
||
|
|
||
|
if type(hpdata) == "number" then
|
||
|
hp_change = hpdata
|
||
|
else
|
||
|
hp_change = hpdata.hp
|
||
|
saturation = hpdata.sat
|
||
|
end
|
||
|
|
||
|
local name = player:get_player_name()
|
||
|
|
||
|
hunger.hunger[name] = hunger.hunger[name] + hp_change
|
||
|
if hunger.hunger[name] > 20 then
|
||
|
hunger.hunger[name] = 20
|
||
|
end
|
||
|
|
||
|
hunger.saturation[name] = hunger.saturation[name] + saturation
|
||
|
if hunger.saturation[name] > 100 then
|
||
|
hunger.saturation[name] = 100
|
||
|
end
|
||
|
|
||
|
local headpos = player:getpos()
|
||
|
headpos.y = headpos.y + 1
|
||
|
minetest.sound_play("hunger_eat", {pos = headpos, max_hear_distance = 8})
|
||
|
hunger.update_bar(player)
|
||
|
hunger.save_hunger()
|
||
|
|
||
|
itemstack:take_item(1)
|
||
|
|
||
|
return itemstack
|
||
|
end)
|
||
|
|
||
|
-- Main function
|
||
|
local timer = 0
|
||
|
minetest.register_globalstep(
|
||
|
function(dtime)
|
||
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||
|
local name = player:get_player_name()
|
||
|
local controls = player:get_player_control()
|
||
|
local moving = 0
|
||
|
|
||
|
if controls.up or controls.down or controls.left or controls.right then
|
||
|
moving = moving + 1
|
||
|
end
|
||
|
|
||
|
if controls.sneak and not controls.aux1 then
|
||
|
moving = moving - 1
|
||
|
end
|
||
|
|
||
|
if controls.jump then
|
||
|
moving = moving + 1
|
||
|
end
|
||
|
|
||
|
if controls.jump then
|
||
|
moving = moving + 1
|
||
|
end
|
||
|
|
||
|
if controls.aux1 then
|
||
|
moving = moving + 2
|
||
|
end
|
||
|
|
||
|
if moving < 0 then moving = 0 end
|
||
|
|
||
|
hunger.moving[name] = moving
|
||
|
end
|
||
|
|
||
|
timer = timer + dtime;
|
||
|
|
||
|
if timer < base_interval then return end
|
||
|
timer = 0
|
||
|
local change = false
|
||
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||
|
local name = player:get_player_name()
|
||
|
local hp = player:get_hp()
|
||
|
|
||
|
if not hunger.hunger[name] then hunger.hunger[name] = 20 end
|
||
|
if not hunger.saturation[name] then hunger.saturation[name] = 0 end
|
||
|
|
||
|
if not player_step[name] then player_step[name] = 0 end
|
||
|
if not hunger.active[name] then hunger.active[name] = 0 end
|
||
|
if hunger.moving[name] == nil then hunger.moving[name] = 0 end
|
||
|
|
||
|
hunger.active[name] = hunger.active[name] + hunger.moving[name]
|
||
|
|
||
|
player_step[name] = player_step[name] + hunger.active[name] + 1
|
||
|
|
||
|
hunger.saturation[name] = hunger.saturation[name] - 1
|
||
|
|
||
|
if hunger.saturation[name] <= 0 then
|
||
|
hunger.saturation[name] = 0
|
||
|
if player_step[name] >= 24 then -- how much the player has been active
|
||
|
player_step[name] = 0
|
||
|
hunger.hunger[name] = hunger.hunger[name] - 1
|
||
|
if hunger.hunger[name] <= 0 and hp >= 0 then
|
||
|
player:set_hp(hp - 1)
|
||
|
hunger.hunger[name] = 0
|
||
|
|
||
|
local pos_sound = player:getpos()
|
||
|
player:set_physics_override({speed = 0.8})
|
||
|
minetest.chat_send_player(name, "You are hungry.")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
change = true
|
||
|
end
|
||
|
|
||
|
hunger.active[name] = 0
|
||
|
hunger.update_bar(player)
|
||
|
|
||
|
if player_health_step[name] == nil then player_health_step[name] = 0 end
|
||
|
|
||
|
player_health_step[name] = player_health_step[name] + 1
|
||
|
|
||
|
if player_health_step[name] >= 5 and player:get_hp() < 20 and hunger.hunger[name] >= 16 then
|
||
|
player_health_step[name] = 0
|
||
|
player:set_hp(hp+1)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if change then hunger.save_hunger() end
|
||
|
end)
|
||
|
else
|
||
|
minetest.register_on_item_eat(
|
||
|
function(hpdata, replace_with_item, itemstack, player, pointed_thing)
|
||
|
return
|
||
|
end)
|
||
|
end
|