# HG changeset patch # User Wuzzy # Date 1533584108 -7200 # Node ID c9642782778b7113e023faae2c51d7117a20e449 # Parent d6b79a080a3ec7a26962f19fec53b28bec0f9239 Fix cake walking through land when reaching wrap world edge But there still is some cake weirdness remaining, sadly. See code comments. diff -r d6b79a080a3e -r c9642782778b ChangeLog.txt --- 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 diff -r d6b79a080a3e -r c9642782778b hedgewars/uGearsHandlers.pas --- 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); diff -r d6b79a080a3e -r c9642782778b hedgewars/uGearsHandlersMess.pas --- 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;