hedgewars/uAIMisc.pas
changeset 6767 ccbf07b38a43
parent 6766 31ba56a8ec43
child 6768 a142cf8dbbd3
equal deleted inserted replaced
6766:31ba56a8ec43 6767:ccbf07b38a43
    47 procedure initModule;
    47 procedure initModule;
    48 procedure freeModule;
    48 procedure freeModule;
    49 
    49 
    50 procedure FillTargets;
    50 procedure FillTargets;
    51 procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType = []);
    51 procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType = []);
    52 procedure AwareOfExplosion(x, y, r: LongInt);
    52 procedure AwareOfExplosion(x, y, r: LongInt); inline;
    53 function RatePlace(Gear: PGear): LongInt;
    53 function RatePlace(Gear: PGear): LongInt;
    54 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean;
    54 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
    55 function TestColl(x, y, r: LongInt): boolean;
    55 function TestColl(x, y, r: LongInt): boolean; inline;
    56 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt;
    56 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt;
    57 function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt;
    57 function RateShove(Me: PGear; x, y, r, power: LongInt): LongInt;
    58 function RateShotgun(Me: PGear; x, y: LongInt): LongInt;
    58 function RateShotgun(Me: PGear; x, y: LongInt): LongInt;
    59 function RateHammer(Me: PGear): LongInt;
    59 function RateHammer(Me: PGear): LongInt;
    60 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
    60 function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
    61 function AIrndSign(num: LongInt): LongInt;
    61 function AIrndSign(num: LongInt): LongInt;
   113 
   113 
   114 if e > f then friendlyfactor:= 300 + (e - f) * 30
   114 if e > f then friendlyfactor:= 300 + (e - f) * 30
   115 else friendlyfactor:= max(30, 300 - f * 80 div max(1,e))
   115 else friendlyfactor:= max(30, 300 - f * 80 div max(1,e))
   116 end;
   116 end;
   117 
   117 
   118 procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt);
   118 procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); inline;
   119 begin
   119 begin
   120 bonuses.ar[bonuses.Count].x:= x;
   120 bonuses.ar[bonuses.Count].x:= x;
   121 bonuses.ar[bonuses.Count].y:= y;
   121 bonuses.ar[bonuses.Count].y:= y;
   122 bonuses.ar[bonuses.Count].Radius:= r;
   122 bonuses.ar[bonuses.Count].Radius:= r;
   123 bonuses.ar[bonuses.Count].Score:= s;
   123 bonuses.ar[bonuses.Count].Score:= s;
   232     exit(true);
   232     exit(true);
   233     
   233     
   234 TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0)
   234 TestColl:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] <> 0)
   235 end;
   235 end;
   236 
   236 
   237 function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt;
   237 function TestCollWithLand(x, y, r: LongInt): boolean; inline;
   238 var i, dmg, dmgBase, rate: LongInt;
   238 var b: boolean;
       
   239 begin
       
   240 b:= (((x-r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > 255);
       
   241 if b then
       
   242     exit(true);
       
   243     
       
   244 b:=(((x-r) and LAND_WIDTH_MASK) = 0)and(((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > 255);
       
   245 if b then
       
   246     exit(true);
       
   247     
       
   248 b:=(((x+r) and LAND_WIDTH_MASK) = 0)and(((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > 255);
       
   249 if b then
       
   250     exit(true);
       
   251     
       
   252 TestCollWithLand:=(((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255)
       
   253 end;
       
   254 
       
   255 function TraceDrown(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): boolean;
       
   256 var skipLandCheck: boolean;
       
   257     rCorner: real;
       
   258 begin
       
   259     if x - eX < 0 then dX*=-1;
       
   260     if y - eY < 0 then dY*=-1;
       
   261     // ok. attempt approximate search for an unbroken trajectory into water.  if it continues far enough, assume out of map
       
   262     rCorner:= r * 0.75;
       
   263     while true do
       
   264         begin
       
   265         x:= x + dX;
       
   266         y:= y + dY + cGravityf;
       
   267         skipLandCheck:= (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner));
       
   268         if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then exit(false);
       
   269         if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(true);
       
   270         end;
       
   271 end;
       
   272 
       
   273 // Flags are not defined yet but 1 for checking drowning and 2 for assuming land erasure.
       
   274 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord = 0): LongInt;
       
   275 var i, dmg, dmgBase, rate, erasure: LongInt;
       
   276     dX, dY: real;
   239 begin
   277 begin
   240 rate:= 0;
   278 rate:= 0;
   241 // add our virtual position
   279 // add our virtual position
   242 with Targets.ar[Targets.Count] do
   280 with Targets.ar[Targets.Count] do
   243     begin
   281     begin
   245     Point.y:= hwRound(Me^.Y);
   283     Point.y:= hwRound(Me^.Y);
   246     Score:= - ThinkingHH^.Health
   284     Score:= - ThinkingHH^.Health
   247     end;
   285     end;
   248 // rate explosion
   286 // rate explosion
   249 dmgBase:= r + cHHRadius div 2;
   287 dmgBase:= r + cHHRadius div 2;
       
   288 if (Flags and 2 <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r
       
   289 else erasure:= 0;
   250 for i:= 0 to Targets.Count do
   290 for i:= 0 to Targets.Count do
   251     with Targets.ar[i] do
   291     with Targets.ar[i] do
   252         begin
   292         begin
   253         dmg:= 0;
   293         dmg:= 0;
   254         if abs(Point.x - x) + abs(Point.y - y) < dmgBase then
   294         if abs(Point.x - x) + abs(Point.y - y) < dmgBase then
   255             dmg:= hwRound(_0_01 * cDamageModifier * min((dmgBase - LongInt(DistanceI(Point.x - x, Point.y - y).Round)) div 2, r) * cDamagePercent);
   295             dmg:= hwRound(_0_01 * cDamageModifier * min((dmgBase - LongInt(DistanceI(Point.x - x, Point.y - y).Round)) div 2, r) * cDamagePercent);
   256 
   296 
   257         if dmg > 0 then
   297         if dmg > 0 then
   258             begin
   298             begin
   259             if dmg >= abs(Score) then
   299             if Flags and 1 <> 0 then
       
   300                 begin
       
   301                 dX:= 0.005 * dmg + 0.01;
       
   302                 dY:= dX;
       
   303                 end;
       
   304             if (Flags and 1 <> 0) and TraceDrown(x, y, Point.x, Point.y, dX, dY, erasure) then
       
   305                 if Score > 0 then
       
   306                     begin
       
   307                     inc(rate, KillScore)
       
   308                     end
       
   309                 else
       
   310                     dec(rate, KillScore * friendlyfactor div 100)
       
   311             else if dmg >= abs(Score) then
   260                 if Score > 0 then
   312                 if Score > 0 then
   261                     inc(rate, KillScore)
   313                     inc(rate, KillScore)
   262                 else
   314                 else
   263                     dec(rate, KillScore * friendlyfactor div 100)
   315                     dec(rate, KillScore * friendlyfactor div 100)
   264             else
   316             else