hedgewars/uAIMisc.pas
branch0.9.19
changeset 8924 13ac59499066
parent 8895 95177c18e38c
child 8939 b26aaf28c920
equal deleted inserted replaced
8904:6ea838b8dcd5 8924:13ac59499066
    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;
       
    68 
    67 
    69 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
    68 function  RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
    70 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
    69 function  RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
    71 function  RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
    70 function  RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
    72 function  RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
    71 function  RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
    88         ar: array[0..Pred(MAXBONUS div 8)] of TBonus;  // don't use too many
    87         ar: array[0..Pred(MAXBONUS div 8)] of TBonus;  // don't use too many
    89         end;
    88         end;
    90 
    89 
    91 const KillScore = 200;
    90 const KillScore = 200;
    92 var friendlyfactor: LongInt = 300;
    91 var friendlyfactor: LongInt = 300;
       
    92 var dmgMod: real = 1.0;
    93 
    93 
    94 implementation
    94 implementation
    95 uses uCollisions, uVariables, uUtils, uLandTexture, uGearsUtils;
    95 uses uCollisions, uVariables, uUtils, uLandTexture, uGearsUtils;
    96 
    96 
    97 var 
    97 var
    98     KnownExplosion: record
    98     KnownExplosion: record
    99         X, Y, Radius: LongInt
    99         X, Y, Radius: LongInt
   100         end = (X: 0; Y: 0; Radius: 0);
   100         end = (X: 0; Y: 0; Radius: 0);
   101 
   101 
   102 procedure FillTargets;
   102 procedure FillTargets;
   111         if not hasGone then
   111         if not hasGone then
   112             begin
   112             begin
   113             for i:= 0 to cMaxHHIndex do
   113             for i:= 0 to cMaxHHIndex do
   114                 if (Hedgehogs[i].Gear <> nil)
   114                 if (Hedgehogs[i].Gear <> nil)
   115                 and (Hedgehogs[i].Gear <> ThinkingHH)
   115                 and (Hedgehogs[i].Gear <> ThinkingHH)
   116                 and (Hedgehogs[i].Gear^.Health > Hedgehogs[i].Gear^.Damage) 
   116                 and (Hedgehogs[i].Gear^.Health > Hedgehogs[i].Gear^.Damage)
   117                     then
   117                     then
   118                     begin
   118                     begin
   119                     with Targets.ar[Targets.Count], Hedgehogs[i] do
   119                     with Targets.ar[Targets.Count], Hedgehogs[i] do
   120                         begin
   120                         begin
   121                         skip:= false;
   121                         skip:= false;
   122                         matters:= (Hedgehogs[i].Gear^.AIHints and aihDoesntMatter) = 0;
   122                         matters:= (Hedgehogs[i].Gear^.AIHints and aihDoesntMatter) = 0;
   123                         
   123 
   124                         Point.X:= hwRound(Gear^.X);
   124                         Point.X:= hwRound(Gear^.X);
   125                         Point.Y:= hwRound(Gear^.Y);
   125                         Point.Y:= hwRound(Gear^.Y);
   126                         if Clan <> CurrentTeam^.Clan then
   126                         if Clan <> CurrentTeam^.Clan then
   127                             begin
   127                             begin
   128                             Score:= Gear^.Health - Gear^.Damage;
   128                             Score:= Gear^.Health - Gear^.Damage;
   179             gtCase:
   179             gtCase:
   180                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y) + 3, 37, 25);
   180                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y) + 3, 37, 25);
   181             gtFlame:
   181             gtFlame:
   182                 if (Gear^.State and gsttmpFlag) <> 0 then
   182                 if (Gear^.State and gsttmpFlag) <> 0 then
   183                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 20, -50);
   183                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 20, -50);
   184 // avoid mines unless they are very likely to be duds, or are duds. also avoid if they are about to blow 
   184 // avoid mines unless they are very likely to be duds, or are duds. also avoid if they are about to blow
   185             gtMine:
   185             gtMine:
   186                 if ((Gear^.State and gstAttacking) = 0) and (((cMineDudPercent < 90) and (Gear^.Health <> 0))
   186                 if ((Gear^.State and gstAttacking) = 0) and (((cMineDudPercent < 90) and (Gear^.Health <> 0))
   187                 or (isAfterAttack and (Gear^.Health = 0) and (Gear^.Damage > 30))) then
   187                 or (isAfterAttack and (Gear^.Health = 0) and (Gear^.Damage > 30))) then
   188                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 50, -50)
   188                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 50, -50)
   189                 else if (Gear^.State and gstAttacking) <> 0 then
   189                 else if (Gear^.State and gstAttacking) <> 0 then
   190                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, -50); // mine is on
   190                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, -50); // mine is on
   191                     
   191 
   192             gtExplosives:
   192             gtExplosives:
   193             if isAfterAttack then
   193             if isAfterAttack then
   194                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 75, -60 + Gear^.Health);
   194                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 75, -60 + Gear^.Health);
   195                 
   195 
   196             gtSMine:
   196             gtSMine:
   197                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 50, -30);
   197                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 50, -30);
   198                 
   198 
   199             gtDynamite:
   199             gtDynamite:
   200                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 150, -75);
   200                 AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 150, -75);
   201                 
   201 
   202             gtHedgehog:
   202             gtHedgehog:
   203                 begin
   203                 begin
   204                 if Gear^.Damage >= Gear^.Health then
   204                 if Gear^.Damage >= Gear^.Health then
   205                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 60, -25)
   205                     AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 60, -25)
   206                 else
   206                 else
   268 function TestCollWithEverything(x, y, r: LongInt): boolean; inline;
   268 function TestCollWithEverything(x, y, r: LongInt): boolean; inline;
   269 begin
   269 begin
   270     if not CheckBounds(x, y, r) then
   270     if not CheckBounds(x, y, r) then
   271         exit(false);
   271         exit(false);
   272 
   272 
   273     if (Land[y-r, x-r] <> 0) or    
   273     if (Land[y-r, x-r] <> 0) or
   274        (Land[y+r, x-r] <> 0) or 
   274        (Land[y+r, x-r] <> 0) or
   275        (Land[y-r, x+r] <> 0) or
   275        (Land[y-r, x+r] <> 0) or
   276        (Land[y+r, x+r] <> 0) then
   276        (Land[y+r, x+r] <> 0) then
   277        exit(true);
   277        exit(true);
   278 
   278 
   279     TestCollWithEverything := false;
   279     TestCollWithEverything := false;
   283 begin
   283 begin
   284     if not CheckBounds(x, y, r) then
   284     if not CheckBounds(x, y, r) then
   285         exit(false);
   285         exit(false);
   286 
   286 
   287     if (Land[y-r, x-r] > lfAllObjMask) or
   287     if (Land[y-r, x-r] > lfAllObjMask) or
   288        (Land[y+r, x-r] > lfAllObjMask) or 
   288        (Land[y+r, x-r] > lfAllObjMask) or
   289        (Land[y-r, x+r] > lfAllObjMask) or
   289        (Land[y-r, x+r] > lfAllObjMask) or
   290        (Land[y+r, x+r] > lfAllObjMask) then
   290        (Land[y+r, x+r] > lfAllObjMask) then
   291        exit(true);
   291        exit(true);
   292 
   292 
   293     TestCollExcludingObjects:= false;
   293     TestCollExcludingObjects:= false;
   297 begin
   297 begin
   298     if not CheckBounds(x, y, r) then
   298     if not CheckBounds(x, y, r) then
   299         exit(false);
   299         exit(false);
   300 
   300 
   301     if (Land[y-r, x-r] and lfNotCurrentMask <> 0) or
   301     if (Land[y-r, x-r] and lfNotCurrentMask <> 0) or
   302        (Land[y+r, x-r] and lfNotCurrentMask <> 0) or 
   302        (Land[y+r, x-r] and lfNotCurrentMask <> 0) or
   303        (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) then
   304        (Land[y+r, x+r] and lfNotCurrentMask <> 0) then
   305        exit(true);
   305        exit(true);
   306     
   306 
   307     TestColl:= false;
   307     TestColl:= false;
   308 end;
       
   309 
       
   310 function TestCollWithLand(x, y, r: LongInt): boolean; inline;
       
   311 begin
       
   312     if not CheckBounds(x, y, r) then
       
   313         exit(false);
       
   314 
       
   315     if (Land[y-r, x-r] > lfAllObjMask) or
       
   316        (Land[y+r, x-r] > lfAllObjMask) or 
       
   317        (Land[y-r, x+r] > lfAllObjMask) or
       
   318        (Land[y+r, x+r] > lfAllObjMask) then
       
   319        exit(true);
       
   320     
       
   321     TestCollWithLand:= false;
       
   322 end;
   308 end;
   323 
   309 
   324 
   310 
   325 // Wrapper to test various approaches.  If it works reasonably, will just replace.
   311 // Wrapper to test various approaches.  If it works reasonably, will just replace.
   326 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with...
   312 // Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with...
   354     begin
   340     begin
   355         x:= x + dX;
   341         x:= x + dX;
   356         y:= y + dY;
   342         y:= y + dY;
   357         dY:= dY + cGravityf;
   343         dY:= dY + cGravityf;
   358         skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner));
   344         skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner));
   359         if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then
   345         if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then
   360         begin
   346         begin
   361             if 0.4 < dY then
   347             if 0.4 < dY then
   362             begin
   348             begin
   363                 dmg := 1 + trunc((abs(dY) - 0.4) * 70);
   349                 dmg := 1 + trunc((abs(dY) - 0.4) * 70);
   364                 if dmg >= 1 then
   350                 if dmg >= 1 then
   379     begin
   365     begin
   380         x:= x + dX;
   366         x:= x + dX;
   381         y:= y + dY;
   367         y:= y + dY;
   382         dY:= dY + cGravityf;
   368         dY:= dY + cGravityf;
   383 
   369 
   384 {        if ((trunc(y) and LAND_HEIGHT_MASK) = 0) and ((trunc(x) and LAND_WIDTH_MASK) = 0) then 
   370 {        if ((trunc(y) and LAND_HEIGHT_MASK) = 0) and ((trunc(x) and LAND_WIDTH_MASK) = 0) then
   385             begin
   371             begin
   386             LandPixels[trunc(y), trunc(x)]:= v;
   372             LandPixels[trunc(y), trunc(x)]:= v;
   387             UpdateLandTexture(trunc(X), 1, trunc(Y), 1, true);
   373             UpdateLandTexture(trunc(X), 1, trunc(Y), 1, true);
   388             end;}
   374             end;}
   389 
   375 
   410     RateExplosion:= RateExplosion(Me, x, y, r, 0);
   396     RateExplosion:= RateExplosion(Me, x, y, r, 0);
   411 end;
   397 end;
   412 
   398 
   413 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
   399 function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
   414 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt;
   400 var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt;
   415     dX, dY, dmgMod: real;
   401     dX, dY: real;
   416     hadSkips: boolean;
   402     hadSkips: boolean;
   417 begin
   403 begin
   418 fallDmg:= 0;
   404 fallDmg:= 0;
   419 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
       
   420 rate:= 0;
   405 rate:= 0;
   421 // add our virtual position
   406 // add our virtual position
   422 with Targets.ar[Targets.Count] do
   407 with Targets.ar[Targets.Count] do
   423     begin
   408     begin
   424     Point.x:= hwRound(Me^.X);
   409     Point.x:= hwRound(Me^.X);
   448             begin
   433             begin
   449             if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then
   434             if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then
   450                 begin
   435                 begin
   451                 dX:= 0.005 * dmg + 0.01;
   436                 dX:= 0.005 * dmg + 0.01;
   452                 dY:= dX;
   437                 dY:= dX;
   453                 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and 
   438                 if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
   454                    (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
   439                    (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
   455                      fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod)
   440                      fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod)
   456                 else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod)
   441                 else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod)
   457                 end;
   442                 end;
   458             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   443             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   478     RateExplosion:= rate;
   463     RateExplosion:= rate;
   479 end;
   464 end;
   480 
   465 
   481 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   466 function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
   482 var i, fallDmg, dmg, rate: LongInt;
   467 var i, fallDmg, dmg, rate: LongInt;
   483     dX, dY, dmgMod: real;
   468     dX, dY: real;
   484 begin
   469 begin
   485 fallDmg:= 0;
   470 fallDmg:= 0;
   486 dX:= gdX * 0.01 * kick;
   471 dX:= gdX * 0.01 * kick;
   487 dY:= gdY * 0.01 * kick;
   472 dY:= gdY * 0.01 * kick;
   488 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
       
   489 rate:= 0;
   473 rate:= 0;
   490 for i:= 0 to Pred(Targets.Count) do
   474 for i:= 0 to Pred(Targets.Count) do
   491     with Targets.ar[i] do
   475     with Targets.ar[i] do
   492       if skip then 
   476       if skip then
   493         if (Flags and afSetSkip = 0) then skip:= false else {still skip}
   477         if (Flags and afSetSkip = 0) then skip:= false else {still skip}
   494       else if matters then
   478       else if matters then
   495         begin
   479         begin
   496         dmg:= 0;
   480         dmg:= 0;
   497         if abs(Point.x - x) + abs(Point.y - y) < r then
   481         if abs(Point.x - x) + abs(Point.y - y) < r then
   498             dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   482             dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   499 
   483 
   500         if dmg > 0 then
   484         if dmg > 0 then
   501             begin
   485             begin
   502             if (Flags and afSetSkip <> 0) then skip:= true;
   486             if (Flags and afSetSkip <> 0) then skip:= true;
   503             if (Flags and afTrackFall <> 0) and (Score > 0) then 
   487             if (Flags and afTrackFall <> 0) and (Score > 0) then
   504                 fallDmg:= trunc(TraceShoveFall(Point.x, Point.y - 2, dX, dY) * dmgMod);
   488                 fallDmg:= trunc(TraceShoveFall(Point.x, Point.y - 2, dX, dY) * dmgMod);
   505             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   489             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   506                 if Score > 0 then
   490                 if Score > 0 then
   507                     inc(rate, KillScore + Score div 10)   // Add a bit of a bonus for bigger hog drownings
   491                     inc(rate, KillScore + Score div 10)   // Add a bit of a bonus for bigger hog drownings
   508                 else
   492                 else
   522 RateShove:= rate * 1024
   506 RateShove:= rate * 1024
   523 end;
   507 end;
   524 
   508 
   525 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
   509 function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
   526 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt;
   510 var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt;
   527     dX, dY, dmgMod: real;
   511     dX, dY: real;
   528     hadSkips: boolean;
   512     hadSkips: boolean;
   529 begin
   513 begin
   530 dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
       
   531 rate:= 0;
   514 rate:= 0;
   532 gdX:= gdX * 0.01;
   515 gdX:= gdX * 0.01;
   533 gdY:= gdX * 0.01;
   516 gdY:= gdX * 0.01;
   534 // add our virtual position
   517 // add our virtual position
   535 with Targets.ar[Targets.Count] do
   518 with Targets.ar[Targets.Count] do
   563             begin
   546             begin
   564             dX:= gdX * dmg;
   547             dX:= gdX * dmg;
   565             dY:= gdY * dmg;
   548             dY:= gdY * dmg;
   566             if dX < 0 then dX:= dX - 0.01
   549             if dX < 0 then dX:= dX - 0.01
   567             else dX:= dX + 0.01;
   550             else dX:= dX + 0.01;
   568             if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and 
   551             if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
   569                (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
   552                (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
   570                  fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod)
   553                  fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod)
   571             else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod);
   554             else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod);
   572             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   555             if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
   573                 if Score > 0 then
   556                 if Score > 0 then
   608         if abs(Point.x - x) + abs(Point.y - y) < 18 then
   591         if abs(Point.x - x) + abs(Point.y - y) < 18 then
   609             begin
   592             begin
   610             r:= trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   593             r:= trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
   611 
   594 
   612             if r <= 18 then
   595             if r <= 18 then
   613                 if Score > 0 then 
   596                 if Score > 0 then
   614                     inc(rate, Score div 3)
   597                     inc(rate, Score div 3)
   615                 else
   598                 else
   616                     inc(rate, Score div 3 * friendlyfactor div 100)
   599                     inc(rate, Score div 3 * friendlyfactor div 100)
   617             end;
   600             end;
   618 RateHammer:= rate * 1024;
   601 RateHammer:= rate * 1024;
   626 GoInfo.JumpType:= jmpNone;
   609 GoInfo.JumpType:= jmpNone;
   627 bX:= hwRound(Gear^.X);
   610 bX:= hwRound(Gear^.X);
   628 bY:= hwRound(Gear^.Y);
   611 bY:= hwRound(Gear^.Y);
   629 case JumpType of
   612 case JumpType of
   630     jmpNone: exit(false);
   613     jmpNone: exit(false);
   631     
   614 
   632     jmpHJump:
   615     jmpHJump:
   633         if TestCollisionYwithGear(Gear, -1) = 0 then
   616         if TestCollisionYwithGear(Gear, -1) = 0 then
   634         begin
   617         begin
   635             Gear^.dY:= -_0_2;
   618             Gear^.dY:= -_0_2;
   636             SetLittle(Gear^.dX);
   619             SetLittle(Gear^.dX);
   637             Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
   620             Gear^.State:= Gear^.State or gstMoving or gstHHJumping;
   638         end
   621         end
   639     else
   622     else
   640         exit(false);
   623         exit(false);
   641         
   624 
   642     jmpLJump:
   625     jmpLJump:
   643         begin
   626         begin
   644             if TestCollisionYwithGear(Gear, -1) <> 0 then
   627             if TestCollisionYwithGear(Gear, -1) <> 0 then
   645                 if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then
   628                 if not TestCollisionXwithXYShift(Gear, _0, -2, hwSign(Gear^.dX)) then
   646                     Gear^.Y:= Gear^.Y - int2hwFloat(2)
   629                     Gear^.Y:= Gear^.Y - int2hwFloat(2)
   658             exit(false)
   641             exit(false)
   659         end
   642         end
   660 end;
   643 end;
   661 
   644 
   662 repeat
   645 repeat
   663         {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then 
   646         {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then
   664             begin
   647             begin
   665             LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= Gear^.Hedgehog^.Team^.Clan^.Color;
   648             LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= Gear^.Hedgehog^.Team^.Clan^.Color;
   666             UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
   649             UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
   667             end;}
   650             end;}
   668             
   651 
   669     if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then
   652     if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then
   670         exit(false);
   653         exit(false);
   671     if (Gear^.State and gstMoving) <> 0 then
   654     if (Gear^.State and gstMoving) <> 0 then
   672     begin
   655     begin
   673         if (GoInfo.Ticks = 350) then
   656         if (GoInfo.Ticks = 350) then
   721 GoInfo.Ticks:= 0;
   704 GoInfo.Ticks:= 0;
   722 GoInfo.FallPix:= 0;
   705 GoInfo.FallPix:= 0;
   723 GoInfo.JumpType:= jmpNone;
   706 GoInfo.JumpType:= jmpNone;
   724 tY:= hwRound(Gear^.Y);
   707 tY:= hwRound(Gear^.Y);
   725 repeat
   708 repeat
   726         {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then 
   709         {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then
   727             begin
   710             begin
   728             LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= random($FFFFFFFF);//Gear^.Hedgehog^.Team^.Clan^.Color;
   711             LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= random($FFFFFFFF);//Gear^.Hedgehog^.Team^.Clan^.Color;
   729             UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
   712             UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
   730             end;}
   713             end;}
   731 
   714 
   735         begin
   718         begin
   736         if AltGear^.Hedgehog^.BotLevel < 4 then
   719         if AltGear^.Hedgehog^.BotLevel < 4 then
   737             AddWalkBonus(pX, tY, 250, -40);
   720             AddWalkBonus(pX, tY, 250, -40);
   738         exit(false)
   721         exit(false)
   739         end;
   722         end;
   740         
   723 
   741     // hog is falling    
   724     // hog is falling
   742     if (Gear^.State and gstMoving) <> 0 then
   725     if (Gear^.State and gstMoving) <> 0 then
   743         begin
   726         begin
   744         inc(GoInfo.Ticks);
   727         inc(GoInfo.Ticks);
   745         Gear^.dY:= Gear^.dY + cGravity;
   728         Gear^.dY:= Gear^.dY + cGravity;
   746         if Gear^.dY > _0_4 then
   729         if Gear^.dY > _0_4 then
   747             begin
   730             begin
   748             GoInfo.FallPix:= 0;
   731             GoInfo.FallPix:= 0;
   749             // try ljump instead of fall with damage
   732             // try ljump instead of fall with damage
   750             HHJump(AltGear, jmpLJump, GoInfo); 
   733             HHJump(AltGear, jmpLJump, GoInfo);
   751             if AltGear^.Hedgehog^.BotLevel < 4 then
   734             if AltGear^.Hedgehog^.BotLevel < 4 then
   752                 AddWalkBonus(pX, tY, 175, -20);
   735                 AddWalkBonus(pX, tY, 175, -20);
   753             exit(false)
   736             exit(false)
   754             end;
   737             end;
   755         Gear^.Y:= Gear^.Y + Gear^.dY;
   738         Gear^.Y:= Gear^.Y + Gear^.dY;