-minetest.register_on_joinplayer(function(player)
- local meta = player:get_meta()
- player:hud_add({
- hud_elem_type = "statbar",
- position = {x = 0.5, y = 1},
- text = "hunger_icon_bg.png",
- number = 20,
- direction = 1,
- size = {x = 24, y = 24},
- offset = {x = 24*10, y= -(48 + 50 + 39)},
- })
- local hunger_bar = player:hud_add({
- hud_elem_type = "statbar",
- position = {x = 0.5, y = 1},
- text = "hunger_icon.png",
- number = meta:get_int("hunger"),
- direction = 1,
- size = {x = 24, y = 24},
- offset = {x = 24*10, y= -(48 + 50 + 39)},
- })
- meta:set_int("hunger_bar", hunger_bar)
-end)
+local minetest,math = minetest,math
+local mod_storage = minetest.get_mod_storage()
+local pool = {}
-minetest.register_on_newplayer(function(player)
- local meta = player:get_meta()
- --give players new hunger when they join
- if meta:get_int("hunger") == 0 then
- meta:set_int("hunger", 20)
- meta:set_int("satiation", 5)
- meta:set_int("exhaustion_tick", 0)
+
+-- loads data from mod storage
+local name
+local temp_pool
+local load_data = function(player)
+ name = player:get_player_name()
+ pool[name] = {}
+ temp_pool = pool[name]
+ if mod_storage:get_int(name.."h_save") > 0 then
+ temp_pool.hunger = mod_storage:get_int(name.."hunger" )
+ temp_pool.satiation = mod_storage:get_int(name.."satiation" )
+ temp_pool.exhaustion = mod_storage:get_int(name.."exhaustion" )
+ temp_pool.regeneration_interval = mod_storage:get_int(name.."regeneration_interval")
+ else
+ temp_pool.hunger = 20
+ temp_pool.satiation = 20
+ temp_pool.regeneration_interval = 0
+ temp_pool.exhaustion = 0
+ end
+end
+
+-- saves data to be utilized on next login
+local name
+local temp_pool
+local save_data = function(name)
+ if type(name) ~= "string" and name:is_player() then
+ name = name:get_player_name()
end
+ temp_pool = pool[name]
+ mod_storage:set_int(name.."hunger", temp_pool.hunger )
+ mod_storage:set_int(name.."satiation", temp_pool.satiation )
+ mod_storage:set_int(name.."exhaustion", temp_pool.exhaustion )
+ mod_storage:set_int(name.."regeneration_interval",temp_pool.regeneration_interval)
+
+ mod_storage:set_int(name.."h_save",1)
+
+ pool[name] = nil
+end
+
+
+-- is used for shutdowns to save all data
+local save_all = function()
+ for name,_ in pairs(pool) do
+ save_data(name)
+ end
+end
+
+-- an easy translation pool
+local satiation_pool = {
+ [0] = 1,
+ [0.5] = 3,
+ [1] = 6,
+ [2] = 8,
+ [3] = 1
+}
+-- ticks up the exhaustion when counting down satiation
+local tick_up_satiation = function(state,exhaustion)
+ return(exhaustion + satiation_pool[state])
+end
+
+-- an easy translation pool
+local hunger_pool = {
+ [0] = 1,
+ [0.5] = 2,
+ [1] = 3,
+ [2] = 4,
+ [3] = 1
+}
+-- ticks up the exhaustion when counting down hunger
+local tick_up_hunger = function(state,exhaustion)
+ return(exhaustion + hunger_pool[state])
+end
+
+-- allows other mods to set hunger data
+local name
+get_player_hunger = function(player)
+ name = player:get_player_name()
+ return(pool[name].hunger)
+end
+
+
+-- saves specific users data for when they relog
+minetest.register_on_leaveplayer(function(player)
+ save_data(player)
end)
-minetest.register_on_respawnplayer(function(player)
- local meta = player:get_meta()
- meta:set_int("hunger", 20)
- meta:set_int("satiation", 5)
- meta:set_int("exhaustion_tick", 0)
- meta:set_int("dead", 0)
- local hunger_bar = meta:get_int("hunger_bar")
- player:hud_change(hunger_bar, "number", 20)
+-- save all data to mod storage on shutdown
+minetest.register_on_shutdown(function()
+ save_all()
end)
-minetest.register_on_dieplayer(function(player)
- local meta = player:get_meta()
- meta:set_int("dead", 1)
+-- create new data for hunger per player
+local name
+minetest.register_on_joinplayer(function(player)
+ name = player:get_player_name()
+ load_data(player)
+ hud_manager.add_hud(player,"hunger_bg",{
+ hud_elem_type = "statbar",
+ position = {x = 0.5, y = 1},
+ text = "hunger_icon_bg.png",
+ number = 20,
+ direction = 1,
+ size = {x = 24, y = 24},
+ offset = {x = 24*10, y= -(48 + 24 + 39)},
+ })
+ hud_manager.add_hud(player,"hunger",{
+ hud_elem_type = "statbar",
+ position = {x = 0.5, y = 1},
+ text = "hunger_icon.png",
+ number = pool[name].hunger,
+ direction = 1,
+ size = {x = 24, y = 24},
+ offset = {x = 24*10, y= -(48 + 24 + 39)},
+ })
end)
---this is the max exhaustion a player will get before their
---satiation goes down and rolls over
-local exhaustion_peak = 384
---when satiation runs out this is when the hunger peak variable
---is used, everytime the player rolls over this their hunger ticks down
---based on what they're doing
-local hunger_peak = 64
+-- resets the players hunger settings to max
+local name
+local temp_pool
+minetest.register_on_respawnplayer(function(player)
+ name = player:get_player_name()
+ temp_pool = pool[name]
+ temp_pool.hunger = 20
+ temp_pool.satiation = 20
+ temp_pool.regeneration_interval = 0
+ temp_pool.exhaustion = 0
+ hud_manager.change_hud({
+ player = player ,
+ hud_name = "hunger",
+ element = "number",
+ data = temp_pool.hunger
+ })
+end)
-local function hunger_update()
+local exhaustion_peak = 512
+local hunger_peak = 128
+local temp_pool
+local state
+local input
+local hp
+local drowning
+hunger_update = function()
for _,player in ipairs(minetest.get_connected_players()) do
-
- --get the metas
- local meta = player:get_meta()
-
--do not regen player's health if dead - this will be reused for 1up apples
- if meta:get_int("dead") == 0 then --and meta:get_int("regeneration")
-
- --internal variables
- local satiation = meta:get_int("satiation")
- local hunger = meta:get_int("hunger")
- local exhaustion_tick = meta:get_int("exhaustion_tick")
-
- --movement states
- local movement_state = meta:get_string("player.player_movement_state")
- local running = (movement_state == "1")
- local bunny_hopping = (movement_state == "2")
- local sneaking = (movement_state == "3")
- local standing = false
- local walking = false
-
- --we must seperate these two values because I forgot to
- --write in a seperate clientside state for walking/standing
- if movement_state == "0" then
- local input = player:get_player_control()
+ if player:get_hp() > 0 then
+ name = player:get_player_name()
+ temp_pool = pool[name]
+
+ --movement state
+ state = get_player_state(player)
+
+ -- if player is moving in state 0 add 0.5
+ if state == 0 then
+ input = player:get_player_control()
if input.jump or input.right or input.left or input.down or input.up then
- walking = true
- else
- standing = true
+ state = 0.5
end
end
-
- --we count up the exhaustion of the player moving around
- --based on their states
- if satiation > 0 then
- if running then
- exhaustion_tick = exhaustion_tick + 6
- elseif bunny_hopping then
- exhaustion_tick = exhaustion_tick + 8
- elseif sneaking then
- exhaustion_tick = exhaustion_tick + 1
-
- elseif walking then
- exhaustion_tick = exhaustion_tick + 3
- elseif standing then
- exhaustion_tick = exhaustion_tick + 1
- end
-
-
- if exhaustion_tick >= exhaustion_peak then
- print("should be wroking")
- satiation = satiation - 1
- exhaustion_tick = exhaustion_tick - exhaustion_peak
+ -- count down invisible satiation bar
+ if temp_pool.satiation > 0 and temp_pool.hunger >= 20 then
+
+ temp_pool.exhaustion = tick_up_satiation(state, temp_pool.exhaustion)
+
+ if temp_pool.exhaustion > exhaustion_peak then
+
+ temp_pool.satiation = temp_pool.satiation - 1
+
+ temp_pool.exhaustion = temp_pool.exhaustion - exhaustion_peak
--reset this to use for the hunger tick
- if satiation == 0 then
- exhaustion_tick = 0
+ if temp_pool.satiation == 0 then
+ temp_pool.exhaustion = 0
end
-
- meta:set_int("satiation", satiation)
end
+ -- count down hunger bars
+ elseif temp_pool.hunger > 0 then
+
+ temp_pool.exhaustion = tick_up_hunger(state,temp_pool.exhaustion)
- meta:set_int("exhaustion_tick", exhaustion_tick)
- elseif hunger > 0 then
- --this is copied again because this is for future tuning
- if running then
- exhaustion_tick = exhaustion_tick + 3
- elseif bunny_hopping then
- exhaustion_tick = exhaustion_tick + 4
- elseif sneaking then
- exhaustion_tick = exhaustion_tick + 1
- elseif walking then
- exhaustion_tick = exhaustion_tick + 2
- elseif standing then
- exhaustion_tick = exhaustion_tick + 1
- end
- if exhaustion_tick >= hunger_peak then
+ if temp_pool.exhaustion >= hunger_peak then
--don't allow hunger to go negative
- if hunger > 0 then
- exhaustion_tick = 0
- hunger = hunger - 1
- meta:set_int("hunger", hunger)
- local hunger_bar = meta:get_int("hunger_bar")
- player:hud_change(hunger_bar, "number", hunger)
+ if temp_pool.hunger > 0 then
+
+ temp_pool.exhaustion = temp_pool.exhaustion - hunger_peak
+
+ temp_pool.hunger = temp_pool.hunger - 1
+
end
+
+ hud_manager.change_hud({
+ player = player ,
+ hud_name = "hunger",
+ element = "number",
+ data = temp_pool.hunger
+ })
end
- meta:set_int("exhaustion_tick", exhaustion_tick)
- elseif hunger <= 0 then
- exhaustion_tick = exhaustion_tick + 1
- local hp = player:get_hp()
- if hp > 0 and exhaustion_tick >= 2 then
- player:set_hp(hp-1)
- exhaustion_tick = 0
- end
- meta:set_int("exhaustion_tick", exhaustion_tick)
+ -- hurt the player if hunger bar empty
+ elseif temp_pool.hunger <= 0 then
+
+ temp_pool.exhaustion = temp_pool.exhaustion + 1
+
+ hp = player:get_hp()
+
+ if hp > 0 and temp_pool.exhaustion >= 2 then
+ player:set_hp( hp - 1 )
+ temp_pool.exhaustion = 0
+ end
end
- --print("satiation:",satiation,"exhaustion_tick:",exhaustion_tick)
- local hp = player:get_hp()
- if hunger >= 20 and hp < 20 then
- player:set_hp(hp+1)
- exhaustion_tick = 0
- satiation = satiation - 1
- if satiation < 0 then
- satiation = 0
+
+ hp = player:get_hp()
+
+ drowning = is_player_drowning(player)
+
+ --make regeneration happen every second
+ if drowning == 0 and temp_pool.hunger >= 20 and hp < 20 then -- meta:get_int("on_fire") == 0
+
+ temp_pool.regeneration_interval = temp_pool.regeneration_interval + 1
+
+ if temp_pool.regeneration_interval >= 2 then
+
+ player:set_hp( hp + 1 )
+
+ temp_pool.exhaustion = temp_pool.exhaustion + 32
+
+ temp_pool.regeneration_interval = 0
+
end
- meta:set_int("exhaustion_tick", exhaustion_tick)
+ --reset the regen interval
+ else
+ temp_pool.regeneration_interval = 0
end
-
- meta:set_int("satiation", satiation)
end
end
end)
end
-hunger_update()
+minetest.register_on_mods_loaded(function()
+ minetest.after(0.5,function()
+ hunger_update()
+ end)
+end)
--take away hunger and satiation randomly while mining
+local name
minetest.register_on_dignode(function(pos, oldnode, digger)
- local meta = digger:get_meta()
- local exhaustion_tick = meta:get_int("exhaustion_tick")
- exhaustion_tick = exhaustion_tick + math.random(0,2)
- meta:set_int("exhaustion_tick", exhaustion_tick)
+ if digger and digger:is_player() then
+ name = digger:get_player_name()
+ pool[name].exhaustion = pool[name].exhaustion + math.random(0,2)
+ end
end)
---allow players to eat food
-function minetest.eat_food(player,item)
- local meta = player:get_meta()
-
- local player_hunger = meta:get_int("hunger")
- local player_satiation = meta:get_int("satiation")
-
-
+-- take the eaten food
+local item
+local take_food = function(player)
+ item = player:get_wielded_item()
+ item:take_item()
+ player:set_wielded_item(item)
+end
+
+-- players eat food
+local name
+local temp_pool
+local item
+local satiation
+local hunger
+player_eat_food = function(player,item)
+ name = player:get_player_name()
+ temp_pool = pool[name]
if type(item) == "string" then
item = ItemStack(item)
elseif type(item) == "table" then
item = ItemStack(item.name)
end
-
item = item:get_name()
- local satiation = minetest.get_item_group(item, "satiation")
- local hunger = minetest.get_item_group(item, "hunger")
+ satiation = minetest.get_item_group( item, "satiation" )
+ hunger = minetest.get_item_group( item, "hunger" )
- if player_hunger < 20 then
- player_hunger = player_hunger + hunger
- if player_hunger > 20 then
- player_hunger = 20
- end
- end
- if player_satiation < 20 then
- player_satiation = player_satiation + satiation
- if player_satiation > 20 then
- player_satiation = 20
- end
+ temp_pool.hunger = temp_pool.hunger + hunger
+
+ if temp_pool.hunger > 20 then
+ temp_pool.hunger = 20
end
- meta:set_int("exhaustion_tick", 0)
- meta:set_int("hunger", player_hunger)
- meta:set_int("satiation", player_satiation)
- local hunger_bar = meta:get_int("hunger_bar")
- player:hud_change(hunger_bar, "number", player_hunger)
- local stack = player:get_wielded_item()
- stack:take_item()
- player:set_wielded_item(stack)
+ -- unlimited
+ -- this makes the game easier
+ temp_pool.satiation = temp_pool.satiation + satiation
+
+ take_food(player)
+
+ hud_manager.change_hud({
+ player = player ,
+ hud_name = "hunger",
+ element = "number",
+ data = temp_pool.hunger
+ })
end
+
+-- easily allows mods to register food
+minetest.register_food = function(name,def)
+ minetest.register_craftitem(":"..name, {
+ description = def.description,
+ inventory_image = def.texture,
+ groups = {satiation=def.satiation,hunger=def.hunger},
+ })
+
+ minetest.register_node(":"..name.."node", {
+ tiles = {def.texture},
+ drawtype = "allfaces",
+ })
+end
+
+
+minetest.register_chatcommand("hungry", {
+ params = "<mob>",
+ description = "A debug command to test food",
+ privs = {server = true},
+ func = function(name)
+ local temp_pool = pool[name]
+ temp_pool.exhaustion = 0
+ temp_pool.hunger = 1
+ temp_pool.satiation = 0
+ hud_manager.change_hud({
+ player = minetest.get_player_by_name(name) ,
+ hud_name = "hunger",
+ element = "number",
+ data = temp_pool.hunger
+ })
+ end
+})