hedgewars/uAIMisc.pas
changeset 7439 0a494f951dcf
parent 7437 a46ce1812419
child 7471 ce5d3e39361e
equal deleted inserted replaced
7358:57a508884052 7439:0a494f951dcf
    52 
    52 
    53 procedure initModule;
    53 procedure initModule;
    54 procedure freeModule;
    54 procedure freeModule;
    55 
    55 
    56 procedure FillTargets;
    56 procedure FillTargets;
       
    57 procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); inline;
    57 procedure FillBonuses(isAfterAttack: boolean);
    58 procedure FillBonuses(isAfterAttack: boolean);
    58 procedure AwareOfExplosion(x, y, r: LongInt); inline;
    59 procedure AwareOfExplosion(x, y, r: LongInt); inline;
    59 
    60 
    60 function  RatePlace(Gear: PGear): LongInt;
    61 function  RatePlace(Gear: PGear): LongInt;
    61 function  TestColl(x, y, r: LongInt): boolean; inline;
    62 function  TestColl(x, y, r: LongInt): boolean; inline;
    76     Targets: TTargets;
    77     Targets: TTargets;
    77 
    78 
    78     bonuses: record
    79     bonuses: record
    79         Count: Longword;
    80         Count: Longword;
    80         ar: array[0..Pred(MAXBONUS)] of TBonus;
    81         ar: array[0..Pred(MAXBONUS)] of TBonus;
       
    82         end;
       
    83 
       
    84     walkbonuses: record
       
    85         Count: Longword;
       
    86         ar: array[0..Pred(MAXBONUS div 8)] of TBonus;  // don't use too many
    81         end;
    87         end;
    82 
    88 
    83 implementation
    89 implementation
    84 uses uCollisions, uVariables, uUtils, uDebug, uLandTexture;
    90 uses uCollisions, uVariables, uUtils, uDebug, uLandTexture;
    85 
    91 
   138     bonuses.ar[bonuses.Count].Score:= s;
   144     bonuses.ar[bonuses.Count].Score:= s;
   139     inc(bonuses.Count);
   145     inc(bonuses.Count);
   140     end;
   146     end;
   141 end;
   147 end;
   142 
   148 
       
   149 procedure AddWalkBonus(x, y: LongInt; r: Longword; s: LongInt); inline;
       
   150 begin
       
   151 if(walkbonuses.Count < MAXBONUS div 8) then
       
   152     begin
       
   153     walkbonuses.ar[walkbonuses.Count].x:= x;
       
   154     walkbonuses.ar[walkbonuses.Count].y:= y;
       
   155     walkbonuses.ar[walkbonuses.Count].Radius:= r;
       
   156     walkbonuses.ar[walkbonuses.Count].Score:= s;
       
   157     inc(walkbonuses.Count);
       
   158     end;
       
   159 end;
       
   160 
   143 procedure FillBonuses(isAfterAttack: boolean);
   161 procedure FillBonuses(isAfterAttack: boolean);
   144 var Gear: PGear;
   162 var Gear: PGear;
   145     MyClan: PClan;
   163     MyClan: PClan;
       
   164     i: Longint;
   146 begin
   165 begin
   147 bonuses.Count:= 0;
   166 bonuses.Count:= 0;
   148 MyClan:= ThinkingHH^.Hedgehog^.Team^.Clan;
   167 MyClan:= ThinkingHH^.Hedgehog^.Team^.Clan;
   149 Gear:= GearsList;
   168 Gear:= GearsList;
   150 while Gear <> nil do
   169 while Gear <> nil do
   151     begin
   170     begin
   152         case Gear^.Kind of
   171         case Gear^.Kind of
   153             gtCase:
   172             gtCase:
   154             AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 33, 25);
   173                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y) + 3, 37, 25);
   155             gtFlame:
   174             gtFlame:
   156                 if (Gear^.State and gsttmpFlag) <> 0 then
   175                 if (Gear^.State and gsttmpFlag) <> 0 then
   157                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 20, -50);
   176                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 20, -50);
   158 // avoid mines unless they are very likely to be duds, or are duds. also avoid if they are about to blow 
   177 // avoid mines unless they are very likely to be duds, or are duds. also avoid if they are about to blow 
   159             gtMine:
   178             gtMine:
   176             gtHedgehog:
   195             gtHedgehog:
   177                 begin
   196                 begin
   178                 if Gear^.Damage >= Gear^.Health then
   197                 if Gear^.Damage >= Gear^.Health then
   179                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 60, -25)
   198                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 60, -25)
   180                 else
   199                 else
   181                     if isAfterAttack and (ThinkingHH^.Hedgehog <> Gear^.Hedgehog) then
   200                     if isAfterAttack
       
   201                       and (ThinkingHH^.Hedgehog <> Gear^.Hedgehog)
       
   202                       and ((hwAbs(Gear^.dX) + hwAbs(Gear^.dY)) < _0_1) then
   182                         if (ClansCount > 2) or (MyClan = Gear^.Hedgehog^.Team^.Clan) then
   203                         if (ClansCount > 2) or (MyClan = Gear^.Hedgehog^.Team^.Clan) then
   183                             AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 150, -3) // hedgehog-friend
   204                             AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 150, -3) // hedgehog-friend
   184                         else
   205                         else
   185                             AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, 3)
   206                             AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, 3)
   186                 end;
   207                 end;
   188     Gear:= Gear^.NextGear
   209     Gear:= Gear^.NextGear
   189     end;
   210     end;
   190 if isAfterAttack and (KnownExplosion.Radius > 0) then
   211 if isAfterAttack and (KnownExplosion.Radius > 0) then
   191     with KnownExplosion do
   212     with KnownExplosion do
   192         AddBonus(X, Y, Radius + 10, -Radius);
   213         AddBonus(X, Y, Radius + 10, -Radius);
       
   214 if isAfterAttack then
       
   215     begin
       
   216     for i:= 0 to Pred(walkbonuses.Count) do
       
   217         with walkbonuses.ar[i] do
       
   218             AddBonus(X, Y, Radius, Score);
       
   219     walkbonuses.Count:= 0
       
   220     end;
   193 end;
   221 end;
   194 
   222 
   195 procedure AwareOfExplosion(x, y, r: LongInt); inline;
   223 procedure AwareOfExplosion(x, y, r: LongInt); inline;
   196 begin
   224 begin
   197     KnownExplosion.X:= x;
   225     KnownExplosion.X:= x;
   341     while true do
   369     while true do
   342     begin
   370     begin
   343         x:= x + dX;
   371         x:= x + dX;
   344         y:= y + dY;
   372         y:= y + dY;
   345         dY:= dY + cGravityf;
   373         dY:= dY + cGravityf;
   346 (*
   374 
   347         if ((trunc(y) and LAND_HEIGHT_MASK) = 0) and ((trunc(x) and LAND_WIDTH_MASK) = 0) then 
   375 {        if ((trunc(y) and LAND_HEIGHT_MASK) = 0) and ((trunc(x) and LAND_WIDTH_MASK) = 0) then 
   348             begin
   376             begin
   349             LandPixels[trunc(y), trunc(x)]:= v;
   377             LandPixels[trunc(y), trunc(x)]:= v;
   350             UpdateLandTexture(trunc(X), 1, trunc(Y), 1, true);
   378             UpdateLandTexture(trunc(X), 1, trunc(Y), 1, true);
   351             end;
   379             end;}
   352 *)
   380 
   353 
   381 
   354         // consider adding dX/dY calc here for fall damage
   382         // consider adding dX/dY calc here for fall damage
   355         if TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then
   383         if TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then
   356         begin
   384         begin
   357             if 0.4 < dY then
   385             if 0.4 < dY then
   402             begin
   430             begin
   403             if Flags and afTrackFall <> 0 then
   431             if Flags and afTrackFall <> 0 then
   404                 begin
   432                 begin
   405                 dX:= 0.005 * dmg + 0.01;
   433                 dX:= 0.005 * dmg + 0.01;
   406                 dY:= dX;
   434                 dY:= dX;
   407                 fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod);
   435                 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and 
       
   436                    (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
       
   437                      fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod)
       
   438                 else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod)
   408                 end;
   439                 end;
   409             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   440             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   410                 if Score > 0 then
   441                 if Score > 0 then
   411                     inc(rate, KillScore + Score div 10)   // Add a bit of a bonus for bigger hog drownings
   442                     inc(rate, (KillScore + Score div 10) * 1024)   // Add a bit of a bonus for bigger hog drownings
   412                 else
   443                 else
   413                     dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
   444                     dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs
   414             else if (dmg+fallDmg) >= abs(Score) then
   445             else if (dmg+fallDmg) >= abs(Score) then
   415                 if Score > 0 then
   446                 if Score > 0 then
   416                     inc(rate, KillScore)
   447                     inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill
   417                 else
   448                 else
   418                     dec(rate, KillScore * friendlyfactor div 100)
   449                     dec(rate, KillScore * friendlyfactor div 100 * 1024)
   419             else
   450             else
   420                 if Score > 0 then
   451                 if Score > 0 then
   421                     inc(rate, dmg+fallDmg)
   452                     inc(rate, (dmg + fallDmg) * 1024)
   422                 else dec(rate, (dmg+fallDmg) * friendlyfactor div 100)
   453                 else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024)
   423             end;
   454             end;
   424         end;
   455         end;
   425 RateExplosion:= rate * 1024;
   456 RateExplosion:= rate;
   426 end;
   457 end;
   427 
   458 
   428 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   459 function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   429 var i, fallDmg, dmg, rate: LongInt;
   460 var i, fallDmg, dmg, rate: LongInt;
   430     dX, dY, dmgMod: real;
   461     dX, dY, dmgMod: real;
   501             begin
   532             begin
   502             dX:= gdX * dmg;
   533             dX:= gdX * dmg;
   503             dY:= gdY * dmg;
   534             dY:= gdY * dmg;
   504             if dX < 0 then dX:= dX - 0.01
   535             if dX < 0 then dX:= dX - 0.01
   505             else dX:= dX + 0.01;
   536             else dX:= dX + 0.01;
   506             fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod);
   537             if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and 
       
   538                (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
       
   539                  fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod)
       
   540             else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod);
   507             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   541             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   508                 if Score > 0 then
   542                 if Score > 0 then
   509                     inc(rate, KillScore + Score div 10)   // Add a bit of a bonus for bigger hog drownings
   543                     inc(rate, KillScore + Score div 10)   // Add a bit of a bonus for bigger hog drownings
   510                 else
   544                 else
   511                     dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
   545                     dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
   588             exit(false)
   622             exit(false)
   589         end
   623         end
   590 end;
   624 end;
   591 
   625 
   592 repeat
   626 repeat
       
   627         {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then 
       
   628             begin
       
   629             LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= Gear^.Hedgehog^.Team^.Clan^.Color;
       
   630             UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
       
   631             end;}
       
   632             
   593     if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then
   633     if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then
   594         exit(false);
   634         exit(false);
   595     if (Gear^.State and gstMoving) <> 0 then
   635     if (Gear^.State and gstMoving) <> 0 then
   596     begin
   636     begin
   597         if (GoInfo.Ticks = 350) then
   637         if (GoInfo.Ticks = 350) then
   609         if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then
   649         if (Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, -1) <> 0) then
   610             Gear^.dY:= _0;
   650             Gear^.dY:= _0;
   611         Gear^.Y:= Gear^.Y + Gear^.dY;
   651         Gear^.Y:= Gear^.Y + Gear^.dY;
   612         if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then
   652         if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then
   613             begin
   653             begin
   614             Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping);
   654             Gear^.State:= Gear^.State and (not (gstMoving or gstHHJumping));
   615             Gear^.dY:= _0;
   655             Gear^.dY:= _0;
   616             case JumpType of
   656             case JumpType of
   617                 jmpHJump:
   657                 jmpHJump:
   618                     if bY - hwRound(Gear^.Y) > 5 then
   658                     if bY - hwRound(Gear^.Y) > 5 then
   619                         begin
   659                         begin
   634     end;
   674     end;
   635 until false
   675 until false
   636 end;
   676 end;
   637 
   677 
   638 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
   678 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
   639 var pX, pY: LongInt;
   679 var pX, pY, tY: LongInt;
   640 begin
   680 begin
   641 HHGo:= false;
   681 HHGo:= false;
       
   682 Gear^.CollisionMask:= $FF7F;
   642 AltGear^:= Gear^;
   683 AltGear^:= Gear^;
   643 
   684 
   644 GoInfo.Ticks:= 0;
   685 GoInfo.Ticks:= 0;
   645 GoInfo.FallPix:= 0;
   686 GoInfo.FallPix:= 0;
   646 GoInfo.JumpType:= jmpNone;
   687 GoInfo.JumpType:= jmpNone;
   647 
   688 tY:= hwRound(Gear^.Y);
   648 repeat
   689 repeat
       
   690         {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then 
       
   691             begin
       
   692             LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= random($FFFFFFFF);//Gear^.Hedgehog^.Team^.Clan^.Color;
       
   693             UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
       
   694             end;}
       
   695 
   649     pX:= hwRound(Gear^.X);
   696     pX:= hwRound(Gear^.X);
   650     pY:= hwRound(Gear^.Y);
   697     pY:= hwRound(Gear^.Y);
   651     if pY + cHHRadius >= cWaterLine then
   698     if pY + cHHRadius >= cWaterLine then
   652         exit(false);
   699         begin
       
   700         if AltGear^.Hedgehog^.BotLevel < 4 then
       
   701             AddWalkBonus(pX, tY, 250, -40);
       
   702         exit(false)
       
   703         end;
   653         
   704         
   654     // hog is falling    
   705     // hog is falling    
   655     if (Gear^.State and gstMoving) <> 0 then
   706     if (Gear^.State and gstMoving) <> 0 then
   656         begin
   707         begin
   657         inc(GoInfo.Ticks);
   708         inc(GoInfo.Ticks);
   658         Gear^.dY:= Gear^.dY + cGravity;
   709         Gear^.dY:= Gear^.dY + cGravity;
   659         if Gear^.dY > _0_4 then
   710         if Gear^.dY > _0_4 then
   660             begin
   711             begin
   661             Goinfo.FallPix:= 0;
   712             GoInfo.FallPix:= 0;
   662             // try ljump instead of fall with damage
   713             // try ljump instead of fall with damage
   663             HHJump(AltGear, jmpLJump, GoInfo); 
   714             HHJump(AltGear, jmpLJump, GoInfo); 
       
   715             if AltGear^.Hedgehog^.BotLevel < 4 then
       
   716                 AddWalkBonus(pX, tY, 175, -20);
   664             exit(false)
   717             exit(false)
   665             end;
   718             end;
   666         Gear^.Y:= Gear^.Y + Gear^.dY;
   719         Gear^.Y:= Gear^.Y + Gear^.dY;
   667         if hwRound(Gear^.Y) > pY then
   720         if hwRound(Gear^.Y) > pY then
   668             inc(GoInfo.FallPix);
   721             inc(GoInfo.FallPix);
   669         if TestCollisionYwithGear(Gear, 1) <> 0 then
   722         if TestCollisionYwithGear(Gear, 1) <> 0 then
   670             begin
   723             begin
   671             inc(GoInfo.Ticks, 410);
   724             inc(GoInfo.Ticks, 410);
   672             Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping);
   725             Gear^.State:= Gear^.State and (not (gstMoving or gstHHJumping));
   673             Gear^.dY:= _0;
   726             Gear^.dY:= _0;
   674             // try ljump instead of fall
   727             // try ljump instead of fall
   675             HHJump(AltGear, jmpLJump, GoInfo);
   728             HHJump(AltGear, jmpLJump, GoInfo);
   676             exit(true)
   729             exit(true)
   677             end;
   730             end;