X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=mods%2Fhunger%2Finit.lua;h=adb6913eae408762bbf7287c44eae5ba202cc505;hb=275f652a1ce6b8d8c3b89d61a347fb54e41f850c;hp=d4c2d7ecc62c5936a6cfac8cb85cf0d562818bb0;hpb=6a0572a6839b294446cfc71fcf92f8209dfab67c;p=Crafter.git diff --git a/mods/hunger/init.lua b/mods/hunger/init.lua index d4c2d7e..adb6913 100644 --- a/mods/hunger/init.lua +++ b/mods/hunger/init.lua @@ -1,174 +1,243 @@ -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 @@ -177,54 +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) - 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 = "", + 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 +})