From 7e7d94ca8938050adff9321a789a6467a5afdc1f Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Sat, 13 Aug 2022 11:37:57 +0100 Subject: [PATCH] Fix Locomotor CellCache to not consider transit only cells as crushable. 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. --- OpenRA.Mods.Common/Traits/World/Locomotor.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/World/Locomotor.cs b/OpenRA.Mods.Common/Traits/World/Locomotor.cs index 8fc0712929..59f8c866a7 100644 --- a/OpenRA.Mods.Common/Traits/World/Locomotor.cs +++ b/OpenRA.Mods.Common/Traits/World/Locomotor.cs @@ -252,8 +252,10 @@ namespace OpenRA.Mods.Common.Traits 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) @@ -485,10 +487,7 @@ namespace OpenRA.Mods.Common.Traits var isTransitOnly = actor.OccupiesSpace is Building building && building.TransitOnlyCells().Contains(cell); if (isTransitOnly) - { cellFlag |= CellFlag.HasTransitOnlyActor; - continue; - } if (crushables.Any()) {