diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index aab482ad1a..78a2848592 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -16,6 +16,7 @@ using OpenRA.Activities; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Pathfinder; using OpenRA.Primitives; +using OpenRA.Support; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -48,6 +49,10 @@ namespace OpenRA.Mods.Common.Traits [Desc("Display order for the facing slider in the map editor")] public readonly int EditorFacingDisplayOrder = 3; + [ConsumedConditionReference] + [Desc("Boolean expression defining the condition under which the regular (non-force) move cursor is disabled.")] + public readonly BooleanExpression RequireForceMoveCondition = null; + IEnumerable IActorPreviewInitInfo.ActorPreviewInits(ActorInfo ai, ActorPreviewType type) { yield return new FacingInit(PreviewFacing); @@ -124,7 +129,7 @@ namespace OpenRA.Mods.Common.Traits } public class Mobile : PausableConditionalTrait, IIssueOrder, IResolveOrder, IOrderVoice, IPositionable, IMove, ITick, - IFacing, IDeathActorInitModifier, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, IActorPreviewInitModifier, INotifyBecomingIdle + IFacing, IDeathActorInitModifier, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, IActorPreviewInitModifier, INotifyBecomingIdle, IObservesVariables { readonly Actor self; readonly Lazy> speedModifiers; @@ -158,6 +163,7 @@ namespace OpenRA.Mods.Common.Traits INotifyMoving[] notifyMoving; INotifyFinishedMoving[] notifyFinishedMoving; IWrapMove[] moveWrappers; + bool requireForceMove; #region IFacing [Sync] @@ -746,6 +752,17 @@ namespace OpenRA.Mods.Common.Traits Nudge(self, blocking, true); } + IEnumerable IObservesVariables.GetVariableObservers() + { + if (Info.RequireForceMoveCondition != null) + yield return new VariableObserver(RequireForceMoveConditionChanged, Info.RequireForceMoveCondition.Variables); + } + + void RequireForceMoveConditionChanged(Actor self, IReadOnlyDictionary conditions) + { + requireForceMove = Info.RequireForceMoveCondition.Evaluate(conditions); + } + IEnumerable IIssueOrder.Orders { get @@ -836,7 +853,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) + 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/mods/ts/rules/gdi-vehicles.yaml b/mods/ts/rules/gdi-vehicles.yaml index 3e88775924..c9c914b4cf 100644 --- a/mods/ts/rules/gdi-vehicles.yaml +++ b/mods/ts/rules/gdi-vehicles.yaml @@ -331,6 +331,7 @@ JUGG: Speed: 71 TurnSpeed: 5 PauseOnCondition: empdisable || being-captured + RequireForceMoveCondition: !undeployed RevealsShroud: RequiresCondition: !inside-tunnel Range: 9c0 diff --git a/mods/ts/rules/nod-vehicles.yaml b/mods/ts/rules/nod-vehicles.yaml index 12fe1e5e4a..165cbf2aad 100644 --- a/mods/ts/rules/nod-vehicles.yaml +++ b/mods/ts/rules/nod-vehicles.yaml @@ -105,6 +105,7 @@ TTNK: TurnSpeed: 5 Speed: 85 PauseOnCondition: empdisable || being-captured + RequireForceMoveCondition: !undeployed Health: HP: 35000 Armor: @@ -227,6 +228,7 @@ ART2: Speed: 71 TurnSpeed: 2 PauseOnCondition: empdisable || being-captured + RequireForceMoveCondition: !undeployed RevealsShroud: RequiresCondition: !inside-tunnel Range: 9c0 diff --git a/mods/ts/rules/shared-vehicles.yaml b/mods/ts/rules/shared-vehicles.yaml index 1dca7fb96e..1aa6ec08ef 100644 --- a/mods/ts/rules/shared-vehicles.yaml +++ b/mods/ts/rules/shared-vehicles.yaml @@ -127,6 +127,7 @@ LPST: Speed: 85 TurnSpeed: 5 PauseOnCondition: empdisable || being-captured + RequireForceMoveCondition: !undeployed RevealsShroud: RequiresCondition: !inside-tunnel && undeployed Range: 10c0