hedgewars/uAIAmmoTests.pas
changeset 15656 21dece8f55fe
parent 15642 92ce801d0681
child 15658 34c32a11203e
equal deleted inserted replaced
15655:0bf5dda8fa43 15656:21dece8f55fe
   569 TestSnowball:= valueResult
   569 TestSnowball:= valueResult
   570 end;
   570 end;
   571 
   571 
   572 function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   572 function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   573 const timeLimit = 50;
   573 const timeLimit = 50;
       
   574       Density : real = 2.0;
   574 var Vx, Vy, r, meX, meY: real;
   575 var Vx, Vy, r, meX, meY: real;
   575     rTime: LongInt;
   576     rTime: LongInt;
   576     EX, EY: LongInt;
   577     EX, EY: LongInt;
   577     valueResult: LongInt;
   578     valueResult: LongInt;
   578     targXWrap, x, y, dX, dY: real;
   579     targXWrap, x, y, dX, dY: real;
   594     rTime:= rTime + 300 + Level * 50 + random(300);
   595     rTime:= rTime + 300 + Level * 50 + random(300);
   595     if (WorldEdge = weWrap) and (random(2)=0) then
   596     if (WorldEdge = weWrap) and (random(2)=0) then
   596          Vx:= (targXWrap + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime
   597          Vx:= (targXWrap + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime
   597     else
   598     else
   598          Vx:= (Targ.Point.X + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime;
   599          Vx:= (Targ.Point.X + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime;
       
   600     if (GameFlags and gfMoreWind) <> 0 then
       
   601          Vx:= -(windSpeed / Density) * rTime * 0.5 + Vx;
   599     Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime;
   602     Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime;
   600     r:= sqr(Vx) + sqr(Vy);
   603     r:= sqr(Vx) + sqr(Vy);
   601 
   604 
   602     if not (r > 1) then
   605     if not (r > 1) then
   603         begin
   606         begin
   607         dY:= -Vy;
   610         dY:= -Vy;
   608         t:= rTime;
   611         t:= rTime;
   609         repeat
   612         repeat
   610             x:= CheckWrap(x);
   613             x:= CheckWrap(x);
   611             x:= x + dX;
   614             x:= x + dX;
       
   615             if (GameFlags and gfMoreWind) <> 0 then
       
   616                 dX:= dX + windSpeed / Density;
   612 
   617 
   613             y:= y + dY;
   618             y:= y + dY;
   614             dY:= dY + cGravityf;
   619             dY:= dY + cGravityf;
   615             dec(t)
   620             dec(t)
   616         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   621         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   652 TestMolotov:= valueResult
   657 TestMolotov:= valueResult
   653 end;
   658 end;
   654 
   659 
   655 function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   660 function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   656 const tDelta = 24;
   661 const tDelta = 24;
       
   662       Density : real = 1.5;
   657 var Vx, Vy, r: real;
   663 var Vx, Vy, r: real;
   658     Score, EX, EY, valueResult: LongInt;
   664     Score, EX, EY, valueResult: LongInt;
   659     TestTime: LongInt;
   665     TestTime: LongInt;
   660     targXWrap, x, y, meX, meY, dY: real;
   666     targXWrap, x, y, meX, meY, dX, dY: real;
   661     t: LongInt;
   667     t: LongInt;
   662 begin
   668 begin
   663 valueResult:= BadTurn;
   669 valueResult:= BadTurn;
   664 TestTime:= 0;
   670 TestTime:= 0;
   665 ap.Bounce:= 0;
   671 ap.Bounce:= 0;
   672     else targXWrap:= Targ.Point.X - (RightX-LeftX);
   678     else targXWrap:= Targ.Point.X - (RightX-LeftX);
   673 repeat
   679 repeat
   674     inc(TestTime, 1000);
   680     inc(TestTime, 1000);
   675     if (WorldEdge = weWrap) and (random(2)=0) then
   681     if (WorldEdge = weWrap) and (random(2)=0) then
   676          Vx:= (targXWrap + AIrndOffset(Targ, Level) - meX) / (TestTime + tDelta)
   682          Vx:= (targXWrap + AIrndOffset(Targ, Level) - meX) / (TestTime + tDelta)
   677     else Vx:= (Targ.Point.X + AIrndOffset(Targ, Level) - meX) / (TestTime + tDelta);
   683     else
       
   684          Vx:= (Targ.Point.X + AIrndOffset(Targ, Level) - meX) / (TestTime + tDelta);
       
   685     if (GameFlags and gfMoreWind) <> 0 then
       
   686          Vx:= -(windSpeed / Density) * (TestTime + tDelta) * 0.5 + Vx;
   678     Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Point.Y - meY) / (TestTime + tDelta);
   687     Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Point.Y - meY) / (TestTime + tDelta);
   679     r:= sqr(Vx) + sqr(Vy);
   688     r:= sqr(Vx) + sqr(Vy);
   680     if not (r > 1) then
   689     if not (r > 1) then
   681         begin
   690         begin
   682         x:= meX;
   691         x:= meX;
   683         y:= meY;
   692         y:= meY;
       
   693         dX:= Vx;
   684         dY:= -Vy;
   694         dY:= -Vy;
   685         t:= TestTime;
   695         t:= TestTime;
   686         repeat
   696         repeat
   687             x:= CheckWrap(x);
   697             x:= CheckWrap(x);
   688             x:= x + Vx;
   698             x:= x + dX;
       
   699             if (GameFlags and gfMoreWind) <> 0 then
       
   700                 dX:= dX + windSpeed / Density;
   689             y:= y + dY;
   701             y:= y + dY;
   690             dY:= dY + cGravityf;
   702             dY:= dY + cGravityf;
   691             dec(t)
   703             dec(t)
   692         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   704         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   693                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0);
   705                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0);
   716 TestGrenade:= valueResult
   728 TestGrenade:= valueResult
   717 end;
   729 end;
   718 
   730 
   719 function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   731 function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   720 const tDelta = 24;
   732 const tDelta = 24;
       
   733       Density : real = 1.5;
   721 var Vx, Vy, r: real;
   734 var Vx, Vy, r: real;
   722     Score, EX, EY, valueResult: LongInt;
   735     Score, EX, EY, valueResult: LongInt;
   723     TestTime: Longword;
   736     TestTime: Longword;
   724     x, y, dY, meX, meY: real;
   737     x, y, dX, dY, meX, meY: real;
   725     t: LongInt;
   738     t: LongInt;
   726 begin
   739 begin
   727 Flags:= Flags; // avoid compiler hint
   740 Flags:= Flags; // avoid compiler hint
   728 valueResult:= BadTurn;
   741 valueResult:= BadTurn;
   729 TestTime:= 500;
   742 TestTime:= 500;
   731 ap.ExplR:= 0;
   744 ap.ExplR:= 0;
   732 meX:= hwFloat2Float(Me^.X);
   745 meX:= hwFloat2Float(Me^.X);
   733 meY:= hwFloat2Float(Me^.Y);
   746 meY:= hwFloat2Float(Me^.Y);
   734 repeat
   747 repeat
   735     inc(TestTime, 900);
   748     inc(TestTime, 900);
       
   749     if (GameFlags and gfMoreWind) <> 0 then
       
   750         Vx:= (-(windSpeed / Density) * (TestTime + tDelta) * 0.5) + ((Targ.Point.X - meX) / (TestTime + tDelta))
   736     // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster
   751     // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster
   737     if meX<Targ.Point.X then
   752     else if meX<Targ.Point.X then
   738         Vx:= ((Targ.Point.X+10) - meX) / (TestTime + tDelta)
   753         Vx:= ((Targ.Point.X+10) - meX) / (TestTime + tDelta)
   739     else
   754     else
   740         Vx:= ((Targ.Point.X-10) - meX) / (TestTime + tDelta);
   755         Vx:= ((Targ.Point.X-10) - meX) / (TestTime + tDelta);
   741     Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta);
   756     Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta);
   742     r:= sqr(Vx)+sqr(Vy);
   757     r:= sqr(Vx)+sqr(Vy);
   743     if not (r > 1) then
   758     if not (r > 1) then
   744         begin
   759         begin
   745         x:= meX;
   760         x:= meX;
       
   761         dX:= Vx;
   746         y:= meY;
   762         y:= meY;
   747         dY:= -Vy;
   763         dY:= -Vy;
   748         t:= TestTime;
   764         t:= TestTime;
   749     repeat
   765     repeat
   750         x:= x + Vx;
   766         x:= x + dX;
       
   767         if (GameFlags and gfMoreWind) <> 0 then
       
   768             dX:= dX + windSpeed / Density;
   751         y:= y + dY;
   769         y:= y + dY;
   752         dY:= dY + cGravityf;
   770         dY:= dY + cGravityf;
   753         dec(t)
   771         dec(t)
   754     until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   772     until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   755            ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0);
   773            ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0);
   775 TestClusterBomb:= valueResult
   793 TestClusterBomb:= valueResult
   776 end;
   794 end;
   777 
   795 
   778 function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   796 function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   779 const tDelta = 24;
   797 const tDelta = 24;
       
   798       Density : real = 2.0;
   780 var Vx, Vy, r: real;
   799 var Vx, Vy, r: real;
   781     Score, EX, EY, valueResult: LongInt;
   800     Score, EX, EY, valueResult: LongInt;
   782     TestTime: Longword;
   801     TestTime: Longword;
   783     targXWrap, x, y, dY, meX, meY: real;
   802     targXWrap, x, y, dX, dY, meX, meY: real;
   784     t: LongInt;
   803     t: LongInt;
   785 begin
   804 begin
   786 Flags:= Flags; // avoid compiler hint
   805 Flags:= Flags; // avoid compiler hint
   787 valueResult:= BadTurn;
   806 valueResult:= BadTurn;
   788 TestTime:= 500;
   807 TestTime:= 500;
   794          targXWrap:= Targ.Point.X + (RightX-LeftX)
   813          targXWrap:= Targ.Point.X + (RightX-LeftX)
   795     else targXWrap:= Targ.Point.X - (RightX-LeftX);
   814     else targXWrap:= Targ.Point.X - (RightX-LeftX);
   796 repeat
   815 repeat
   797     inc(TestTime, 900);
   816     inc(TestTime, 900);
   798     if (WorldEdge = weWrap) and (random(2)=0) then
   817     if (WorldEdge = weWrap) and (random(2)=0) then
   799 		 Vx:= (targXWrap - meX) / (TestTime + tDelta)
   818         Vx:= (targXWrap - meX) / (TestTime + tDelta)
   800     else Vx:= (Targ.Point.X - meX) / (TestTime + tDelta);
   819     else
       
   820         Vx:= (Targ.Point.X - meX) / (TestTime + tDelta);
       
   821     if (GameFlags and gfMoreWind) <> 0 then
       
   822         Vx:= -(windSpeed / Density) * (TestTime + tDelta) * 0.5 + Vx;
       
   823 
   801     Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta);
   824     Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta);
   802     r:= sqr(Vx)+sqr(Vy);
   825     r:= sqr(Vx)+sqr(Vy);
   803     if not (r > 1) then
   826     if not (r > 1) then
   804         begin
   827         begin
   805         x:= meX;
   828         x:= meX;
       
   829         dX:= Vx;
   806         y:= meY;
   830         y:= meY;
   807         dY:= -Vy;
   831         dY:= -Vy;
   808         t:= TestTime;
   832         t:= TestTime;
   809         repeat
   833         repeat
   810             x:= CheckWrap(x);
   834             x:= CheckWrap(x);
   811             x:= x + Vx;
   835             x:= x + dX;
       
   836             if (GameFlags and gfMoreWind) <> 0 then
       
   837                  dX:= dX + windSpeed / Density;
   812             y:= y + dY;
   838             y:= y + dY;
   813             dY:= dY + cGravityf;
   839             dY:= dY + cGravityf;
   814             dec(t)
   840             dec(t)
   815        until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
   841        until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
   816                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0);
   842                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0);
   858             else
   884             else
   859                 Solve:= 0
   885                 Solve:= 0
   860     end;
   886     end;
   861 
   887 
   862 function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   888 function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
   863 //const tDelta = 24;
   889 const Density : real = 1.0;
   864 var Vx, Vy: real;
   890 var Vx, Vy: real;
   865     Score, EX, EY: LongInt;
   891     Score, EX, EY: LongInt;
   866     TestTime: Longword;
   892     TestTime: Longword;
   867     x, y, dY, meX, meY: real;
   893     x, y, dX, dY, meX, meY: real;
   868 begin
   894 begin
   869 Flags:= Flags; // avoid compiler hint
   895 Flags:= Flags; // avoid compiler hint
   870     TestMortar:= BadTurn;
   896     TestMortar:= BadTurn;
   871     ap.ExplR:= 0;
   897     ap.ExplR:= 0;
   872 
   898 
   880 
   906 
   881     if TestTime = 0 then
   907     if TestTime = 0 then
   882         exit(BadTurn);
   908         exit(BadTurn);
   883 
   909 
   884     Vx:= (Targ.Point.X - meX) / TestTime;
   910     Vx:= (Targ.Point.X - meX) / TestTime;
       
   911     if (GameFlags and gfMoreWind) <> 0 then
       
   912         Vx:= -(windSpeed / Density) * TestTime * 0.5 + Vx;
   885     Vy:= cGravityf * (TestTime div 2) - (Targ.Point.Y - meY) / TestTime;
   913     Vy:= cGravityf * (TestTime div 2) - (Targ.Point.Y - meY) / TestTime;
   886 
   914 
   887     x:= meX;
   915     x:= meX;
       
   916     dX:= Vx;
   888     y:= meY;
   917     y:= meY;
   889     dY:= -Vy;
   918     dY:= -Vy;
   890 
   919 
   891     repeat
   920     repeat
   892         x:= x + Vx;
   921         x:= x + dX;
       
   922         if (GameFlags and gfMoreWind) <> 0 then
       
   923             dX:= dX + windSpeed / Density;
   893         y:= y + dY;
   924         y:= y + dY;
   894         dY:= dY + cGravityf;
   925         dY:= dY + cGravityf;
   895         EX:= trunc(x);
   926         EX:= trunc(x);
   896         EY:= trunc(y);
   927         EY:= trunc(y);
   897     until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or
   928     until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or
  1359 TestHammer:= rate;
  1390 TestHammer:= rate;
  1360 end;
  1391 end;
  1361 
  1392 
  1362 function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  1393 function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  1363 const cShift = 4;
  1394 const cShift = 4;
  1364 var bombsSpeed, X, Y, dY: real;
  1395       Density : real = 2.0;
       
  1396 var bombsSpeed, X, Y, dX, dY: real;
  1365     b: array[0..9] of boolean;
  1397     b: array[0..9] of boolean;
  1366     dmg: array[0..9] of LongInt;
  1398     dmg: array[0..9] of LongInt;
  1367     fexit: boolean;
  1399     fexit: boolean;
  1368     i, t, valueResult: LongInt;
  1400     i, t, valueResult: LongInt;
  1369 begin
  1401 begin
  1379 
  1411 
  1380 bombsSpeed:= hwFloat2Float(cBombsSpeed);
  1412 bombsSpeed:= hwFloat2Float(cBombsSpeed);
  1381 X:= Targ.Point.X - 135 - cShift; // hh center - cShift
  1413 X:= Targ.Point.X - 135 - cShift; // hh center - cShift
  1382 X:= X - bombsSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf);
  1414 X:= X - bombsSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf);
  1383 Y:= -128;
  1415 Y:= -128;
       
  1416 dX:= bombsSpeed;
  1384 dY:= 0;
  1417 dY:= 0;
  1385 
  1418 
  1386 for i:= 0 to 9 do
  1419 for i:= 0 to 9 do
  1387     begin
  1420     begin
  1388     b[i]:= true;
  1421     b[i]:= true;
  1389     dmg[i]:= 0
  1422     dmg[i]:= 0
  1390     end;
  1423     end;
  1391 valueResult:= 0;
  1424 valueResult:= 0;
  1392 
  1425 
  1393 repeat
  1426 repeat
  1394     X:= X + bombsSpeed;
  1427     X:= X + dX;
       
  1428     if (GameFlags and gfMoreWind) <> 0 then
       
  1429         dX:= dX + windSpeed / Density;
  1395     Y:= Y + dY;
  1430     Y:= Y + dY;
  1396     dY:= dY + cGravityf;
  1431     dY:= dY + cGravityf;
  1397     fexit:= true;
  1432     fexit:= true;
  1398 
  1433 
  1399     for i:= 0 to 9 do
  1434     for i:= 0 to 9 do
  1441     fexit, collided: boolean;
  1476     fexit, collided: boolean;
  1442     i, t, value, valueResult, attackTime, drillTimer, targetX: LongInt;
  1477     i, t, value, valueResult, attackTime, drillTimer, targetX: LongInt;
  1443 begin
  1478 begin
  1444 Flags:= Flags; // avoid compiler hint
  1479 Flags:= Flags; // avoid compiler hint
  1445 ap.ExplR:= 0;
  1480 ap.ExplR:= 0;
  1446 if (Level > 3) or (cGravityf = 0) then
  1481 // TODO: Add support for More Wind
       
  1482 if (Level > 3) or (cGravityf = 0) or ((GameFlags and gfMoreWind) <> 0) then
  1447     exit(BadTurn);
  1483     exit(BadTurn);
  1448 
  1484 
  1449 ap.Angle:= 0;
  1485 ap.Angle:= 0;
  1450 targetX:= Targ.Point.X;
  1486 targetX:= Targ.Point.X;
  1451 ap.AttackPutY:= Targ.Point.Y;
  1487 ap.AttackPutY:= Targ.Point.Y;
  1569 TestDrillStrike:= valueResult;
  1605 TestDrillStrike:= valueResult;
  1570 end;
  1606 end;
  1571 
  1607 
  1572 function TestMineStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  1608 function TestMineStrike(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  1573 const cShift = 4;
  1609 const cShift = 4;
  1574 var minesSpeed, X, Y, dY: real;
  1610       Density : real = 1.0;
       
  1611 var minesSpeed, X, Y, dX, dY: real;
  1575     b: array[0..9] of boolean;
  1612     b: array[0..9] of boolean;
  1576     dmg: array[0..9] of LongInt;
  1613     dmg: array[0..9] of LongInt;
  1577     fexit: boolean;
  1614     fexit: boolean;
  1578     i, t, valueResult: LongInt;
  1615     i, t, valueResult: LongInt;
  1579 begin
  1616 begin
  1596 
  1633 
  1597 minesSpeed:= hwFloat2Float(cBombsSpeed);
  1634 minesSpeed:= hwFloat2Float(cBombsSpeed);
  1598 X:= Targ.Point.X - 135 - cShift; // hh center - cShift
  1635 X:= Targ.Point.X - 135 - cShift; // hh center - cShift
  1599 X:= X - minesSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf);
  1636 X:= X - minesSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf);
  1600 Y:= -128;
  1637 Y:= -128;
       
  1638 dX:= minesSpeed;
  1601 dY:= 0;
  1639 dY:= 0;
  1602 
  1640 
  1603 for i:= 0 to 9 do
  1641 for i:= 0 to 9 do
  1604     begin
  1642     begin
  1605     b[i]:= true;
  1643     b[i]:= true;
  1606     dmg[i]:= 0
  1644     dmg[i]:= 0
  1607     end;
  1645     end;
  1608 valueResult:= 0;
  1646 valueResult:= 0;
  1609 
  1647 
  1610 repeat
  1648 repeat
  1611     X:= X + minesSpeed;
  1649     X:= X + dX;
       
  1650     if (GameFlags and (gfMoreWind or gfInfAttack)) <> 0 then
       
  1651         dX:= dX + windSpeed / Density;
  1612     Y:= Y + dY;
  1652     Y:= Y + dY;
  1613     dY:= dY + cGravityf;
  1653     dY:= dY + cGravityf;
  1614     fexit:= true;
  1654     fexit:= true;
  1615 
  1655 
  1616     for i:= 0 to 9 do
  1656     for i:= 0 to 9 do
  1648 TestMineStrike:= valueResult;
  1688 TestMineStrike:= valueResult;
  1649 end;
  1689 end;
  1650 
  1690 
  1651 function TestSMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  1691 function TestSMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  1652 const timeLimit = 50;
  1692 const timeLimit = 50;
       
  1693       Density : real = 1.6;
  1653 var Vx, Vy, r, meX, meY: real;
  1694 var Vx, Vy, r, meX, meY: real;
  1654     rTime: LongInt;
  1695     rTime: LongInt;
  1655     EX, EY: LongInt;
  1696     EX, EY: LongInt;
  1656     valueResult: LongInt;
  1697     valueResult: LongInt;
  1657     targXWrap, x, y, dX, dY: real;
  1698     targXWrap, x, y, dX, dY: real;
  1673     rTime:= rTime + 300 + Level * 50 + random(300);
  1714     rTime:= rTime + 300 + Level * 50 + random(300);
  1674     if (WorldEdge = weWrap) and (random(2)=0) then
  1715     if (WorldEdge = weWrap) and (random(2)=0) then
  1675          Vx:= (targXWrap + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime
  1716          Vx:= (targXWrap + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime
  1676     else
  1717     else
  1677          Vx:= (Targ.Point.X + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime;
  1718          Vx:= (Targ.Point.X + AIrndSign(2) + AIrndOffset(Targ, Level) - meX) / rTime;
       
  1719     if (GameFlags and gfMoreWind) <> 0 then
       
  1720          Vx:= -(windSpeed / Density) * rTime * 0.5 + Vx;
  1678     Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime;
  1721     Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime;
  1679     r:= sqr(Vx) + sqr(Vy);
  1722     r:= sqr(Vx) + sqr(Vy);
  1680 
  1723 
  1681     if not (r > 1) then
  1724     if not (r > 1) then
  1682         begin
  1725         begin
  1686         dY:= -Vy;
  1729         dY:= -Vy;
  1687         t:= rTime;
  1730         t:= rTime;
  1688         repeat
  1731         repeat
  1689             x:= CheckWrap(x);
  1732             x:= CheckWrap(x);
  1690             x:= x + dX;
  1733             x:= x + dX;
       
  1734             if (GameFlags and gfMoreWind) <> 0 then
       
  1735                 dX:= dX + windSpeed / Density;
  1691 
  1736 
  1692             y:= y + dY;
  1737             y:= y + dY;
  1693             dY:= dY + cGravityf;
  1738             dY:= dY + cGravityf;
  1694             dec(t)
  1739             dec(t)
  1695         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 2)) or
  1740         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 2)) or
  1930     rate:= BadTurn;
  1975     rate:= BadTurn;
  1931 TestSeduction:= rate;
  1976 TestSeduction:= rate;
  1932 end;
  1977 end;
  1933 
  1978 
  1934 function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  1979 function TestDynamite(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
       
  1980 const Density : real = 2.0;
  1935 var valueResult: LongInt;
  1981 var valueResult: LongInt;
  1936     x, y, dx, dy: real;
  1982     x, y, dx, dy: real;
  1937     EX, EY, t: LongInt;
  1983     EX, EY, t: LongInt;
  1938 begin
  1984 begin
  1939 Flags:= Flags; // avoid compiler hint
  1985 Flags:= Flags; // avoid compiler hint
  1940 Targ:= Targ; // avoid compiler hint
  1986 Targ:= Targ; // avoid compiler hint
  1941 
  1987 
  1942 x:= hwFloat2Float(Me^.X) + hwSign(Me^.dX) * 7;
  1988 x:= hwFloat2Float(Me^.X) + hwSign(Me^.dX) * 7;
  1943 y:= hwFloat2Float(Me^.Y);
  1989 y:= hwFloat2Float(Me^.Y);
  1944 dx:= hwSign(Me^.dX) * 0.03;
  1990 dx:= hwSign(Me^.dX) * 0.03;
       
  1991 if (GameFlags and gfMoreWind) <> 0 then
       
  1992     dx:= -(windSpeed / Density) + dx;
  1945 dy:= 0;
  1993 dy:= 0;
  1946 t:= 5000;
  1994 t:= 5000;
  1947 repeat
  1995 repeat
  1948     dec(t);
  1996     dec(t);
       
  1997     if (GameFlags and gfMoreWind) <> 0 then
       
  1998         dx:= dx + windSpeed / Density;
  1949     x:= x + dx;
  1999     x:= x + dx;
  1950     dy:= dy + cGravityf;
  2000     dy:= dy + cGravityf;
  1951     y:= y + dy;
  2001     y:= y + dy;
  1952 
  2002 
  1953     if TestColl(trunc(x), trunc(y), 3) then
  2003     if TestColl(trunc(x), trunc(y), 3) then
  1975 
  2025 
  1976 TestDynamite:= valueResult
  2026 TestDynamite:= valueResult
  1977 end;
  2027 end;
  1978 
  2028 
  1979 function TestMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  2029 function TestMine(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
       
  2030 const Density : real = 1.0;
  1980 var valueResult: LongInt;
  2031 var valueResult: LongInt;
  1981     x, y, dx, dy: real;
  2032     x, y, dx, dy: real;
  1982     EX, EY, t: LongInt;
  2033     EX, EY, t: LongInt;
  1983 begin
  2034 begin
  1984 Flags:= Flags; // avoid compiler hint
  2035 Flags:= Flags; // avoid compiler hint
  1985 Targ:= Targ; // avoid compiler hint
  2036 Targ:= Targ; // avoid compiler hint
  1986 
  2037 
  1987 x:= hwFloat2Float(Me^.X) + hwSign(Me^.dX) * 7;
  2038 x:= hwFloat2Float(Me^.X) + hwSign(Me^.dX) * 7;
  1988 y:= hwFloat2Float(Me^.Y);
  2039 y:= hwFloat2Float(Me^.Y);
  1989 dx:= hwSign(Me^.dX) * 0.02;
  2040 dx:= hwSign(Me^.dX) * 0.02;
       
  2041 if (GameFlags and gfMoreWind) <> 0 then
       
  2042     dx:= -(windSpeed / Density) + dx;
  1990 dy:= 0;
  2043 dy:= 0;
  1991 t:= 10000;
  2044 t:= 10000;
  1992 repeat
  2045 repeat
  1993     dec(t);
  2046     dec(t);
       
  2047     if (GameFlags and gfMoreWind) <> 0 then
       
  2048          dx:= dx + windSpeed / Density;
  1994     x:= x + dx;
  2049     x:= x + dx;
  1995     dy:= dy + cGravityf;
  2050     dy:= dy + cGravityf;
  1996     y:= y + dy;
  2051     y:= y + dy;
  1997     if ((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 2)) or
  2052     if ((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 2)) or
  1998         ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 2)) then
  2053         ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 2)) then
  2026 TestMine:= valueResult
  2081 TestMine:= valueResult
  2027 end;
  2082 end;
  2028 
  2083 
  2029 function TestKnife(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  2084 function TestKnife(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams; Flags: LongWord): LongInt;
  2030 const timeLimit = 300;
  2085 const timeLimit = 300;
       
  2086       Density : real = 4.0;
  2031 var Vx, Vy, r, meX, meY: real;
  2087 var Vx, Vy, r, meX, meY: real;
  2032     rTime: LongInt;
  2088     rTime: LongInt;
  2033     EX, EY: LongInt;
  2089     EX, EY: LongInt;
  2034     valueResult: LongInt;
  2090     valueResult: LongInt;
  2035     targXWrap, x, y, dX, dY: real;
  2091     targXWrap, x, y, dX, dY: real;
  2052     rTime:= rTime + 300 + Level * 50 + random(300);
  2108     rTime:= rTime + 300 + Level * 50 + random(300);
  2053     if (WorldEdge = weWrap) and (random(2)=0) then
  2109     if (WorldEdge = weWrap) and (random(2)=0) then
  2054          Vx:= (targXWrap - meX) / rTime
  2110          Vx:= (targXWrap - meX) / rTime
  2055     else
  2111     else
  2056          Vx:= (Targ.Point.X - meX) / rTime;
  2112          Vx:= (Targ.Point.X - meX) / rTime;
       
  2113     if (GameFlags and gfMoreWind) <> 0 then
       
  2114          Vx:= -(windSpeed / Density) * rTime * 0.5 + Vx;
  2057     Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime;
  2115     Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - meY) / rTime;
  2058     r:= sqr(Vx) + sqr(Vy);
  2116     r:= sqr(Vx) + sqr(Vy);
  2059 
  2117 
  2060     if not (r > 1) then
  2118     if not (r > 1) then
  2061         begin
  2119         begin
  2065         dY:= -Vy;
  2123         dY:= -Vy;
  2066         t:= rTime;
  2124         t:= rTime;
  2067         repeat
  2125         repeat
  2068             x:= CheckWrap(x);
  2126             x:= CheckWrap(x);
  2069             x:= x + dX;
  2127             x:= x + dX;
       
  2128             if (GameFlags and gfMoreWind) <> 0 then
       
  2129                 dX:= dX + windSpeed / Density;
  2070 
  2130 
  2071             y:= y + dY;
  2131             y:= y + dY;
  2072             dY:= dY + cGravityf;
  2132             dY:= dY + cGravityf;
  2073             dec(t)
  2133             dec(t)
  2074         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 7)) or
  2134         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 7)) or