]> git.lizzy.rs Git - Crafter.git/blobdiff - mods/hunger/init.lua
remove server debug
[Crafter.git] / mods / hunger / init.lua
index 65d88cb99532d86b86c1259f833f18f95797a59c..fbe0ae088b02b3983f9183c2d9d8a73696c9f51a 100644 (file)
-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 and hunger >= 20 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
-                                       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
                        
                        
-                       local hp = player:get_hp()
+                       hp = player:get_hp()
+
+                       drowning = is_player_drowning(player)           
+
                        --make regeneration happen every second
-                       if hunger >= 20 and hp < 20 and satiation > 0 then
-                               local regeneration_interval = meta:get_int("regeneration_interval")
-                               --print(regeneration_interval,"--------------------------")
-                               regeneration_interval = regeneration_interval + 1
-                               if regeneration_interval >= 2 then
-                                       player:set_hp(hp+1)
-                                       exhaustion_tick = exhaustion_tick + 32
-                                       meta:set_int("exhaustion_tick", exhaustion_tick)
-                                       meta:set_int("satiation", satiation)
-                                       regeneration_interval = 0
+                       if not is_player_on_fire(player) and 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("regeneration_interval",regeneration_interval)
                        --reset the regen interval
                        else
-                               meta:set_int("regeneration_interval",0)
+                               temp_pool.regeneration_interval = 0
                        end
-                       
-                       --print("satiation:",satiation,"exhaustion_tick:",exhaustion_tick)
                end
        end
        
@@ -184,56 +246,97 @@ local function hunger_update()
        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)
        if digger and digger:is_player() then
-               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)
+               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
+})