let sinegun bounce on weBounce
authorsheepluva
Thu, 11 Dec 2014 13:35:35 +0100
changeset 10657 f2507005be87
parent 10656 2093cf51eea1
child 10658 a3872ffdeab1
let sinegun bounce on weBounce
hedgewars/uGearsHandlersMess.pas
--- a/hedgewars/uGearsHandlersMess.pas	Thu Dec 11 21:00:42 2014 +0900
+++ b/hedgewars/uGearsHandlersMess.pas	Thu Dec 11 13:35:35 2014 +0100
@@ -4574,7 +4574,7 @@
 var
     x, y, rX, rY, t, tmp, initHealth: LongInt;
     oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
-    justCollided: boolean;
+    justCollided, justBounced: boolean;
 begin
     AllInactive := false;
     initHealth := Gear^.Health;
@@ -4597,6 +4597,8 @@
 
     // used for a work-around detection of area that is within land array, but outside borders
     justCollided := false;
+    // this variable is just to ensure we don't run in infinite loop due to precision errors
+    justBounced:= false;
 
     repeat
         lX := lX + ldX;
@@ -4609,7 +4611,6 @@
         amp := _128 * (_1 - hwSqr(int2hwFloat(Gear^.Health)/initHealth));
         sine := amp * AngleSin(tmp mod 2048);
         sine.isNegative := (tmp < 2048);
-        inc(t,Gear^.Health div 313);
         Gear^.X := lX + (sine * sdX);
         Gear^.Y := ly + (sine * sdY);
         Gear^.dX := Gear^.X - oX;
@@ -4630,8 +4631,28 @@
                 inc(x,  playWidth);
                 inc(rx, playWidth);
                 until x >= LongInt(leftX);
+            end
+        else if (WorldEdge = weBounce) then
+            begin
+            if (not justBounced) and ((x > LongInt(rightX)) or (x < LongInt(leftX))) then
+                begin
+                // reflect
+                lX:= lX - ldX + ((oX - lX) * 2);
+                lY:= lY - ldY;
+                Gear^.X:= oX;
+                Gear^.Y:= oY;
+                ldX.isNegative:= (not ldX.isNegative);
+                sdX.isNegative:= (not sdX.isNegative);
+                justBounced:= true;
+                continue;
+                end
+            else
+                justBounced:= false;
             end;
 
+
+        inc(t,Gear^.Health div 313);
+
         // if borders are on, stop outside land array
         if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then
             begin