Bounce world edge: Fix buggy gear behaviour if gear spawned inside bounce edge area
authorWuzzy <Wuzzy2@mail.ru>
Thu, 11 Jul 2019 00:45:49 +0200
changeset 15223 32678e65b25e
parent 15222 deaa316af414
child 15224 f16376e9374f
Bounce world edge: Fix buggy gear behaviour if gear spawned inside bounce edge area
hedgewars/uConsts.pas
hedgewars/uGearsList.pas
hedgewars/uGearsUtils.pas
--- a/hedgewars/uConsts.pas	Tue Jul 09 12:55:58 2019 +0200
+++ b/hedgewars/uConsts.pas	Thu Jul 11 00:45:49 2019 +0200
@@ -286,6 +286,7 @@
     gstSubmersible    = $00400000; // can survive in water
     gstFrozen         = $00800000; // frozen
     gstNoGravity      = $01000000; // ignores gravity
+    gstInBounceEdge   = $02000000; // spawned in bounce edge
 
     // gear messages
     gmLeft           = $00000001; // left
--- a/hedgewars/uGearsList.pas	Tue Jul 09 12:55:58 2019 +0200
+++ b/hedgewars/uGearsList.pas	Thu Jul 11 00:45:49 2019 +0200
@@ -219,6 +219,53 @@
     gear^.Z:= cHHZ+1
 else gear^.Z:= cUsualZ;
 
+// set gstInBounceEdge if gear spawned inside the bounce world edge
+if WorldEdge = weBounce then
+    if (hwRound(gear^.X) - Gear^.Radius < leftX) or (hwRound(gear^.X) + Gear^.Radius > rightX) then
+        case gear^.Kind of
+            // list all gears here that could collide with the bounce world edge
+            gtHedgehog,
+            gtMine,
+            gtAirBomb,
+            gtDrill,
+            gtNapalmBomb,
+            gtCase,
+            gtAirMine,
+            gtExplosives,
+            gtGrenade,
+            gtShell,
+            gtBee,
+            gtDynamite,
+            gtClusterBomb,
+            gtMelonPiece,
+            gtCluster,
+            gtMortar,
+            gtKamikaze,
+            gtCake,
+            gtWatermelon,
+            gtGasBomb,
+            gtHellishBomb,
+            gtBall,
+            gtRCPlane,
+            gtSniperRifleShot,
+            gtShotgunShot,
+            gtDEagleShot,
+            gtSineGunShot,
+            gtMinigunBullet,
+            gtEgg,
+            gtPiano,
+            gtSMine,
+            gtSnowball,
+            gtKnife,
+            gtCreeper,
+            gtMolotov,
+            gtFlake,
+            gtGrave,
+            gtPortal,
+            gtTarget:
+            gear^.State := gear^.State or gstInBounceEdge;
+        end;
+
 case Kind of
           gtFlame: Gear^.Boom := 2;  // some additional expl in there are x3, x4 this
        gtHedgehog: Gear^.Boom := 30;
--- a/hedgewars/uGearsUtils.pas	Tue Jul 09 12:55:58 2019 +0200
+++ b/hedgewars/uGearsUtils.pas	Thu Jul 11 00:45:49 2019 +0200
@@ -1807,20 +1807,31 @@
     else if WorldEdge = weBounce then
         begin
         bounced:= false;
+        // Bounce left
         if (hwRound(Gear^.X) - Gear^.Radius < leftX) and (((hwSign(Gear^.dX) = -1) and (not isZero(Gear^.dX))) or (Gear^.Kind = gtHedgehog)) then
             begin
             LeftImpactTimer:= 333;
+            // Set X coordinate to bounce edge, unless the gear spawned inside the bounce edge before
+            if (Gear^.State and gstInBounceEdge) = 0 then
+                Gear^.X:= int2hwfloat(leftX + Gear^.Radius);
+            // Invert horizontal speed
             Gear^.dX.isNegative:= false;
-            Gear^.X:= int2hwfloat(leftX + Gear^.Radius);
             bounced:= true;
             end
+        // Bounce right
         else if (hwRound(Gear^.X) + Gear^.Radius > rightX) and (((hwSign(Gear^.dX) = 1) and (not isZero(Gear^.dX))) or (Gear^.Kind = gtHedgehog)) then
             begin
             RightImpactTimer:= 333;
+            // Set X coordinate to bounce edge, unless the gear spawned inside the bounce edge before
+            if (Gear^.State and gstInBounceEdge) = 0 then
+                Gear^.X:= int2hwfloat(rightX - Gear^.Radius);
+            // Invert horizontal speed
             Gear^.dX.isNegative:= true;
-            Gear^.X:= int2hwfloat(rightX-Gear^.Radius);
             bounced:= true;
             end;
+        // Clear gstInBounceEdge when gear is no longer inside a bounce edge area
+        if ((Gear^.State and gstInBounceEdge) <> 0) and (hwRound(Gear^.X) - Gear^.Radius >= leftX) and (hwRound(Gear^.X) + Gear^.Radius <= rightX) then
+            Gear^.State:= Gear^.State and (not gstInBounceEdge);
         if (bounced) then
             begin
             WorldWrap:= true;