hedgewars/uAIMisc.pas
changeset 8887 539380a498e4
parent 8884 08fe08651130
child 8895 95177c18e38c
equal deleted inserted replaced
8792:af4ab297b2b7 8887:539380a498e4
    62 function  RatePlace(Gear: PGear): LongInt;
    62 function  RatePlace(Gear: PGear): LongInt;
    63 function  TestColl(x, y, r: LongInt): boolean; inline;
    63 function  TestColl(x, y, r: LongInt): boolean; inline;
    64 function  TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
    64 function  TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
    65 function  TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
    65 function  TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
    66 function  TraceShoveFall(x, y, dX, dY: Real): LongInt;
    66 function  TraceShoveFall(x, y, dX, dY: Real): LongInt;
       
    67 function  TestCollWithLand(x, y, r: LongInt): boolean; inline;
    67 
    68 
    68 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
    69 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
    69 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
    70 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
    70 function  RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
    71 function  RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
    71 function  RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
    72 function  RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
    87         ar: array[0..Pred(MAXBONUS div 8)] of TBonus;  // don't use too many
    88         ar: array[0..Pred(MAXBONUS div 8)] of TBonus;  // don't use too many
    88         end;
    89         end;
    89 
    90 
    90 const KillScore = 200;
    91 const KillScore = 200;
    91 var friendlyfactor: LongInt = 300;
    92 var friendlyfactor: LongInt = 300;
       
    93 var dmgMod: real = 1.0;
    92 
    94 
    93 implementation
    95 implementation
    94 uses uCollisions, uVariables, uUtils, uLandTexture, uGearsUtils;
    96 uses uCollisions, uVariables, uUtils, uLandTexture, uGearsUtils;
    95 
    97 
    96 var 
    98 var 
   253                 inc(rate, Score * (Radius - r))
   255                 inc(rate, Score * (Radius - r))
   254         end;
   256         end;
   255     RatePlace:= rate;
   257     RatePlace:= rate;
   256 end;
   258 end;
   257 
   259 
       
   260 function CheckBounds(x, y, r: Longint): boolean; inline;
       
   261 begin
       
   262     CheckBounds := (((x-r) and LAND_WIDTH_MASK) = 0) and
       
   263         (((x+r) and LAND_WIDTH_MASK) = 0) and
       
   264         (((y-r) and LAND_HEIGHT_MASK) = 0) and
       
   265         (((y+r) and LAND_HEIGHT_MASK) = 0);
       
   266 end;
       
   267 
       
   268 
       
   269 function TestCollWithEverything(x, y, r: LongInt): boolean; inline;
       
   270 begin
       
   271     if not CheckBounds(x, y, r) then
       
   272         exit(false);
       
   273 
       
   274     if (Land[y-r, x-r] <> 0) or    
       
   275        (Land[y+r, x-r] <> 0) or 
       
   276        (Land[y-r, x+r] <> 0) or
       
   277        (Land[y+r, x+r] <> 0) then
       
   278        exit(true);
       
   279 
       
   280     TestCollWithEverything := false;
       
   281 end;
       
   282 
       
   283 function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
       
   284 begin
       
   285     if not CheckBounds(x, y, r) then
       
   286         exit(false);
       
   287 
       
   288     if (Land[y-r, x-r] > lfAllObjMask) or
       
   289        (Land[y+r, x-r] > lfAllObjMask) or 
       
   290        (Land[y-r, x+r] > lfAllObjMask) or
       
   291        (Land[y+r, x+r] > lfAllObjMask) then
       
   292        exit(true);
       
   293 
       
   294     TestCollExcludingObjects:= false;
       
   295 end;
       
   296 
       
   297 function TestColl(x, y, r: LongInt): boolean; inline;
       
   298 begin
       
   299     if not CheckBounds(x, y, r) then
       
   300         exit(false);
       
   301 
       
   302     if (Land[y-r, x-r] and lfNotCurrentMask <> 0) or
       
   303        (Land[y+r, x-r] and lfNotCurrentMask <> 0) or 
       
   304        (Land[y-r, x+r] and lfNotCurrentMask <> 0) or
       
   305        (Land[y+r, x+r] and lfNotCurrentMask <> 0) then
       
   306        exit(true);
       
   307     
       
   308     TestColl:= false;
       
   309 end;
       
   310 
       
   311 function TestCollWithLand(x, y, r: LongInt): boolean; inline;
       
   312 begin
       
   313     if not CheckBounds(x, y, r) then
       
   314         exit(false);
       
   315 
       
   316     if (Land[y-r, x-r] > lfAllObjMask) or
       
   317        (Land[y+r, x-r] > lfAllObjMask) or 
       
   318        (Land[y-r, x+r] > lfAllObjMask) or
       
   319        (Land[y+r, x+r] > lfAllObjMask) then
       
   320        exit(true);
       
   321     
       
   322     TestCollWithLand:= false;
       
   323 end;
       
   324 
       
   325 
   258 // Wrapper to test various approaches.  If it works reasonably, will just replace.
   326 // Wrapper to test various approaches.  If it works reasonably, will just replace.
   259 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with...
   327 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with...
   260 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
   328 function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
   261 var MeX, MeY: LongInt;
   329 var MeX, MeY: LongInt;
   262 begin
   330 begin
   263     if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
   331     if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
   264     begin
   332     begin
   265         MeX:= hwRound(Me^.X);
   333         MeX:= hwRound(Me^.X);
   266         MeY:= hwRound(Me^.Y);
   334         MeY:= hwRound(Me^.Y);
   267         // We are still inside the hog. Skip radius test
   335         // We are still inside the hog. Skip radius test
   268         if ((((x-MeX)*(x-MeX)) + ((y-MeY)*(y-MeY))) < 256) and (Land[y, x] <= lfAllObjMask) then
   336         if ((sqr(x-MeX) + sqr(y-MeY)) < 256) and (Land[y, x] and lfObjMask = 0) then
   269             exit(false);
   337             exit(false);
   270     end;
   338     end;
   271     TestCollExcludingMe:= TestColl(x, y, r)
   339     TestCollExcludingMe:= TestCollWithEverything(x, y, r)
   272 end;
   340 end;
   273 
   341 
   274 function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
   342 
   275 var b: boolean;
       
   276 begin
       
   277     b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > lfAllObjMask);
       
   278     if b then
       
   279         exit(true);
       
   280     
       
   281     b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > lfAllObjMask);
       
   282     if b then
       
   283         exit(true);
       
   284     
       
   285     b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > lfAllObjMask);
       
   286     if b then
       
   287         exit(true);
       
   288     
       
   289     b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > lfAllObjMask);
       
   290     if b then
       
   291         exit(true);
       
   292     
       
   293     TestCollExcludingObjects:= false;
       
   294 end;
       
   295 
       
   296 function TestColl(x, y, r: LongInt): boolean; inline;
       
   297 var b: boolean;
       
   298 begin
       
   299     b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] and lfNotCurrentMask <> 0);
       
   300     if b then
       
   301         exit(true);
       
   302     
       
   303     b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] and lfNotCurrentMask <> 0);
       
   304     if b then
       
   305         exit(true);
       
   306     
       
   307     b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] and lfNotCurrentMask <> 0);
       
   308     if b then
       
   309         exit(true);
       
   310     
       
   311     b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] and lfNotCurrentMask <> 0);
       
   312     if b then
       
   313         exit(true);
       
   314     
       
   315     TestColl:= false;
       
   316 end;
       
   317 
       
   318 function TestCollWithLand(x, y, r: LongInt): boolean; inline;
       
   319 var b: boolean;
       
   320 begin
       
   321     b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > lfAllObjMask);
       
   322     if b then
       
   323         exit(true);
       
   324         
       
   325     b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > lfAllObjMask);
       
   326     if b then
       
   327         exit(true);
       
   328         
       
   329     b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > lfAllObjMask);
       
   330     if b then
       
   331         exit(true);
       
   332         
       
   333     b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > lfAllObjMask);
       
   334     if b then
       
   335         exit(true);
       
   336 
       
   337     TestCollWithLand:= false;
       
   338 end;
       
   339 
   343 
   340 function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt;
   344 function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt;
   341 var skipLandCheck: boolean;
   345 var skipLandCheck: boolean;
   342     rCorner: real;
   346     rCorner: real;
   343     dmg: LongInt;
   347     dmg: LongInt;
   407     RateExplosion:= RateExplosion(Me, x, y, r, 0);
   411     RateExplosion:= RateExplosion(Me, x, y, r, 0);
   408 end;
   412 end;
   409 
   413 
   410 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
   414 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
   411 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt;
   415 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt;
   412     dX, dY, dmgMod: real;
   416     dX, dY: real;
   413     hadSkips: boolean;
   417     hadSkips: boolean;
   414 begin
   418 begin
   415 fallDmg:= 0;
   419 fallDmg:= 0;
   416 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
       
   417 rate:= 0;
   420 rate:= 0;
   418 // add our virtual position
   421 // add our virtual position
   419 with Targets.ar[Targets.Count] do
   422 with Targets.ar[Targets.Count] do
   420     begin
   423     begin
   421     Point.x:= hwRound(Me^.X);
   424     Point.x:= hwRound(Me^.X);
   475     RateExplosion:= rate;
   478     RateExplosion:= rate;
   476 end;
   479 end;
   477 
   480 
   478 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   481 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   479 var i, fallDmg, dmg, rate: LongInt;
   482 var i, fallDmg, dmg, rate: LongInt;
   480     dX, dY, dmgMod: real;
   483     dX, dY: real;
   481 begin
   484 begin
   482 fallDmg:= 0;
   485 fallDmg:= 0;
   483 dX:= gdX * 0.01 * kick;
   486 dX:= gdX * 0.01 * kick;
   484 dY:= gdY * 0.01 * kick;
   487 dY:= gdY * 0.01 * kick;
   485 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
       
   486 rate:= 0;
   488 rate:= 0;
   487 for i:= 0 to Pred(Targets.Count) do
   489 for i:= 0 to Pred(Targets.Count) do
   488     with Targets.ar[i] do
   490     with Targets.ar[i] do
   489       if skip then 
   491       if skip then 
   490         if (Flags and afSetSkip = 0) then skip:= false else {still skip}
   492         if (Flags and afSetSkip = 0) then skip:= false else {still skip}
   519 RateShove:= rate * 1024
   521 RateShove:= rate * 1024
   520 end;
   522 end;
   521 
   523 
   522 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
   524 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
   523 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt;
   525 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt;
   524     dX, dY, dmgMod: real;
   526     dX, dY: real;
   525     hadSkips: boolean;
   527     hadSkips: boolean;
   526 begin
   528 begin
   527 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
       
   528 rate:= 0;
   529 rate:= 0;
   529 gdX:= gdX * 0.01;
   530 gdX:= gdX * 0.01;
   530 gdY:= gdX * 0.01;
   531 gdY:= gdX * 0.01;
   531 // add our virtual position
   532 // add our virtual position
   532 with Targets.ar[Targets.Count] do
   533 with Targets.ar[Targets.Count] do