hedgewars/uAIMisc.pas
changeset 8013 5cbf6e4361f4
parent 7996 66e8ac9c2274
child 8026 4a4f21070479
child 8744 6c87486fd89b
equal deleted inserted replaced
8011:ffd5eba8f7c2 8013:5cbf6e4361f4
    26 
    26 
    27       afTrackFall  = $00000001;
    27       afTrackFall  = $00000001;
    28       afErasesLand = $00000002;
    28       afErasesLand = $00000002;
    29       afSetSkip    = $00000004;
    29       afSetSkip    = $00000004;
    30 
    30 
       
    31       BadTurn = Low(LongInt) div 4;
    31 
    32 
    32 type TTarget = record
    33 type TTarget = record
    33     Point: TPoint;
    34     Point: TPoint;
    34     Score: LongInt;
    35     Score: LongInt;
    35     skip: boolean;
    36     skip, matters: boolean;
    36     end;
    37     end;
    37 TTargets = record
    38 TTargets = record
    38     Count: Longword;
    39     Count: Longword;
    39     ar: array[0..Pred(cMaxHHs)] of TTarget;
    40     ar: array[0..Pred(cMaxHHs)] of TTarget;
    40     end;
    41     end;
   115                     then
   116                     then
   116                     begin
   117                     begin
   117                     with Targets.ar[Targets.Count], Hedgehogs[i] do
   118                     with Targets.ar[Targets.Count], Hedgehogs[i] do
   118                         begin
   119                         begin
   119                         skip:= false;
   120                         skip:= false;
       
   121                         matters:= (Hedgehogs[i].Gear^.AIHints and aihDoesntMatter) = 0;
       
   122                         
   120                         Point.X:= hwRound(Gear^.X);
   123                         Point.X:= hwRound(Gear^.X);
   121                         Point.Y:= hwRound(Gear^.Y);
   124                         Point.Y:= hwRound(Gear^.Y);
   122                         if (Hedgehogs[i].Gear^.AIHints and aihDoesntMatter) <> 0 then
   125                         if Clan <> CurrentTeam^.Clan then
   123                             Score:= 0
   126                             begin
   124                             else if Clan <> CurrentTeam^.Clan then
   127                             Score:= Gear^.Health - Gear^.Damage;
   125                                 begin
   128                             inc(e)
   126                                 Score:= Gear^.Health - Gear^.Damage;
   129                             end else
   127                                 inc(e)
   130                             begin
   128                                 end else
   131                             Score:= Gear^.Damage - Gear^.Health;
   129                                 begin
   132                             inc(f)
   130                                 Score:= Gear^.Damage - Gear^.Health;
   133                             end
   131                                 inc(f)
       
   132                                 end
       
   133                         end;
   134                         end;
   134                     inc(Targets.Count)
   135                     inc(Targets.Count)
   135                     end;
   136                     end;
   136             end;
   137             end;
   137 
   138 
   407 end;
   408 end;
   408 
   409 
   409 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
   410 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
   410 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt;
   411 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt;
   411     dX, dY, dmgMod: real;
   412     dX, dY, dmgMod: real;
       
   413     hadSkips: boolean;
   412 begin
   414 begin
   413 fallDmg:= 0;
   415 fallDmg:= 0;
   414 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
   416 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
   415 rate:= 0;
   417 rate:= 0;
   416 // add our virtual position
   418 // add our virtual position
   417 with Targets.ar[Targets.Count] do
   419 with Targets.ar[Targets.Count] do
   418     begin
   420     begin
   419     Point.x:= hwRound(Me^.X);
   421     Point.x:= hwRound(Me^.X);
   420     Point.y:= hwRound(Me^.Y);
   422     Point.y:= hwRound(Me^.Y);
       
   423     skip:= false;
       
   424     matters:= true;
   421     Score:= - ThinkingHH^.Health
   425     Score:= - ThinkingHH^.Health
   422     end;
   426     end;
   423 // rate explosion
   427 // rate explosion
   424 dmgBase:= r + cHHRadius div 2;
   428 dmgBase:= r + cHHRadius div 2;
       
   429 
   425 if (Flags and afErasesLand <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r
   430 if (Flags and afErasesLand <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r
   426 else erasure:= 0;
   431 else erasure:= 0;
       
   432 
       
   433 hadSkips:= false;
       
   434 
   427 for i:= 0 to Targets.Count do
   435 for i:= 0 to Targets.Count do
   428     with Targets.ar[i] do
   436     with Targets.ar[i] do
       
   437       if not matters then hadSkips:= true
       
   438         else
   429         begin
   439         begin
   430         dmg:= 0;
   440         dmg:= 0;
   431         if abs(Point.x - x) + abs(Point.y - y) < dmgBase then
   441         if abs(Point.x - x) + abs(Point.y - y) < dmgBase then
   432             dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r));
   442             dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r));
   433 
   443 
   456                 if Score > 0 then
   466                 if Score > 0 then
   457                     inc(rate, (dmg + fallDmg) * 1024)
   467                     inc(rate, (dmg + fallDmg) * 1024)
   458                 else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024)
   468                 else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024)
   459             end;
   469             end;
   460         end;
   470         end;
   461 RateExplosion:= rate;
   471 
       
   472 if hadSkips and (rate = 0) then
       
   473     RateExplosion:= BadTurn
       
   474     else
       
   475     RateExplosion:= rate;
   462 end;
   476 end;
   463 
   477 
   464 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   478 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   465 var i, fallDmg, dmg, rate: LongInt;
   479 var i, fallDmg, dmg, rate: LongInt;
   466     dX, dY, dmgMod: real;
   480     dX, dY, dmgMod: real;
   472 rate:= 0;
   486 rate:= 0;
   473 for i:= 0 to Pred(Targets.Count) do
   487 for i:= 0 to Pred(Targets.Count) do
   474     with Targets.ar[i] do
   488     with Targets.ar[i] do
   475       if skip then 
   489       if skip then 
   476         if (Flags and afSetSkip = 0) then skip:= false else {still skip}
   490         if (Flags and afSetSkip = 0) then skip:= false else {still skip}
   477       else  
   491       else if matters then
   478         begin
   492         begin
   479         dmg:= 0;
   493         dmg:= 0;
   480         if abs(Point.x - x) + abs(Point.y - y) < r then
   494         if abs(Point.x - x) + abs(Point.y - y) < r then
   481             dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   495             dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   482 
   496 
   506 end;
   520 end;
   507 
   521 
   508 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
   522 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
   509 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt;
   523 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt;
   510     dX, dY, dmgMod: real;
   524     dX, dY, dmgMod: real;
       
   525     hadSkips: boolean;
   511 begin
   526 begin
   512 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
   527 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
   513 rate:= 0;
   528 rate:= 0;
   514 gdX:= gdX * 0.01;
   529 gdX:= gdX * 0.01;
   515 gdY:= gdX * 0.01;
   530 gdY:= gdX * 0.01;
   516 // add our virtual position
   531 // add our virtual position
   517 with Targets.ar[Targets.Count] do
   532 with Targets.ar[Targets.Count] do
   518     begin
   533     begin
   519     Point.x:= hwRound(Me^.X);
   534     Point.x:= hwRound(Me^.X);
   520     Point.y:= hwRound(Me^.Y);
   535     Point.y:= hwRound(Me^.Y);
       
   536     skip:= false;
       
   537     matters:= true;
   521     Score:= - ThinkingHH^.Health
   538     Score:= - ThinkingHH^.Health
   522     end;
   539     end;
   523 // rate shot
   540 // rate shot
   524 baseDmg:= cHHRadius + cShotgunRadius + 4;
   541 baseDmg:= cHHRadius + cShotgunRadius + 4;
       
   542 
   525 if GameFlags and gfSolidLand = 0 then erasure:= cShotgunRadius
   543 if GameFlags and gfSolidLand = 0 then erasure:= cShotgunRadius
   526 else erasure:= 0;
   544 else erasure:= 0;
       
   545 
       
   546 hadSkips:= false;
       
   547 
   527 for i:= 0 to Targets.Count do
   548 for i:= 0 to Targets.Count do
   528     with Targets.ar[i] do
   549     with Targets.ar[i] do
       
   550       if not matters then hadSkips:= true
       
   551         else
   529         begin
   552         begin
   530         dmg:= 0;
   553         dmg:= 0;
   531         if abs(Point.x - x) + abs(Point.y - y) < baseDmg then
   554         if abs(Point.x - x) + abs(Point.y - y) < baseDmg then
   532             begin
   555             begin
   533             dmg:= min(baseDmg - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y))), 25);
   556             dmg:= min(baseDmg - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y))), 25);
   557                 if Score > 0 then
   580                 if Score > 0 then
   558                     inc(rate, dmg+fallDmg)
   581                     inc(rate, dmg+fallDmg)
   559             else
   582             else
   560                 dec(rate, (dmg+fallDmg) * friendlyfactor div 100)
   583                 dec(rate, (dmg+fallDmg) * friendlyfactor div 100)
   561             end;
   584             end;
   562         end;        
   585         end;
   563 RateShotgun:= rate * 1024;
   586 
       
   587 if hadSkips and (rate = 0) then
       
   588     RateShotgun:= BadTurn
       
   589     else
       
   590     RateShotgun:= rate * 1024;
   564 end;
   591 end;
   565 
   592 
   566 function RateHammer(Me: PGear): LongInt;
   593 function RateHammer(Me: PGear): LongInt;
   567 var x, y, i, r, rate: LongInt;
   594 var x, y, i, r, rate: LongInt;
   568 begin
   595 begin
   571 y:= hwRound(Me^.Y);
   598 y:= hwRound(Me^.Y);
   572 rate:= 0;
   599 rate:= 0;
   573 
   600 
   574 for i:= 0 to Pred(Targets.Count) do
   601 for i:= 0 to Pred(Targets.Count) do
   575     with Targets.ar[i] do
   602     with Targets.ar[i] do
       
   603       if matters then
   576          // hammer hit radius is 8, shift is 10
   604          // hammer hit radius is 8, shift is 10
   577         if abs(Point.x - x) + abs(Point.y - y) < 18 then
   605         if abs(Point.x - x) + abs(Point.y - y) < 18 then
   578             begin
   606             begin
   579             r:= trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   607             r:= trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   580 
   608