Fix projectiles reacing incorrectly with land just behind the wrap world edge
authorWuzzy <Wuzzy2@mail.ru>
Mon, 06 Aug 2018 18:55:22 +0200
changeset 13615 f1b6070a6e14
parent 13614 13f68f3e7153
child 13616 65a10215ba43
Fix projectiles reacing incorrectly with land just behind the wrap world edge
ChangeLog.txt
hedgewars/uGearsHandlersMess.pas
hedgewars/uGearsHedgehog.pas
hedgewars/uGearsList.pas
hedgewars/uTypes.pas
--- a/ChangeLog.txt	Mon Aug 06 15:56:03 2018 +0200
+++ b/ChangeLog.txt	Mon Aug 06 18:55:22 2018 +0200
@@ -17,6 +17,7 @@
  * Fix cake walking through bounce world edge
  * Cake now stops at wrap world edge instead of walking through land (temporary fix)
  * 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
  * Fix hog being unable to walk after using sniper rifle without firing both shots
  * Fix video recorder not working when game audio was disabled
--- a/hedgewars/uGearsHandlersMess.pas	Mon Aug 06 15:56:03 2018 +0200
+++ b/hedgewars/uGearsHandlersMess.pas	Mon Aug 06 18:55:22 2018 +0200
@@ -325,11 +325,20 @@
     tX:= Gear^.X;
     gX:= hwRound(Gear^.X);
     gY:= hwRound(Gear^.Y);
-    if (Gear^.Kind <> gtGenericFaller) and WorldWrap(Gear) and (WorldEdge = weWrap) and (Gear^.AdvBounce <> 0) and
+    Gear^.State := Gear^.State and (not gstCollision);
+
+    // World wrap
+    if (Gear^.Kind <> gtGenericFaller) and WorldWrap(Gear) and (WorldEdge = weWrap) and
       ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0))  then
         begin
-        Gear^.X:= tX;
-        Gear^.dX.isNegative:= (gX > LongInt(leftX) + Gear^.Radius*2)
+        // Collision with land that *just* behind the other side of the world wrap edge
+        if (not Gear^.Sticky) then
+            begin
+            Gear^.X:= tX;
+            Gear^.dX.isNegative:= (gX > LongInt(leftX) + Gear^.Radius*2);
+            Gear^.dX := Gear^.dX * Gear^.Friction;
+            end;
+        Gear^.State := Gear^.State or gstCollision;
         end;
 
     // clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems.
@@ -344,7 +353,6 @@
         Gear^.dY:= Gear^.dY * _0_999
         end;
 
-    Gear^.State := Gear^.State and (not gstCollision);
     collV := 0;
     collH := 0;
     tdX := Gear^.dX;
--- a/hedgewars/uGearsHedgehog.pas	Mon Aug 06 15:56:03 2018 +0200
+++ b/hedgewars/uGearsHedgehog.pas	Mon Aug 06 18:55:22 2018 +0200
@@ -1564,9 +1564,14 @@
        (CurAmmoGear <> nil) and (CurAmmoGear^.Kind =gtRope) and (CurAmmoGear^.Elasticity <> _0) then
        CurAmmoGear^.PortalCounter:= 1;
     if (WorldEdge = weWrap) and ((TestCollisionXwithGear(Gear, 1) <> 0) or (TestCollisionXwithGear(Gear, -1) <> 0))  then
+        // Stop hedgehog if it collides with land *just* behind other side of world wrap edge
         begin
-        Gear^.X:= tX;
-        Gear^.dX.isNegative:= (hwRound(tX) > LongInt(leftX) + Gear^.Radius * 2)
+        if (hwRound(tX) > LongInt(leftX) + Gear^.Radius * 2) then
+            Gear^.X:= int2HwFloat(RightX)
+        else
+            Gear^.X:= int2HwFloat(LeftX);
+        Gear^.dX.QWordValue:= 0;
+        Gear^.State := Gear^.State or gstCollision;
         end
     end;
 
--- a/hedgewars/uGearsList.pas	Mon Aug 06 15:56:03 2018 +0200
+++ b/hedgewars/uGearsList.pas	Mon Aug 06 18:55:22 2018 +0200
@@ -207,6 +207,7 @@
 gear^.CollisionMask:= lfAll;
 gear^.Tint:= $FFFFFFFF;
 gear^.Data:= nil;
+gear^.Sticky:= false;
 
 if CurrentHedgehog <> nil then
     begin
@@ -353,6 +354,7 @@
                     Pos:= 0;
                     Radius:= 1;
                     DirAngle:= random(360);
+                    Sticky:= true;
                     if State and gstTmpFlag = 0 then
                         begin
                         dx.isNegative:= GetRandom(2) = 0;
@@ -463,6 +465,7 @@
                 gear^.Friction:= _0_995;
                 gear^.Density:= _1_6;
                 gear^.AdvBounce:= 1;
+                gear^.Sticky:= true;
                 if gear^.Timer = 0 then gear^.Timer:= 500;
                 end;
        gtKnife: begin
@@ -471,7 +474,8 @@
                 gear^.Elasticity:= _0_8;
                 gear^.Friction:= _0_8;
                 gear^.Density:= _4;
-                gear^.Radius:= 7
+                gear^.Radius:= 7;
+                gear^.Sticky:= true;
                 end;
         gtCase: begin
                 gear^.ImpactSound:= sndGraveImpact;
@@ -671,6 +675,7 @@
                 gear^.Timer:= 15000;
                 gear^.RenderTimer:= false;
                 gear^.Health:= 100;
+                gear^.Sticky:= true;
                 end;
        gtPiano: begin
                 gear^.Radius:= 32;
--- a/hedgewars/uTypes.pas	Mon Aug 06 15:56:03 2018 +0200
+++ b/hedgewars/uTypes.pas	Mon Aug 06 18:55:22 2018 +0200
@@ -268,6 +268,7 @@
             Radius: LongInt;     // Radius. If not using uCollisions, is usually used to indicate area of effect
             CollisionMask: Word; // Masking off Land impact  FF7F for example ignores current hog and crates
             AdvBounce: Longword; // Triggers 45 bounces. Is a counter to avoid edge cases
+            Sticky: Boolean;     // True if gear is *normally* able to stick to landscape on impact
             Elasticity: hwFloat;
             Friction  : hwFloat;
             Density   : hwFloat; // Density is kind of a mix of size and density. Impacts distance thrown, wind.