hedgewars/uAIMisc.pas
changeset 8952 a6ee1e7310fb
parent 8951 95dd846caf5d
child 8953 d0e5c1002fe1
equal deleted inserted replaced
8951:95dd846caf5d 8952:a6ee1e7310fb
    31       BadTurn = Low(LongInt) div 4;
    31       BadTurn = Low(LongInt) div 4;
    32 
    32 
    33 type TTarget = record
    33 type TTarget = record
    34     Point: TPoint;
    34     Point: TPoint;
    35     Score: LongInt;
    35     Score: LongInt;
       
    36     Density: real;
    36     skip, matters, dead: boolean;
    37     skip, matters, dead: boolean;
    37     Kind: TGearType;
    38     Kind: TGearType;
    38     end;
    39     end;
    39 TTargets = record
    40 TTargets = record
    40     Count: Longword;
    41     Count: Longword;
    64 
    65 
    65 function  RatePlace(Gear: PGear): LongInt;
    66 function  RatePlace(Gear: PGear): LongInt;
    66 function  TestColl(x, y, r: LongInt): boolean; inline;
    67 function  TestColl(x, y, r: LongInt): boolean; inline;
    67 function  TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
    68 function  TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
    68 function  TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
    69 function  TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
    69 function  TraceShoveFall(x, y, dX, dY: Real): LongInt;
    70 function  TraceShoveFall(x, y, dX, dY: Real; Kind: TGearType): LongInt;
    70 
    71 
    71 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
    72 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
    72 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline;
    73 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline;
    73 function  RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
    74 function  RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
    74 function  RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
    75 function  RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   142             matters:= (iter^.AIHints and aihDoesntMatter) = 0;
   143             matters:= (iter^.AIHints and aihDoesntMatter) = 0;
   143 
   144 
   144             Point.X:= hwRound(iter^.X);
   145             Point.X:= hwRound(iter^.X);
   145             Point.Y:= hwRound(iter^.Y);
   146             Point.Y:= hwRound(iter^.Y);
   146             if (iter^.Kind = gtHedgehog) then
   147             if (iter^.Kind = gtHedgehog) then
       
   148                 begin
   147                 if (iter^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then
   149                 if (iter^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then
   148                     begin
   150                     begin
   149                     Score:= iter^.Damage - iter^.Health;
   151                     Score:= iter^.Damage - iter^.Health;
   150                     inc(f)
   152                     inc(f)
   151                     end
   153                     end
   152                 else 
   154                 else 
   153                     begin
   155                     begin
   154                     Score:= iter^.Health - iter^.Damage;
   156                     Score:= iter^.Health - iter^.Damage;
   155                     inc(e)
   157                     inc(e)
   156                     end
   158                     end;
   157             else if iter^.Kind = gtExplosives then Score:= iter^.Health - iter^.Damage
   159                 Density:= 1;
   158             else if iter^.Kind = gtMine then Score:= max(0,35-iter^.Damage)
   160                 end
       
   161             else if iter^.Kind = gtExplosives then
       
   162                 begin
       
   163                 Score:= iter^.Health - iter^.Damage;
       
   164                 Density:= 2
       
   165                 end
       
   166             else if iter^.Kind = gtMine then 
       
   167                 begin
       
   168                 Score:= max(0,35-iter^.Damage);
       
   169                 Density:= 1/3
       
   170                 end
   159             end;
   171             end;
   160         inc(Targets.Count)
   172         inc(Targets.Count)
   161         end;
   173         end;
   162     iter:= iter^.NextGear
   174     iter:= iter^.NextGear
   163     end;
   175     end;
   349     TestCollExcludingMe:= TestCollWithEverything(x, y, r)
   361     TestCollExcludingMe:= TestCollWithEverything(x, y, r)
   350 end;
   362 end;
   351 
   363 
   352 
   364 
   353 
   365 
   354 function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord): LongInt;
   366 function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord; Kind: TGearType): LongInt;
   355 var skipLandCheck: boolean;
   367 var skipLandCheck: boolean;
   356     rCorner: real;
   368     rCorner: real;
   357     dmg: LongInt;
   369     dmg, radius: LongInt;
   358 begin
   370 begin
   359     skipLandCheck:= true;
   371     skipLandCheck:= true;
   360     if x - eX < 0 then dX:= -dX;
   372     if x - eX < 0 then dX:= -dX;
   361     if y - eY < 0 then dY:= -dY;
   373     if y - eY < 0 then dY:= -dY;
   362     // ok. attempt approximate search for an unbroken trajectory into water.  if it continues far enough, assume out of map
   374     // ok. attempt approximate search for an unbroken trajectory into water.  if it continues far enough, assume out of map
       
   375     if Kind = gtHedgehog then 
       
   376         radius:= cHHRadius
       
   377     else if Kind = gtExplosives then
       
   378         radius:= 16
       
   379     else if Kind = gtMine then
       
   380         radius:= 2;
   363     rCorner:= r * 0.75;
   381     rCorner:= r * 0.75;
   364     while true do
   382     while true do
   365     begin
   383         begin
   366         x:= x + dX;
   384         x:= x + dX;
   367         y:= y + dY;
   385         y:= y + dY;
   368         dY:= dY + cGravityf;
   386         dY:= dY + cGravityf;
   369         skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner));
   387         skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner));
   370         if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then
   388         if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), radius) then
   371         begin
   389             begin
   372             if 0.4 < dY then
   390             if (Kind = gtHedgehog) and (0.4 < dY) then
   373             begin
   391                 begin
   374                 dmg := 1 + trunc((abs(dY) - 0.4) * 70);
   392                 dmg := 1 + trunc((abs(dY) - 0.4) * 70);
   375                 if dmg >= 1 then
   393                 if dmg >= 1 then exit(dmg)
   376                     exit(dmg);
   394                 end
   377             end;
   395 // so. the problem w/ explosives is it only uses dX or dY depending on impact, and we don't know which we hit.  Maybe we didn't even hit, given TestColl check corners.
       
   396             else 
       
   397                 begin
       
   398                 if ((dY > 0.2) and (Land[trunc(y)+radius, trunc(x)] > lfAllObjMask)) or 
       
   399                    ((dY < -0.2) and (Land[trunc(y)-radius, trunc(x)] > lfAllObjMask)) then
       
   400                     begin
       
   401                     dmg := 1 + trunc(abs(dY) * 70);
       
   402                     if dmg >= 1 then exit(dmg)
       
   403                     end
       
   404 // so we don't know at present if a barrel is already rolling.  Would need to add that to target info I guess
       
   405                 else if ((Kind = gtMine) or (abs(dX) > 0.15) or ((abs(dY) > 0.15) and  (abs(dX) > 0.02))) and
       
   406                         (((dX > 0.2) and (Land[trunc(y), trunc(x)+radius] > lfAllObjMask)) or 
       
   407                          ((dX < -0.2) and (Land[trunc(y), trunc(x)-radius] > lfAllObjMask))) then
       
   408                     begin
       
   409                     dmg := 1 + trunc(abs(dX) * 70);
       
   410                     if dmg >= 1 then exit(dmg)
       
   411                     end
       
   412                 end;
   378             exit(0)
   413             exit(0)
   379         end;
   414             end;
   380         if (y > cWaterLine) or (x > 4096) or (x < 0) then
   415         if (y > cWaterLine) or (x > 4096) or (x < 0) then exit(-1)
   381             exit(-1);
   416         end
   382     end;
   417 end;
   383 end;
   418 
   384 
   419 function TraceShoveFall(x, y, dX, dY: Real; Kind: TGearType): LongInt;
   385 function TraceShoveFall(x, y, dX, dY: Real): LongInt;
       
   386 var dmg: LongInt;
   420 var dmg: LongInt;
   387 begin
   421 begin
   388 //v:= random($FFFFFFFF);
   422 //v:= random($FFFFFFFF);
   389     while true do
   423     while true do
   390     begin
   424     begin
   465                 begin
   499                 begin
   466                 pX:= Point.x;
   500                 pX:= Point.x;
   467                 pY:= Point.y;
   501                 pY:= Point.y;
   468                 if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then
   502                 if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then
   469                     begin
   503                     begin
   470                     dX:= 0.005 * dmg + 0.01;
   504                     dX:= 0.005 * dmg + 0.01 * Density;
   471                     dY:= dX;
   505                     dY:= dX;
   472                     if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
   506                     if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
   473                        (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
   507                        (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
   474                          fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod)
   508                          fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Kind) * dmgMod)
   475                     else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod)
   509                     else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod)
   476                     end;
   510                     end;
   477                 if Kind = gtHedgehog then
   511                 if Kind = gtHedgehog then
   478                     begin
   512                     begin
   479                     if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   513                     if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   480                         begin
   514                         begin
   544             begin
   578             begin
   545             pX:= Point.x;
   579             pX:= Point.x;
   546             pY:= Point.y;
   580             pY:= Point.y;
   547             if (Flags and afSetSkip <> 0) then skip:= true;
   581             if (Flags and afSetSkip <> 0) then skip:= true;
   548             if (Flags and afTrackFall <> 0) and (Score > 0) then
   582             if (Flags and afTrackFall <> 0) and (Score > 0) then
   549                 fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY) * dmgMod);
   583                 fallDmg:= trunc(TraceShoveFall(pX, pY - 2, dX, dY, Kind) * dmgMod);
   550             if Kind = gtHedgehog then
   584             if Kind = gtHedgehog then
   551                 begin
   585                 begin
   552                 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   586                 if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   553                     begin
   587                     begin
   554                     if Score > 0 then
   588                     if Score > 0 then
   632                 end;
   666                 end;
   633             if dmg > 0 then
   667             if dmg > 0 then
   634                 begin
   668                 begin
   635                 pX:= Point.x;
   669                 pX:= Point.x;
   636                 pY:= Point.y;
   670                 pY:= Point.y;
   637                 dX:= gdX * dmg;
   671                 dX:= gdX * dmg * Density;
   638                 dY:= gdY * dmg;
   672                 dY:= gdY * dmg * Density;
   639                 if dX < 0 then dX:= dX - 0.01
   673                 if dX < 0 then dX:= dX - 0.01
   640                 else dX:= dX + 0.01;
   674                 else dX:= dX + 0.01;
   641                 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
   675                 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
   642                    (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
   676                    (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
   643                      fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0) * dmgMod)
   677                      fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Kind) * dmgMod)
   644                 else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure) * dmgMod);
   678                 else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Kind) * dmgMod);
   645                 if Kind = gtHedgehog then
   679                 if Kind = gtHedgehog then
   646                     begin
   680                     begin
   647                     if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   681                     if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   648                         begin
   682                         begin
   649                         if Score > 0 then
   683                         if Score > 0 then