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 |