hedgewars/uGearsUtils.pas
changeset 10272 31ee88c9b4d0
parent 10245 3ccc054c3c3e
child 10274 07adc8b6288c
equal deleted inserted replaced
10271:e770bfcf488a 10272:31ee88c9b4d0
   547 function CountNonZeroz(x, y, r, c: LongInt; mask: LongWord): LongInt;
   547 function CountNonZeroz(x, y, r, c: LongInt; mask: LongWord): LongInt;
   548 var i: LongInt;
   548 var i: LongInt;
   549     count: LongInt = 0;
   549     count: LongInt = 0;
   550 begin
   550 begin
   551     if (y and LAND_HEIGHT_MASK) = 0 then
   551     if (y and LAND_HEIGHT_MASK) = 0 then
   552         for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do
   552         for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 1) do
   553             if Land[y, i] and mask <> 0 then
   553             if Land[y, i] and mask <> 0 then
   554             begin
   554             begin
   555                 inc(count);
   555                 inc(count);
   556                 if count = c then
   556                 if count = c then
   557                 begin
   557                 begin
   558                     CountNonZeroz:= count;
   558                     CountNonZeroz:= count;
   559                     exit
   559                     exit
   560                 end;
   560                 end;
   561             end;
   561             end;
   562     CountNonZeroz:= count;
   562     CountNonZeroz:= count;
       
   563 end;
       
   564 
       
   565 function isSteadyPosition(x, y, r, c: LongInt; mask: Longword): boolean;
       
   566 var cnt, i: LongInt;
       
   567 begin
       
   568     cnt:= 0;
       
   569     isSteadyPosition:= false;
       
   570 
       
   571     if ((y and LAND_HEIGHT_MASK) = 0) and (x - r >= 0) and (x + r < LAND_WIDTH) then
       
   572     begin
       
   573         for i:= r - c + 2 to r do
       
   574         begin
       
   575             if (Land[y, x - i] and mask <> 0) then inc(cnt);
       
   576             if (Land[y, x + i] and mask <> 0) then inc(cnt);
       
   577 
       
   578             if cnt >= c then
       
   579             begin
       
   580                 isSteadyPosition:= true;
       
   581                 exit
       
   582             end;
       
   583         end;
       
   584     end;
   563 end;
   585 end;
   564 
   586 
   565 
   587 
   566 function NoGearsToAvoid(mX, mY: LongInt; rX, rY: LongInt): boolean;
   588 function NoGearsToAvoid(mX, mY: LongInt; rX, rY: LongInt): boolean;
   567 var t: PGear;
   589 var t: PGear;
   627                     inc(y);
   649                     inc(y);
   628                 until (y >= cWaterLine) or
   650                 until (y >= cWaterLine) or
   629                         ((not ignoreOverlap) and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) <> 0)) or
   651                         ((not ignoreOverlap) and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) <> 0)) or
   630                         (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, lfLandMask) <> 0));
   652                         (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, lfLandMask) <> 0));
   631 
   653 
   632                 if (y - sy > Gear^.Radius * 2)
   654                 if (y - sy > Gear^.Radius * 2) and (y < cWaterLine)
   633                     and (((Gear^.Kind = gtExplosives)
   655                     and (((Gear^.Kind = gtExplosives)
   634                     and (y < cWaterLine)
   656                         and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60))
   635                     and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60))
   657                         and (isSteadyPosition(x, y+1, Gear^.Radius - 1, 3, $FFFF)))
   636                     and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1, $FFFF) > Gear^.Radius))
   658                     or
   637                 or
   659                         ((Gear^.Kind <> gtExplosives)
   638                     ((Gear^.Kind <> gtExplosives)
   660                         and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 110, 110))
   639                     and (y < cWaterLine)
   661                         )) then
   640                     and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 110, 110))
       
   641                     )) then
       
   642                     begin
   662                     begin
   643                     ar[cnt].X:= x;
   663                     ar[cnt].X:= x;
   644                     if withFall then
   664                     if withFall then
   645                         ar[cnt].Y:= sy + Gear^.Radius
   665                         ar[cnt].Y:= sy + Gear^.Radius
   646                     else
   666                     else