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 |
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^.Hedgehog^.Gear, 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); |
224 x:= x + dX; |
224 x:= x + dX; |
225 y:= y + dY; |
225 y:= y + dY; |
226 dX:= dX + windSpeed; |
226 dX:= dX + windSpeed; |
227 dY:= dY + cGravityf; |
227 dY:= dY + cGravityf; |
228 dec(t) |
228 dec(t) |
229 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
229 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
230 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (y > cWaterLine); |
230 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (y > cWaterLine); |
231 |
231 |
232 if TestCollWithLand(trunc(x), trunc(y), 5) and (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) > 21) then |
232 if TestCollExcludingObjects(trunc(x), trunc(y), 5) and (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) > 21) then |
233 begin |
233 begin |
234 timer := 500; |
234 timer := 500; |
235 t2 := 0.5 / sqrt(sqr(dX) + sqr(dY)); |
235 t2 := 0.5 / sqrt(sqr(dX) + sqr(dY)); |
236 dX := dX * t2; |
236 dX := dX * t2; |
237 dY := dY * t2; |
237 dY := dY * t2; |
242 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 22) |
242 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 22) |
243 or (x < 0) |
243 or (x < 0) |
244 or (y < 0) |
244 or (y < 0) |
245 or (trunc(x) > LAND_WIDTH) |
245 or (trunc(x) > LAND_WIDTH) |
246 or (trunc(y) > LAND_HEIGHT) |
246 or (trunc(y) > LAND_HEIGHT) |
247 or not TestCollWithLand(trunc(x), trunc(y), 5) |
247 or not TestCollExcludingObjects(trunc(x), trunc(y), 5) |
248 or (timer = 0) |
248 or (timer = 0) |
249 end; |
249 end; |
250 EX:= trunc(x); |
250 EX:= trunc(x); |
251 EY:= trunc(y); |
251 EY:= trunc(y); |
|
252 // Try to prevent AI from thinking firing into water will cause a drowning |
|
253 if (EY < cWaterLine-5) and (Timer > 0) and (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) > 21) then exit(BadTurn); |
252 if Level = 1 then |
254 if Level = 1 then |
253 value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
255 value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
254 else value:= RateExplosion(Me, EX, EY, 101); |
256 else value:= RateExplosion(Me, EX, EY, 101); |
255 if valueResult <= value then |
257 if valueResult <= value then |
256 begin |
258 begin |
260 ap.ExplX:= EX; |
262 ap.ExplX:= EX; |
261 ap.ExplY:= EY; |
263 ap.ExplY:= EY; |
262 valueResult:= value-2500 // trying to make it slightly less attractive than a bazooka, to prevent waste. AI could use awareness of weapon count |
264 valueResult:= value-2500 // trying to make it slightly less attractive than a bazooka, to prevent waste. AI could use awareness of weapon count |
263 end; |
265 end; |
264 end |
266 end |
265 until rTime > 4250; |
267 until rTime > 5050 - Level * 800; |
266 TestDrillRocket:= valueResult |
268 TestDrillRocket:= valueResult |
267 end; |
269 end; |
268 |
270 |
269 |
271 |
270 function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
272 function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
299 x:= x + dX; |
301 x:= x + dX; |
300 y:= y + dY; |
302 y:= y + dY; |
301 dX:= dX + windSpeed; |
303 dX:= dX + windSpeed; |
302 dY:= dY + cGravityf; |
304 dY:= dY + cGravityf; |
303 dec(t) |
305 dec(t) |
304 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
306 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
305 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0); |
307 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t <= 0); |
306 EX:= trunc(x); |
308 EX:= trunc(x); |
307 EY:= trunc(y); |
309 EY:= trunc(y); |
308 |
310 |
309 value:= RateShove(trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall); |
311 value:= RateShove(trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall); |
310 // LOL copypasta: this is score for digging with... snowball |
312 // LOL copypasta: this is score for digging with... snowball |
351 repeat |
353 repeat |
352 x:= x + Vx; |
354 x:= x + Vx; |
353 y:= y + dY; |
355 y:= y + dY; |
354 dY:= dY + cGravityf; |
356 dY:= dY + cGravityf; |
355 dec(t) |
357 dec(t) |
356 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or |
358 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or |
357 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0); |
359 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0); |
358 EX:= trunc(x); |
360 EX:= trunc(x); |
359 EY:= trunc(y); |
361 EY:= trunc(y); |
360 if t < 50 then |
362 if t < 50 then |
361 Score:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly |
363 Score:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly |
362 else |
364 else |
363 Score:= BadTurn; |
365 Score:= BadTurn; |
364 |
366 |
365 if valueResult < Score then |
367 if valueResult < Score then |
366 begin |
368 begin |
367 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
369 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
368 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
370 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
369 ap.ExplR:= 100; |
371 ap.ExplR:= 100; |
370 ap.ExplX:= EX; |
372 ap.ExplX:= EX; |
371 ap.ExplY:= EY; |
373 ap.ExplY:= EY; |
372 valueResult:= Score |
374 valueResult:= Score |
373 end; |
375 end; |
374 end |
376 end |
375 until (TestTime > 4250); |
377 until (TestTime > 5050 - Level * 800); |
376 TestMolotov:= valueResult |
378 TestMolotov:= valueResult |
377 end; |
379 end; |
378 |
380 |
379 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
381 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
380 const tDelta = 24; |
382 const tDelta = 24; |
395 Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Y - meY) / (TestTime + tDelta); |
397 Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Y - meY) / (TestTime + tDelta); |
396 r:= sqr(Vx) + sqr(Vy); |
398 r:= sqr(Vx) + sqr(Vy); |
397 if not (r > 1) then |
399 if not (r > 1) then |
398 begin |
400 begin |
399 x:= meX; |
401 x:= meX; |
400 y:= meY; |
402 y:= meY; |
401 dY:= -Vy; |
403 dY:= -Vy; |
402 t:= TestTime; |
404 t:= TestTime; |
403 repeat |
405 repeat |
404 x:= x + Vx; |
406 x:= x + Vx; |
405 y:= y + dY; |
407 y:= y + dY; |
406 dY:= dY + cGravityf; |
408 dY:= dY + cGravityf; |
407 dec(t) |
409 dec(t) |
408 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
410 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
409 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0); |
411 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0); |
410 EX:= trunc(x); |
412 EX:= trunc(x); |
411 EY:= trunc(y); |
413 EY:= trunc(y); |
412 if t < 50 then |
414 if t < 50 then |
413 if Level = 1 then |
415 if Level = 1 then |
414 Score:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
416 Score:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand) |
415 else Score:= RateExplosion(Me, EX, EY, 101) |
417 else Score:= RateExplosion(Me, EX, EY, 101) |
416 else |
418 else |
417 Score:= BadTurn; |
419 Score:= BadTurn; |
418 |
420 |
419 if (valueResult < Score) and (Score > 0) then |
421 if (valueResult < Score) and (Score > 0) then |
420 begin |
422 begin |
421 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
423 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level * 3)); |
422 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
424 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 20); |
423 ap.Time:= TestTime; |
425 ap.Time:= TestTime; |
424 ap.ExplR:= 100; |
426 ap.ExplR:= 100; |
425 ap.ExplX:= EX; |
427 ap.ExplX:= EX; |
426 ap.ExplY:= EY; |
428 ap.ExplY:= EY; |
427 valueResult:= Score |
429 valueResult:= Score |
428 end; |
430 end; |
429 end |
431 end |
430 //until (Score > 204800) or (TestTime > 4000); |
432 //until (Score > 204800) or (TestTime > 4000); |
431 until TestTime > 4000; |
433 until TestTime > 4500 - Level * 512; |
432 TestGrenade:= valueResult |
434 TestGrenade:= valueResult |
433 end; |
435 end; |
434 |
436 |
435 function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
437 function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; |
436 const tDelta = 24; |
438 const tDelta = 24; |
463 repeat |
465 repeat |
464 x:= x + Vx; |
466 x:= x + Vx; |
465 y:= y + dY; |
467 y:= y + dY; |
466 dY:= dY + cGravityf; |
468 dY:= dY + cGravityf; |
467 dec(t) |
469 dec(t) |
468 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
470 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or |
469 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0); |
471 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0); |
470 EX:= trunc(x); |
472 EX:= trunc(x); |
471 EY:= trunc(y); |
473 EY:= trunc(y); |
472 if t < 50 then |
474 if t < 50 then |
473 Score:= RateExplosion(Me, EX, EY, 41) |
475 Score:= RateExplosion(Me, EX, EY, 41) |
474 else |
476 else |
475 Score:= BadTurn; |
477 Score:= BadTurn; |
476 |
478 |
477 if valueResult < Score then |
479 if valueResult < Score then |
478 begin |
480 begin |
479 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
481 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level * 2)); |
480 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
482 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
481 ap.Time:= TestTime div 1000 * 1000; |
483 ap.Time:= TestTime div 1000 * 1000; |
482 ap.ExplR:= 90; |
484 ap.ExplR:= 90; |
483 ap.ExplX:= EX; |
485 ap.ExplX:= EX; |
484 ap.ExplY:= EY; |
486 ap.ExplY:= EY; |
516 repeat |
518 repeat |
517 x:= x + Vx; |
519 x:= x + Vx; |
518 y:= y + dY; |
520 y:= y + dY; |
519 dY:= dY + cGravityf; |
521 dY:= dY + cGravityf; |
520 dec(t) |
522 dec(t) |
521 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or |
523 until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or |
522 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0); |
524 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0); |
523 |
525 |
524 EX:= trunc(x); |
526 EX:= trunc(x); |
525 EY:= trunc(y); |
527 EY:= trunc(y); |
526 if t < 50 then |
528 if t < 50 then |
527 Score:= RateExplosion(Me, EX, EY, 200) + RateExplosion(Me, EX, EY + 120, 200) |
529 Score:= RateExplosion(Me, EX, EY, 200) + RateExplosion(Me, EX, EY + 120, 200) |
528 else |
530 else |
529 Score:= BadTurn; |
531 Score:= BadTurn; |
530 |
532 |
531 if valueResult < Score then |
533 if valueResult < Score then |
532 begin |
534 begin |
533 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
535 ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level)); |
534 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
536 ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15); |
535 ap.Time:= TestTime div 1000 * 1000; |
537 ap.Time:= TestTime div 1000 * 1000; |
597 x:= x + Vx; |
599 x:= x + Vx; |
598 y:= y + dY; |
600 y:= y + dY; |
599 dY:= dY + cGravityf; |
601 dY:= dY + cGravityf; |
600 EX:= trunc(x); |
602 EX:= trunc(x); |
601 EY:= trunc(y); |
603 EY:= trunc(y); |
602 until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or |
604 until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or |
603 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, EX, EY, 4))) or (EY > cWaterLine); |
605 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, EX, EY, 4))) or (EY > cWaterLine); |
604 |
606 |
605 if (EY < cWaterLine) and (dY >= 0) then |
607 if (EY < cWaterLine) and (dY >= 0) then |
606 begin |
608 begin |
607 Score:= RateExplosion(Me, EX, EY, 91); |
609 Score:= RateExplosion(Me, EX, EY, 91); |
608 if (Score = 0) then |
610 if (Score = 0) then |
651 repeat |
653 repeat |
652 x:= x + vX; |
654 x:= x + vX; |
653 y:= y + vY; |
655 y:= y + vY; |
654 rx:= trunc(x); |
656 rx:= trunc(x); |
655 ry:= trunc(y); |
657 ry:= trunc(y); |
656 if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or |
658 if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or |
657 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, rx, ry, 2)) then |
659 ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, rx, ry, 2)) then |
658 begin |
660 begin |
659 x:= x + vX * 8; |
661 x:= x + vX * 8; |
660 y:= y + vY * 8; |
662 y:= y + vY * 8; |
661 valueResult:= RateShotgun(Me, vX, vY, rx, ry); |
663 valueResult:= RateShotgun(Me, vX, vY, rx, ry); |
662 |
664 |
663 if valueResult = 0 then |
665 if valueResult = 0 then |
664 valueResult:= 1024 - Metric(Targ.X, Targ.Y, rx, ry) div 64 |
666 valueResult:= 1024 - Metric(Targ.X, Targ.Y, rx, ry) div 64 |
665 else |
667 else |
666 dec(valueResult, Level * 4000); |
668 dec(valueResult, Level * 4000); |
667 // 27/20 is reuse bonus |
669 // 27/20 is reuse bonus |
668 exit(valueResult * 27 div 20) |
670 exit(valueResult * 27 div 20) |
669 end |
671 end |
670 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4) |
672 until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4) |
766 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4 then |
768 if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4 then |
767 begin |
769 begin |
768 fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00166 * dmg, vY * 0.00166 * dmg); |
770 fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00166 * dmg, vY * 0.00166 * dmg); |
769 if fallDmg < 0 then |
771 if fallDmg < 0 then |
770 TestSniperRifle:= BadTurn |
772 TestSniperRifle:= BadTurn |
771 else |
773 else |
772 TestSniperRifle:= Max(0, trunc((dmg + fallDmg) * dmgMod) * 1024) |
774 TestSniperRifle:= Max(0, trunc((dmg + fallDmg) * dmgMod) * 1024) |
773 end |
775 end |
774 else |
776 else |
775 TestSniperRifle:= BadTurn |
777 TestSniperRifle:= BadTurn |
776 end; |
778 end; |
805 , -dx, -dy, trackFall); |
807 , -dx, -dy, trackFall); |
806 v2:= RateShove(x + 10, y + 2 |
808 v2:= RateShove(x + 10, y + 2 |
807 , 32, 30, 115 |
809 , 32, 30, 115 |
808 , dx, -dy, trackFall); |
810 , dx, -dy, trackFall); |
809 if (v1 > valueResult) or (v2 > valueResult) then |
811 if (v1 > valueResult) or (v2 > valueResult) then |
810 if (v2 > v1) |
812 if (v2 > v1) |
811 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
813 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
812 begin |
814 begin |
813 ap.Angle:= a; |
815 ap.Angle:= a; |
814 valueResult:= v2 |
816 valueResult:= v2 |
815 end |
817 end |
816 else |
818 else |
817 begin |
819 begin |
818 ap.Angle:= -a; |
820 ap.Angle:= -a; |
819 valueResult:= v1 |
821 valueResult:= v1 |
820 end; |
822 end; |
821 |
823 |
822 a:= a - 15 - random(cMaxAngle div 16) |
824 a:= a - 15 - random(cMaxAngle div 16) |
823 end; |
825 end; |
824 |
826 |
825 if valueResult <= 0 then |
827 if valueResult <= 0 then |
826 valueResult:= BadTurn; |
828 valueResult:= BadTurn; |
827 |
829 |
828 TestBaseballBat:= valueResult; |
830 TestBaseballBat:= valueResult; |
829 end; |
831 end; |
865 end; |
867 end; |
866 v2:= v2 + RateShove(x + 5, y - 90 |
868 v2:= v2 + RateShove(x + 5, y - 90 |
867 , 19, 30, 40 |
869 , 19, 30, 40 |
868 , 0.45, -0.9, trackFall); |
870 , 0.45, -0.9, trackFall); |
869 |
871 |
870 if (v2 > v1) |
872 if (v2 > v1) |
871 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
873 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
872 begin |
874 begin |
873 ap.Angle:= 1; |
875 ap.Angle:= 1; |
874 valueResult:= v2 |
876 valueResult:= v2 |
875 end |
877 end |
876 else |
878 else |
877 begin |
879 begin |
878 ap.Angle:= -1; |
880 ap.Angle:= -1; |
879 valueResult:= v1 |
881 valueResult:= v1 |
880 end; |
882 end; |
881 |
883 |
882 if valueResult <= 0 then |
884 if valueResult <= 0 then |
883 valueResult:= BadTurn; |
885 valueResult:= BadTurn; |
884 |
886 |
885 TestFirePunch:= valueResult; |
887 TestFirePunch:= valueResult; |
886 end; |
888 end; |
900 ap.Power:= 1; |
902 ap.Power:= 1; |
901 x:= hwRound(Me^.X); |
903 x:= hwRound(Me^.X); |
902 y:= hwRound(Me^.Y); |
904 y:= hwRound(Me^.Y); |
903 |
905 |
904 // check left direction |
906 // check left direction |
905 {first RateShove checks farthermost of two whip's AmmoShove attacks |
907 {first RateShove checks farthermost of two whip's AmmoShove attacks |
906 to encourage distant attacks (damaged hog is excluded from view of second |
908 to encourage distant attacks (damaged hog is excluded from view of second |
907 RateShove call)} |
909 RateShove call)} |
908 v1:= RateShove(x - 13, y |
910 v1:= RateShove(x - 13, y |
909 , 30, 30, 25 |
911 , 30, 30, 25 |
910 , -1, -0.8, trackFall or afSetSkip); |
912 , -1, -0.8, trackFall or afSetSkip); |
911 v1:= v1 + |
913 v1:= v1 + |
919 v2:= v2 + |
921 v2:= v2 + |
920 RateShove(x + 2, y |
922 RateShove(x + 2, y |
921 , 30, 30, 25 |
923 , 30, 30, 25 |
922 , 1, -0.8, trackFall); |
924 , 1, -0.8, trackFall); |
923 |
925 |
924 if (v2 > v1) |
926 if (v2 > v1) |
925 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
927 or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then |
926 begin |
928 begin |
927 ap.Angle:= 1; |
929 ap.Angle:= 1; |
928 valueResult:= v2 |
930 valueResult:= v2 |
929 end |
931 end |
930 else |
932 else |
931 begin |
933 begin |
932 ap.Angle:= -1; |
934 ap.Angle:= -1; |
933 valueResult:= v1 |
935 valueResult:= v1 |
934 end; |
936 end; |
935 |
937 |
936 if valueResult <= 0 then |
938 if valueResult <= 0 then |
937 valueResult:= BadTurn |
939 valueResult:= BadTurn |
938 else |
940 else |
939 inc(valueResult); |
941 inc(valueResult); |
940 |
942 |
976 dx:= (Targ.X - x) * t; |
978 dx:= (Targ.X - x) * t; |
977 dy:= (Targ.Y - y) * t; |
979 dy:= (Targ.Y - y) * t; |
978 |
980 |
979 ap.Angle:= DxDy2AttackAnglef(dx, -dy) |
981 ap.Angle:= DxDy2AttackAnglef(dx, -dy) |
980 end; |
982 end; |
981 |
983 |
982 if dx >= 0 then cx:= 0.45 else cx:= -0.45; |
984 if dx >= 0 then cx:= 0.45 else cx:= -0.45; |
983 |
985 |
984 for i:= 0 to 512 div step - 2 do |
986 for i:= 0 to 512 div step - 2 do |
985 begin |
987 begin |
986 valueResult:= valueResult + |
988 valueResult:= valueResult + |
987 RateShove(trunc(x), trunc(y) |
989 RateShove(trunc(x), trunc(y) |
988 , 30, 30, 25 |
990 , 30, 30, 25 |
989 , cx, -0.9, trackFall or afSetSkip); |
991 , cx, -0.9, trackFall or afSetSkip); |
990 |
992 |
991 x:= x + dx; |
993 x:= x + dx; |
992 y:= y + dy; |
994 y:= y + dy; |
993 end; |
995 end; |
994 if dx = 0 then |
996 if dx = 0 then |
995 begin |
997 begin |
1000 , 30, 30, 25 |
1002 , 30, 30, 25 |
1001 , -cx, -0.9, trackFall); |
1003 , -cx, -0.9, trackFall); |
1002 for i:= 1 to 512 div step - 2 do |
1004 for i:= 1 to 512 div step - 2 do |
1003 begin |
1005 begin |
1004 y:= y + dy; |
1006 y:= y + dy; |
1005 v:= v + |
1007 v:= v + |
1006 RateShove(tx, trunc(y) |
1008 RateShove(tx, trunc(y) |
1007 , 30, 30, 25 |
1009 , 30, 30, 25 |
1008 , -cx, -0.9, trackFall or afSetSkip); |
1010 , -cx, -0.9, trackFall or afSetSkip); |
1009 end |
1011 end |
1010 end; |
1012 end; |
1124 if bonuses.Count = 0 then |
1126 if bonuses.Count = 0 then |
1125 begin |
1127 begin |
1126 if Me^.Health <= 100 then |
1128 if Me^.Health <= 100 then |
1127 begin |
1129 begin |
1128 maxTop := Targ.Y - cHHRadius * 2; |
1130 maxTop := Targ.Y - cHHRadius * 2; |
1129 |
1131 |
1130 while not TestColl(Targ.X, maxTop, cHHRadius) and (maxTop > topY + cHHRadius * 2 + 1) do |
1132 while not TestColl(Targ.X, maxTop, cHHRadius) and (maxTop > topY + cHHRadius * 2 + 1) do |
1131 dec(maxTop, cHHRadius*2); |
1133 dec(maxTop, cHHRadius*2); |
1132 if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then |
1134 if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then |
1133 begin |
1135 begin |
1134 ap.AttackPutX := Targ.X; |
1136 ap.AttackPutX := Targ.X; |
1143 repeat |
1145 repeat |
1144 i := random(bonuses.Count); |
1146 i := random(bonuses.Count); |
1145 inc(failNum); |
1147 inc(failNum); |
1146 until not TestColl(bonuses.ar[i].X, bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius, cHHRadius) |
1148 until not TestColl(bonuses.ar[i].X, bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius, cHHRadius) |
1147 or (failNum = bonuses.Count*2); |
1149 or (failNum = bonuses.Count*2); |
1148 |
1150 |
1149 if failNum < bonuses.Count*2 then |
1151 if failNum < bonuses.Count*2 then |
1150 begin |
1152 begin |
1151 ap.AttackPutX := bonuses.ar[i].X; |
1153 ap.AttackPutX := bonuses.ar[i].X; |
1152 ap.AttackPutY := bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius; |
1154 ap.AttackPutY := bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius; |
1153 TestTeleport := 0; |
1155 TestTeleport := 0; |
1165 |
1167 |
1166 for i:= 0 to 2040 do |
1168 for i:= 0 to 2040 do |
1167 begin |
1169 begin |
1168 cakeStep(Gear); |
1170 cakeStep(Gear); |
1169 v:= RateExplosion(Me, hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg * 2, afTrackFall); |
1171 v:= RateExplosion(Me, hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg * 2, afTrackFall); |
1170 if v > ap.Power then |
1172 if v > ap.Power then |
1171 begin |
1173 begin |
1172 ap.ExplX:= hwRound(Gear^.X); |
1174 ap.ExplX:= hwRound(Gear^.X); |
1173 ap.ExplY:= hwRound(Gear^.Y); |
1175 ap.ExplY:= hwRound(Gear^.Y); |
1174 ap.Power:= v |
1176 ap.Power:= v |
1175 end |
1177 end |