hedgewars/uGearsUtils.pas
changeset 7190 aa8d68817c32
parent 7176 fb4b0c6dfdbd
child 7272 71df899c4163
equal deleted inserted replaced
7189:c45b0ef1eb4c 7190:aa8d68817c32
   481         gear^.State := gstWait;
   481         gear^.State := gstWait;
   482     end;
   482     end;
   483     RecountTeamHealth(tempTeam);
   483     RecountTeamHealth(tempTeam);
   484 end;
   484 end;
   485 
   485 
   486 function CountNonZeroz(x, y, r, c: LongInt): LongInt;
   486 function CountNonZeroz(x, y, r, c: LongInt; mask: LongWord): LongInt;
   487 var i: LongInt;
   487 var i: LongInt;
   488     count: LongInt = 0;
   488     count: LongInt = 0;
   489 begin
   489 begin
   490     if (y and LAND_HEIGHT_MASK) = 0 then
   490     if (y and LAND_HEIGHT_MASK) = 0 then
   491         for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do
   491         for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do
   492             if Land[y, i] <> 0 then
   492             if Land[y, i] and mask <> 0 then
   493             begin
   493             begin
   494                 inc(count);
   494                 inc(count);
   495                 if count = c then
   495                 if count = c then
   496                 begin
   496                 begin
   497                     CountNonZeroz:= count;
   497                     CountNonZeroz:= count;
   529     y, sy: LongInt;
   529     y, sy: LongInt;
   530     ar: array[0..511] of TPoint;
   530     ar: array[0..511] of TPoint;
   531     ar2: array[0..1023] of TPoint;
   531     ar2: array[0..1023] of TPoint;
   532     cnt, cnt2: Longword;
   532     cnt, cnt2: Longword;
   533     delta: LongInt;
   533     delta: LongInt;
   534     reallySkip, tryAgain: boolean;
   534     ignoreNearObjects, ignoreOverlap, tryAgain: boolean;
   535 begin
   535 begin
   536 reallySkip:= false; // try not skipping proximity at first
   536 ignoreNearObjects:= false; // try not skipping proximity at first
       
   537 ignoreOverlap:= false; // this not only skips proximity, but allows overlapping objects (barrels, mines, hogs, crates).  Saving it for a 3rd pass.  With this active, winning AI Survival goes back to virtual impossibility
   537 tryAgain:= true;
   538 tryAgain:= true;
   538 while tryAgain do
   539 while tryAgain do
   539     begin
   540     begin
   540     delta:= 250;
   541     delta:= 250;
   541     cnt2:= 0;
   542     cnt2:= 0;
   547             y:= min(1024, topY) - 2 * Gear^.Radius;
   548             y:= min(1024, topY) - 2 * Gear^.Radius;
   548             while y < cWaterLine do
   549             while y < cWaterLine do
   549                 begin
   550                 begin
   550                 repeat
   551                 repeat
   551                     inc(y, 2);
   552                     inc(y, 2);
   552                 until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) = 0);
   553                 until (y >= cWaterLine) or
       
   554                         (not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) = 0)) or 
       
   555                         (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FF00) = 0));
   553 
   556 
   554                 sy:= y;
   557                 sy:= y;
   555 
   558 
   556                 repeat
   559                 repeat
   557                     inc(y);
   560                     inc(y);
   558                 until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0);
   561                 until (y >= cWaterLine) or
       
   562                         (not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) <> 0)) or 
       
   563                         (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FF00) <> 0)); 
   559 
   564 
   560                 if (y - sy > Gear^.Radius * 2)
   565                 if (y - sy > Gear^.Radius * 2)
   561                     and (((Gear^.Kind = gtExplosives)
   566                     and (((Gear^.Kind = gtExplosives)
   562                     and (y < cWaterLine)
   567                     and (y < cWaterLine)
   563                     and (reallySkip or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60))
   568                     and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60))
   564                     and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius))
   569                     and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1, $FFFF) > Gear^.Radius))
   565                 or
   570                 or
   566                     ((Gear^.Kind <> gtExplosives)
   571                     ((Gear^.Kind <> gtExplosives)
   567                     and (y < cWaterLine)
   572                     and (y < cWaterLine)
   568                     and (reallySkip or NoGearsToAvoid(x, y - Gear^.Radius, 110, 110))
   573                     and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 110, 110))
   569                     )) then
   574                     )) then
   570                     begin
   575                     begin
   571                     ar[cnt].X:= x;
   576                     ar[cnt].X:= x;
   572                     if withFall then
   577                     if withFall then
   573                         ar[cnt].Y:= sy + Gear^.Radius
   578                         ar[cnt].Y:= sy + Gear^.Radius
   588                     end
   593                     end
   589         until (x + Delta > Right);
   594         until (x + Delta > Right);
   590 
   595 
   591         dec(Delta, 60)
   596         dec(Delta, 60)
   592     until (cnt2 > 0) or (Delta < 70);
   597     until (cnt2 > 0) or (Delta < 70);
   593     if (cnt2 = 0) and skipProximity and (not reallySkip) then
   598     // if either of these has not been tried, do another pass
       
   599     if (cnt2 = 0) and skipProximity and (not ignoreOverlap) then
   594         tryAgain:= true
   600         tryAgain:= true
   595     else tryAgain:= false;
   601     else tryAgain:= false;
   596     reallySkip:= true;
   602     if ignoreNearObjects then ignoreOverlap:= true;
       
   603     ignoreNearObjects:= true;
   597     end;
   604     end;
   598 
   605 
   599 if cnt2 > 0 then
   606 if cnt2 > 0 then
   600     with ar2[GetRandom(cnt2)] do
   607     with ar2[GetRandom(cnt2)] do
   601         begin
   608         begin