Make air mines follow hedgehogs across wrap world edge
authorWuzzy <Wuzzy2@mail.ru>
Mon, 23 Oct 2017 22:45:35 +0200
changeset 12744 058a5d373e4a
parent 12743 f45ffb4cf1e1
child 12745 c162995831d8
Make air mines follow hedgehogs across wrap world edge
hedgewars/uGearsHandlersMess.pas
hedgewars/uUtils.pas
--- a/hedgewars/uGearsHandlersMess.pas	Mon Oct 23 17:29:56 2017 +0200
+++ b/hedgewars/uGearsHandlersMess.pas	Mon Oct 23 22:45:35 2017 +0200
@@ -209,7 +209,7 @@
         begin
         if (gi^.Kind = gtHedgehog) then
             begin
-            d := r - hwRound(Distance(gi^.X - x, gi^.Y - y));
+            d := r - hwRound(PointDistance(gi^.X, x, gi^.Y, y, true));
             if (d > 1) and (gi^.Hedgehog^.Effects[heInvulnerable] = 0) and (GetRandom(2) = 0) then
                 begin
                 if (CurrentHedgehog^.Gear = gi) then
@@ -1808,7 +1808,7 @@
 procedure doStepAirMine(Gear: PGear);
 var i,t,targDist,tmpDist: LongWord;
     targ, tmpG: PGear;
-    trackSpeed, airFriction, tX, tY: hwFloat;
+    trackSpeed, airFriction: hwFloat;
     isUnderwater: Boolean;
 begin
     isUnderwater:= CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + Gear^.Radius);
@@ -1835,12 +1835,9 @@
         targ:= Gear^.Hedgehog^.Gear;
     if targ <> nil then
         begin
-        tX:=Gear^.X-targ^.X;
-        tY:=Gear^.Y-targ^.Y;
         // allow escaping - should maybe flag this too
         if (GameTicks > Gear^.FlightTime+10000) or 
-            ((tX.Round+tY.Round > Gear^.Angle*6) and
-            (hwRound(hwSqr(tX) + hwSqr(tY)) > sqr(Gear^.Angle*6))) then
+            (hwRound(PointDistance(Gear^.X, targ^.X, Gear^.Y, targ^.Y, true)) > Gear^.Angle*6) then
             targ:= nil
         end;
 
@@ -1860,7 +1857,7 @@
         begin
         gear^.State:= gear^.State or gstChooseTarget;
         if targ <> nil then
-             targDist:= Distance(Gear^.X-targ^.X,Gear^.Y-targ^.Y).Round
+             targDist:= PointDistance(Gear^.X, targ^.X, Gear^.Y, targ^.Y, true).Round
         else targDist:= 0;
         for t:= 0 to Pred(TeamsCount) do
             with TeamsArray[t]^ do
@@ -1868,16 +1865,13 @@
                     if Hedgehogs[i].Gear <> nil then
                         begin
                         tmpG:= Hedgehogs[i].Gear;
-                        tX:=Gear^.X-tmpG^.X;
-                        tY:=Gear^.Y-tmpG^.Y;
                         if (Gear^.Angle = $FFFFFFFF) or
-                            ((tX.Round+tY.Round < Gear^.Angle) and
-                            (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Angle))) then
+                            (hwRound(PointDistance(Gear^.X, tmpG^.X, Gear^.Y, tmpG^.Y, true)) < Gear^.Angle) then
                             begin
-                            if targ <> nil then tmpDist:= Distance(tX,tY).Round;
+                            if targ <> nil then tmpDist:= PointDistance(Gear^.X, tmpG^.X, Gear^.Y, tmpG^.Y, true).Round;
                             if (targ = nil) or (tmpDist < targDist) then
                                 begin
-                                if targ = nil then targDist:= Distance(tX,tY).Round
+                                if targ = nil then targDist:= PointDistance(Gear^.X, tmpG^.X, Gear^.Y, tmpG^.Y, true).Round
                                 else targDist:= tmpDist;
                                 Gear^.Hedgehog:= @Hedgehogs[i];
                                 targ:= tmpG;
@@ -1894,9 +1888,15 @@
         else
             trackSpeed.QWordValue:= Gear^.Power;
         if (Gear^.X < targ^.X) and (Gear^.dX < _0_1)  then
-             Gear^.dX:= Gear^.dX+trackSpeed // please leave as an add.  I like the effect
+            if (WorldEdge = weWrap) and ((targ^.X - Gear^.X) > ((Gear^.X - int2hwFloat(LeftX)) + (int2hwFloat(RightX) - targ^.X))) then
+                 Gear^.dX:= Gear^.dX-trackSpeed
+            else
+                 Gear^.dX:= Gear^.dX+trackSpeed // please leave as an add.  I like the effect
         else if (Gear^.X > targ^.X) and (Gear^.dX > -_0_1) then
-            Gear^.dX:= Gear^.dX-trackSpeed;
+            if (WorldEdge = weWrap) and ((Gear^.X - targ^.X) > ((targ^.X - int2hwFloat(LeftX)) + (int2hwFloat(RightX) - Gear^.X))) then
+                Gear^.dX:= Gear^.dX+trackSpeed
+            else
+                Gear^.dX:= Gear^.dX-trackSpeed;
         if (Gear^.Y < targ^.Y) and (Gear^.dY < _0_1)  then
              Gear^.dY:= Gear^.dY+trackSpeed
         else if (Gear^.Y > targ^.Y) and (Gear^.dY > -_0_1) then
@@ -1912,10 +1912,7 @@
                 begin
                 if targ <> nil then
                     begin
-                    tX:=Gear^.X-targ^.X;
-                    tY:=Gear^.Y-targ^.Y;
-                    if (tX.Round+tY.Round < Gear^.Karma) and
-                       (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Karma)) then
+                    if (hwRound(PointDistance(Gear^.X, targ^.X, Gear^.Y, targ^.Y, true)) < Gear^.Karma) then
                     Gear^.State := Gear^.State or gstAttacking
                     end
                 else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Karma, Gear^.Karma) <> nil) then
@@ -1932,10 +1929,7 @@
                 // recheck
                 if targ <> nil then
                     begin
-                    tX:=Gear^.X-targ^.X;
-                    tY:=Gear^.Y-targ^.Y;
-                    if (tX.Round+tY.Round < Gear^.Karma) and
-                       (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Karma)) then
+                    if (hwRound(PointDistance(Gear^.X, targ^.X, Gear^.Y, targ^.Y, true)) < Gear^.Karma) then
                         begin
                         Gear^.Hedgehog:= CurrentHedgehog;
                         tmpG:= FollowGear;
--- a/hedgewars/uUtils.pas	Mon Oct 23 17:29:56 2017 +0200
+++ b/hedgewars/uUtils.pas	Mon Oct 23 22:45:35 2017 +0200
@@ -57,6 +57,8 @@
 function  DxDy2AttackAngle(const _dY, _dX: hwFloat): LongInt;
 function  DxDy2AttackAnglef(const _dY, _dX: extended): LongInt;
 
+function PointDistance(const x1, x2, y1, y2: hwFloat; checkWrap: boolean): hwFloat;
+
 procedure SetLittle(var r: hwFloat);
 
 function  Str2PChar(const s: shortstring): PChar;
@@ -377,6 +379,37 @@
 DxDy2AttackAnglef:= trunc(arctan2(_dY, _dX) * (cMaxAngle/pi))
 end;
 
+function PointDistance(const x1, x2, y1, y2: hwFloat; checkWrap: boolean): hwFloat;
+var dist_center, dist_across: hwFloat;
+vx1, vx2, vy1, vy2: hwFloat;
+begin
+    // Sort values
+    vx1:= x1;
+    vx2:= x2;
+    vy1:= y1;
+    vy2:= y2;
+    if x1 < x2 then
+        begin
+        vx1:= x2;
+        vx2:= x1;
+        end;
+    if y1 < y2 then
+        begin
+        vy1:= y2;
+        vy2:= y1;
+        end;
+    if checkWrap and (WorldEdge = weWrap) then
+        begin
+        dist_center:= Distance(vx2-vx1, vy2-vy1);
+        dist_across:= Distance((vx2 - int2hwFloat(LeftX)) + (int2hwFloat(RightX) - vx1), vy2-vy1);
+        if (dist_across < dist_center) then
+            PointDistance:= dist_across
+        else
+            PointDistance:= dist_center;
+        end
+    else
+        PointDistance:= Distance(vx2-vx1, vy2-vy1);
+end;
 
 procedure SetLittle(var r: hwFloat);
 begin