1. Hey Guest! We've announced our new game Wargroove, check out the new forums!
    Dismiss Notice

RELEASED Regeneration 1.1.3

Provides configurable health and stamina regeneration.

  1. Hammurabi

    Hammurabi Aquatic Astronaut

    Hammurabi submitted a new mod:

    Regeneration - Provides configurable health and stamina regeneration.

    Read more about this mod...
     
      littleraskol likes this.
    • Hammurabi

      Hammurabi Aquatic Astronaut

      Source code:

      Code:
      using System;
      using StardewModdingAPI;
      using StardewModdingAPI.Events;
      using StardewValley;
      
      namespace Regeneration {
      
         public class ModConfig {
           public float healthRegenAbsolutePerSecond { get; set; }
           public float healthRegenPercentagePerSecond { get; set; }
           public double healthIdleSeconds { get; set; }
           public float regenHealthWhileRunningRate { get; set; }
           public bool loseFractionalHealthWhenInjured { get; set; }
      
           public float staminaRegenAbsolutePerSecond { get; set; }
           public float staminaRegenPercentagePerSecond { get; set; }
           public double staminaIdleSeconds { get; set; }
           public float regenStaminaWhileRunningRate { get; set; }
      
           public bool removeExhaustion { get; set; }
           public float removeExhaustionStaminaPercentage { get; set; }
      
      
           public ModConfig() {
             healthRegenAbsolutePerSecond = 0.1f;
             healthRegenPercentagePerSecond = 0.0f;
             healthIdleSeconds = 15.0;
             regenHealthWhileRunningRate = 0.0f;
             loseFractionalHealthWhenInjured = false;
      
             staminaRegenAbsolutePerSecond = 0.0f;
             staminaRegenPercentagePerSecond = (1.0f / 270.0f); // Recover 1 stamina per second at game start, but increase as max stamina increases.
             staminaIdleSeconds = 10.0;
             regenStaminaWhileRunningRate = 0.25f;
      
             removeExhaustion = false;
             removeExhaustionStaminaPercentage = 1.0f;
           }
         }
      
         public class Regeneration : Mod {
           // Health values
           int lastHealth;
           float healthAccum;  // Accumulated health regenerated while running.
           double healthRegenStartTime;  // The time when health regeneration should next begin. Updated after taking damage.
      
           // Stamina values
           float lastStamina;  // Last recorded player stamina value.
           double staminaRegenStartTime;       // The time when stamina regeneration should next begin. Updated after losing stamina.
      
           // Control values
           double lastTickTime;  // The time at the last tick processed.
           bool playerIsRunning;  // Whether the player has run since the preceeding update tick.
      
           Farmer Player;  // Our player.
           ModConfig myConfig;  // Config data.
      
           public override void Entry(IModHelper helper) {
             myConfig = helper.ReadConfig<ModConfig>();
      
             // Validate settings and re-save the config file.
      
             // Percentage values can't be greater than 100%.
             if (myConfig.healthRegenPercentagePerSecond > 1.0) { myConfig.healthRegenPercentagePerSecond = 1.0f; }
             if (myConfig.staminaRegenPercentagePerSecond > 1.0) { myConfig.staminaRegenPercentagePerSecond = 1.0f; }
             if (myConfig.removeExhaustionStaminaPercentage > 1.0) { myConfig.removeExhaustionStaminaPercentage = 1.0f; }
      
             // Remove Exhaustion percentage shouldn't be less than 0%.
             if (myConfig.removeExhaustionStaminaPercentage < 0.0) { myConfig.removeExhaustionStaminaPercentage = 0.0f; }
      
             // Max running rate can't be higher than base.
             if (myConfig.regenHealthWhileRunningRate > 1.0) { myConfig.regenHealthWhileRunningRate = 1.0f; }
             if (myConfig.regenStaminaWhileRunningRate > 1.0) { myConfig.regenStaminaWhileRunningRate = 1.0f; }
             
             // Idle times can't be negative.
             if (myConfig.healthIdleSeconds < 0) { myConfig.healthIdleSeconds = 0; }
             if (myConfig.staminaIdleSeconds < 0) { myConfig.staminaIdleSeconds = 0; }
      
             helper.WriteConfig<ModConfig>(myConfig);
      
             healthAccum = 0.0f;
             lastHealth = 0;
             lastStamina = 0;
             lastTickTime = 0.0;
             playerIsRunning = false;
      
             GameEvents.UpdateTick += OnUpdateTick;
           }
      
           private void OnUpdateTick(object sender, EventArgs e) {
             Player = Game1.player;
      
             // If game is running, and time can pass (i.e., are not in an event/cutscene/menu/festival)
             if (Game1.hasLoadedGame && Game1.shouldTimePass()) {
               // Make sure we know exactly how much time has elapsed
               double currentTime = Game1.currentGameTime.TotalGameTime.TotalSeconds;
               float timeElapsed = (float) (currentTime - lastTickTime);
               lastTickTime = currentTime;
      
               // Check for player injury. If player has been injured since last tick, recalculate the time when health regeneration should start.
               if (Player.health < lastHealth)
               {
                 healthRegenStartTime = currentTime + myConfig.healthIdleSeconds;
                 if (myConfig.loseFractionalHealthWhenInjured) { healthAccum = 0; }
               }
      
               // Check for player exertion. If player has used stamina since last tick, recalculate the time when stamina regeneration should start.
               if (Player.stamina < lastStamina) { staminaRegenStartTime = currentTime + myConfig.staminaIdleSeconds; }
      
               /* Determine whether movement status will block normal regeneration: If player is...
        * 1. running, and
        * 2. has moved recently, and
        * 3. is not on horseback, then
        * movement blocks normal regen and the running rate prevails. (If the running rate is 0, there is no regeneration.)
        */
               if (Player.running && Player.movedDuringLastTick() && !Player.isRidingHorse()) { playerIsRunning = true; }
               else { playerIsRunning = false; }
      
               // Process health regeneration.
               if (healthRegenStartTime <= currentTime && Player.health < Player.maxHealth) {
                 float absRegen = myConfig.healthRegenAbsolutePerSecond * timeElapsed;
                 float percRegen = myConfig.healthRegenPercentagePerSecond * Player.maxHealth * timeElapsed;
                 healthAccum += (absRegen + percRegen) * (playerIsRunning ? myConfig.regenHealthWhileRunningRate : 1);
                 if (healthAccum >= 1) {
                   Player.health += 1;
                   healthAccum -= 1;
                 }
               }
      
               // Process stamina regeneration.
               if (staminaRegenStartTime <= currentTime && Player.stamina < Player.maxStamina) {
                 float absRegen = myConfig.staminaRegenAbsolutePerSecond * timeElapsed;
                 float percRegen = myConfig.staminaRegenPercentagePerSecond * Player.maxStamina * timeElapsed;
                 Player.stamina += (absRegen + percRegen) * (playerIsRunning ? myConfig.regenStaminaWhileRunningRate : 1);
      
                 // Final sanity check
                 if (Player.stamina > Player.maxStamina) { Player.stamina = Player.maxStamina; }
               }
      
               // Updated stored health/stamina values.
               lastHealth = Player.health;
               lastStamina = Player.stamina;
      
               // Remove exhaustion if the player is sufficiently recovered.
               if (myConfig.removeExhaustion && (Player.stamina / Player.maxStamina) > myConfig.removeExhaustionStaminaPercentage) {
                 Player.exhausted = false;
               }
             }
           }
         }
      }
       
      • littleraskol

        littleraskol Twenty-three is number one

        Very disappointed you did not call this "ReReRegeneration" tbh :p
         
        • Hammurabi

          Hammurabi Aquatic Astronaut

          I was considering it, LOL.

          Also, major update coming soon; probably tonight, unless I find some unexpected bugs.
           
            littleraskol likes this.
          • Hammurabi

            Hammurabi Aquatic Astronaut

            Hammurabi updated Regeneration with a new update entry:

            v1.1.0

            Read the rest of this update entry...
             
            • Hammurabi

              Hammurabi Aquatic Astronaut

              Hammurabi updated Regeneration with a new update entry:

              v1.1.1

              Read the rest of this update entry...
               
              • Hammurabi

                Hammurabi Aquatic Astronaut

                Hammurabi updated Regeneration with a new update entry:

                v1.1.2

                Read the rest of this update entry...
                 
                • Hammurabi

                  Hammurabi Aquatic Astronaut

                  Hammurabi updated Regeneration with a new update entry:

                  v1.1.3

                  Read the rest of this update entry...
                   

                  Share This Page