Fix cake walking through land when reaching wrap world edge
But there still is some cake weirdness remaining, sadly. See code comments.
--- a/ChangeLog.txt Mon Aug 06 19:33:46 2018 +0200
+++ b/ChangeLog.txt Mon Aug 06 21:35:08 2018 +0200
@@ -15,7 +15,7 @@
* Fix freezer ray not working through wrap world edge
* Fix freezer ray going through bounce world edge
* Fix cake walking through bounce world edge
- * Cake now stops at wrap world edge instead of walking through land (temporary fix)
+ * Fix cake walking through land when reaching wrap world edge
* Laser sight now works properly through wrap world edge
* Fix projectiles reacing incorrectly with land just behind the wrap world edge
* Fix extreme amounts of droplets when shooting with minigun into ocean world edge
--- a/hedgewars/uGearsHandlers.pas Mon Aug 06 19:33:46 2018 +0200
+++ b/hedgewars/uGearsHandlers.pas Mon Aug 06 21:35:08 2018 +0200
@@ -97,12 +97,12 @@
// Handle world wrap and bounce edge manually
if (WorldEdge = weWrap) and
- ((hwRound(Gear^.X) <= LongInt(leftX)) or (hwRound(Gear^.X) >= LongInt(rightX))) then
+ ((hwRound(Gear^.X) < LongInt(leftX)) or (hwRound(Gear^.X) > LongInt(rightX))) then
begin
LeftImpactTimer:= 150;
RightImpactTimer:= 150;
- Gear^.WDTimer:= 4;
- Gear^.Karma:= 2;
+ Gear^.WDTimer:= 0;
+ Gear^.Karma:= 1;
end
else if (WorldEdge = weBounce) and
(((hwRound(Gear^.X) - Gear^.Radius) < LongInt(leftX)) or ((hwRound(Gear^.X) + Gear^.Radius) > LongInt(rightX))) then
@@ -111,7 +111,7 @@
LeftImpactTimer:= 333
else
RightImpactTimer:= 333;
- Gear^.Karma:= 1;
+ Gear^.Karma:= 2;
Gear^.WDTimer:= 0;
if (Gear^.Radius > 2) and (Gear^.dX.QWordValue > _0_001.QWordValue) then
AddBounceEffectForGear(Gear);
--- a/hedgewars/uGearsHandlersMess.pas Mon Aug 06 19:33:46 2018 +0200
+++ b/hedgewars/uGearsHandlersMess.pas Mon Aug 06 21:35:08 2018 +0200
@@ -3568,18 +3568,58 @@
if not cakeStep(Gear) then Gear^.doStep:= @doStepCakeFall;
+ // Cake passed world edge.
if (Gear^.Karma = 1) then
- begin
- // Cake hit bouncy edge, turn around
+ (* This code is not ideal, but at least not horribly broken.
+ The cake tries to reach the other side and continue to walk,
+ but there are some exceptions.
+ This code is called *after* the X coordinate have been wrapped.
+ Depending on terrain on the other side, the cake does this:
+ * Cake collides horizontally (even by 1 pixel): Turn around
+ * Cake does not see walkable ground above or below: Fall
+ * Otherwise: Walk normally
+ *)
+ begin
+ // Update coordinates
+ tdx:=Gear^.X;
+ if (hwRound(Gear^.X) < LongInt(leftX)) then
+ Gear^.X:= Gear^.X + int2hwfloat(rightX - leftX)
+ else Gear^.X:= Gear^.X - int2hwfloat(rightX - leftX);
+
+ Gear^.Tag:= 0;
+ if ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0)) then
+ // Cake collided horizontally, turn around. Prevents cake from being stuck in infinite loop.
+ // This can also happen if the terrain is just a slight slope. :-(
+ begin
+ Gear^.X := tdx;
+ Gear^.Karma := 3;
+ end
+ else
+ begin
+ // Check if cake has something to walk on the other side. If not, make it drop.
+ // There is nothing for the cake to stand on.
+ if (TestCollisionYwithGear(Gear, 1) = 0) and (TestCollisionYwithGear(Gear, -1) = 0) then
+ Gear^.doStep:= @doStepCakeFall;
+ Gear^.Karma := 4;
+ end;
+ end;
+ // Cake bounced!
+ if (Gear^.Karma = 2) or (Gear^.Karma = 3) then
+ begin
+ // Turn cake around
Gear^.dX.isNegative := (not Gear^.dX.isNegative);
Gear^.WDTimer := 0;
Gear^.Angle := (LongInt(Gear^.Angle) + 2) and 3;
- Gear^.Karma := 0;
// Bounce effect
- if (Gear^.Radius > 2) then
+ if (Gear^.Karma = 2) and (Gear^.Radius > 2) then
AddBounceEffectForGear(Gear, 0.55);
+ Gear^.Tag:= 0;
+ Gear^.Karma := 4;
+ end;
+ if (Gear^.Karma = 4) then
+ begin
// Reset CakePoints to fix cake angle
cakeData:= PCakeData(Gear^.Data);
with cakeData^ do
@@ -3591,15 +3631,6 @@
end;
CakeI:= 0;
end;
- Gear^.Tag:= 0;
- end
- else if (Gear^.Karma = 2) then
- begin
- (* Cake passed world edge.
- Cake doesn't know yet how walk through
- world wrap so it gives up and stops.
- TODO: Teach cake how to deal with world wrap. *)
- Gear^.Health := 0;
Gear^.Karma := 0;
end;