|
|
@ -2,7 +2,7 @@ |
|
|
|
* `EntityIterator` / `TracingIterator` implementation for `KF1_Frontend`. |
|
|
|
* `EntityIterator` / `TracingIterator` implementation for `KF1_Frontend`. |
|
|
|
* Both iterators do essentially the same and can be implemented with |
|
|
|
* Both iterators do essentially the same and can be implemented with |
|
|
|
* a single class. |
|
|
|
* a single class. |
|
|
|
* Copyright 2022 Anton Tarasenko |
|
|
|
* Copyright 2022-2023 Anton Tarasenko |
|
|
|
*------------------------------------------------------------------------------ |
|
|
|
*------------------------------------------------------------------------------ |
|
|
|
* This file is part of Acedia. |
|
|
|
* This file is part of Acedia. |
|
|
|
* |
|
|
|
* |
|
|
@ -112,11 +112,11 @@ protected function Finalizer() |
|
|
|
iterated = false; |
|
|
|
iterated = false; |
|
|
|
// Clear conditions |
|
|
|
// Clear conditions |
|
|
|
// ~ Simple conditions |
|
|
|
// ~ Simple conditions |
|
|
|
pawnsFilter = ITF_Nothing; |
|
|
|
pawnsFilter = IF_Nothing; |
|
|
|
placeablesFilter = ITF_Nothing; |
|
|
|
placeablesFilter = IF_Nothing; |
|
|
|
collidingFilter = ITF_Nothing; |
|
|
|
collidingFilter = IF_Nothing; |
|
|
|
visibleFilter = ITF_Nothing; |
|
|
|
visibleFilter = IF_Nothing; |
|
|
|
staticFilter = ITF_Nothing; |
|
|
|
staticFilter = IF_Nothing; |
|
|
|
// ~ Distance conditions |
|
|
|
// ~ Distance conditions |
|
|
|
distanceCheck = false; |
|
|
|
distanceCheck = false; |
|
|
|
_.memory.Free(shortestLimitation.placeable); |
|
|
|
_.memory.Free(shortestLimitation.placeable); |
|
|
@ -162,7 +162,7 @@ public final function InitializeTracing(Vector start, Vector end) |
|
|
|
} |
|
|
|
} |
|
|
|
startPosition = start; |
|
|
|
startPosition = start; |
|
|
|
endPosition = end; |
|
|
|
endPosition = end; |
|
|
|
collidingFilter = ITF_Have; |
|
|
|
collidingFilter = IF_Have; |
|
|
|
initialized = true; |
|
|
|
initialized = true; |
|
|
|
tracingIterator = true; |
|
|
|
tracingIterator = true; |
|
|
|
} |
|
|
|
} |
|
|
@ -237,30 +237,30 @@ private final function bool ProcessActor( |
|
|
|
if (allowedList.length > 0 && IsAllowed(nextActor, allowedList)) { |
|
|
|
if (allowedList.length > 0 && IsAllowed(nextActor, allowedList)) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (staticFilter == ITF_Have && !nextActor.bStatic) { |
|
|
|
if (staticFilter == IF_Have && !nextActor.bStatic) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (staticFilter == ITF_NotHave && nextActor.bStatic) { |
|
|
|
if (staticFilter == IF_NotHave && nextActor.bStatic) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
isCollidable = (nextActor.bCollideActors || (LevelInfo(nextActor) != none)); |
|
|
|
isCollidable = (nextActor.bCollideActors || (LevelInfo(nextActor) != none)); |
|
|
|
if (collidingFilter == ITF_Have && !isCollidable) { |
|
|
|
if (collidingFilter == IF_Have && !isCollidable) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (collidingFilter == ITF_NotHave && isCollidable) { |
|
|
|
if (collidingFilter == IF_NotHave && isCollidable) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (placeablesFilter == ITF_Have && nextActor.bWorldGeometry) { |
|
|
|
if (placeablesFilter == IF_Have && nextActor.bWorldGeometry) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (placeablesFilter == ITF_NotHave && !nextActor.bWorldGeometry) { |
|
|
|
if (placeablesFilter == IF_NotHave && !nextActor.bWorldGeometry) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
isVisible = IsActorVisible(nextActor); |
|
|
|
isVisible = IsActorVisible(nextActor); |
|
|
|
if (visibleFilter == ITF_Have && !isVisible) { |
|
|
|
if (visibleFilter == IF_Have && !isVisible) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (visibleFilter == ITF_NotHave && isVisible) { |
|
|
|
if (visibleFilter == IF_NotHave && isVisible) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (distanceCheck && !IsCloseEnough(nextActor)) { |
|
|
|
if (distanceCheck && !IsCloseEnough(nextActor)) { |
|
|
@ -395,7 +395,7 @@ private final function TryIterating() |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
core = ServerLevelCore(class'ServerLevelCore'.static.GetInstance()); |
|
|
|
core = ServerLevelCore(class'ServerLevelCore'.static.GetInstance()); |
|
|
|
if (pawnsFilter == ITF_Have) { |
|
|
|
if (pawnsFilter == IF_Have) { |
|
|
|
targetClass = class'Pawn'; |
|
|
|
targetClass = class'Pawn'; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
@ -456,7 +456,7 @@ private final function DoIterate_PickBest( |
|
|
|
// preferable, but only doable if we're also filtering by distance. |
|
|
|
// preferable, but only doable if we're also filtering by distance. |
|
|
|
if (distanceCheck) |
|
|
|
if (distanceCheck) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (collidingFilter == ITF_Have) { |
|
|
|
if (collidingFilter == IF_Have) { |
|
|
|
DoIterate_Colliding(core, targetClass); |
|
|
|
DoIterate_Colliding(core, targetClass); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
@ -466,7 +466,7 @@ private final function DoIterate_PickBest( |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
// If above fails - try to at least limit iteration to dynamic actors |
|
|
|
// If above fails - try to at least limit iteration to dynamic actors |
|
|
|
if (staticFilter == ITF_NotHave) |
|
|
|
if (staticFilter == IF_NotHave) |
|
|
|
{ |
|
|
|
{ |
|
|
|
DoIterate_Dynamic(core, targetClass); |
|
|
|
DoIterate_Dynamic(core, targetClass); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -581,14 +581,13 @@ private final function DoIterate_All( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function Iter Next() |
|
|
|
public function bool Next() |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!initialized) { |
|
|
|
if (!initialized) { |
|
|
|
return self; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
TryIterating(); |
|
|
|
|
|
|
|
currentIndex += 1; |
|
|
|
currentIndex += 1; |
|
|
|
return self; |
|
|
|
return HasFinished(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function AcediaObject Get() |
|
|
|
public function AcediaObject Get() |
|
|
@ -655,11 +654,10 @@ public function bool HasFinished() |
|
|
|
return (currentIndex >= foundActors.length); |
|
|
|
return (currentIndex >= foundActors.length); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function Iter LeaveOnlyNotNone() |
|
|
|
public function LeaveOnlyNotNone() |
|
|
|
{ |
|
|
|
{ |
|
|
|
// We cannot iterate over `none` actors with native iterators, so this |
|
|
|
// We cannot iterate over `none` actors with native iterators, so this |
|
|
|
// condition is automatically satisfied |
|
|
|
// condition is automatically satisfied |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private final function UpdateFilter( |
|
|
|
private final function UpdateFilter( |
|
|
@ -669,8 +667,8 @@ private final function UpdateFilter( |
|
|
|
if (!initialized) return; |
|
|
|
if (!initialized) return; |
|
|
|
if (iterated) return; |
|
|
|
if (iterated) return; |
|
|
|
|
|
|
|
|
|
|
|
if (actualValue == ITF_Nothing) { |
|
|
|
if (actualValue == IF_Nothing) { |
|
|
|
actualValue = ITF_Have; |
|
|
|
actualValue = IF_Have; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (actualValue != newValue) |
|
|
|
else if (actualValue != newValue) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -679,65 +677,54 @@ private final function UpdateFilter( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyPawns() |
|
|
|
public function LeaveOnlyPawns() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(pawnsFilter, ITF_Have); |
|
|
|
UpdateFilter(pawnsFilter, IF_Have); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyNonPawns() |
|
|
|
public function LeaveOnlyNonPawns() |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
UpdateFilter(pawnsFilter, IF_NotHave); |
|
|
|
UpdateFilter(pawnsFilter, ITF_NotHave); |
|
|
|
|
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyPlaceables() |
|
|
|
public function LeaveOnlyPlaceables() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(placeablesFilter, ITF_Have); |
|
|
|
UpdateFilter(placeablesFilter, IF_Have); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyNonPlaceables() |
|
|
|
public function LeaveOnlyNonPlaceables() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(placeablesFilter, ITF_NotHave); |
|
|
|
UpdateFilter(placeablesFilter, IF_NotHave); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyVisible() |
|
|
|
public function LeaveOnlyVisible() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(visibleFilter, ITF_Have); |
|
|
|
UpdateFilter(visibleFilter, IF_Have); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyInvisible() |
|
|
|
public function LeaveOnlyInvisible() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(visibleFilter, ITF_NotHave); |
|
|
|
UpdateFilter(visibleFilter, IF_NotHave); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyColliding() |
|
|
|
public function LeaveOnlyColliding() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(collidingFilter, ITF_Have); |
|
|
|
UpdateFilter(collidingFilter, IF_Have); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyNonColliding() |
|
|
|
public function LeaveOnlyNonColliding() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(collidingFilter, ITF_NotHave); |
|
|
|
UpdateFilter(collidingFilter, IF_NotHave); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyStatic() |
|
|
|
public function LeaveOnlyStatic() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(staticFilter, ITF_Have); |
|
|
|
UpdateFilter(staticFilter, IF_Have); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyDynamic() |
|
|
|
public function LeaveOnlyDynamic() |
|
|
|
{ |
|
|
|
{ |
|
|
|
UpdateFilter(staticFilter, ITF_NotHave); |
|
|
|
UpdateFilter(staticFilter, IF_NotHave); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private function AddDistanceLimitation(NearbyLimitation newLimitation) |
|
|
|
private function AddDistanceLimitation(NearbyLimitation newLimitation) |
|
|
@ -761,15 +748,15 @@ private function AddDistanceLimitation(NearbyLimitation newLimitation) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyNearby( |
|
|
|
public function LeaveOnlyNearby( |
|
|
|
EPlaceable placeable, |
|
|
|
EPlaceable placeable, |
|
|
|
float radius) |
|
|
|
float radius) |
|
|
|
{ |
|
|
|
{ |
|
|
|
local NearbyLimitation newLimitation; |
|
|
|
local NearbyLimitation newLimitation; |
|
|
|
|
|
|
|
|
|
|
|
if (!initialized) return self; |
|
|
|
if (!initialized) return; |
|
|
|
if (iterated) return self; |
|
|
|
if (iterated) return; |
|
|
|
if (placeable == none) return self; |
|
|
|
if (placeable == none) return; |
|
|
|
|
|
|
|
|
|
|
|
placeable.NewRef(); |
|
|
|
placeable.NewRef(); |
|
|
|
newLimitation.placeable = placeable; |
|
|
|
newLimitation.placeable = placeable; |
|
|
@ -777,35 +764,32 @@ public function EntityIterator LeaveOnlyNearby( |
|
|
|
newLimitation.distance = radius; |
|
|
|
newLimitation.distance = radius; |
|
|
|
newLimitation.distanceSquared = radius * radius; |
|
|
|
newLimitation.distanceSquared = radius * radius; |
|
|
|
AddDistanceLimitation(newLimitation); |
|
|
|
AddDistanceLimitation(newLimitation); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyNearbyToLocation( |
|
|
|
public function LeaveOnlyNearbyToLocation( |
|
|
|
Vector location, |
|
|
|
Vector location, |
|
|
|
float radius) |
|
|
|
float radius) |
|
|
|
{ |
|
|
|
{ |
|
|
|
local NearbyLimitation newLimitation; |
|
|
|
local NearbyLimitation newLimitation; |
|
|
|
|
|
|
|
|
|
|
|
if (!initialized) return self; |
|
|
|
if (!initialized) return; |
|
|
|
if (iterated) return self; |
|
|
|
if (iterated) return; |
|
|
|
|
|
|
|
|
|
|
|
newLimitation.location = location; |
|
|
|
newLimitation.location = location; |
|
|
|
newLimitation.distance = radius; |
|
|
|
newLimitation.distance = radius; |
|
|
|
newLimitation.distanceSquared = radius * radius; |
|
|
|
newLimitation.distanceSquared = radius * radius; |
|
|
|
AddDistanceLimitation(newLimitation); |
|
|
|
AddDistanceLimitation(newLimitation); |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function EntityIterator LeaveOnlyTouching(EPlaceable placeable) |
|
|
|
public function LeaveOnlyTouching(EPlaceable placeable) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!initialized) return self; |
|
|
|
if (!initialized) return; |
|
|
|
if (iterated) return self; |
|
|
|
if (iterated) return; |
|
|
|
if (placeable == none) return self; |
|
|
|
if (placeable == none) return; |
|
|
|
|
|
|
|
|
|
|
|
touchingCheck = true; |
|
|
|
touchingCheck = true; |
|
|
|
placeable.NewRef(); |
|
|
|
placeable.NewRef(); |
|
|
|
touchers[touchers.length] = placeable; |
|
|
|
touchers[touchers.length] = placeable; |
|
|
|
return self; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
defaultproperties |
|
|
|
defaultproperties |
|
|
|