Allow freezing airmines because whyyy not
authornemo
Wed, 23 May 2018 20:45:42 -0400
changeset 13399 3d6aae2ae698
parent 13398 d5db8f71e52e
child 13400 6476721e1a38
Allow freezing airmines because whyyy not
hedgewars/uGearsHandlersMess.pas
hedgewars/uGearsHedgehog.pas
hedgewars/uGearsList.pas
hedgewars/uGearsRender.pas
hedgewars/uGearsUtils.pas
--- a/hedgewars/uGearsHandlersMess.pas	Tue May 22 17:54:07 2018 -0400
+++ b/hedgewars/uGearsHandlersMess.pas	Wed May 23 20:45:42 2018 -0400
@@ -1936,6 +1936,15 @@
     trackSpeed, airFriction, tX, tY: hwFloat;
     isUnderwater: Boolean;
 begin
+	if (Gear^.State and gstFrozen) <> 0 then
+		begin
+		if Gear^.Damage > 0 then
+			begin
+			doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound);
+			DeleteGear(Gear)
+			end;
+		exit
+		end;
     isUnderwater:= CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + Gear^.Radius);
     if Gear^.Pos > 0 then
         begin
@@ -2045,11 +2054,11 @@
                     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 (tX.Round+tY.Round < Gear^.Boom) and
+                       (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Boom)) then
                     Gear^.State := Gear^.State or gstAttacking
                     end
-                else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Karma, Gear^.Karma) <> nil) then
+                else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Boom, Gear^.Boom) <> nil) then
                     Gear^.State := Gear^.State or gstAttacking
                 end
             end
@@ -2065,21 +2074,21 @@
                     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 (tX.Round+tY.Round < Gear^.Boom) and
+                       (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Boom)) then
                         begin
                         Gear^.Hedgehog:= CurrentHedgehog;
                         tmpG:= FollowGear;
-                        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Karma, Gear^.Hedgehog, EXPLAutoSound);
+                        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound);
                         FollowGear:= tmpG;
                         DeleteGear(Gear);
                         exit
                         end
                     end
-                else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Karma, Gear^.Karma) <> nil) then
+                else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Boom, Gear^.Boom) <> nil) then
                     begin
                     Gear^.Hedgehog:= CurrentHedgehog;
-                    doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Karma, Gear^.Hedgehog, EXPLAutoSound);
+                    doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound);
                     DeleteGear(Gear);
                     exit
                     end;
@@ -6144,9 +6153,9 @@
         ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
         ndY:= -AngleCos(HHGear^.Angle) * _4;
         if (ndX <> dX) or (ndY <> dY) or
-           ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and
+           (((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and
              (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0)) and
-             (not CheckCoordInWater(Target.X, Target.Y))) then
+             (not CheckCoordInWater(Target.X, Target.Y))) and (CheckGearNear(gtAirMine, int2hwFloat(Target.X),int2hwFloat(Target.Y), Gear^.Radius*2, Gear^.Radius*2) = nil)) then
             begin
             updateTarget(Gear, ndX, ndY);
             Timer := iceWaitCollision;
@@ -6162,7 +6171,7 @@
             if Target.X <> NoPointX then
                 begin
                 CheckCollision(Gear);
-                if (State and gstCollision) <> 0 then
+                if ((State and gstCollision) <> 0) or (CheckGearNear(gtAirMine, int2hwFloat(Target.X),int2hwFloat(Target.Y), Gear^.Radius*3, Gear^.Radius*3) <> nil) then
                     begin
                     if Timer = iceWaitCollision then
                         begin
@@ -6207,7 +6216,7 @@
                     while iter <> nil do
                         begin
                         if (iter^.State and gstFrozen = 0) and
-                           ((iter^.Kind = gtExplosives) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine) or (iter^.Kind = gtSMine)) and
+                           ((iter^.Kind = gtExplosives) or (iter^.Kind = gtAirMine) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine) or (iter^.Kind = gtSMine)) and
                            (abs(LongInt(iter^.X.Round) - target.x) + abs(LongInt(iter^.Y.Round) - target.y) + 2 < 2 * iceRadius)
                            and (Distance(iter^.X - int2hwFloat(target.x), iter^.Y - int2hwFloat(target.y)) < int2hwFloat(iceRadius * 2)) then
                             begin
@@ -6251,6 +6260,11 @@
                                 iter^.State:= iter^.State or gstFrozen;
                                 AddCI(iter)
                                 end
+                            else if iter^.Kind = gtAirMine then
+                                begin
+                                AddCI(iter);
+                                iter^.State:= iter^.State or gstFrozen
+                                end
                             else // gtExplosives
                                 begin
                                 iter^.State:= iter^.State or gstFrozen;
@@ -6321,7 +6335,14 @@
                 Target.Y:= gY;
                 X:= HHGear^.X;
                 Y:= HHGear^.Y
-                end;
+                end
+			else if CheckGearNear(Gear, gtAirMine, Gear^.Radius*2, Gear^.Radius*2) <> nil then
+				begin
+                Target.X:= gX;
+                Target.Y:= gY;
+                X:= HHGear^.X;
+                Y:= HHGear^.Y
+				end; 
             if (gX > max(LAND_WIDTH,4096)*2) or
                     (gX < -max(LAND_WIDTH,4096)) or
                     (gY < -max(LAND_HEIGHT,4096)) or
--- a/hedgewars/uGearsHedgehog.pas	Tue May 22 17:54:07 2018 -0400
+++ b/hedgewars/uGearsHedgehog.pas	Wed May 23 20:45:42 2018 -0400
@@ -788,7 +788,6 @@
 procedure HedgehogStep(Gear: PGear);
 var PrevdX: LongInt;
     CurWeapon: PAmmo;
-    portals: PGearArrayS;
 begin
 CurWeapon:= GetCurAmmoEntry(Gear^.Hedgehog^);
 if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then
@@ -851,12 +850,9 @@
         exit
         end;
 
-    if (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.State and gstMoving = 0) then
-        begin
-        // slightly inefficient since it doesn't halt after one portal, maybe could add a param to GearsNear for number desired.
-        portals:= GearsNear(Gear^.X, Gear^.Y, gtPortal, 26);
-        if portals.size = 0 then Gear^.PortalCounter:= 0
-        end;
+    if (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.State and gstMoving = 0) and 
+		(CheckGearNear(Gear, gtPortal, 26, 26) <> nil) then 
+		Gear^.PortalCounter:= 0;
     PrevdX:= hwSign(Gear^.dX);
     if (Gear^.Message and gmLeft  )<>0 then
         Gear^.dX:= -cLittle else
--- a/hedgewars/uGearsList.pas	Tue May 22 17:54:07 2018 -0400
+++ b/hedgewars/uGearsList.pas	Wed May 23 20:45:42 2018 -0400
@@ -224,7 +224,7 @@
        gtHedgehog: Gear^.Boom := 30;
            gtMine: Gear^.Boom := 50;
            gtCase: Gear^.Boom := 25;
-        gtAirMine: Gear^.Boom := 25;
+        gtAirMine: Gear^.Boom := 30;
      gtExplosives: Gear^.Boom := 75;
         gtGrenade: Gear^.Boom := 50;
           gtShell: Gear^.Boom := 50;
@@ -446,7 +446,6 @@
                 gear^.Angle:= 175; // Radius at which air bombs will start "seeking". $FFFFFFFF = unlimited. check is skipped.
                 gear^.Power:= cMaxWindSpeed.QWordValue div 2; // hwFloat converted. 1/2 g default. defines the "seek" speed when a gear is in range.
                 gear^.Pos:= cMaxWindSpeed.QWordValue * 3 div 2; // air friction. slows it down when not hitting stuff
-                gear^.Karma:= 30; // damage
                 if gear^.Timer = 0 then
                     begin
                     if cMinesTime < 0 then
--- a/hedgewars/uGearsRender.pas	Tue May 22 17:54:07 2018 -0400
+++ b/hedgewars/uGearsRender.pas	Wed May 23 20:45:42 2018 -0400
@@ -1289,9 +1289,9 @@
                        DrawSpriteRotated(sprMineOn, x, y, 0, Gear^.DirAngle)
                     else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle);
                     end;
-         gtAirMine: if Gear^.State and gstTmpFlag = 0 then                // mine is inactive
+         gtAirMine: if (Gear^.State and gstTmpFlag = 0) or (Gear^.State and gstFrozen <> 0) then                // mine is inactive
                         begin
-                        Tint(150,150,150,255);
+						if (Gear^.State and gstTmpFlag = 0) then Tint(150,150,150,255);
                         DrawSprite(sprAirMine, x-16, y-16, 15);
                         untint
                         end
--- a/hedgewars/uGearsUtils.pas	Tue May 22 17:54:07 2018 -0400
+++ b/hedgewars/uGearsUtils.pas	Wed May 23 20:45:42 2018 -0400
@@ -40,6 +40,7 @@
 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline;
 procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
 
+function  CheckGearNear(Kind: TGearType; X, Y: hwFloat; rX, rY: LongInt): PGear;
 function  CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
 function  CheckGearDrowning(var Gear: PGear): boolean;
 procedure CheckCollision(Gear: PGear); inline;
@@ -1025,20 +1026,48 @@
     end
 end;
 
-function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
+function CheckGearNear(Kind: TGearType; X, Y: hwFloat; rX, rY: LongInt): PGear;
 var t: PGear;
+	width: hwFloat;
 begin
 t:= GearsList;
 rX:= sqr(rX);
 rY:= sqr(rY);
+width:= int2hwFloat(RightX-LeftX);
+
+while t <> nil do
+    begin
+    if (t^.Kind = Kind) then
+        if (not ((hwSqr(X - t^.X) / rX + hwSqr(Y - t^.Y) / rY) > _1)) or
+        ((WorldEdge = weWrap) and (
+        (not ((hwSqr(X - width - t^.X) / rX + hwSqr(Y - t^.Y) / rY) > _1)) or
+        (not ((hwSqr(X + width - t^.X) / rX + hwSqr(Y - t^.Y) / rY) > _1)))) then
+        begin
+            CheckGearNear:= t;
+            exit;
+        end;
+    t:= t^.NextGear
+    end;
+
+CheckGearNear:= nil
+end;
+
+function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
+var t: PGear;
+	width: hwFloat;
+begin
+t:= GearsList;
+rX:= sqr(rX);
+rY:= sqr(rY);
+width:= int2hwFloat(RightX-LeftX);
 
 while t <> nil do
     begin
     if (t <> Gear) and (t^.Kind = Kind) then
         if (not ((hwSqr(Gear^.X - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)) or
         ((WorldEdge = weWrap) and (
-        (not ((hwSqr(Gear^.X - int2hwFloat(RightX-LeftX) - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)) or
-        (not ((hwSqr(Gear^.X + int2hwFloat(RightX-LeftX) - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)))) then
+        (not ((hwSqr(Gear^.X - width - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)) or
+        (not ((hwSqr(Gear^.X + width - t^.X) / rX + hwSqr(Gear^.Y - t^.Y) / rY) > _1)))) then
         begin
             CheckGearNear:= t;
             exit;
@@ -1290,6 +1319,7 @@
         case Gear^.Kind of
             gtHedgehog,
             gtMine,
+            gtAirMine,
             gtSMine,
             gtKnife,
             gtTarget,
@@ -1481,7 +1511,6 @@
     GearsNear.ar:= @GearsNearArray
 end;
 
-
 procedure SpawnBoxOfSmth;
 var t, aTot, uTot, a, h: LongInt;
     i: TAmmoType;