diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index f065e28d93..84a8bbdf6c 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -324,7 +324,7 @@ namespace OpenRA.Traits public interface IPositionableInfo : IOccupySpaceInfo { - bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All); + bool CanEnterCell(World world, Actor self, CPos cell, SubCell subCell = SubCell.FullCell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All); } public interface IPositionable : IOccupySpace diff --git a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs index 73857b9d18..00bacbde33 100644 --- a/OpenRA.Mods.Cnc/Traits/TDGunboat.cs +++ b/OpenRA.Mods.Cnc/Traits/TDGunboat.cs @@ -47,12 +47,9 @@ namespace OpenRA.Mods.Cnc.Traits bool IOccupySpaceInfo.SharesCell { get { return false; } } // Used to determine if actor can spawn - public bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) + public bool CanEnterCell(World world, Actor self, CPos cell, SubCell subCell = SubCell.FullCell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) { - if (!world.Map.Contains(cell)) - return false; - - return true; + return world.Map.Contains(cell); } } diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index c48ef71192..f093e118f0 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -158,7 +158,7 @@ namespace OpenRA.Mods.Common.Traits bool IOccupySpaceInfo.SharesCell { get { return false; } } // Used to determine if an aircraft can spawn landed - public bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) + public bool CanEnterCell(World world, Actor self, CPos cell, SubCell subCell = SubCell.FullCell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) { if (!world.Map.Contains(cell)) return false; @@ -173,6 +173,7 @@ namespace OpenRA.Mods.Common.Traits if (check == BlockedByActor.None) return true; + // Since aircraft don't share cells, we don't pass the subCell parameter return !world.ActorMap.GetActorsAt(cell).Any(x => x != ignoreActor); } diff --git a/OpenRA.Mods.Common/Traits/Crates/Crate.cs b/OpenRA.Mods.Common/Traits/Crates/Crate.cs index 21e147f083..95f4c2a6cb 100644 --- a/OpenRA.Mods.Common/Traits/Crates/Crate.cs +++ b/OpenRA.Mods.Common/Traits/Crates/Crate.cs @@ -40,8 +40,9 @@ namespace OpenRA.Mods.Common.Traits bool IOccupySpaceInfo.SharesCell { get { return false; } } - public bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) + public bool CanEnterCell(World world, Actor self, CPos cell, SubCell subCell = SubCell.FullCell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) { + // Since crates don't share cells and GetAvailableSubCell only returns SubCell.Full or SubCell.Invalid, we ignore the subCell parameter return GetAvailableSubCell(world, cell, ignoreActor, check) != SubCell.Invalid; } diff --git a/OpenRA.Mods.Common/Traits/Husk.cs b/OpenRA.Mods.Common/Traits/Husk.cs index fb5df595ff..28516ff0b6 100644 --- a/OpenRA.Mods.Common/Traits/Husk.cs +++ b/OpenRA.Mods.Common/Traits/Husk.cs @@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits bool IOccupySpaceInfo.SharesCell { get { return false; } } - public bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) + public bool CanEnterCell(World world, Actor self, CPos cell, SubCell subCell = SubCell.FullCell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) { // IPositionable*Info*.CanEnterCell is only ever used for things like exiting production facilities, // all places relevant for husks check IPositionable.CanEnterCell instead, so we can safely set this to true. diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 0180f2e82f..8884b47685 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -86,7 +86,7 @@ namespace OpenRA.Mods.Common.Traits // initialized and used by CanEnterCell Locomotor locomotor; - public bool CanEnterCell(World world, Actor self, CPos cell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) + public bool CanEnterCell(World world, Actor self, CPos cell, SubCell subCell = SubCell.FullCell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) { // PERF: Avoid repeated trait queries on the hot path if (locomotor == null) @@ -96,7 +96,7 @@ namespace OpenRA.Mods.Common.Traits if (locomotor.MovementCostForCell(cell) == short.MaxValue) return false; - return locomotor.CanMoveFreelyInto(self, cell, check, ignoreActor); + return locomotor.CanMoveFreelyInto(self, cell, subCell, check, ignoreActor); } public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) @@ -501,7 +501,7 @@ namespace OpenRA.Mods.Common.Traits public bool CanEnterCell(CPos cell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All) { - return Info.CanEnterCell(self.World, self, cell, ignoreActor, check); + return Info.CanEnterCell(self.World, self, cell, SubCell.FullCell, ignoreActor, check); } #endregion diff --git a/OpenRA.Mods.Common/Traits/Production.cs b/OpenRA.Mods.Common/Traits/Production.cs index c8b4f7a295..68149dd18d 100644 --- a/OpenRA.Mods.Common/Traits/Production.cs +++ b/OpenRA.Mods.Common/Traits/Production.cs @@ -130,7 +130,7 @@ namespace OpenRA.Mods.Common.Traits self.NotifyBlocker(self.Location + s.ExitCell); return mobileInfo == null || - mobileInfo.CanEnterCell(self.World, self, self.Location + s.ExitCell, self); + mobileInfo.CanEnterCell(self.World, self, self.Location + s.ExitCell, ignoreActor: self); } } } diff --git a/OpenRA.Mods.Common/Traits/World/Locomotor.cs b/OpenRA.Mods.Common/Traits/World/Locomotor.cs index 93cd0c0645..cf67bbeb16 100644 --- a/OpenRA.Mods.Common/Traits/World/Locomotor.cs +++ b/OpenRA.Mods.Common/Traits/World/Locomotor.cs @@ -246,6 +246,11 @@ namespace OpenRA.Mods.Common.Traits // Determines whether the actor is blocked by other Actors public bool CanMoveFreelyInto(Actor actor, CPos cell, BlockedByActor check, Actor ignoreActor) + { + return CanMoveFreelyInto(actor, cell, SubCell.FullCell, check, ignoreActor); + } + + public bool CanMoveFreelyInto(Actor actor, CPos cell, SubCell subCell, BlockedByActor check, Actor ignoreActor) { var cellCache = GetCache(cell); var cellFlag = cellCache.CellFlag; @@ -296,7 +301,8 @@ namespace OpenRA.Mods.Common.Traits return false; } - foreach (var otherActor in world.ActorMap.GetActorsAt(cell)) + var otherActors = subCell == SubCell.FullCell ? world.ActorMap.GetActorsAt(cell) : world.ActorMap.GetActorsAt(cell, subCell); + foreach (var otherActor in otherActors) if (IsBlockedBy(actor, otherActor, ignoreActor, check, cellFlag)) return false;