64 function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline; |
66 function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline; |
65 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; |
67 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline; |
66 function TraceShoveFall(x, y, dX, dY: Real): LongInt; |
68 function TraceShoveFall(x, y, dX, dY: Real): LongInt; |
67 |
69 |
68 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; |
70 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; |
69 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; |
71 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline; |
|
72 function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; |
70 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
73 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
71 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
74 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; inline; |
|
75 function RealRateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
72 function RateHammer(Me: PGear): LongInt; |
76 function RateHammer(Me: PGear): LongInt; |
73 |
77 |
74 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
78 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean; |
75 function AIrndSign(num: LongInt): LongInt; |
79 function AIrndSign(num: LongInt): LongInt; |
76 |
80 |
389 // returning -1 for drowning so it can be considered in the Rate routine |
403 // returning -1 for drowning so it can be considered in the Rate routine |
390 exit(-1) |
404 exit(-1) |
391 end; |
405 end; |
392 end; |
406 end; |
393 |
407 |
394 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; |
408 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline; |
395 begin |
409 begin |
396 RateExplosion:= RateExplosion(Me, x, y, r, 0); |
410 RateExplosion:= RealRateExplosion(Me, x, y, r, 0); |
397 end; |
411 ResetTargets; |
398 |
412 end; |
399 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; |
413 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline; |
|
414 begin |
|
415 RateExplosion:= RealRateExplosion(Me, x, y, r, Flags); |
|
416 ResetTargets; |
|
417 end; |
|
418 |
|
419 function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; |
400 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt; |
420 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt; |
401 dX, dY: real; |
421 pX, pY, dX, dY: real; |
402 hadSkips: boolean; |
422 hadSkips: boolean; |
403 begin |
423 begin |
404 fallDmg:= 0; |
424 fallDmg:= 0; |
405 rate:= 0; |
425 rate:= 0; |
406 // add our virtual position |
426 // add our virtual position |
419 else erasure:= 0; |
439 else erasure:= 0; |
420 |
440 |
421 hadSkips:= false; |
441 hadSkips:= false; |
422 |
442 |
423 for i:= 0 to Targets.Count do |
443 for i:= 0 to Targets.Count do |
424 with Targets.ar[i] do |
444 if not Targets.ar[i].dead then |
425 if not matters then hadSkips:= true |
445 with Targets.ar[i] do |
426 else |
446 if not matters then hadSkips:= true |
427 begin |
447 else |
428 dmg:= 0; |
448 begin |
429 if abs(Point.x - x) + abs(Point.y - y) < dmgBase then |
449 dmg:= 0; |
430 dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r)); |
450 if abs(Point.x - x) + abs(Point.y - y) < dmgBase then |
431 |
451 dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r)); |
432 if dmg > 0 then |
452 |
433 begin |
453 if dmg > 0 then |
434 if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then |
|
435 begin |
454 begin |
436 dX:= 0.005 * dmg + 0.01; |
455 pX:= Point.x; |
437 dY:= dX; |
456 pY:= Point.y; |
438 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
457 if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then |
439 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
458 begin |
440 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod) |
459 dX:= 0.005 * dmg + 0.01; |
441 else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod) |
460 dY:= dX; |
|
461 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
|
462 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
|
463 fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod) |
|
464 else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod) |
|
465 end; |
|
466 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
|
467 if Score > 0 then |
|
468 inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings |
|
469 else |
|
470 dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs |
|
471 else if (dmg+fallDmg) >= abs(Score) then |
|
472 begin |
|
473 dead:= true; |
|
474 Targets.reset:= true; |
|
475 if dX < 0.035 then |
|
476 inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or (Flags and afTrackFall))); |
|
477 if Score > 0 then |
|
478 inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill |
|
479 else |
|
480 dec(rate, KillScore * friendlyfactor div 100 * 1024) |
|
481 end |
|
482 else |
|
483 if Score > 0 then |
|
484 inc(rate, (dmg + fallDmg) * 1024) |
|
485 else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024) |
442 end; |
486 end; |
443 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
487 end; |
444 if Score > 0 then |
|
445 inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings |
|
446 else |
|
447 dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs |
|
448 else if (dmg+fallDmg) >= abs(Score) then |
|
449 if Score > 0 then |
|
450 inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill |
|
451 else |
|
452 dec(rate, KillScore * friendlyfactor div 100 * 1024) |
|
453 else |
|
454 if Score > 0 then |
|
455 inc(rate, (dmg + fallDmg) * 1024) |
|
456 else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024) |
|
457 end; |
|
458 end; |
|
459 |
488 |
460 if hadSkips and (rate = 0) then |
489 if hadSkips and (rate = 0) then |
461 RateExplosion:= BadTurn |
490 RealRateExplosion:= BadTurn |
462 else |
491 else |
463 RateExplosion:= rate; |
492 RealRateExplosion:= rate; |
464 end; |
493 end; |
465 |
494 |
466 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
495 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; |
467 var i, fallDmg, dmg, rate: LongInt; |
496 var i, fallDmg, dmg, rate: LongInt; |
468 dX, dY: real; |
497 dX, dY: real; |
504 end; |
533 end; |
505 end; |
534 end; |
506 RateShove:= rate * 1024 |
535 RateShove:= rate * 1024 |
507 end; |
536 end; |
508 |
537 |
509 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
538 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; inline; |
|
539 begin |
|
540 RateShotgun:= RealRateShotgun(Me, gdX, gdY, x, y); |
|
541 ResetTargets; |
|
542 end; |
|
543 function RealRateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt; |
510 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt; |
544 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt; |
511 dX, dY: real; |
545 pX, pY, dX, dY: real; |
512 hadSkips: boolean; |
546 hadSkips: boolean; |
513 begin |
547 begin |
514 rate:= 0; |
548 rate:= 0; |
515 gdX:= gdX * 0.01; |
549 gdX:= gdX * 0.01; |
516 gdY:= gdX * 0.01; |
550 gdY:= gdX * 0.01; |
530 else erasure:= 0; |
564 else erasure:= 0; |
531 |
565 |
532 hadSkips:= false; |
566 hadSkips:= false; |
533 |
567 |
534 for i:= 0 to Targets.Count do |
568 for i:= 0 to Targets.Count do |
535 with Targets.ar[i] do |
569 if not Targets.ar[i].dead then |
536 if not matters then hadSkips:= true |
570 with Targets.ar[i] do |
537 else |
571 if not matters then hadSkips:= true |
538 begin |
572 else |
539 dmg:= 0; |
573 begin |
540 if abs(Point.x - x) + abs(Point.y - y) < baseDmg then |
574 dmg:= 0; |
541 begin |
575 if abs(Point.x - x) + abs(Point.y - y) < baseDmg then |
542 dmg:= min(baseDmg - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y))), 25); |
576 begin |
543 dmg:= trunc(dmg * dmgMod); |
577 dmg:= min(baseDmg - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y))), 25); |
544 end; |
578 dmg:= trunc(dmg * dmgMod); |
545 if dmg > 0 then |
579 end; |
546 begin |
580 if dmg > 0 then |
547 dX:= gdX * dmg; |
581 begin |
548 dY:= gdY * dmg; |
582 pX:= Point.x; |
549 if dX < 0 then dX:= dX - 0.01 |
583 pY:= Point.y; |
550 else dX:= dX + 0.01; |
584 dX:= gdX * dmg; |
551 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
585 dY:= gdY * dmg; |
552 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
586 if dX < 0 then dX:= dX - 0.01 |
553 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod) |
587 else dX:= dX + 0.01; |
554 else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod); |
588 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and |
555 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
589 (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then |
556 if Score > 0 then |
590 fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod) |
557 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
591 else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod); |
|
592 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI |
|
593 if Score > 0 then |
|
594 inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings |
|
595 else |
|
596 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
|
597 else if (dmg+fallDmg) >= abs(Score) then |
|
598 begin |
|
599 dead:= true; |
|
600 Targets.reset:= true; |
|
601 if dX < 0.035 then |
|
602 inc(Rate,RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall) div 1024); |
|
603 if Score > 0 then |
|
604 inc(rate, KillScore) |
|
605 else |
|
606 dec(rate, KillScore * friendlyfactor div 100) |
|
607 end |
558 else |
608 else |
559 dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs |
609 if Score > 0 then |
560 else if (dmg+fallDmg) >= abs(Score) then |
610 inc(rate, dmg+fallDmg) |
561 if Score > 0 then |
|
562 inc(rate, KillScore) |
|
563 else |
611 else |
564 dec(rate, KillScore * friendlyfactor div 100) |
612 dec(rate, (dmg+fallDmg) * friendlyfactor div 100) |
565 else |
613 end; |
566 if Score > 0 then |
614 end; |
567 inc(rate, dmg+fallDmg) |
|
568 else |
|
569 dec(rate, (dmg+fallDmg) * friendlyfactor div 100) |
|
570 end; |
|
571 end; |
|
572 |
615 |
573 if hadSkips and (rate = 0) then |
616 if hadSkips and (rate = 0) then |
574 RateShotgun:= BadTurn |
617 RealRateShotgun:= BadTurn |
575 else |
618 else |
576 RateShotgun:= rate * 1024; |
619 RealRateShotgun:= rate * 1024; |
577 end; |
620 end; |
578 |
621 |
579 function RateHammer(Me: PGear): LongInt; |
622 function RateHammer(Me: PGear): LongInt; |
580 var x, y, i, r, rate: LongInt; |
623 var x, y, i, r, rate: LongInt; |
581 begin |
624 begin |