hedgewars/uAIMisc.pas
changeset 15623 6c689729b745
parent 15617 e21285b7c5e6
child 15685 78e383fff605
equal deleted inserted replaced
15622:237d691e5069 15623:6c689729b745
    25 const MAXBONUS = 1024;
    25 const MAXBONUS = 1024;
    26 
    26 
    27       afTrackFall  = $00000001;
    27       afTrackFall  = $00000001;
    28       afErasesLand = $00000002;
    28       afErasesLand = $00000002;
    29       afSetSkip    = $00000004;
    29       afSetSkip    = $00000004;
       
    30       afIgnoreMe   = $00000008;
    30 
    31 
    31       BadTurn = Low(LongInt) div 4;
    32       BadTurn = Low(LongInt) div 4;
    32 
    33 
    33 type TTarget = record // starting to look more and more like a gear
    34 type TTarget = record // starting to look more and more like a gear
    34     Point: TPoint;
    35     Point: TPoint;
    84 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
    85 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
    85 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline;
    86 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline;
    86 function  RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
    87 function  RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
    87 function  RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
    88 function  RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
    88 function  RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
    89 function  RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
       
    90 function  RateSeduction(Me: PGear): LongInt;
    89 function  RateHammer(Me: PGear): LongInt;
    91 function  RateHammer(Me: PGear): LongInt;
    90 
    92 
    91 function  HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
    93 function  HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
    92 function  AIrndSign(num: LongInt): LongInt; inline;
    94 function  AIrndSign(num: LongInt): LongInt; inline;
    93 function  AIrndOffset(targ: TTarget; Level: LongWord): LongInt; inline;
    95 function  AIrndOffset(targ: TTarget; Level: LongWord): LongInt; inline;
   537     hadSkips: boolean;
   539     hadSkips: boolean;
   538 begin
   540 begin
   539 x:= round(CheckWrap(real(x)));
   541 x:= round(CheckWrap(real(x)));
   540 fallDmg:= 0;
   542 fallDmg:= 0;
   541 rate:= 0;
   543 rate:= 0;
   542 // add our virtual position
   544 
   543 with Targets.ar[Targets.Count] do
   545 if (Flags and afIgnoreMe) = 0 then
   544     begin
   546     // add our virtual position
   545     Point.x:= hwRound(Me^.X);
   547     with Targets.ar[Targets.Count] do
   546     Point.y:= hwRound(Me^.Y);
   548         begin
   547     skip:= false;
   549         Point.x:= hwRound(Me^.X);
   548     matters:= true;
   550         Point.y:= hwRound(Me^.Y);
   549     Kind:= gtHedgehog;
   551         skip:= false;
   550     Density:= 1;
   552         matters:= true;
   551     Radius:= cHHRadius;
   553         Kind:= gtHedgehog;
   552     Score:= - ThinkingHH^.Health
   554         Density:= 1;
   553     end;
   555         Radius:= cHHRadius;
       
   556         Score:= - ThinkingHH^.Health
       
   557         end;
       
   558 
   554 // rate explosion
   559 // rate explosion
   555 
       
   556 if (Flags and afErasesLand <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r
   560 if (Flags and afErasesLand <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r
   557 else erasure:= 0;
   561 else erasure:= 0;
   558 
   562 
   559 hadSkips:= false;
   563 hadSkips:= false;
   560 
   564 
   561 for i:= 0 to Targets.Count do
   565 for i:= 0 to Targets.Count do
   562     if not Targets.ar[i].dead then
   566     if not Targets.ar[i].dead then
   563         with Targets.ar[i] do
   567         with Targets.ar[i] do
   564           if not matters then hadSkips:= true
   568           if not matters then
   565             else
   569             hadSkips:= true
       
   570           else
   566             begin
   571             begin
   567             dmg:= 0;
   572             dmg:= 0;
   568             dmgBase:= r + Radius div 2;
   573             dmgBase:= r + Radius div 2;
   569             if abs(Point.x - x) + abs(Point.y - y) < dmgBase then
   574             if abs(Point.x - x) + abs(Point.y - y) < dmgBase then
   570                 dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r));
   575                 dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r));
   830 else
   835 else
   831     RateShotgun:= rate * 1024;
   836     RateShotgun:= rate * 1024;
   832 ResetTargets;
   837 ResetTargets;
   833 end;
   838 end;
   834 
   839 
       
   840 function RateSeduction(Me: PGear): LongInt;
       
   841 var pX, pY, i, r, rate, subrate, fallDmg: LongInt;
       
   842     diffX, diffY: LongInt;
       
   843     meX, meY, dX, dY: hwFloat;
       
   844     pXr, pYr: real;
       
   845     hadSkips: boolean;
       
   846 begin
       
   847 meX:= Me^.X;
       
   848 meY:= Me^.Y;
       
   849 rate:= 0;
       
   850 for i:= 0 to Targets.Count do
       
   851     if not Targets.ar[i].dead then
       
   852         with Targets.ar[i] do
       
   853             begin
       
   854             pX:= Point.X;
       
   855             pY:= Point.Y;
       
   856             diffX:= pX - hwRound(meX);
       
   857             diffY:= pY - hwRound(meY);
       
   858             if (Me^.Hedgehog^.BotLevel < 4) and (abs(diffX) <= cHHRadius*2) and (diffY >= 0) and (diffY <= cHHRadius*2) then
       
   859                 // Don't use seduction if too close to other hog. We could be
       
   860                 // standing on it, so using seduction would remove the ground on
       
   861                 // which we stand on, which is dangerous
       
   862                 exit(BadTurn);
       
   863 
       
   864             if (not matters) then
       
   865                 hadSkips:= true
       
   866             else if matters and (Kind = gtHedgehog) and (abs(pX - hwRound(meX)) + abs(pY - hwRound(meY)) < cSeductionDist) then
       
   867                 begin
       
   868                 r:= trunc(sqrt(sqr(abs(pX - hwRound(meX)))+sqr(abs(pY - hwRound(meY)))));
       
   869                 if r < cSeductionDist then
       
   870                     begin
       
   871 
       
   872                     if (WorldEdge <> weWrap) or (not (hwAbs(meX - int2hwFloat(pX)) > int2hwFloat(cSeductionDist))) then
       
   873                         dX:= _50 * cGravity * (meX - int2hwFloat(pX)) / _25
       
   874                     else if (not (hwAbs(meX + int2hwFloat((RightX-LeftX) - pX)) > int2hwFloat(cSeductionDist))) then
       
   875                         dX:= _50 * cGravity * (meX + (int2hwFloat((RightX-LeftX) - pX))) / _25
       
   876                     else
       
   877                         dX:= _50 * cGravity * (meX - (int2hwFloat((RightX-LeftX) - pX))) / _25;
       
   878                     dY:= -_450 * cMaxWindSpeed * 2;
       
   879 
       
   880 
       
   881                     pXr:= pX;
       
   882                     pYr:= pY;
       
   883                     fallDmg:= trunc(TraceShoveFall(pXr, pYr, hwFloat2Float(dX), hwFloat2Float(dY), Targets.ar[i]) * dmgMod);
       
   884 
       
   885                     // rate damage
       
   886                     if fallDmg < 0 then // drowning
       
   887                         begin
       
   888                         if Score > 0 then
       
   889                             inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings
       
   890                         else
       
   891                             dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs
       
   892                         end
       
   893                     else if (fallDmg) >= abs(Score) then // deadly fall damage
       
   894                         begin
       
   895                         dead:= true;
       
   896                         Targets.reset:= true;
       
   897                         if (hwFloat2Float(dX) < 0.035) then
       
   898                             begin
       
   899                             subrate:= RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall); // hog explodes
       
   900                             if abs(subrate) > 2000 then
       
   901                                 inc(rate, subrate)
       
   902                             end;
       
   903                         if Score > 0 then
       
   904                              inc(rate, KillScore * 1024 + (fallDmg)) // tiny bonus for dealing more damage than needed to kill
       
   905                         else
       
   906                              dec(rate, KillScore * friendlyfactor div 100 * 1024)
       
   907                         end
       
   908                     else if (fallDmg <> 0) then // non-deadly fall damage
       
   909                         if Score > 0 then
       
   910                              inc(rate, fallDmg * 1024)
       
   911                         else
       
   912                              dec(rate, fallDmg * friendlyfactor div 100 * 1024)
       
   913                     else // no damage, just shoved
       
   914                         if (Score < 0) then
       
   915                             dec(rate, 100); // small penalty for shoving friendly hogs as it might be dangerous
       
   916                     end;
       
   917                 end;
       
   918             end;
       
   919 
       
   920 if hadSkips and (rate <= 0) then
       
   921     RateSeduction:= BadTurn
       
   922 else
       
   923     RateSeduction:= rate * 1024;
       
   924 end;
       
   925 
   835 function RateHammer(Me: PGear): LongInt;
   926 function RateHammer(Me: PGear): LongInt;
   836 var x, y, i, r, rate: LongInt;
   927 var x, y, i, r, rate: LongInt;
   837     hadSkips: boolean;
   928     hadSkips: boolean;
   838 begin
   929 begin
   839 // hammer hit shift against attecker hog is 10
   930 // hammer hit shift against attecker hog is 10