From d1d11f97406500ada5fe8e29577a36bd5bd6bf31 Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Thu, 4 Nov 2021 20:58:54 +0100 Subject: [PATCH 1/6] Fixed debug hudbars for player saturation and exhaustion when mcl_hunger_debug=true is set in .config file --- mods/PLAYER/mcl_hunger/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 8c154700a..90a622a18 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -91,8 +91,8 @@ end -- register saturation hudbar hb.register_hudbar("hunger", 0xFFFFFF, S("Food"), { icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, 1, 20, 20, false) if mcl_hunger.debug then - hb.register_hudbar("saturation", 0xFFFFFF, S("Saturation"), { icon = "mcl_hunger_icon_saturation.png", bgicon = "mcl_hunger_bgicon_saturation.png", bar = "mcl_hunger_bar_saturation.png" }, 1, mcl_hunger.SATURATION_INIT, 200, false, S("%s: %.1f/%d")) - hb.register_hudbar("exhaustion", 0xFFFFFF, S("Exhaust."), { icon = "mcl_hunger_icon_exhaustion.png", bgicon = "mcl_hunger_bgicon_exhaustion.png", bar = "mcl_hunger_bar_exhaustion.png" }, 1, 0, mcl_hunger.EXHAUST_LVL, false, S("%s: %d/%d")) + hb.register_hudbar("saturation", 0xFFFFFF, S("Saturation"), { icon = "mcl_hunger_icon_saturation.png", bgicon = "mcl_hunger_bgicon_saturation.png", bar = "mcl_hunger_bar_saturation.png" }, 1, mcl_hunger.SATURATION_INIT, 200, false) + hb.register_hudbar("exhaustion", 0xFFFFFF, S("Exhaust."), { icon = "mcl_hunger_icon_exhaustion.png", bgicon = "mcl_hunger_bgicon_exhaustion.png", bar = "mcl_hunger_bar_exhaustion.png" }, 1, 0, mcl_hunger.EXHAUST_LVL, false) end minetest.register_on_joinplayer(function(player) From d0d60804a39da1b8d8a980861440b1146747ec20 Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Thu, 4 Nov 2021 21:01:28 +0100 Subject: [PATCH 2/6] Implemented health regeneration mechanics as described in minecraft wiki. Saturation values and different regeneration speeds now used. --- mods/PLAYER/mcl_hunger/init.lua | 84 +++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 90a622a18..535ccbed1 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -134,46 +134,58 @@ minetest.register_on_player_hpchange(function(player, hp_change) end end) -local main_timer = 0 -local timer = 0 -- Half second timer -local timerMult = 1 -- Cycles from 0 to 7, each time when timer hits half a second -minetest.register_globalstep(function(dtime) - main_timer = main_timer + dtime - timer = timer + dtime - if main_timer > mcl_hunger.HUD_TICK or timer > 0.25 then - if main_timer > mcl_hunger.HUD_TICK then main_timer = 0 end - for _,player in pairs(minetest.get_connected_players()) do - local name = player:get_player_name() - local h = tonumber(mcl_hunger.get_hunger(player)) - local hp = player:get_hp() - if timer > 0.25 then - -- Slow health regeneration, and hunger damage (every 4s). - -- Regeneration rate based on tutorial video . - -- Minecraft Wiki seems to be wrong in claiming that full hunger gives 0.5s regen rate. - if timerMult == 0 then - if h >= 18 and hp > 0 and hp < 20 then - -- +1 HP, +exhaustion - player:set_hp(hp+1) - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - elseif h == 0 then - -- Damage hungry player down to 1 HP - -- TODO: Allow starvation at higher difficulty levels - if hp-1 > 0 then - mcl_util.deal_damage(player, 1, {type = "starve"}) + +local fastFoodTickTimer = 0 -- 0.5 second cycle +local slowFoodTickTimer = 0 -- 4 second cycle +minetest.register_globalstep(function(dtime) + fastFoodTickTimer = fastFoodTickTimer + dtime + slowFoodTickTimer = slowFoodTickTimer + dtime + + local fastTimerWrapped = false -- if the fastFoodTickTimer wrapped around and everything dependent should be updated + local slowTimerWrapped = false + + if fastFoodTickTimer > 0.5 then + fastFoodTickTimer = 0 + fastTimerWrapped = true + end + if slowFoodTickTimer > 4.0 then + slowFoodTickTimer = 0 + slowTimerWrapped = true + end + + if fastTimerWrapped or slowTimerWrapped then -- only update players if something must be updated + for _,player in ipairs(minetest.get_connected_players()) do + + local playerName = player:get_player_name() + local foodLevel = mcl_hunger.get_hunger(player) + local foodSaturationLevel = mcl_hunger.get_saturation(player) + local playerHealth = player:get_hp() + + if playerHealth < 20 then + if foodLevel == 20 and foodSaturationLevel >= 6 then -- fast regeneration (2 health per second) + if fastTimerWrapped then + player:set_hp(playerHealth+1) + mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + end + elseif foodLevel >= 18 then -- slow regeneration (1 health every 4 seconds) + if slowTimerWrapped then + player:set_hp(playerHealth+1) + mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) end end end - - end - end - end - if timer > 0.25 then - timer = 0 - timerMult = timerMult + 2 - if timerMult > 7 then - timerMult = 0 + + if foodLevel == 0 then --starvation + maximumStarvation = 1 -- the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + -- TODO: implement Minecraft-like difficulty modes and the update maximumStarvation here + if playerHealth > maximumStarvation and slowTimerWrapped then + mcl_util.deal_damage(player, 1, {type = "starve"}) + end + end + end end end) From 976f522b9d25952768a77f7d6a9ae990d186da37 Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Mon, 8 Nov 2021 15:33:53 +0100 Subject: [PATCH 3/6] Combine slowFoodTickTimer and fastFoodTickTimer to a single food_tick_timer --- mods/PLAYER/mcl_hunger/init.lua | 69 +++++++++++++-------------------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 535ccbed1..0405c28ef 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -136,57 +136,42 @@ end) -local fastFoodTickTimer = 0 -- 0.5 second cycle -local slowFoodTickTimer = 0 -- 4 second cycle + +local food_tick_timer = 0 minetest.register_globalstep(function(dtime) - fastFoodTickTimer = fastFoodTickTimer + dtime - slowFoodTickTimer = slowFoodTickTimer + dtime + food_tick_timer = food_tick_timer + dtime - local fastTimerWrapped = false -- if the fastFoodTickTimer wrapped around and everything dependent should be updated - local slowTimerWrapped = false - - if fastFoodTickTimer > 0.5 then - fastFoodTickTimer = 0 - fastTimerWrapped = true - end - if slowFoodTickTimer > 4.0 then - slowFoodTickTimer = 0 - slowTimerWrapped = true - end - - if fastTimerWrapped or slowTimerWrapped then -- only update players if something must be updated - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in ipairs(minetest.get_connected_players()) do + + local player_name = player:get_player_name() + local food_level = mcl_hunger.get_hunger(player) + local food_saturation_level = mcl_hunger.get_saturation(player) + local player_health = player:get_hp() + + if food_tick_timer > 4.0 then + food_tick_timer = 0 - local playerName = player:get_player_name() - local foodLevel = mcl_hunger.get_hunger(player) - local foodSaturationLevel = mcl_hunger.get_saturation(player) - local playerHealth = player:get_hp() + if food_level >= 18 and player_health < 20 then --slow regenration + food_tick_timer = 0 + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - if playerHealth < 20 then - if foodLevel == 20 and foodSaturationLevel >= 6 then -- fast regeneration (2 health per second) - if fastTimerWrapped then - player:set_hp(playerHealth+1) - mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - end - elseif foodLevel >= 18 then -- slow regeneration (1 health every 4 seconds) - if slowTimerWrapped then - player:set_hp(playerHealth+1) - mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - end - end - end - - if foodLevel == 0 then --starvation - maximumStarvation = 1 -- the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + elseif food_level == 0 then --starvation + maximumStarvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) -- TODO: implement Minecraft-like difficulty modes and the update maximumStarvation here - if playerHealth > maximumStarvation and slowTimerWrapped then + if player_health > maximumStarvation then mcl_util.deal_damage(player, 1, {type = "starve"}) end end - + + elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level >= 6 then --fast regeneration + food_tick_timer = 0 + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) end + end end) From 2f053885414d0cc5d480e92d2acc63e7e7de8b1a Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Mon, 8 Nov 2021 15:49:05 +0100 Subject: [PATCH 4/6] Add one food_tick_timer per player instead of using one for all players. --- mods/PLAYER/mcl_hunger/init.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 0405c28ef..1e3d07a47 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -137,11 +137,16 @@ end) -local food_tick_timer = 0 +local food_tick_timers = {} --one food_tick_timer per player, keys are the player-objects minetest.register_globalstep(function(dtime) - food_tick_timer = food_tick_timer + dtime - for _,player in ipairs(minetest.get_connected_players()) do + + local food_tick_timer = food_tick_timers[player] + if food_tick_timer == nil then + food_tick_timer = 0 + else + food_tick_timer = food_tick_timer + dtime + end local player_name = player:get_player_name() local food_level = mcl_hunger.get_hunger(player) @@ -172,6 +177,7 @@ minetest.register_globalstep(function(dtime) mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) end + food_tick_timers[player] = food_tick_timer --update food_tick_timer table end end) From e82d21040c952e78fa8c64c8a32405d311a8a43c Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Mon, 8 Nov 2021 19:15:56 +0100 Subject: [PATCH 5/6] minor changes, ipairs() replaced with pairs() --- mods/PLAYER/mcl_hunger/init.lua | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 1e3d07a47..3a7af7e67 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -139,15 +139,9 @@ end) local food_tick_timers = {} --one food_tick_timer per player, keys are the player-objects minetest.register_globalstep(function(dtime) - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do - local food_tick_timer = food_tick_timers[player] - if food_tick_timer == nil then - food_tick_timer = 0 - else - food_tick_timer = food_tick_timer + dtime - end - + local food_tick_timer = food_tick_timers[player] and food_tick_timers[player] + dtime or 0 local player_name = player:get_player_name() local food_level = mcl_hunger.get_hunger(player) local food_saturation_level = mcl_hunger.get_saturation(player) @@ -157,15 +151,14 @@ minetest.register_globalstep(function(dtime) food_tick_timer = 0 if food_level >= 18 and player_health < 20 then --slow regenration - food_tick_timer = 0 player:set_hp(player_health+1) mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) elseif food_level == 0 then --starvation - maximumStarvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + local maximum_starvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) -- TODO: implement Minecraft-like difficulty modes and the update maximumStarvation here - if player_health > maximumStarvation then + if player_health > maximum_starvation then mcl_util.deal_damage(player, 1, {type = "starve"}) end end From 017bf705e9f5b549a45d448b89a0d1d347db370c Mon Sep 17 00:00:00 2001 From: Dieter44 <55900078+Dieter44@users.noreply.github.com> Date: Tue, 9 Nov 2021 19:35:32 +0100 Subject: [PATCH 6/6] Fixing that player can regenerate health in death screen and then respawn without HP being set to maximum --- mods/PLAYER/mcl_hunger/init.lua | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 3a7af7e67..e54fb2fb2 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -150,10 +150,12 @@ minetest.register_globalstep(function(dtime) if food_tick_timer > 4.0 then food_tick_timer = 0 - if food_level >= 18 and player_health < 20 then --slow regenration - player:set_hp(player_health+1) - mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + if food_level >= 18 then --slow regenration + if player_health > 0 and player_health < 20 then + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + end elseif food_level == 0 then --starvation local maximum_starvation = 1 --the amount of health at which a player will stop to get harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) @@ -164,10 +166,12 @@ minetest.register_globalstep(function(dtime) end elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level >= 6 then --fast regeneration - food_tick_timer = 0 - player:set_hp(player_health+1) - mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + if player_health > 0 and player_health < 20 then + food_tick_timer = 0 + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + end end food_tick_timers[player] = food_tick_timer --update food_tick_timer table