hedgewars/uAIAmmoTests.pas
branchwebgl
changeset 8330 aaefa587e277
parent 8096 453917e94e55
parent 8161 0b8beacff8a5
child 8444 75db7bb8dce8
equal deleted inserted replaced
8116:d24257910f8d 8330:aaefa587e277
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uAIAmmoTests;
    21 unit uAIAmmoTests;
    22 interface
    22 interface
    23 uses SDLh, uConsts, uFloat, uTypes;
    23 uses SDLh, uConsts, uFloat, uTypes;
    24 const 
    24 const
    25     amtest_Rare     = $00000001; // check only several positions
    25     amtest_Rare     = $00000001; // check only several positions
    26     amtest_NoTarget = $00000002; // each pos, but no targetting
    26     amtest_NoTarget = $00000002; // each pos, but no targetting
    27 
    27 
    28 var windSpeed: real;
    28 var windSpeed: real;
    29 
    29 
   114             (proc: @TestHammer;      flags: amtest_NoTarget), // amHammer
   114             (proc: @TestHammer;      flags: amtest_NoTarget), // amHammer
   115             (proc: nil;              flags: 0), // amResurrector
   115             (proc: nil;              flags: 0), // amResurrector
   116             (proc: nil;              flags: 0), // amDrillStrike
   116             (proc: nil;              flags: 0), // amDrillStrike
   117             (proc: nil;              flags: 0), // amSnowball
   117             (proc: nil;              flags: 0), // amSnowball
   118             (proc: nil;              flags: 0), // amTardis
   118             (proc: nil;              flags: 0), // amTardis
   119             (proc: nil;              flags: 0), // amStructure
   119             //(proc: nil;              flags: 0), // amStructure
   120             (proc: nil;              flags: 0), // amLandGun
   120             (proc: nil;              flags: 0), // amLandGun
   121             (proc: nil;              flags: 0), // amIceGun
   121             (proc: nil;              flags: 0), // amIceGun
   122             (proc: nil;              flags: 0)  // amKnife
   122             (proc: nil;              flags: 0)  // amKnife
   123             );
   123             );
   124 
   124 
   161             x:= x + dX;
   161             x:= x + dX;
   162             y:= y + dY;
   162             y:= y + dY;
   163             dX:= dX + windSpeed;
   163             dX:= dX + windSpeed;
   164             dY:= dY + cGravityf;
   164             dY:= dY + cGravityf;
   165             dec(t)
   165             dec(t)
   166         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or 
   166         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   167                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0);
   167                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0);
   168         
   168 
   169         EX:= trunc(x);
   169         EX:= trunc(x);
   170         EY:= trunc(y);
   170         EY:= trunc(y);
   171         if Level = 1 then
   171         if Level = 1 then
   172             value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
   172             value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
   173         else value:= RateExplosion(Me, EX, EY, 101);
   173         else value:= RateExplosion(Me, EX, EY, 101);
   220                 x:= x + dX;
   220                 x:= x + dX;
   221                 y:= y + dY;
   221                 y:= y + dY;
   222                 dX:= dX + windSpeed;
   222                 dX:= dX + windSpeed;
   223                 dY:= dY + cGravityf;
   223                 dY:= dY + cGravityf;
   224                 dec(t)
   224                 dec(t)
   225             until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or 
   225             until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   226                    ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (y > cWaterLine);
   226                    ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (y > cWaterLine);
   227             
   227 
   228             EX:= trunc(x);
   228             EX:= trunc(x);
   229             EY:= trunc(y);
   229             EY:= trunc(y);
   230             if Level = 1 then
   230             if Level = 1 then
   231                 value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
   231                 value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
   232             else value:= RateExplosion(Me, EX, EY, 101);
   232             else value:= RateExplosion(Me, EX, EY, 101);
   279             x:= x + dX;
   279             x:= x + dX;
   280             y:= y + dY;
   280             y:= y + dY;
   281             dX:= dX + windSpeed;
   281             dX:= dX + windSpeed;
   282             dY:= dY + cGravityf;
   282             dY:= dY + cGravityf;
   283             dec(t)
   283             dec(t)
   284         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or 
   284         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   285                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0);
   285                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0);
   286         EX:= trunc(x);
   286         EX:= trunc(x);
   287         EY:= trunc(y);
   287         EY:= trunc(y);
   288 
   288 
   289         value:= RateShove(trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall);
   289         value:= RateShove(trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall);
   331         repeat
   331         repeat
   332             x:= x + Vx;
   332             x:= x + Vx;
   333             y:= y + dY;
   333             y:= y + dY;
   334             dY:= dY + cGravityf;
   334             dY:= dY + cGravityf;
   335             dec(t)
   335             dec(t)
   336         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or 
   336         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
   337                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0);
   337                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0);
   338         EX:= trunc(x);
   338         EX:= trunc(x);
   339         EY:= trunc(y);
   339         EY:= trunc(y);
   340         if t < 50 then
   340         if t < 50 then
   341             Score:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
   341             Score:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
   342         else
   342         else
   343             Score:= BadTurn;
   343             Score:= BadTurn;
   344                   
   344 
   345         if valueResult < Score then
   345         if valueResult < Score then
   346             begin
   346             begin
   347             ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   347             ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   348             ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
   348             ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
   349             ap.ExplR:= 100;
   349             ap.ExplR:= 100;
   375     Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Y - meY) / (TestTime + tDelta);
   375     Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Y - meY) / (TestTime + tDelta);
   376     r:= sqr(Vx) + sqr(Vy);
   376     r:= sqr(Vx) + sqr(Vy);
   377     if not (r > 1) then
   377     if not (r > 1) then
   378         begin
   378         begin
   379         x:= meX;
   379         x:= meX;
   380         y:= meY; 
   380         y:= meY;
   381         dY:= -Vy;
   381         dY:= -Vy;
   382         t:= TestTime;
   382         t:= TestTime;
   383         repeat
   383         repeat
   384             x:= x + Vx;
   384             x:= x + Vx;
   385             y:= y + dY;
   385             y:= y + dY;
   386             dY:= dY + cGravityf;
   386             dY:= dY + cGravityf;
   387             dec(t)
   387             dec(t)
   388         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or 
   388         until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   389                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0);
   389                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0);
   390     EX:= trunc(x);
   390     EX:= trunc(x);
   391     EY:= trunc(y);
   391     EY:= trunc(y);
   392     if t < 50 then 
   392     if t < 50 then
   393         if Level = 1 then
   393         if Level = 1 then
   394             Score:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
   394             Score:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
   395         else Score:= RateExplosion(Me, EX, EY, 101)
   395         else Score:= RateExplosion(Me, EX, EY, 101)
   396     else 
   396     else
   397         Score:= BadTurn;
   397         Score:= BadTurn;
   398 
   398 
   399     if (valueResult < Score) and (Score > 0) then
   399     if (valueResult < Score) and (Score > 0) then
   400         begin
   400         begin
   401         ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   401         ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   443     repeat
   443     repeat
   444         x:= x + Vx;
   444         x:= x + Vx;
   445         y:= y + dY;
   445         y:= y + dY;
   446         dY:= dY + cGravityf;
   446         dY:= dY + cGravityf;
   447         dec(t)
   447         dec(t)
   448     until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or 
   448     until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
   449            ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0);
   449            ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0);
   450     EX:= trunc(x);
   450     EX:= trunc(x);
   451     EY:= trunc(y);
   451     EY:= trunc(y);
   452     if t < 50 then 
   452     if t < 50 then
   453         Score:= RateExplosion(Me, EX, EY, 41)
   453         Score:= RateExplosion(Me, EX, EY, 41)
   454     else 
   454     else
   455         Score:= BadTurn;
   455         Score:= BadTurn;
   456 
   456 
   457      if valueResult < Score then
   457      if valueResult < Score then
   458         begin
   458         begin
   459         ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   459         ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   496         repeat
   496         repeat
   497             x:= x + Vx;
   497             x:= x + Vx;
   498             y:= y + dY;
   498             y:= y + dY;
   499             dY:= dY + cGravityf;
   499             dY:= dY + cGravityf;
   500             dec(t)
   500             dec(t)
   501        until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or 
   501        until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
   502                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0);
   502                ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0);
   503         
   503 
   504         EX:= trunc(x);
   504         EX:= trunc(x);
   505         EY:= trunc(y);
   505         EY:= trunc(y);
   506         if t < 50 then 
   506         if t < 50 then
   507             Score:= RateExplosion(Me, EX, EY, 200) + RateExplosion(Me, EX, EY + 120, 200)
   507             Score:= RateExplosion(Me, EX, EY, 200) + RateExplosion(Me, EX, EY + 120, 200)
   508         else 
   508         else
   509             Score:= BadTurn;
   509             Score:= BadTurn;
   510             
   510 
   511         if valueResult < Score then
   511         if valueResult < Score then
   512             begin
   512             begin
   513             ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   513             ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
   514             ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
   514             ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
   515             ap.Time:= TestTime div 1000 * 1000;
   515             ap.Time:= TestTime div 1000 * 1000;
   542             Solve:= trunc(T)
   542             Solve:= trunc(T)
   543             end
   543             end
   544             else
   544             else
   545                 Solve:= 0
   545                 Solve:= 0
   546     end;
   546     end;
   547     
   547 
   548 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   548 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   549 //const tDelta = 24;
   549 //const tDelta = 24;
   550 var Vx, Vy: real;
   550 var Vx, Vy: real;
   551     Score, EX, EY: LongInt;
   551     Score, EX, EY: LongInt;
   552     TestTime: Longword;
   552     TestTime: Longword;
   577         x:= x + Vx;
   577         x:= x + Vx;
   578         y:= y + dY;
   578         y:= y + dY;
   579         dY:= dY + cGravityf;
   579         dY:= dY + cGravityf;
   580         EX:= trunc(x);
   580         EX:= trunc(x);
   581         EY:= trunc(y);
   581         EY:= trunc(y);
   582     until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or 
   582     until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or
   583            ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, EX, EY, 4))) or (EY > cWaterLine);
   583            ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, EX, EY, 4))) or (EY > cWaterLine);
   584 
   584 
   585     if (EY < cWaterLine) and (dY >= 0) then
   585     if (EY < cWaterLine) and (dY >= 0) then
   586         begin
   586         begin
   587         Score:= RateExplosion(Me, EX, EY, 91);
   587         Score:= RateExplosion(Me, EX, EY, 91);
   631 repeat
   631 repeat
   632     x:= x + vX;
   632     x:= x + vX;
   633     y:= y + vY;
   633     y:= y + vY;
   634     rx:= trunc(x);
   634     rx:= trunc(x);
   635     ry:= trunc(y);
   635     ry:= trunc(y);
   636     if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or 
   636     if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or
   637         ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, rx, ry, 2)) then
   637         ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, rx, ry, 2)) then
   638     begin
   638     begin
   639         x:= x + vX * 8;
   639         x:= x + vX * 8;
   640         y:= y + vY * 8;
   640         y:= y + vY * 8;
   641         valueResult:= RateShotgun(Me, vX, vY, rx, ry);
   641         valueResult:= RateShotgun(Me, vX, vY, rx, ry);
   642      
   642 
   643         if valueResult = 0 then 
   643         if valueResult = 0 then
   644             valueResult:= 1024 - Metric(Targ.X, Targ.Y, rx, ry) div 64
   644             valueResult:= 1024 - Metric(Targ.X, Targ.Y, rx, ry) div 64
   645         else 
   645         else
   646             dec(valueResult, Level * 4000);
   646             dec(valueResult, Level * 4000);
   647         // 27/20 is reuse bonus
   647         // 27/20 is reuse bonus
   648         exit(valueResult * 27 div 20)
   648         exit(valueResult * 27 div 20)
   649     end
   649     end
   650 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
   650 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
   746 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4 then
   746 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4 then
   747     begin
   747     begin
   748     fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00166 * dmg, vY * 0.00166 * dmg);
   748     fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00166 * dmg, vY * 0.00166 * dmg);
   749     if fallDmg < 0 then
   749     if fallDmg < 0 then
   750         TestSniperRifle:= BadTurn
   750         TestSniperRifle:= BadTurn
   751     else 
   751     else
   752         TestSniperRifle:= Max(0, trunc((dmg + fallDmg) * dmgMod) * 1024)
   752         TestSniperRifle:= Max(0, trunc((dmg + fallDmg) * dmgMod) * 1024)
   753     end
   753     end
   754 else
   754 else
   755     TestSniperRifle:= BadTurn
   755     TestSniperRifle:= BadTurn
   756 end;
   756 end;
   785                 , -dx, -dy, trackFall);
   785                 , -dx, -dy, trackFall);
   786         v2:= RateShove(x + 10, y + 2
   786         v2:= RateShove(x + 10, y + 2
   787                 , 32, 30, 115
   787                 , 32, 30, 115
   788                 , dx, -dy, trackFall);
   788                 , dx, -dy, trackFall);
   789         if (v1 > valueResult) or (v2 > valueResult) then
   789         if (v1 > valueResult) or (v2 > valueResult) then
   790             if (v2 > v1) 
   790             if (v2 > v1)
   791                 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
   791                 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
   792                 begin
   792                 begin
   793                 ap.Angle:= a;
   793                 ap.Angle:= a;
   794                 valueResult:= v2
   794                 valueResult:= v2
   795                 end
   795                 end
   796             else 
   796             else
   797                 begin
   797                 begin
   798                 ap.Angle:= -a;
   798                 ap.Angle:= -a;
   799                 valueResult:= v1
   799                 valueResult:= v1
   800                 end;
   800                 end;
   801 
   801 
   802         a:= a - 15 - random(cMaxAngle div 16)
   802         a:= a - 15 - random(cMaxAngle div 16)
   803         end;
   803         end;
   804    
   804 
   805     if valueResult <= 0 then
   805     if valueResult <= 0 then
   806         valueResult:= BadTurn;
   806         valueResult:= BadTurn;
   807 
   807 
   808     TestBaseballBat:= valueResult;
   808     TestBaseballBat:= valueResult;
   809 end;
   809 end;
   845         end;
   845         end;
   846     v2:= v2 + RateShove(x + 5, y - 90
   846     v2:= v2 + RateShove(x + 5, y - 90
   847             , 19, 30, 40
   847             , 19, 30, 40
   848             , 0.45, -0.9, trackFall);
   848             , 0.45, -0.9, trackFall);
   849 
   849 
   850     if (v2 > v1) 
   850     if (v2 > v1)
   851         or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
   851         or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
   852         begin
   852         begin
   853         ap.Angle:= 1;
   853         ap.Angle:= 1;
   854         valueResult:= v2
   854         valueResult:= v2
   855         end
   855         end
   856     else 
   856     else
   857         begin
   857         begin
   858         ap.Angle:= -1;
   858         ap.Angle:= -1;
   859         valueResult:= v1
   859         valueResult:= v1
   860         end;
   860         end;
   861     
   861 
   862     if valueResult <= 0 then
   862     if valueResult <= 0 then
   863         valueResult:= BadTurn;
   863         valueResult:= BadTurn;
   864 
   864 
   865     TestFirePunch:= valueResult;
   865     TestFirePunch:= valueResult;
   866 end;
   866 end;
   880     ap.Power:= 1;
   880     ap.Power:= 1;
   881     x:= hwRound(Me^.X);
   881     x:= hwRound(Me^.X);
   882     y:= hwRound(Me^.Y);
   882     y:= hwRound(Me^.Y);
   883 
   883 
   884     // check left direction
   884     // check left direction
   885     {first RateShove checks farthermost of two whip's AmmoShove attacks 
   885     {first RateShove checks farthermost of two whip's AmmoShove attacks
   886     to encourage distant attacks (damaged hog is excluded from view of second 
   886     to encourage distant attacks (damaged hog is excluded from view of second
   887     RateShove call)}
   887     RateShove call)}
   888     v1:= RateShove(x - 13, y
   888     v1:= RateShove(x - 13, y
   889             , 30, 30, 25
   889             , 30, 30, 25
   890             , -1, -0.8, trackFall or afSetSkip);
   890             , -1, -0.8, trackFall or afSetSkip);
   891     v1:= v1 +
   891     v1:= v1 +
   899     v2:= v2 +
   899     v2:= v2 +
   900         RateShove(x + 2, y
   900         RateShove(x + 2, y
   901             , 30, 30, 25
   901             , 30, 30, 25
   902             , 1, -0.8, trackFall);
   902             , 1, -0.8, trackFall);
   903 
   903 
   904     if (v2 > v1) 
   904     if (v2 > v1)
   905         or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
   905         or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
   906         begin
   906         begin
   907         ap.Angle:= 1;
   907         ap.Angle:= 1;
   908         valueResult:= v2
   908         valueResult:= v2
   909         end
   909         end
   910     else 
   910     else
   911         begin
   911         begin
   912         ap.Angle:= -1;
   912         ap.Angle:= -1;
   913         valueResult:= v1
   913         valueResult:= v1
   914         end;
   914         end;
   915     
   915 
   916     if valueResult <= 0 then
   916     if valueResult <= 0 then
   917         valueResult:= BadTurn
   917         valueResult:= BadTurn
   918     else
   918     else
   919         inc(valueResult);
   919         inc(valueResult);
   920 
   920 
   929 begin
   929 begin
   930     ap.ExplR:= 0;
   930     ap.ExplR:= 0;
   931     ap.Time:= 0;
   931     ap.Time:= 0;
   932     ap.Power:= 1;
   932     ap.Power:= 1;
   933 
   933 
   934     if Level = 1 then 
   934     if Level = 1 then
   935         trackFall:= afTrackFall
   935         trackFall:= afTrackFall
   936     else if Level = 2 then
   936     else if Level = 2 then
   937         trackFall:= 0
   937         trackFall:= 0
   938     else
   938     else
   939         exit(BadTurn);
   939         exit(BadTurn);
   940         
   940 
   941     valueResult:= 0;
   941     valueResult:= 0;
   942     v:= 0;
   942     v:= 0;
   943 
   943 
   944     x:= hwFloat2Float(Me^.X);
   944     x:= hwFloat2Float(Me^.X);
   945     y:= hwFloat2Float(Me^.Y);
   945     y:= hwFloat2Float(Me^.Y);
   956         dx:= (Targ.X - x) * t;
   956         dx:= (Targ.X - x) * t;
   957         dy:= (Targ.Y - y) * t;
   957         dy:= (Targ.Y - y) * t;
   958 
   958 
   959         ap.Angle:= DxDy2AttackAnglef(dx, -dy)
   959         ap.Angle:= DxDy2AttackAnglef(dx, -dy)
   960         end;
   960         end;
   961     
   961 
   962     if dx >= 0 then cx:= 0.45 else cx:= -0.45;
   962     if dx >= 0 then cx:= 0.45 else cx:= -0.45;
   963 
   963 
   964     for i:= 0 to 512 div step - 2 do
   964     for i:= 0 to 512 div step - 2 do
   965         begin
   965         begin
   966         valueResult:= valueResult + 
   966         valueResult:= valueResult +
   967             RateShove(trunc(x), trunc(y)
   967             RateShove(trunc(x), trunc(y)
   968                 , 30, 30, 25
   968                 , 30, 30, 25
   969                 , cx, -0.9, trackFall or afSetSkip);
   969                 , cx, -0.9, trackFall or afSetSkip);
   970                 
   970 
   971         x:= x + dx;
   971         x:= x + dx;
   972         y:= y + dy;
   972         y:= y + dy;
   973         end;
   973         end;
   974     if dx = 0 then
   974     if dx = 0 then
   975         begin
   975         begin
   980                 , 30, 30, 25
   980                 , 30, 30, 25
   981                 , -cx, -0.9, trackFall);
   981                 , -cx, -0.9, trackFall);
   982         for i:= 1 to 512 div step - 2 do
   982         for i:= 1 to 512 div step - 2 do
   983             begin
   983             begin
   984             y:= y + dy;
   984             y:= y + dy;
   985             v:= v + 
   985             v:= v +
   986                 RateShove(tx, trunc(y)
   986                 RateShove(tx, trunc(y)
   987                     , 30, 30, 25
   987                     , 30, 30, 25
   988                     , -cx, -0.9, trackFall or afSetSkip);
   988                     , -cx, -0.9, trackFall or afSetSkip);
   989             end
   989             end
   990         end;
   990         end;
  1013 
  1013 
  1014 ap.ExplR:= 0;
  1014 ap.ExplR:= 0;
  1015 ap.Time:= 0;
  1015 ap.Time:= 0;
  1016 ap.Power:= 1;
  1016 ap.Power:= 1;
  1017 ap.Angle:= 0;
  1017 ap.Angle:= 0;
  1018          
  1018 
  1019 rate:= RateHammer(Me);
  1019 rate:= RateHammer(Me);
  1020 if rate = 0 then
  1020 if rate = 0 then
  1021     rate:= BadTurn;
  1021     rate:= BadTurn;
  1022 TestHammer:= rate;
  1022 TestHammer:= rate;
  1023 end;
  1023 end;
  1104     if bonuses.Count = 0 then
  1104     if bonuses.Count = 0 then
  1105         begin
  1105         begin
  1106         if Me^.Health <= 100  then
  1106         if Me^.Health <= 100  then
  1107             begin
  1107             begin
  1108             maxTop := Targ.Y - cHHRadius * 2;
  1108             maxTop := Targ.Y - cHHRadius * 2;
  1109             
  1109 
  1110             while (not TestColl(Targ.X, maxTop, cHHRadius)) and (maxTop > topY + cHHRadius * 2 + 1) do
  1110             while (not TestColl(Targ.X, maxTop, cHHRadius)) and (maxTop > topY + cHHRadius * 2 + 1) do
  1111                 dec(maxTop, cHHRadius*2);
  1111                 dec(maxTop, cHHRadius*2);
  1112             if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then
  1112             if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then
  1113                 begin
  1113                 begin
  1114                 ap.AttackPutX := Targ.X;
  1114                 ap.AttackPutX := Targ.X;
  1123         repeat
  1123         repeat
  1124             i := random(bonuses.Count);
  1124             i := random(bonuses.Count);
  1125             inc(failNum);
  1125             inc(failNum);
  1126         until not TestColl(bonuses.ar[i].X, bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius, cHHRadius)
  1126         until not TestColl(bonuses.ar[i].X, bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius, cHHRadius)
  1127         or (failNum = bonuses.Count*2);
  1127         or (failNum = bonuses.Count*2);
  1128         
  1128 
  1129         if failNum < bonuses.Count*2 then
  1129         if failNum < bonuses.Count*2 then
  1130             begin
  1130             begin
  1131             ap.AttackPutX := bonuses.ar[i].X;
  1131             ap.AttackPutX := bonuses.ar[i].X;
  1132             ap.AttackPutY := bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius;
  1132             ap.AttackPutY := bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius;
  1133             TestTeleport := 0;
  1133             TestTeleport := 0;
  1145 
  1145 
  1146 for i:= 0 to 2040 do
  1146 for i:= 0 to 2040 do
  1147     begin
  1147     begin
  1148     cakeStep(Gear);
  1148     cakeStep(Gear);
  1149     v:= RateExplosion(Me, hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg * 2, afTrackFall);
  1149     v:= RateExplosion(Me, hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg * 2, afTrackFall);
  1150     if v > ap.Power then 
  1150     if v > ap.Power then
  1151         begin
  1151         begin
  1152         ap.ExplX:= hwRound(Gear^.X);
  1152         ap.ExplX:= hwRound(Gear^.X);
  1153         ap.ExplY:= hwRound(Gear^.Y);
  1153         ap.ExplY:= hwRound(Gear^.Y);
  1154         ap.Power:= v
  1154         ap.Power:= v
  1155         end
  1155         end