Cap hedgehog health to prevent overflow bugs
authorWuzzy <Wuzzy2@mail.ru>
Thu, 02 Aug 2018 03:16:08 +0200
changeset 13602 f7cbf7d8298d
parent 13601 7699987d9f70
child 13603 f4d51ecf6043
Cap hedgehog health to prevent overflow bugs
ChangeLog.txt
hedgewars/uConsts.pas
hedgewars/uGearsHedgehog.pas
hedgewars/uGearsUtils.pas
hedgewars/uScript.pas
hedgewars/uTeams.pas
--- a/ChangeLog.txt	Thu Aug 02 01:52:01 2018 +0200
+++ b/ChangeLog.txt	Thu Aug 02 03:16:08 2018 +0200
@@ -21,6 +21,7 @@
  * Fix cursor teleporting to center after leaving game with a video recording
  * Fix teleport tooltip claiming it doesn't end turn in hog placing phase with inf. attack
  * Fix /hta, /hsa and /hya commands not writing message in chat
+ * Limit hedgehog health to 268435455 to prevent some bugs
 
 Frontend:
  * Controllers are detected again
@@ -82,6 +83,7 @@
  + Can enable infinite fly time for jetpack/Birdy by setting health to JETPACK_FUEL_INFINITE or BIRDY_ENERGY_INFINITE, respectively
  + New global: NoPointX. Value of CursorX and CursorY if cursor is inactive
  + New global: AMMO_INFINITE. Value for infinite ammo count for AddAmmo and other functions
+ + New global: cMaxHogHealth. Maximum possible hedgehog health
  * Changed global: lfCurrentHog becomes lfCurHogCrate
  * Fixed variable: TotalRounds was -1 (instead of 0) in first real round after hog placement phase
  * AI sometimes intentionally shot hedgehogs with aihDoesntMatter set
--- a/hedgewars/uConsts.pas	Thu Aug 02 01:52:01 2018 +0200
+++ b/hedgewars/uConsts.pas	Thu Aug 02 03:16:08 2018 +0200
@@ -181,6 +181,8 @@
     cHHRadius = 9;
     cHHStepTicks = 29;
 
+    cMaxHogHealth : LongInt = High(LongInt) div (cMaxHHIndex+1);
+
     cHHZ = 1000;
     cCurrHHZ = Succ(cHHZ);
 
--- a/hedgewars/uGearsHedgehog.pas	Thu Aug 02 01:52:01 2018 +0200
+++ b/hedgewars/uGearsHedgehog.pas	Thu Aug 02 03:16:08 2018 +0200
@@ -830,6 +830,9 @@
      posCaseHealth: begin
                     PlaySound(sndShotgunReload);
                     inc(HH^.Health, Gear^.Health);
+                    // Prevent overflow
+                    if (HH^.Health < 0) or (HH^.Health > cMaxHogHealth) then
+                        HH^.Health:= cMaxHogHealth;
                     HH^.Hedgehog^.Effects[hePoisoned] := 0;
                     RenderHealth(HH^.Hedgehog^);
                     RecountTeamHealth(HH^.Hedgehog^.Team);
--- a/hedgewars/uGearsUtils.pas	Thu Aug 02 01:52:01 2018 +0200
+++ b/hedgewars/uGearsUtils.pas	Thu Aug 02 03:16:08 2018 +0200
@@ -290,6 +290,9 @@
                     // was considering pulsing on attack, Tiy thinks it should be permanent while in play
                     //CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstVampiric;
                     inc(CurrentHedgehog^.Gear^.Health,vampDmg);
+                    // Prevent overflow
+                    if (CurrentHedgehog^.Gear^.Health < 0) or (CurrentHedgehog^.Gear^.Health > cMaxHogHealth) then
+                        CurrentHedgehog^.Gear^.Health:= cMaxHogHealth;
                     RenderHealth(CurrentHedgehog^);
                     RecountTeamHealth(CurrentHedgehog^.Team);
                     HHHeal(CurrentHedgehog, vampDmg, true, $FF0000FF);
--- a/hedgewars/uScript.pas	Thu Aug 02 01:52:01 2018 +0200
+++ b/hedgewars/uScript.pas	Thu Aug 02 03:16:08 2018 +0200
@@ -1791,6 +1791,10 @@
 
             if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
                 begin
+                if gear^.Health > cMaxHogHealth then
+                    gear^.Health:= cMaxHogHealth;
+                if gear^.Health < 0 then
+                    gear^.Health:= 0;
                 RenderHealth(gear^.Hedgehog^);
                 RecountTeamHealth(gear^.Hedgehog^.Team)
                 end;
@@ -1813,7 +1817,10 @@
         healthBoost:= Trunc(lua_tonumber(L, 2));
         if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (healthBoost >= 1) then
             begin
-            gear^.Health:= gear^.Health + healthBoost;
+            inc(gear^.Health, healthBoost);
+            // Prevent overflow
+            if (gear^.Health < 0) or (gear^.Health > cMaxHogHealth) then
+                gear^.Health:= cMaxHogHealth;
 
             RenderHealth(gear^.Hedgehog^);
             RecountTeamHealth(gear^.Hedgehog^.Team);
@@ -3921,6 +3928,7 @@
 ScriptSetInteger('JETPACK_FUEL_INFINITE', JETPACK_FUEL_INFINITE);
 ScriptSetInteger('BIRDY_ENERGY_INFINITE', BIRDY_ENERGY_INFINITE);
 ScriptSetInteger('NoPointX', NoPointX);
+ScriptSetInteger('cMaxHogHealth', cMaxHogHealth);
 
 // register gear types
 for at:= Low(TGearType) to High(TGearType) do
--- a/hedgewars/uTeams.pas	Thu Aug 02 01:52:01 2018 +0200
+++ b/hedgewars/uTeams.pas	Thu Aug 02 03:16:08 2018 +0200
@@ -495,6 +495,9 @@
                 end
             else
                 Hedgehogs[0].Gear^.Health:= h;
+            // Prevent overflow
+            if (Hedgehogs[0].Gear^.Health < 0) or (Hedgehogs[0].Gear^.Health > cMaxHogHealth) then
+                Hedgehogs[0].Gear^.Health:= cMaxHogHealth;
             Hedgehogs[0].InitialHealth:= Hedgehogs[0].Gear^.Health
             end;
         end;
@@ -614,7 +617,7 @@
     Gear:= AddGear(0, 0, gtHedgehog, 0, _0, _0, 0);
     SplitBySpace(s, id);
     Gear^.Health:= StrToInt(s);
-    if checkFails(Gear^.Health > 0, 'Invalid hedgehog health', true) then exit;
+    if checkFails((Gear^.Health > 0) and (Gear^.Health <= cMaxHogHealth), 'Invalid hedgehog health (must be between 1 and '+IntToStr(cMaxHogHealth)+')', true) then exit;
     if (GameFlags and gfSharedAmmo) <> 0 then
         CurrentHedgehog^.AmmoStore:= Clan^.ClanIndex
     else if (GameFlags and gfPerHogAmmo) <> 0 then