some portal changes, warning: no loop prevention yet, note: entry angle not preserved yet
authorsheepluva
Tue, 04 May 2010 00:44:32 +0000
changeset 3414 b2f3bb44777e
parent 3413 d08eaae8d3e8
child 3415 1ca22b3493e9
some portal changes, warning: no loop prevention yet, note: entry angle not preserved yet
hedgewars/GSHandlers.inc
hedgewars/uCollisions.pas
--- a/hedgewars/GSHandlers.inc	Mon May 03 23:56:18 2010 +0000
+++ b/hedgewars/GSHandlers.inc	Tue May 04 00:44:32 2010 +0000
@@ -3043,23 +3043,27 @@
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepPortal(Gear: PGear);
 var iterator: PGear;
+    s: hwFloat;
 begin
     if (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] and $FF00) = 0 then DeleteGear(Gear);
-    if not AllInactive and (Gear^.IntersectGear <> nil) then
+    if Gear^.IntersectGear <> nil then
     //if (Gear^.IntersectGear <> nil) then
         begin
         iterator:= GearsList;
         while iterator <> nil do
             begin
-            if iterator^.Active and (iterator^.Kind <> gtPortal) and 
-               (hwRound(hwAbs(Gear^.X-iterator^.X)+hwAbs(Gear^.Y-iterator^.Y)) < Gear^.Radius+iterator^.Radius) and 
-               ((hwAbs(Gear^.X-(iterator^.X+iterator^.dX))+hwAbs(Gear^.Y-(iterator^.Y+iterator^.dY))).QWordValue < (hwAbs(Gear^.X-iterator^.X)+hwAbs(Gear^.Y-iterator^.Y)).QWordValue) and
-               (hwRound(Distance(Gear^.X-iterator^.X,Gear^.Y-iterator^.Y)) < Gear^.Radius+iterator^.Radius) then // Let's check this one more closely
-                begin
-                iterator^.X:=Gear^.IntersectGear^.X+_128;
-                iterator^.Y:=Gear^.IntersectGear^.Y+_128;
-                iterator^.dX.isNegative:= not iterator^.dX.isNegative;
-                end;
+            if (iterator^.Kind <> gtPortal) then
+                if (((iterator^.State and gstMoving) <> 0) or (Gear^.IntersectGear^.dY.isNegative and not Gear^.dY.isNegative))
+                    and (hwRound(Distance(Gear^.X-iterator^.X,Gear^.Y-iterator^.Y)) < iterator^.Radius+Gear^.Radius) then // Let's check this one more closely
+                        if (Gear^.dX*iterator^.dX + Gear^.dY*iterator^.dY).isNegative then // make sure object moves towards the portal
+                            begin
+                            s:= (_1+(Int2hwFloat(Gear^.Radius))) / Distance(Gear^.IntersectGear^.dX, Gear^.IntersectGear^.dY);
+                            iterator^.X:= Gear^.IntersectGear^.X + s * Gear^.IntersectGear^.dX;
+                            iterator^.Y:= Gear^.IntersectGear^.Y + s * Gear^.IntersectGear^.dY;
+                            s:= Distance(iterator^.dX, iterator^.dY) / Distance(Gear^.IntersectGear^.dX, Gear^.IntersectGear^.dY);
+                            iterator^.dX:= s * Gear^.IntersectGear^.dX;
+                            iterator^.dY:= s * Gear^.IntersectGear^.dY;
+                            end;    
 
             iterator:= iterator^.NextGear;
             end;
@@ -3076,6 +3080,7 @@
 procedure doStepMovingPortal(Gear: PGear);
 var x, y, tx, ty: LongInt;//, bx, by, tangle: LongInt;
     iterator: PGear;
+    s, dx, dy: hwFloat;
 begin
 Gear^.X:= Gear^.X + Gear^.dX;
 Gear^.Y:= Gear^.Y + Gear^.dY;
@@ -3090,8 +3095,31 @@
         DeleteGear(Gear);
         EXIT;
         end;
-    if not Gear^.dX.isNegative then ty:= -ty;
-    Gear^.DirAngle:= DxDy2Angle(Int2hwFloat(tx),Int2hwFloat(ty));
+
+    // reject shots at too irregular terrain
+    if DistanceI(tx,ty) < _10 then
+        begin
+        DeleteGear(Gear);
+        EXIT;
+    end;
+    
+    // making a normal, normalized vector
+    s:= _1/DistanceI(tx,ty);
+    dx:= -s * ty;
+    dy:=  s * tx;
+
+    // make sure the vector is pointing outwards
+    if not (Gear^.dX*dx + Gear^.dY*dy).isNegative then
+    begin
+        dx:= -dx;
+        dy:= -dy;
+    end;
+
+    Gear^.dX:= dx;
+    Gear^.dY:= dy;
+
+    Gear^.DirAngle:= DxDy2Angle(-dy,dx);
+    if not Gear^.dX.isNegative then Gear^.DirAngle:= 180-Gear^.DirAngle;
 (* 
 This is not quite doing what I want, but basically hoping to avoid portals just sitting out in midair
 Works ok for right angles, aaaand that's about it.
--- a/hedgewars/uCollisions.pas	Mon May 03 23:56:18 2010 +0000
+++ b/hedgewars/uCollisions.pas	Tue May 04 00:44:32 2010 +0000
@@ -49,7 +49,7 @@
 function  TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean;
 function  TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean;
 
-function  calcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var deltaX, deltaY: LongInt; TestWord: LongWord): Boolean;
+function  calcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): Boolean;
 
 implementation
 uses uMisc, uConsts, uLand, uLandGraphics;
@@ -315,7 +315,7 @@
 end;
 
 
-function calcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var deltaX, deltaY: LongInt; TestWord: LongWord): boolean;
+function calcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): boolean;
 var ldx, ldy, rdx, rdy: LongInt;
     i, j, mx, my, li, ri, jfr, jto, tmpo : ShortInt;
     tmpx, tmpy: LongWord;
@@ -416,8 +416,8 @@
 
     if ((ldx = 0) and (ldy = 0)) then EXIT(false);
 
-deltaX:= ldx;
-deltaY:= ldy;
+outDeltaX:= ldx;
+outDeltaY:= ldy;
 exit(true);
 end;