hedgewars/uAIAmmoTests.pas
changeset 6775 22b5fb7217db
parent 6774 237b96f06aae
child 6782 33009ac4de80
equal deleted inserted replaced
6774:237b96f06aae 6775:22b5fb7217db
   104             (proc: nil;              flags: 0), // amFlamethrower
   104             (proc: nil;              flags: 0), // amFlamethrower
   105             (proc: @TestGrenade;     flags: 0), // amSMine
   105             (proc: @TestGrenade;     flags: 0), // amSMine
   106             (proc: @TestHammer;      flags: 0), // amHammer
   106             (proc: @TestHammer;      flags: 0), // amHammer
   107             (proc: nil;              flags: 0), // amResurrector
   107             (proc: nil;              flags: 0), // amResurrector
   108             (proc: nil;              flags: 0), // amDrillStrike
   108             (proc: nil;              flags: 0), // amDrillStrike
   109             (proc: nil;              flags: 0), // amSnowball
   109             (proc: @TestSnowball;    flags: 0), // amSnowball
   110             (proc: nil;              flags: 0), // amTardis
   110             (proc: nil;              flags: 0), // amTardis
   111             (proc: nil;              flags: 0), // amStructure
   111             (proc: nil;              flags: 0), // amStructure
   112             (proc: nil;              flags: 0) // amLandGun
   112             (proc: nil;              flags: 0) // amLandGun
   113             );
   113             );
   114 
   114 
   139 valueResult:= BadTurn;
   139 valueResult:= BadTurn;
   140 repeat
   140 repeat
   141     rTime:= rTime + 300 + Level * 50 + random(300);
   141     rTime:= rTime + 300 + Level * 50 + random(300);
   142     Vx:= - cWindSpeedf * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime;
   142     Vx:= - cWindSpeedf * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime;
   143     Vy:= cGravityf * rTime * 0.5 - (Targ.Y - mY) / rTime;
   143     Vy:= cGravityf * rTime * 0.5 - (Targ.Y - mY) / rTime;
   144     r:= sqrt(sqr(Vx) + sqr(Vy));
   144     r:= sqr(Vx) + sqr(Vy);
   145     if not (r > 1) then
   145     if not (r > 1) then
   146         begin
   146         begin
   147         x:= mX;
   147         x:= mX;
   148         y:= mY;
   148         y:= mY;
   149         dX:= Vx;
   149         dX:= Vx;
   162         if Me^.Hedgehog^.BotLevel = 1 then
   162         if Me^.Hedgehog^.BotLevel = 1 then
   163             value:= RateExplosion(Me, EX, EY, 101, 3)
   163             value:= RateExplosion(Me, EX, EY, 101, 3)
   164         else value:= RateExplosion(Me, EX, EY, 101);
   164         else value:= RateExplosion(Me, EX, EY, 101);
   165         if value = 0 then
   165         if value = 0 then
   166             value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
   166             value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
   167     if valueResult <= value then
   167         if valueResult <= value then
   168         begin
   168             begin
   169         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
   169             ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
   170         ap.Power:= trunc(r * cMaxPower) - random((Level - 1) * 17 + 1);
   170             ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1);
   171         ap.ExplR:= 100;
   171             ap.ExplR:= 100;
   172         ap.ExplX:= EX;
   172             ap.ExplX:= EX;
   173         ap.ExplY:= EY;
   173             ap.ExplY:= EY;
   174         valueResult:= value
   174             valueResult:= value
   175         end;
   175             end;
   176     end
   176         end
   177 //until (value > 204800) or (rTime > 4250); not so useful since adding score to the drowning
   177 //until (value > 204800) or (rTime > 4250); not so useful since adding score to the drowning
   178 until rTime > 4250;
   178 until rTime > 4250;
   179 TestBazooka:= valueResult
   179 TestBazooka:= valueResult
   180 end;
   180 end;
   181 
   181 
   182 function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   182 function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   183 var Vx, Vy, r: hwFloat;
   183 var Vx, Vy, r: real;
   184     rTime: LongInt;
   184     rTime: LongInt;
   185     EX, EY: LongInt;
   185     EX, EY: LongInt;
   186     valueResult: LongInt;
   186     valueResult: LongInt;
   187     x, y, dX, dY: hwFloat;
   187     x, y, dX, dY, meX, meY: real;
   188     t: LongInt;
   188     t: LongInt;
   189     value: LongInt;
   189     value: LongInt;
   190 
   190 
   191 begin
   191 begin
       
   192 meX:= hwFloat2Float(Me^.X);
       
   193 meY:= hwFloat2Float(Me^.Y);
   192 ap.Time:= 0;
   194 ap.Time:= 0;
   193 rTime:= 350;
   195 rTime:= 350;
   194 ap.ExplR:= 0;
   196 ap.ExplR:= 0;
   195 valueResult:= BadTurn;
   197 valueResult:= BadTurn;
   196 repeat
   198 repeat
   197     rTime:= rTime + 300 + Level * 50 + random(300);
   199     rTime:= rTime + 300 + Level * 50 + random(1000);
   198     Vx:= - cWindSpeed * rTime * _0_5 + (int2hwFloat(Targ.X + AIrndSign(2)) - Me^.X) / int2hwFloat(rTime);
   200     Vx:= - cWindSpeedf * rTime * 0.5 + ((Targ.X + AIrndSign(2)) - meX) / rTime;
   199     Vy:= cGravity * rTime * _0_5 - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(rTime);
   201     Vy:= cGravityf * rTime * 0.5 - (Targ.Y - meY) / rTime;
   200     r:= Distance(Vx, Vy);
   202     r:= sqr(Vx) + sqr(Vy);
   201     if not (r > _1) then
   203     if not (r > 1) then
   202         begin
   204         begin
   203         x:= Me^.X;
   205         x:= meX;
   204         y:= Me^.Y;
   206         y:= meY;
   205         dX:= Vx;
   207         dX:= Vx;
   206         dY:= -Vy;
   208         dY:= -Vy;
   207         t:= rTime;
   209         t:= rTime;
   208         repeat
   210         repeat
   209             x:= x + dX;
   211             x:= x + dX;
   210             y:= y + dY;
   212             y:= y + dY;
   211             dX:= dX + cWindSpeed;
   213             dX:= dX + cWindSpeedf;
   212             dY:= dY + cGravity;
   214             dY:= dY + cGravityf;
   213             dec(t)
   215             dec(t)
   214         until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0);
   216         until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0);
   215         EX:= hwRound(x);
   217         EX:= trunc(x);
   216         EY:= hwRound(y);
   218         EY:= trunc(y);
   217         value:= RateExplosion(Me, EX, EY, 5);
   219 
       
   220         value:= RateShove(Me, trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, 1);
   218         if value = 0 then
   221         if value = 0 then
   219             value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
   222             value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
   220 
   223 
   221         if valueResult <= value then
   224         if valueResult <= value then
   222             begin
   225             begin
   223             ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
   226             ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
   224             ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1);
   227             ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1);
   225             ap.ExplR:= 100;
   228             ap.ExplR:= 0;
   226             ap.ExplX:= EX;
   229             ap.ExplX:= EX;
   227             ap.ExplY:= EY;
   230             ap.ExplY:= EY;
   228             valueResult:= value
   231             valueResult:= value
   229             end;
   232             end;
   230      end
   233      end
   231 until (rTime > 4250);
   234 until (rTime > 4250);
   232 TestSnowball:= valueResult
   235 TestSnowball:= valueResult
   233 end;
   236 end;
   234 
   237 
   235 function TestMolotov(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   238 function TestMolotov(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   236 var Vx, Vy, r: hwFloat;
   239 var Vx, Vy, r: real;
   237     Score, EX, EY, valueResult: LongInt;
   240     Score, EX, EY, valueResult: LongInt;
   238     TestTime: Longword;
   241     TestTime: Longword;
   239     x, y, dY: hwFloat;
   242     x, y, dY, meX, meY: real;
   240     t: LongInt;
   243     t: LongInt;
   241 begin
   244 begin
       
   245 meX:= hwFloat2Float(Me^.X);
       
   246 meY:= hwFloat2Float(Me^.Y);
   242 valueResult:= BadTurn;
   247 valueResult:= BadTurn;
   243 TestTime:= 0;
   248 TestTime:= 0;
   244 ap.ExplR:= 0;
   249 ap.ExplR:= 0;
   245 repeat
   250 repeat
   246     inc(TestTime, 300);
   251     inc(TestTime, 300);
   247     Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
   252     Vx:= (Targ.X - meX) / TestTime;
   248     Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
   253     Vy:= cGravityf * (TestTime div 2) - Targ.Y - meY / TestTime;
   249     r:= Distance(Vx, Vy);
   254     r:= sqr(Vx) + sqr(Vy);
   250     if not (r > _1) then
   255     if not (r > 1) then
   251         begin
   256         begin
   252         x:= Me^.X;
   257         x:= meX;
   253         y:= Me^.Y;
   258         y:= meY;
   254         dY:= -Vy;
   259         dY:= -Vy;
   255         t:= TestTime;
   260         t:= TestTime;
   256         repeat
   261         repeat
   257             x:= x + Vx;
   262             x:= x + Vx;
   258             y:= y + dY;
   263             y:= y + dY;
   259             dY:= dY + cGravity;
   264             dY:= dY + cGravityf;
   260             dec(t)
   265             dec(t)
   261         until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 7) or (t = 0);
   266         until TestCollExcludingMe(Me, trunc(x), trunc(y), 7) or (t = 0);
   262         EX:= hwRound(x);
   267         EX:= trunc(x);
   263         EY:= hwRound(y);
   268         EY:= trunc(y);
   264         if t < 50 then
   269         if t < 50 then
   265             Score:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
   270             Score:= RateExplosion(Me, EX, EY, 97)  // average of 17 attempts, most good, but some failing spectacularly
   266         else
   271         else
   267             Score:= BadTurn;
   272             Score:= BadTurn;
   268                   
   273                   
   269         if valueResult < Score then
   274         if valueResult < Score then
   270             begin
   275             begin
   271             ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   276             ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   272             ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
   277             ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
   273             ap.Time:= TestTime;
   278             ap.Time:= TestTime;
   274             ap.ExplR:= 100;
   279             ap.ExplR:= 100;
   275             ap.ExplX:= EX;
   280             ap.ExplX:= EX;
   276             ap.ExplY:= EY;
   281             ap.ExplY:= EY;
   277             valueResult:= Score
   282             valueResult:= Score
   281 TestMolotov:= valueResult
   286 TestMolotov:= valueResult
   282 end;
   287 end;
   283 
   288 
   284 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   289 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   285 const tDelta = 24;
   290 const tDelta = 24;
   286 var Vx, Vy, r: hwFloat;
   291 var Vx, Vy, r: real;
   287     Score, EX, EY, valueResult: LongInt;
   292     Score, EX, EY, valueResult: LongInt;
   288     TestTime: Longword;
   293     TestTime: Longword;
   289     x, y, dY: hwFloat;
   294     x, y, meX, meY, dY: real;
   290     t: LongInt;
   295     t: LongInt;
   291 begin
   296 begin
   292 valueResult:= BadTurn;
   297 valueResult:= BadTurn;
   293 TestTime:= 0;
   298 TestTime:= 0;
   294 ap.ExplR:= 0;
   299 ap.ExplR:= 0;
       
   300 meX:= hwFloat2Float(Me^.X);
       
   301 meY:= hwFloat2Float(Me^.Y);
   295 repeat
   302 repeat
   296     inc(TestTime, 1000);
   303     inc(TestTime, 1000);
   297     Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta);
   304     Vx:= (Targ.X - meX) / (TestTime + tDelta);
   298     Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   305     Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Y - meY) / (TestTime + tDelta);
   299     r:= Distance(Vx, Vy);
   306     r:= sqr(Vx) + sqr(Vy);
   300     if not (r > _1) then
   307     if not (r > 1) then
   301         begin
   308         begin
   302         x:= Me^.X;
   309         x:= meX;
   303         y:= Me^.Y;
   310         y:= meY; 
   304         dY:= -Vy;
   311         dY:= -Vy;
   305         t:= TestTime;
   312         t:= TestTime;
   306         repeat
   313         repeat
   307             x:= x + Vx;
   314             x:= x + Vx;
   308             y:= y + dY;
   315             y:= y + dY;
   309             dY:= dY + cGravity;
   316             dY:= dY + cGravityf;
   310             dec(t)
   317             dec(t)
   311         until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
   318         until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t = 0);
   312     EX:= hwRound(x);
   319     EX:= trunc(x);
   313     EY:= hwRound(y);
   320     EY:= trunc(y);
   314     if t < 50 then 
   321     if t < 50 then 
   315         if Me^.Hedgehog^.BotLevel = 1 then
   322         if Me^.Hedgehog^.BotLevel = 1 then
   316             Score:= RateExplosion(Me, EX, EY, 101, 3)
   323             Score:= RateExplosion(Me, EX, EY, 101, 3)
   317         else Score:= RateExplosion(Me, EX, EY, 101)
   324         else Score:= RateExplosion(Me, EX, EY, 101)
   318     else 
   325     else 
   319         Score:= BadTurn;
   326         Score:= BadTurn;
   320 
   327 
   321     if valueResult < Score then
   328     if valueResult < Score then
   322         begin
   329         begin
   323         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   330         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   324         ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15);
   331         ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
   325         ap.Time:= TestTime;
   332         ap.Time:= TestTime;
   326         ap.ExplR:= 100;
   333         ap.ExplR:= 100;
   327         ap.ExplX:= EX;
   334         ap.ExplX:= EX;
   328         ap.ExplY:= EY;
   335         ap.ExplY:= EY;
   329         valueResult:= Score
   336         valueResult:= Score
   334 TestGrenade:= valueResult
   341 TestGrenade:= valueResult
   335 end;
   342 end;
   336 
   343 
   337 function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   344 function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   338 const tDelta = 24;
   345 const tDelta = 24;
   339 var Vx, Vy, r: hwFloat;
   346 var Vx, Vy, r: real;
   340     Score, EX, EY, valueResult: LongInt;
   347     Score, EX, EY, valueResult: LongInt;
   341     TestTime: Longword;
   348     TestTime: Longword;
   342     x, y, dY: hwFloat;
   349     x, y, dY, meX, meY: real;
   343     t: LongInt;
   350     t: LongInt;
   344 begin
   351 begin
   345 valueResult:= BadTurn;
   352 valueResult:= BadTurn;
   346 TestTime:= 0;
   353 TestTime:= 0;
   347 ap.ExplR:= 0;
   354 ap.ExplR:= 0;
       
   355 meX:= hwFloat2Float(Me^.X);
       
   356 meY:= hwFloat2Float(Me^.Y);
   348 repeat
   357 repeat
   349     inc(TestTime, 1000);
   358     inc(TestTime, 1000);
   350     // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster
   359     // Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster
   351     if Me^.X<int2hwFloat(Targ.X) then
   360     if meX<Targ.X then
   352         Vx:= (int2hwFloat(Targ.X+10) - Me^.X) / int2hwFloat(TestTime + tDelta)
   361         Vx:= ((Targ.X+10) - meX) / (TestTime + tDelta)
   353     else
   362     else
   354         Vx:= (int2hwFloat(Targ.X-10) - Me^.X) / int2hwFloat(TestTime + tDelta);
   363         Vx:= ((Targ.X-10) - meX) / (TestTime + tDelta);
   355     Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-150) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   364     Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-150) - meY) / (TestTime + tDelta);
   356     r:= Distance(Vx, Vy);
   365     r:= sqr(Vx)+sqr(Vy);
   357     if not (r > _1) then
   366     if not (r > 1) then
   358         begin
   367         begin
   359         x:= Me^.X;
   368         x:= meX;
   360         y:= Me^.Y;
   369         y:= meY;
   361         dY:= -Vy;
   370         dY:= -Vy;
   362         t:= TestTime;
   371         t:= TestTime;
   363     repeat
   372     repeat
   364         x:= x + Vx;
   373         x:= x + Vx;
   365         y:= y + dY;
   374         y:= y + dY;
   366         dY:= dY + cGravity;
   375         dY:= dY + cGravityf;
   367         dec(t)
   376         dec(t)
   368     until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
   377     until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t = 0);
   369     EX:= hwRound(x);
   378     EX:= trunc(x);
   370     EY:= hwRound(y);
   379     EY:= trunc(y);
   371     if t < 50 then 
   380     if t < 50 then 
   372         Score:= RateExplosion(Me, EX, EY, 41)
   381         Score:= RateExplosion(Me, EX, EY, 41)
   373     else 
   382     else 
   374         Score:= BadTurn;
   383         Score:= BadTurn;
   375 
   384 
   376      if valueResult < Score then
   385      if valueResult < Score then
   377         begin
   386         begin
   378         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   387         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   379         ap.Power:= hwRound(r * cMaxPower * _0_9) + AIrndSign(random(Level) * 15);
   388         ap.Power:= trunc(sqrt(r) * cMaxPower * 0.9) + AIrndSign(random(Level) * 15);
   380         ap.Time:= TestTime;
   389         ap.Time:= TestTime;
   381         ap.ExplR:= 90;
   390         ap.ExplR:= 90;
   382         ap.ExplX:= EX;
   391         ap.ExplX:= EX;
   383         ap.ExplY:= EY;
   392         ap.ExplY:= EY;
   384         valueResult:= Score
   393         valueResult:= Score
   388 TestClusterBomb:= valueResult
   397 TestClusterBomb:= valueResult
   389 end;
   398 end;
   390 
   399 
   391 function TestWatermelon(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   400 function TestWatermelon(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   392 const tDelta = 24;
   401 const tDelta = 24;
   393 var Vx, Vy, r: hwFloat;
   402 var Vx, Vy, r: real;
   394     Score, EX, EY, valueResult: LongInt;
   403     Score, EX, EY, valueResult: LongInt;
   395     TestTime: Longword;
   404     TestTime: Longword;
   396     x, y, dY: hwFloat;
   405     x, y, dY, meX, meY: real;
   397     t: LongInt;
   406     t: LongInt;
   398 begin
   407 begin
   399 valueResult:= BadTurn;
   408 valueResult:= BadTurn;
   400 TestTime:= 0;
   409 TestTime:= 0;
   401 ap.ExplR:= 0;
   410 ap.ExplR:= 0;
       
   411 meX:= hwFloat2Float(Me^.X);
       
   412 meY:= hwFloat2Float(Me^.Y);
   402 repeat
   413 repeat
   403     inc(TestTime, 1000);
   414     inc(TestTime, 1000);
   404     Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime + tDelta);
   415     Vx:= (Targ.X - meX) / (TestTime + tDelta);
   405     Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-200) - Me^.Y) / int2hwFloat(TestTime + tDelta);
   416     Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-200) - meY) / (TestTime + tDelta);
   406     r:= Distance(Vx, Vy);
   417     r:= sqr(Vx)+sqr(Vy);
   407     if not (r > _1) then
   418     if not (r > 1) then
   408         begin
   419         begin
   409         x:= Me^.X;
   420         x:= meX;
   410         y:= Me^.Y;
   421         y:= meY;
   411         dY:= -Vy;
   422         dY:= -Vy;
   412         t:= TestTime;
   423         t:= TestTime;
   413     repeat
   424     repeat
   414         x:= x + Vx;
   425         x:= x + Vx;
   415         y:= y + dY;
   426         y:= y + dY;
   416         dY:= dY + cGravity;
   427         dY:= dY + cGravityf;
   417         dec(t)
   428         dec(t)
   418     until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0);
   429     until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t = 0);
   419     EX:= hwRound(x);
   430     EX:= trunc(x);
   420     EY:= hwRound(y);
   431     EY:= trunc(y);
   421     if t < 50 then 
   432     if t < 50 then 
   422         Score:= RateExplosion(Me, EX, EY, 381)
   433         Score:= RateExplosion(Me, EX, EY, 381)
   423     else 
   434     else 
   424         Score:= BadTurn;
   435         Score:= BadTurn;
   425         
   436         
   426     if valueResult < Score then
   437     if valueResult < Score then
   427         begin
   438         begin
   428         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   439         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   429         ap.Power:= hwRound(r * cMaxPower * _0_9) + AIrndSign(random(Level) * 15);
   440         ap.Power:= trunc(sqrt(r) * cMaxPower * 0.9) + AIrndSign(random(Level) * 15);
   430         ap.Time:= TestTime;
   441         ap.Time:= TestTime;
   431         ap.ExplR:= 300;
   442         ap.ExplR:= 300;
   432         ap.ExplX:= EX;
   443         ap.ExplX:= EX;
   433         ap.ExplY:= EY;
   444         ap.ExplY:= EY;
   434         valueResult:= Score
   445         valueResult:= Score
   438 TestWatermelon:= valueResult
   449 TestWatermelon:= valueResult
   439 end;
   450 end;
   440 
   451 
   441 
   452 
   442     function Solve(TX, TY, MX, MY: LongInt): LongWord;
   453     function Solve(TX, TY, MX, MY: LongInt): LongWord;
   443     var A, B, D, T: hwFloat;
   454     var A, B, D, T: real;
   444         C: LongInt;
   455         C: LongInt;
   445     begin
   456     begin
   446         A:= hwSqr(cGravity) * _0_25;
   457         A:= sqr(cGravityf) * 0.25;
   447         B:= - cGravity * (TY - MY) - _1;
   458         B:= - cGravityf * (TY - MY) - 1;
   448         C:= sqr(TY - MY) + sqr(TX - MX);
   459         C:= sqr(TY - MY) + sqr(TX - MX);
   449         D:= hwSqr(B) - (A * C * 4);
   460         D:= sqr(B) - (A * C * 4);
   450         if D.isNegative = false then
   461         if D >= 0 then
   451             begin
   462             begin
   452             D:= ( - B + hwSqrt(D)) * _0_5 / A;
   463             D:= ( - B + sqrt(D)) * 0.5 / A;
   453             if D.isNegative = false then
   464             if D >= 0 then
   454                 T:= hwSqrt(D)
   465                 T:= sqrt(D)
   455             else
   466             else
   456                 T:= _0;
   467                 T:= 0;
   457             Solve:= hwRound(T)
   468             Solve:= trunc(T)
   458             end
   469             end
   459             else
   470             else
   460                 Solve:= 0
   471                 Solve:= 0
   461     end;
   472     end;
   462     
   473     
   463 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   474 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   464 //const tDelta = 24;
   475 //const tDelta = 24;
   465 var Vx, Vy: hwFloat;
   476 var Vx, Vy: real;
   466     Score, EX, EY, valueResult: LongInt;
   477     Score, EX, EY, valueResult: LongInt;
   467     TestTime: Longword;
   478     TestTime: Longword;
   468     x, y, dY: hwFloat;
   479     x, y, dY, meX, meY: real;
   469 begin
   480 begin
   470 valueResult:= BadTurn;
   481 valueResult:= BadTurn;
   471 ap.ExplR:= 0;
   482 ap.ExplR:= 0;
       
   483 meX:= hwFloat2Float(Me^.X);
       
   484 meY:= hwFloat2Float(Me^.Y);
   472 
   485 
   473 if (Level > 2) then
   486 if (Level > 2) then
   474     exit(BadTurn);
   487     exit(BadTurn);
   475 
   488 
   476 TestTime:= Solve(Targ.X, Targ.Y, hwRound(Me^.X), hwRound(Me^.Y));
   489 TestTime:= Solve(Targ.X, Targ.Y, trunc(meX), trunc(meY));
   477 
   490 
   478 if TestTime = 0 then
   491 if TestTime = 0 then
   479     exit(BadTurn);
   492     exit(BadTurn);
   480 
   493 
   481     Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
   494     Vx:= (Targ.X - meX) / TestTime;
   482     Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
   495     Vy:= cGravityf * (TestTime div 2) - (Targ.Y - meY) / TestTime;
   483 
   496 
   484     x:= Me^.X;
   497     x:= meX;
   485     y:= Me^.Y;
   498     y:= meY;
   486     dY:= -Vy;
   499     dY:= -Vy;
   487 
   500 
   488     repeat
   501     repeat
   489         x:= x + Vx;
   502         x:= x + Vx;
   490         y:= y + dY;
   503         y:= y + dY;
   491         dY:= dY + cGravity;
   504         dY:= dY + cGravityf;
   492         EX:= hwRound(x);
   505         EX:= trunc(x);
   493         EY:= hwRound(y);
   506         EY:= trunc(y);
   494     until TestCollExcludingMe(Me, EX, EY, 5) or (EY > cWaterLine);
   507     until TestCollExcludingMe(Me, EX, EY, 5) or (EY > cWaterLine);
   495 
   508 
   496     if (EY < cWaterLine) and (not dY.isNegative) then
   509     if (EY < cWaterLine) and (dY >= 0) then
   497         begin
   510         begin
   498         Score:= RateExplosion(Me, EX, EY, 91);
   511         Score:= RateExplosion(Me, EX, EY, 91);
   499         if (Score = 0) then
   512         if (Score = 0) then
   500             if (dY > _0_15) then
   513             if (dY > 0.15) then
   501                 Score:= - abs(Targ.Y - EY) div 32
   514                 Score:= - abs(Targ.Y - EY) div 32
   502             else
   515             else
   503                 Score:= BadTurn
   516                 Score:= BadTurn
   504         else if (Score < 0) then
   517         else if (Score < 0) then
   505             Score:= BadTurn
   518             Score:= BadTurn
   522 
   535 
   523 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   536 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   524 const
   537 const
   525     MIN_RANGE =  80;
   538     MIN_RANGE =  80;
   526     MAX_RANGE = 400;
   539     MAX_RANGE = 400;
   527 var Vx, Vy, x, y: hwFloat;
   540 var Vx, Vy, x, y: real;
   528     rx, ry, valueResult: LongInt;
   541     rx, ry, valueResult: LongInt;
   529     range: integer;
   542     range: integer;
   530 begin
   543 begin
   531 ap.ExplR:= 0;
   544 ap.ExplR:= 0;
   532 ap.Time:= 0;
   545 ap.Time:= 0;
   533 ap.Power:= 1;
   546 ap.Power:= 1;
   534 x:= Me^.X;
   547 x:= hwFloat2Float(Me^.X);
   535 y:= Me^.Y;
   548 y:= hwFloat2Float(Me^.Y);
   536 range:= Metric(hwRound(x), hwRound(y), Targ.X, Targ.Y);
   549 range:= Metric(trunc(x), trunc(y), Targ.X, Targ.Y);
   537 if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then
   550 if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then
   538     exit(BadTurn);
   551     exit(BadTurn);
   539 Vx:= (int2hwFloat(Targ.X) - x) * _1div1024;
   552 Vx:= (Targ.X - x) * 1 / 1024;
   540 Vy:= (int2hwFloat(Targ.Y) - y) * _1div1024;
   553 Vy:= (Targ.Y - y) * 1 / 1024;
   541 ap.Angle:= DxDy2AttackAngle(Vx, -Vy);
   554 ap.Angle:= DxDy2AttackAngle(Vx, -Vy);
   542 repeat
   555 repeat
   543     x:= x + vX;
   556     x:= x + vX;
   544     y:= y + vY;
   557     y:= y + vY;
   545     rx:= hwRound(x);
   558     rx:= trunc(x);
   546     ry:= hwRound(y);
   559     ry:= trunc(y);
   547     if TestCollExcludingMe(Me, rx, ry, 2) then
   560     if TestCollExcludingMe(Me, rx, ry, 2) then
   548         begin
   561         begin
   549         x:= x + vX * 8;
   562         x:= x + vX * 8;
   550         y:= y + vY * 8;
   563         y:= y + vY * 8;
   551         valueResult:= RateShotgun(Me, hwFloat2Float(vX), hwFloat2Float(vY), rx, ry);
   564         valueResult:= RateShotgun(Me, vX, vY, rx, ry);
   552      
   565      
   553     if valueResult = 0 then 
   566     if valueResult = 0 then 
   554         valueResult:= - Metric(Targ.X, Targ.Y, rx, ry) div 64
   567         valueResult:= - Metric(Targ.X, Targ.Y, rx, ry) div 64
   555     else 
   568     else 
   556         dec(valueResult, Level * 4000);
   569         dec(valueResult, Level * 4000);
   557     exit(valueResult * 27 div 20) // 27/20 is reuse bonus
   570     exit(valueResult * 27 div 20) // 27/20 is reuse bonus
   558     end
   571     end
   559 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4)
   572 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
   560     or (x.isNegative)
   573     or (x < 0)
   561     or (y.isNegative)
   574     or (y < 0)
   562     or (x.Round > LongWord(LAND_WIDTH))
   575     or (trunc(x) > LAND_WIDTH)
   563     or (y.Round > LongWord(LAND_HEIGHT));
   576     or (trunc(y) > LAND_HEIGHT);
   564 
   577 
   565 TestShotgun:= BadTurn
   578 TestShotgun:= BadTurn
   566 end;
   579 end;
   567 
   580 
   568 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   581 function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   569 var Vx, Vy, x, y, t: hwFloat;
   582 var Vx, Vy, x, y, t: real;
   570     d: Longword;
   583     d: Longword;
   571     valueResult: LongInt;
   584     valueResult: LongInt;
   572 begin
   585 begin
   573 Level:= Level; // avoid compiler hint
   586 Level:= Level; // avoid compiler hint
   574 ap.ExplR:= 0;
   587 ap.ExplR:= 0;
   575 ap.Time:= 0;
   588 ap.Time:= 0;
   576 ap.Power:= 1;
   589 ap.Power:= 1;
   577 x:= Me^.X;
   590 x:= hwFloat2Float(Me^.X);
   578 y:= Me^.Y;
   591 y:= hwFloat2Float(Me^.Y);
   579 if Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) < 320 then
   592 if Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) < 40 then
   580    exit(BadTurn);
   593    exit(BadTurn);
   581 t:= _0_5 / Distance(int2hwFloat(Targ.X) - x, int2hwFloat(Targ.Y) - y);
   594 t:= 0.5 / sqrt(sqr(Targ.X - x)+sqr(Targ.Y-y));
   582 Vx:= (int2hwFloat(Targ.X) - x) * t;
   595 Vx:= (Targ.X - x) * t;
   583 Vy:= (int2hwFloat(Targ.Y) - y) * t;
   596 Vy:= (Targ.Y - y) * t;
   584 ap.Angle:= DxDy2AttackAngle(Vx, -Vy);
   597 ap.Angle:= DxDy2AttackAngle(Vx, -Vy);
   585 d:= 0;
   598 d:= 0;
   586 
   599 
   587 repeat
   600 repeat
   588     x:= x + vX;
   601     x:= x + vX;
   589     y:= y + vY;
   602     y:= y + vY;
   590     if ((hwRound(x) and LAND_WIDTH_MASK) = 0)and((hwRound(y) and LAND_HEIGHT_MASK) = 0)
   603     if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0)
   591     and (Land[hwRound(y), hwRound(x)] <> 0) then
   604     and (Land[trunc(y), trunc(x)] <> 0) then
   592         inc(d);
   605         inc(d);
   593 until (Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 4)
   606 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
   594     or (x.isNegative)
   607     or (x < 0)
   595     or (y.isNegative)
   608     or (y < 0)
   596     or (x.Round > LongWord(LAND_WIDTH))
   609     or (trunc(x) > LAND_WIDTH)
   597     or (y.Round > LongWord(LAND_HEIGHT))
   610     or (trunc(y) > LAND_HEIGHT)
   598     or (d > 200);
   611     or (d > 200);
   599 
   612 
   600 if Abs(Targ.X - hwRound(x)) + Abs(Targ.Y - hwRound(y)) < 3 then
   613 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 3 then
   601     begin
   614     begin
   602     if TraceShoveDrown(Me, Targ.X, Targ.Y, hwFloat2Float(vX) * 0.005 * 20, hwFloat2Float(vY) * 0.005 * 20) then
   615     if TraceShoveDrown(Me, Targ.X, Targ.Y, vX * 0.005 * 20, vY * 0.005 * 20) then
   603         valueResult:= 204800
   616         valueResult:= 204800
   604     else valueResult:= Max(0, (4 - d div 50) * 7 * 1024)
   617     else valueResult:= Max(0, (4 - d div 50) * 7 * 1024)
   605     end
   618     end
   606 else
   619 else
   607     valueResult:= BadTurn;
   620     valueResult:= BadTurn;
   608 TestDesertEagle:= valueResult
   621 TestDesertEagle:= valueResult
   609 end;
   622 end;
   610 
   623 
   611 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   624 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   612 var valueResult: LongInt;
   625 var valueResult: LongInt;
   613     x, y: hwFloat;
   626     x, y: real;
   614 begin
   627 begin
   615 Level:= Level; // avoid compiler hint
   628 Level:= Level; // avoid compiler hint
   616 ap.ExplR:= 0;
   629 ap.ExplR:= 0;
   617 if (Level > 2) or (Abs(hwRound(Me^.X) - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) > 25) then
   630 x:= hwFloat2Float(Me^.X);
       
   631 y:= hwFloat2Float(Me^.Y);
       
   632 if (Level > 2) or (Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) > 25) then
   618     exit(BadTurn);
   633     exit(BadTurn);
   619 
   634 
   620 ap.Time:= 0;
   635 ap.Time:= 0;
   621 ap.Power:= 1;
   636 ap.Power:= 1;
   622 x:= Me^.X;
   637 if (Targ.X) - trunc(x) >= 0 then
   623 y:= Me^.Y;
       
   624 if (Targ.X) - hwRound(x) >= 0 then
       
   625     ap.Angle:=   cMaxAngle div 4
   638     ap.Angle:=   cMaxAngle div 4
   626 else
   639 else
   627     ap.Angle:= - cMaxAngle div 4;
   640     ap.Angle:= - cMaxAngle div 4;
   628 
   641 
   629 valueResult:= RateShove(Me, hwRound(x) + 10 * hwSign(int2hwFloat(Targ.X) - x), hwRound(y), 15, 30, 115, hwSign(Me^.dX)*0.353, -0.353, 1);
   642 valueResult:= RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x), trunc(y), 15, 30, 115, hwSign(Me^.dX)*0.353, -0.353, 1);
   630 if valueResult <= 0 then
   643 if valueResult <= 0 then
   631     valueResult:= BadTurn
   644     valueResult:= BadTurn
   632 else
   645 else
   633     inc(valueResult);
   646     inc(valueResult);
   634 TestBaseballBat:= valueResult;
   647 TestBaseballBat:= valueResult;
   635 end;
   648 end;
   636 
   649 
   637 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   650 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   638 var i, valueResult: LongInt;
   651 var i, valueResult: LongInt;
   639     x, y: hwFloat;
   652     x, y: real;
   640 begin
   653 begin
   641 Level:= Level; // avoid compiler hint
   654 Level:= Level; // avoid compiler hint
   642 ap.ExplR:= 0;
   655 ap.ExplR:= 0;
   643 ap.Time:= 0;
   656 ap.Time:= 0;
   644 ap.Power:= 1;
   657 ap.Power:= 1;
   645 ap.Angle:= 0;
   658 ap.Angle:= 0;
   646 x:= Me^.X;
   659 x:= hwFloat2Float(Me^.X);
   647 y:= Me^.Y;
   660 y:= hwFloat2Float(Me^.Y);
   648 if (Abs(hwRound(x) - Targ.X) > 25)
   661 if (Abs(trunc(x) - Targ.X) > 25)
   649 or (Abs(hwRound(y) - 50 - Targ.Y) > 50) then
   662 or (Abs(trunc(y) - 50 - Targ.Y) > 50) then
   650     begin
   663     begin
   651     if TestColl(hwRound(x), hwRound(y) - 16, 6)
   664     if TestColl(trunc(x), trunc(y) - 16, 6)
   652     and (RateShove(Me, hwRound(x) + 10 * hwSign(Me^.dX), hwRound(y) - 40, 30, 30, 40, hwSign(Me^.dX)*0.45, -0.9,  1) = 0) then
   665     and (RateShove(Me, trunc(x) + 10 * hwSign(Me^.dX), trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX)*0.45, -0.9,  1) = 0) then
   653         valueResult:= Succ(BadTurn)
   666         valueResult:= Succ(BadTurn)
   654     else
   667     else
   655         valueResult:= BadTurn;
   668         valueResult:= BadTurn;
   656     exit(valueResult)
   669     exit(valueResult)
   657     end;
   670     end;
   658 
   671 
   659 valueResult:= 0;
   672 valueResult:= 0;
   660 for i:= 0 to 4 do
   673 for i:= 0 to 4 do
   661     valueResult:= valueResult + RateShove(Me, hwRound(x) + 10 * hwSign(int2hwFloat(Targ.X) - x),
   674     valueResult:= valueResult + RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x),
   662                                     hwRound(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1);
   675                                     trunc(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX)*0.45, -0.9, 1);
   663 if valueResult <= 0 then
   676 if valueResult <= 0 then
   664     valueResult:= BadTurn
   677     valueResult:= BadTurn
   665 else
   678 else
   666     inc(valueResult);
   679     inc(valueResult);
   667 
   680 
   668 TestFirePunch:= valueResult;
   681 TestFirePunch:= valueResult;
   669 end;
   682 end;
   670 
   683 
   671 function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   684 function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   672 var i, valueResult: LongInt;
   685 var i, valueResult: LongInt;
   673     x, y: hwFloat;
   686     x, y: real;
   674 begin
   687 begin
   675 Level:= Level; // avoid compiler hint
   688 Level:= Level; // avoid compiler hint
   676 ap.ExplR:= 0;
   689 ap.ExplR:= 0;
   677 ap.Time:= 0;
   690 ap.Time:= 0;
   678 ap.Power:= 1;
   691 ap.Power:= 1;
   679 ap.Angle:= 0;
   692 ap.Angle:= 0;
   680 x:= Me^.X;
   693 x:= hwFloat2Float(Me^.X);
   681 y:= Me^.Y;
   694 y:= hwFloat2Float(Me^.Y);
   682 if (Abs(hwRound(x) - Targ.X) > 25)
   695 if (Abs(trunc(x) - Targ.X) > 25)
   683 or (Abs(hwRound(y) - 50 - Targ.Y) > 50) then
   696 or (Abs(trunc(y) - 50 - Targ.Y) > 50) then
   684     begin
   697     begin
   685     if TestColl(hwRound(x), hwRound(y) - 16, 6)
   698     if TestColl(trunc(x), trunc(y) - 16, 6)
   686     and (RateShove(Me, hwRound(x) + 10 * hwSign(Me^.dX), hwRound(y) - 40, 30, 30, 40, hwSign(Me^.dX), -0.8,  1) = 0) then
   699     and (RateShove(Me, trunc(x) + 10 * hwSign(Me^.dX), trunc(y) - 40, 30, 30, 40, hwSign(Me^.dX), -0.8,  1) = 0) then
   687         valueResult:= Succ(BadTurn)
   700         valueResult:= Succ(BadTurn)
   688     else
   701     else
   689         valueResult:= BadTurn;
   702         valueResult:= BadTurn;
   690     exit(valueResult)
   703     exit(valueResult)
   691     end;
   704     end;
   692 
   705 
   693 valueResult:= 0;
   706 valueResult:= 0;
   694 for i:= 0 to 4 do
   707 for i:= 0 to 4 do
   695     valueResult:= valueResult + RateShove(Me, hwRound(x) + 10 * hwSign(int2hwFloat(Targ.X) - x),
   708     valueResult:= valueResult + RateShove(Me, trunc(x) + 10 * hwSign(Targ.X - x),
   696                                     hwRound(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX), -0.8, 1);
   709                                     trunc(y) - 20 * i - 5, 10, 30, 40, hwSign(Me^.dX), -0.8, 1);
   697 if valueResult <= 0 then
   710 if valueResult <= 0 then
   698     valueResult:= BadTurn
   711     valueResult:= BadTurn
   699 else
   712 else
   700     inc(valueResult);
   713     inc(valueResult);
   701 
   714 
   720 TestHammer:= rate;
   733 TestHammer:= rate;
   721 end;
   734 end;
   722 
   735 
   723 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   736 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   724 const cShift = 4;
   737 const cShift = 4;
   725 var X, Y, dY: hwFloat;
   738 var bombsSpeed, X, Y, dY: real;
   726     b: array[0..9] of boolean;
   739     b: array[0..9] of boolean;
   727     dmg: array[0..9] of LongInt;
   740     dmg: array[0..9] of LongInt;
   728     fexit: boolean;
   741     fexit: boolean;
   729     i, t, valueResult: LongInt;
   742     i, t, valueResult: LongInt;
   730 begin
   743 begin
   734     exit(BadTurn);
   747     exit(BadTurn);
   735 
   748 
   736 ap.AttackPutX:= Targ.X;
   749 ap.AttackPutX:= Targ.X;
   737 ap.AttackPutY:= Targ.Y;
   750 ap.AttackPutY:= Targ.Y;
   738 
   751 
   739 X:= int2hwFloat(Targ.X - 135 - cShift); // hh center - cShift
   752 bombsSpeed:= hwFloat2Float(cBombsSpeed);
   740 X:= X - cBombsSpeed * hwSqrt(int2hwFloat((Targ.Y + 128) * 2) / cGravity);
   753 X:= Targ.X - 135 - cShift; // hh center - cShift
   741 Y:= -_128;
   754 X:= X - bombsSpeed * sqrt(((Targ.Y + 128) * 2) / cGravityf);
   742 dY:= _0;
   755 Y:= -128;
       
   756 dY:= 0;
   743 
   757 
   744 for i:= 0 to 9 do
   758 for i:= 0 to 9 do
   745     begin
   759     begin
   746     b[i]:= true;
   760     b[i]:= true;
   747     dmg[i]:= 0
   761     dmg[i]:= 0
   748     end;
   762     end;
   749 valueResult:= 0;
   763 valueResult:= 0;
   750 
   764 
   751 repeat
   765 repeat
   752     X:= X + cBombsSpeed;
   766     X:= X + bombsSpeed;
   753     Y:= Y + dY;
   767     Y:= Y + dY;
   754     dY:= dY + cGravity;
   768     dY:= dY + cGravityf;
   755     fexit:= true;
   769     fexit:= true;
   756 
   770 
   757     for i:= 0 to 9 do
   771     for i:= 0 to 9 do
   758         if b[i] then
   772         if b[i] then
   759             begin
   773             begin
   760             fexit:= false;
   774             fexit:= false;
   761             if TestColl(hwRound(X) + i * 30, hwRound(Y), 4) then
   775             if TestColl(trunc(X) + i * 30, trunc(Y), 4) then
   762                 begin
   776                 begin
   763                 b[i]:= false;
   777                 b[i]:= false;
   764                 dmg[i]:= RateExplosion(Me, hwRound(X) + i * 30, hwRound(Y), 58)
   778                 dmg[i]:= RateExplosion(Me, trunc(X) + i * 30, trunc(Y), 58)
   765                 // 58 (instead of 60) for better prediction (hh moves after explosion of one of the rockets)
   779                 // 58 (instead of 60) for better prediction (hh moves after explosion of one of the rockets)
   766                 end
   780                 end
   767             end;
   781             end;
   768 until fexit or (Y.Round > cWaterLine);
   782 until fexit or (Y > cWaterLine);
   769 
   783 
   770 for i:= 0 to 5 do inc(valueResult, dmg[i]);
   784 for i:= 0 to 5 do inc(valueResult, dmg[i]);
   771 t:= valueResult;
   785 t:= valueResult;
   772 ap.AttackPutX:= Targ.X - 60;
   786 ap.AttackPutX:= Targ.X - 60;
   773 
   787