diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 9f4bede314..5e7124b86d 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -53,6 +53,10 @@ namespace OpenRA.Mods.Common.Traits [Desc("Boolean expression defining the condition under which the regular (non-force) move cursor is disabled.")] public readonly BooleanExpression RequireForceMoveCondition = null; + [ConsumedConditionReference] + [Desc("Boolean expression defining the condition under which this actor cannot be nudged by other actors.")] + public readonly BooleanExpression ImmovableCondition = null; + IEnumerable IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { yield return new FacingInit(PreviewFacing); @@ -180,7 +184,9 @@ namespace OpenRA.Mods.Common.Traits INotifyMoving[] notifyMoving; INotifyFinishedMoving[] notifyFinishedMoving; IWrapMove[] moveWrappers; - public bool RequireForceMove; + bool requireForceMove; + + public bool IsImmovable { get; private set; } public bool TurnToMove; public bool IsBlocking { get; private set; } @@ -332,7 +338,7 @@ namespace OpenRA.Mods.Common.Traits public void Nudge(Actor nudger) { - if (IsTraitDisabled || IsTraitPaused || RequireForceMove) + if (IsTraitDisabled || IsTraitPaused || IsImmovable) return; var cell = GetAdjacentCell(nudger.Location); @@ -375,7 +381,7 @@ namespace OpenRA.Mods.Common.Traits return false; var mobile = otherActor.TraitOrDefault(); - if (mobile == null || mobile.IsTraitDisabled || mobile.IsTraitPaused || mobile.RequireForceMove) + if (mobile == null || mobile.IsTraitDisabled || mobile.IsTraitPaused || mobile.IsImmovable) return false; return true; @@ -857,11 +863,22 @@ namespace OpenRA.Mods.Common.Traits if (Info.RequireForceMoveCondition != null) yield return new VariableObserver(RequireForceMoveConditionChanged, Info.RequireForceMoveCondition.Variables); + + if (Info.ImmovableCondition != null) + yield return new VariableObserver(ImmovableConditionChanged, Info.ImmovableCondition.Variables); } void RequireForceMoveConditionChanged(Actor self, IReadOnlyDictionary conditions) { - RequireForceMove = Info.RequireForceMoveCondition.Evaluate(conditions); + requireForceMove = Info.RequireForceMoveCondition.Evaluate(conditions); + } + + void ImmovableConditionChanged(Actor self, IReadOnlyDictionary conditions) + { + var wasImmovable = IsImmovable; + IsImmovable = Info.ImmovableCondition.Evaluate(conditions); + if (wasImmovable != IsImmovable) + self.World.ActorMap.UpdateOccupiedCells(self.OccupiesSpace); } IEnumerable IIssueOrder.Orders @@ -957,7 +974,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 16beb435f5..93cd0c0645 100644 --- a/OpenRA.Mods.Common/Traits/World/Locomotor.cs +++ b/OpenRA.Mods.Common/Traits/World/Locomotor.cs @@ -334,7 +334,7 @@ namespace OpenRA.Mods.Common.Traits self.Owner.Stances[otherActor.Owner] == Stance.Ally) { var mobile = otherActor.TraitOrDefault(); - if (mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.RequireForceMove) + if (mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.IsImmovable) return false; } @@ -487,7 +487,7 @@ namespace OpenRA.Mods.Common.Traits var crushables = actor.TraitsImplementing(); var mobile = actor.OccupiesSpace as Mobile; - var isMovable = mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.RequireForceMove; + var isMovable = mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.IsImmovable; var isMoving = isMovable && mobile.CurrentMovementTypes.HasMovementType(MovementType.Horizontal); if (crushables.Any()) diff --git a/mods/ts/rules/gdi-vehicles.yaml b/mods/ts/rules/gdi-vehicles.yaml index 9f685e4d4c..1190673350 100644 --- a/mods/ts/rules/gdi-vehicles.yaml +++ b/mods/ts/rules/gdi-vehicles.yaml @@ -332,6 +332,7 @@ JUGG: Mobile: Speed: 71 TurnSpeed: 5 + ImmovableCondition: !undeployed RequireForceMoveCondition: !undeployed RevealsShroud: RequiresCondition: !inside-tunnel diff --git a/mods/ts/rules/nod-vehicles.yaml b/mods/ts/rules/nod-vehicles.yaml index 4cfee3dba7..7e3f159d46 100644 --- a/mods/ts/rules/nod-vehicles.yaml +++ b/mods/ts/rules/nod-vehicles.yaml @@ -104,6 +104,7 @@ TTNK: Mobile: TurnSpeed: 5 Speed: 85 + ImmovableCondition: !undeployed RequireForceMoveCondition: !undeployed Health: HP: 35000 @@ -232,6 +233,7 @@ ART2: Mobile: Speed: 71 TurnSpeed: 2 + ImmovableCondition: !undeployed RequireForceMoveCondition: !undeployed RevealsShroud: RequiresCondition: !inside-tunnel diff --git a/mods/ts/rules/shared-vehicles.yaml b/mods/ts/rules/shared-vehicles.yaml index 58bff0d37e..a23a975d5b 100644 --- a/mods/ts/rules/shared-vehicles.yaml +++ b/mods/ts/rules/shared-vehicles.yaml @@ -127,6 +127,7 @@ LPST: Mobile: Speed: 85 TurnSpeed: 5 + ImmovableCondition: !undeployed RequireForceMoveCondition: !undeployed RevealsShroud: RequiresCondition: !inside-tunnel && undeployed