Bounce world edge: Fix buggy gear behaviour if gear spawned inside bounce edge area
--- 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;