hedgewars/uAIMisc.pas
changeset 8969 ff121fd3d08f
parent 8966 5ab59d79bc9a
child 8970 35103b1a014c
equal deleted inserted replaced
8968:10a899fd9ac5 8969:ff121fd3d08f
    31       BadTurn = Low(LongInt) div 4;
    31       BadTurn = Low(LongInt) div 4;
    32 
    32 
    33 type TTarget = record // starting to look more and more like a gear
    33 type TTarget = record // starting to look more and more like a gear
    34     Point: TPoint;
    34     Point: TPoint;
    35     Score, Radius: LongInt;
    35     Score, Radius: LongInt;
    36     Flags: LongWord;
    36     State: LongWord;
    37     Density: real;
    37     Density: real;
    38     skip, matters, dead: boolean;
    38     skip, matters, dead: boolean;
    39     Kind: TGearType;
    39     Kind: TGearType;
    40     end;
    40     end;
    41 TTargets = record
    41 TTargets = record
   144             skip:= false;
   144             skip:= false;
   145             dead:= false;
   145             dead:= false;
   146             Kind:= Gear^.Kind;
   146             Kind:= Gear^.Kind;
   147             Radius:= Gear^.Radius;
   147             Radius:= Gear^.Radius;
   148             Density:= hwFloat2Float(Gear^.Density)/3;
   148             Density:= hwFloat2Float(Gear^.Density)/3;
   149             Flags:= Gear^.State;
   149             State:= Gear^.State;
   150             matters:= (Gear^.AIHints and aihDoesntMatter) = 0;
   150             matters:= (Gear^.AIHints and aihDoesntMatter) = 0;
   151 
   151 
   152             Point.X:= hwRound(Gear^.X);
   152             Point.X:= hwRound(Gear^.X);
   153             Point.Y:= hwRound(Gear^.Y);
   153             Point.Y:= hwRound(Gear^.Y);
   154             if (Gear^.Kind = gtHedgehog) then
   154             if (Gear^.Kind = gtHedgehog) then
   392                 else 
   392                 else 
   393                     begin
   393                     begin
   394                     dxdy:= abs(dX)+abs(dY);
   394                     dxdy:= abs(dX)+abs(dY);
   395                     if ((Kind = gtMine) and (dxdy > 0.35)) or 
   395                     if ((Kind = gtMine) and (dxdy > 0.35)) or 
   396                        ((Kind = gtExplosives) and 
   396                        ((Kind = gtExplosives) and 
   397                             (((Flags and gstTmpFlag <> 0) and (dxdy > 0.35)) or
   397                             (((State and gstTmpFlag <> 0) and (dxdy > 0.35)) or
   398                              ((Flags and gstTmpFlag <> 0) and 
   398                              ((State and gstTmpFlag <> 0) and 
   399                                 ((abs(odX) > 0.15) or ((abs(odY) > 0.15) and 
   399                                 ((abs(odX) > 0.15) or ((abs(odY) > 0.15) and 
   400                                 (abs(odX) > 0.02))) and (dxdy > 0.35)))) then
   400                                 (abs(odX) > 0.02))) and (dxdy > 0.35)))) then
   401                         begin
   401                         begin
   402                         dmg := trunc(dxdy * 25);
   402                         dmg := trunc(dxdy * 25);
   403                         exit(dmg)
   403                         exit(dmg)
   444                 else 
   444                 else 
   445                     begin
   445                     begin
   446                     dxdy:= abs(dX)+abs(dY);
   446                     dxdy:= abs(dX)+abs(dY);
   447                     if ((Kind = gtMine) and (dxdy > 0.35)) or 
   447                     if ((Kind = gtMine) and (dxdy > 0.35)) or 
   448                        ((Kind = gtExplosives) and 
   448                        ((Kind = gtExplosives) and 
   449                             (((Flags and gstTmpFlag <> 0) and (dxdy > 0.35)) or
   449                             (((State and gstTmpFlag <> 0) and (dxdy > 0.35)) or
   450                              ((Flags and gstTmpFlag <> 0) and 
   450                              ((State and gstTmpFlag <> 0) and 
   451                                 ((abs(odX) > 0.15) or ((abs(odY) > 0.15) and 
   451                                 ((abs(odX) > 0.15) or ((abs(odY) > 0.15) and 
   452                                 (abs(odX) > 0.02))) and (dxdy > 0.35)))) then
   452                                 (abs(odX) > 0.02))) and (dxdy > 0.35)))) then
   453                         begin
   453                         begin
   454                         dmg := trunc(dxdy * 25);
   454                         dmg := trunc(dxdy * 25);
   455                         exit(dmg)
   455                         exit(dmg)
   589 dX:= gdX * 0.01 * kick;
   589 dX:= gdX * 0.01 * kick;
   590 dY:= gdY * 0.01 * kick;
   590 dY:= gdY * 0.01 * kick;
   591 rate:= 0;
   591 rate:= 0;
   592 for i:= 0 to Pred(Targets.Count) do
   592 for i:= 0 to Pred(Targets.Count) do
   593     with Targets.ar[i] do
   593     with Targets.ar[i] do
   594       if skip then
   594         if skip then
   595         if (Flags and afSetSkip = 0) then skip:= false else {still skip}
   595             begin
   596       else if matters then
   596             if Flags and afSetSkip = 0 then skip:= false
   597         begin
   597             end
   598         dmg:= 0;
   598         else if matters then
   599         if abs(Point.x - x) + abs(Point.y - y) < r then
   599             begin
   600             dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   600             dmg:= 0;
   601 
   601             if abs(Point.x - x) + abs(Point.y - y) < r then
   602         if dmg > 0 then
   602                 dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   603             begin
   603 
   604             pX:= Point.x;
   604             if dmg > 0 then
   605             pY:= Point.y-2;
       
   606             fallDmg:= 0;
       
   607             if (Flags and afSetSkip <> 0) then skip:= true;
       
   608             if (Flags and afTrackFall <> 0) and (Score > 0) then
       
   609                 fallDmg:= trunc(TraceShoveFall(pX, pY, dX, dY, Targets.ar[i]) * dmgMod);
       
   610             if Kind = gtHedgehog then
       
   611                 begin
   605                 begin
   612                 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   606                 pX:= Point.x;
   613                     begin
   607                 pY:= Point.y-2;
   614                     if Score > 0 then
   608                 fallDmg:= 0;
   615                         inc(rate, KillScore + Score div 10)   // Add a bit of a bonus for bigger hog drownings
   609                 if (Flags and afSetSkip <> 0) then skip:= true;
       
   610                 if (Flags and afTrackFall <> 0) and (Score > 0) then
       
   611                     fallDmg:= trunc(TraceShoveFall(pX, pY, dX, dY, Targets.ar[i]) * dmgMod);
       
   612                 if Kind = gtHedgehog then
       
   613                     begin
       
   614                     if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
       
   615                         begin
       
   616                         if Score > 0 then
       
   617                             inc(rate, KillScore + Score div 10)   // Add a bit of a bonus for bigger hog drownings
       
   618                         else
       
   619                             dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
       
   620                         end
       
   621                     else if power+fallDmg >= abs(Score) then
       
   622                         begin
       
   623                         dead:= true;
       
   624                         Targets.reset:= true;
       
   625                         if dX < 0.035 then
       
   626                             begin
       
   627                             subrate:= RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall);
       
   628                             if abs(subrate) > 2000 then inc(Rate,subrate div 1024)
       
   629                             end;
       
   630                         if Score > 0 then
       
   631                             inc(rate, KillScore)
       
   632                         else
       
   633                             dec(rate, KillScore * friendlyfactor div 100)
       
   634                         end
   616                     else
   635                     else
   617                         dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
   636                         begin
       
   637                         if Score > 0 then
       
   638                             inc(rate, power+fallDmg)
       
   639                         else
       
   640                             dec(rate, (power+fallDmg) * friendlyfactor div 100)
       
   641                         end
   618                     end
   642                     end
   619                 else if power+fallDmg >= abs(Score) then
   643                 else if (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then
   620                     begin
   644                     begin
   621                     dead:= true;
   645                     dead:= true;
   622                     Targets.reset:= true;
   646                     Targets.reset:= true;
   623                     if dX < 0.035 then
   647                     if Kind = gtExplosives then
   624                         begin
   648                          subrate:= RealRateExplosion(Me, round(pX), round(pY), 151, afErasesLand or (Flags and afTrackFall))
   625                         subrate:= RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall);
   649                     else subrate:= RealRateExplosion(Me, round(pX), round(pY), 101, afErasesLand or (Flags and afTrackFall));
   626                         if abs(subrate) > 2000 then inc(Rate,subrate div 1024)
   650                     if abs(subrate) > 2000 then inc(Rate,subrate div 1024);
   627                         end;
       
   628                     if Score > 0 then
       
   629                         inc(rate, KillScore)
       
   630                     else
       
   631                         dec(rate, KillScore * friendlyfactor div 100)
       
   632                     end
       
   633                 else
       
   634                     begin
       
   635                     if Score > 0 then
       
   636                         inc(rate, power+fallDmg)
       
   637                     else
       
   638                         dec(rate, (power+fallDmg) * friendlyfactor div 100)
       
   639                     end
   651                     end
   640                 end
   652                 end
   641             else if (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then
   653             end;
   642                 begin
       
   643                 dead:= true;
       
   644                 Targets.reset:= true;
       
   645                 if Kind = gtExplosives then
       
   646                      subrate:= RealRateExplosion(Me, round(pX), round(pY), 151, afErasesLand or (Flags and afTrackFall))
       
   647                 else subrate:= RealRateExplosion(Me, round(pX), round(pY), 101, afErasesLand or (Flags and afTrackFall));
       
   648                 if abs(subrate) > 2000 then inc(Rate,subrate div 1024);
       
   649                 end
       
   650             end
       
   651         end;
       
   652 RateShove:= rate * 1024
   654 RateShove:= rate * 1024
   653 end;
   655 end;
   654 
   656 
   655 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
   657 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
   656 var i, dmg, fallDmg, baseDmg, rate, subrate, erasure: LongInt;
   658 var i, dmg, fallDmg, baseDmg, rate, subrate, erasure: LongInt;