Skip to content

Commit

Permalink
Fix Locomotor CellCache to not consider transit only cells as crushable.
Browse files Browse the repository at this point in the history
When the UpdateCellBlocking encountered a transit-only cell (the bibs around a building) it would bail from the loop. This would leave the cellCrushablePlayers set to all players. It would update the cell cache and mark that cell as a crushable location.

When CanMoveFreelyInto would later evaluate a cell, it would consider it passable because the crushable check would pass (cellCache.Crushable.Overlaps(actor.Owner.PlayerMask)) rather than because the transit check (otherActor.OccupiesSpace is Building building && building.TransitOnlyCells().Contains(cell)) would pass.

Although this meant the cell was treated as passable in either scenario, it means the cache contained incorrect data. The cell does not contain any crushable actors but the cache would indicate it did. Correcting this means we can rely on the crushability information stored in the cache to be accurate.
  • Loading branch information
RoosterDragon committed Aug 31, 2022
1 parent 16babc1 commit 44e9310
Showing 1 changed file with 4 additions and 5 deletions.
9 changes: 4 additions & 5 deletions OpenRA.Mods.Common/Traits/World/Locomotor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,10 @@ public bool CanMoveFreelyInto(Actor actor, CPos cell, SubCell subCell, BlockedBy
if (check <= BlockedByActor.Immovable && !cellCache.Immovable.Overlaps(actor.Owner.PlayerMask))
return true;

// Cache doesn't account for ignored actors, temporary blockers, or subcells - these must use the slow path.
if (ignoreActor == null && !cellFlag.HasCellFlag(CellFlag.HasTemporaryBlocker) && subCell == SubCell.FullCell)
// Cache doesn't account for ignored actors, subcells, temporary blockers or transit only actors.
// These must use the slow path.
if (ignoreActor == null && subCell == SubCell.FullCell &&
!cellFlag.HasCellFlag(CellFlag.HasTemporaryBlocker) && !cellFlag.HasCellFlag(CellFlag.HasTransitOnlyActor))
{
// We already know there are uncrushable actors in the cell so we are always blocked.
if (check == BlockedByActor.All)
Expand Down Expand Up @@ -485,10 +487,7 @@ void UpdateCellBlocking(CPos cell)
var isTransitOnly = actor.OccupiesSpace is Building building && building.TransitOnlyCells().Contains(cell);

if (isTransitOnly)
{
cellFlag |= CellFlag.HasTransitOnlyActor;
continue;
}

if (crushables.Any())
{
Expand Down

0 comments on commit 44e9310

Please sign in to comment.