diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index a47959423c..8608128463 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -331,8 +331,7 @@ namespace OpenRA.Mods.Common.Activities else { var cellInfo = notStupidCells - .SelectMany(c => self.World.ActorMap.GetActorsAt(c) - .Where(a => a.IsIdle && a.Info.HasTraitInfo()), + .SelectMany(c => self.World.ActorMap.GetActorsAt(c).Where(Mobile.Ismovable), (c, a) => new { Cell = c, Actor = a }) .RandomOrDefault(self.World.SharedRandom); if (cellInfo != null) diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 51feeb27ad..2cfebd2bfc 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -180,7 +180,7 @@ namespace OpenRA.Mods.Common.Traits INotifyMoving[] notifyMoving; INotifyFinishedMoving[] notifyFinishedMoving; IWrapMove[] moveWrappers; - bool requireForceMove; + public bool RequireForceMove; public bool TurnToMove; public bool IsBlocking { get; private set; } @@ -308,11 +308,31 @@ namespace OpenRA.Mods.Common.Traits self.World.RemoveFromMaps(self, this); } + protected override void TraitEnabled(Actor self) + { + self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace); + } + + protected override void TraitDisabled(Actor self) + { + self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace); + } + + protected override void TraitResumed(Actor self) + { + self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace); + } + + protected override void TraitPaused(Actor self) + { + self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace); + } + #region Local misc stuff public void Nudge(Actor self, Actor nudger, bool force) { - if (IsTraitDisabled || IsTraitPaused || requireForceMove) + if (IsTraitDisabled || IsTraitPaused || RequireForceMove) return; // Pick an adjacent available cell. @@ -342,8 +362,7 @@ namespace OpenRA.Mods.Common.Traits else { var cellInfo = notStupidCells - .SelectMany(c => self.World.ActorMap.GetActorsAt(c) - .Where(a => a.IsIdle && a.Info.HasTraitInfo()), + .SelectMany(c => self.World.ActorMap.GetActorsAt(c).Where(Ismovable), (c, a) => new { Cell = c, Actor = a }) .RandomOrDefault(self.World.SharedRandom); @@ -364,6 +383,18 @@ namespace OpenRA.Mods.Common.Traits } } + public static bool Ismovable(Actor otherActor) + { + if (!otherActor.IsIdle) + return false; + + var mobile = otherActor.TraitOrDefault(); + if (mobile == null || mobile.IsTraitDisabled || mobile.IsTraitPaused || mobile.RequireForceMove) + return false; + + return true; + } + public bool IsLeaving() { if (CurrentMovementTypes.HasFlag(MovementType.Horizontal)) @@ -844,7 +875,7 @@ namespace OpenRA.Mods.Common.Traits void RequireForceMoveConditionChanged(Actor self, IReadOnlyDictionary conditions) { - requireForceMove = Info.RequireForceMoveCondition.Evaluate(conditions); + RequireForceMove = Info.RequireForceMoveCondition.Evaluate(conditions); } IEnumerable IIssueOrder.Orders @@ -940,7 +971,7 @@ namespace OpenRA.Mods.Common.Traits public bool CanTarget(Actor self, Target target, List othersAtTarget, ref TargetModifiers modifiers, ref string cursor) { - if (rejectMove || target.Type != TargetType.Terrain || (mobile.requireForceMove && !modifiers.HasModifier(TargetModifiers.ForceMove))) + if (rejectMove || target.Type != TargetType.Terrain || (mobile.RequireForceMove && !modifiers.HasModifier(TargetModifiers.ForceMove))) return false; var location = self.World.Map.CellContaining(target.CenterPosition); diff --git a/OpenRA.Mods.Common/Traits/World/Locomotor.cs b/OpenRA.Mods.Common/Traits/World/Locomotor.cs index 392fd88d47..16beb435f5 100644 --- a/OpenRA.Mods.Common/Traits/World/Locomotor.cs +++ b/OpenRA.Mods.Common/Traits/World/Locomotor.cs @@ -331,9 +331,12 @@ namespace OpenRA.Mods.Common.Traits // If the check allows: We are not blocked by units that we can force to move out of the way. if (check <= BlockedByActor.Immovable && cellFlag.HasCellFlag(CellFlag.HasMovableActor) && - self.Owner.Stances[otherActor.Owner] == Stance.Ally && - otherActor.TraitOrDefault() != null) - return false; + self.Owner.Stances[otherActor.Owner] == Stance.Ally) + { + var mobile = otherActor.TraitOrDefault(); + if (mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.RequireForceMove) + return false; + } // If the check allows: we are not blocked by moving units. if (check <= BlockedByActor.Stationary && cellFlag.HasCellFlag(CellFlag.HasMovingActor) && @@ -484,7 +487,7 @@ namespace OpenRA.Mods.Common.Traits var crushables = actor.TraitsImplementing(); var mobile = actor.OccupiesSpace as Mobile; - var isMovable = mobile != null; + var isMovable = mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.RequireForceMove; var isMoving = isMovable && mobile.CurrentMovementTypes.HasMovementType(MovementType.Horizontal); if (crushables.Any())