Allow move orders to cancel DeployForGrantedCondition.
This commit is contained in:
@@ -19,49 +19,71 @@ namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
readonly GrantConditionOnDeploy deploy;
|
||||
readonly bool canTurn;
|
||||
readonly bool moving;
|
||||
bool initiated;
|
||||
|
||||
public DeployForGrantedCondition(Actor self, GrantConditionOnDeploy deploy)
|
||||
public DeployForGrantedCondition(Actor self, GrantConditionOnDeploy deploy, bool moving = false)
|
||||
{
|
||||
this.deploy = deploy;
|
||||
this.moving = moving;
|
||||
canTurn = self.Info.HasTraitInfo<IFacingInfo>();
|
||||
}
|
||||
|
||||
protected override void OnFirstRun(Actor self)
|
||||
{
|
||||
// Turn to the required facing.
|
||||
if (deploy.Info.Facing != -1 && canTurn)
|
||||
if (deploy.DeployState == DeployState.Undeployed && deploy.Info.Facing != -1 && canTurn && !moving)
|
||||
QueueChild(self, new Turn(self, deploy.Info.Facing));
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
// Do turn first, if needed.
|
||||
if (ChildActivity != null)
|
||||
{
|
||||
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
|
||||
return this;
|
||||
if (ChildActivity != null)
|
||||
return this;
|
||||
}
|
||||
|
||||
// Without this, turn for facing deploy angle will be canceled and immediately deploy!
|
||||
if (IsCanceling)
|
||||
if (IsCanceling || initiated || (deploy.DeployState != DeployState.Deployed && moving))
|
||||
return NextActivity;
|
||||
|
||||
if (IsInterruptible)
|
||||
{
|
||||
IsInterruptible = false; // must DEPLOY from now.
|
||||
deploy.Deploy();
|
||||
return this;
|
||||
}
|
||||
QueueChild(self, new DeployInner(self, deploy), true);
|
||||
|
||||
initiated = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class DeployInner : Activity
|
||||
{
|
||||
readonly GrantConditionOnDeploy deployment;
|
||||
bool initiated;
|
||||
|
||||
public DeployInner(Actor self, GrantConditionOnDeploy deployment)
|
||||
{
|
||||
this.deployment = deployment;
|
||||
|
||||
// Once deployment animation starts, the animation must finish.
|
||||
IsInterruptible = false;
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
// Wait for deployment
|
||||
if (deploy.DeployState == DeployState.Deploying)
|
||||
if (deployment.DeployState == DeployState.Deploying || deployment.DeployState == DeployState.Undeploying)
|
||||
return this;
|
||||
|
||||
// Failed or success, we are going to NextActivity.
|
||||
// Deploy() at the first run would have put DeployState == Deploying so
|
||||
// if we are back to DeployState.Undeployed, it means deploy failure.
|
||||
// Parent activity will see the status and will take appropriate action.
|
||||
return NextActivity;
|
||||
if (initiated)
|
||||
return NextActivity;
|
||||
|
||||
if (deployment.DeployState == DeployState.Undeployed)
|
||||
deployment.Deploy();
|
||||
else
|
||||
deployment.Undeploy();
|
||||
|
||||
initiated = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2019 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
public class UndeployForGrantedCondition : Activity
|
||||
{
|
||||
readonly GrantConditionOnDeploy deploy;
|
||||
|
||||
public UndeployForGrantedCondition(Actor self, GrantConditionOnDeploy deploy)
|
||||
{
|
||||
this.deploy = deploy;
|
||||
}
|
||||
|
||||
public override Activity Tick(Actor self)
|
||||
{
|
||||
IsInterruptible = false; // must DEPLOY from now.
|
||||
deploy.Undeploy();
|
||||
|
||||
// Wait for deployment
|
||||
if (deploy.DeployState == DeployState.Undeploying)
|
||||
return this;
|
||||
|
||||
return NextActivity;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Activities;
|
||||
using OpenRA.Mods.Common.Orders;
|
||||
using OpenRA.Traits;
|
||||
@@ -54,6 +55,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Skip make/deploy animation?")]
|
||||
public readonly bool SkipMakeAnimation = false;
|
||||
|
||||
[Desc("Undeploy before the actor tries to move?")]
|
||||
public readonly bool UndeployOnMove = false;
|
||||
|
||||
[VoiceReference]
|
||||
public readonly string Voice = "Action";
|
||||
|
||||
@@ -63,11 +67,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public enum DeployState { Undeployed, Deploying, Deployed, Undeploying }
|
||||
|
||||
public class GrantConditionOnDeploy : PausableConditionalTrait<GrantConditionOnDeployInfo>, IResolveOrder, IIssueOrder, INotifyCreated,
|
||||
INotifyDeployComplete, IIssueDeployOrder, IOrderVoice
|
||||
INotifyDeployComplete, IIssueDeployOrder, IOrderVoice, IWrapMove
|
||||
{
|
||||
readonly Actor self;
|
||||
readonly bool checkTerrainType;
|
||||
readonly bool canTurn;
|
||||
readonly IMove move;
|
||||
|
||||
DeployState deployState;
|
||||
ConditionManager conditionManager;
|
||||
@@ -83,6 +88,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
self = init.Self;
|
||||
checkTerrainType = info.AllowedTerrainTypes.Count > 0;
|
||||
canTurn = self.Info.HasTraitInfo<IFacingInfo>();
|
||||
move = self.TraitOrDefault<IMove>();
|
||||
if (init.Contains<DeployStateInit>())
|
||||
deployState = init.Get<DeployStateInit, DeployState>();
|
||||
}
|
||||
@@ -118,20 +124,32 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IOrderTargeter> Orders
|
||||
Activity IWrapMove.WrapMove(Activity moveInner)
|
||||
{
|
||||
// Note: We can't assume anything about the current deploy state
|
||||
// because WrapMove may be called for a queued order
|
||||
if (!Info.UndeployOnMove)
|
||||
return moveInner;
|
||||
|
||||
var activity = new DeployForGrantedCondition(self, this, true);
|
||||
activity.Queue(self, moveInner);
|
||||
return activity;
|
||||
}
|
||||
|
||||
IEnumerable<IOrderTargeter> IIssueOrder.Orders
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsTraitDisabled)
|
||||
yield return new DeployOrderTargeter("GrantConditionOnDeploy", 5,
|
||||
() => IsCursorBlocked() ? Info.DeployBlockedCursor : Info.DeployCursor);
|
||||
() => CanDeploy() ? Info.DeployCursor : Info.DeployBlockedCursor);
|
||||
}
|
||||
}
|
||||
|
||||
public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
|
||||
{
|
||||
if (order.OrderID == "GrantConditionOnDeploy")
|
||||
return new Order(order.OrderID, self, queued);
|
||||
return new Order(order.OrderID, self, target, queued);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -148,16 +166,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (IsTraitDisabled || IsTraitPaused)
|
||||
return;
|
||||
|
||||
if (order.OrderString != "GrantConditionOnDeploy" || deployState == DeployState.Deploying || deployState == DeployState.Undeploying)
|
||||
if (order.OrderString != "GrantConditionOnDeploy")
|
||||
return;
|
||||
|
||||
if (!order.Queued)
|
||||
self.CancelActivity();
|
||||
|
||||
if (deployState == DeployState.Deployed)
|
||||
self.QueueActivity(new UndeployForGrantedCondition(self, this));
|
||||
else if (deployState == DeployState.Undeployed)
|
||||
self.QueueActivity(new DeployForGrantedCondition(self, this));
|
||||
self.QueueActivity(order.Queued, new DeployForGrantedCondition(self, this));
|
||||
}
|
||||
|
||||
public string VoicePhraseForOrder(Actor self, Order order)
|
||||
@@ -165,12 +177,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return order.OrderString == "GrantConditionOnDeploy" ? Info.Voice : null;
|
||||
}
|
||||
|
||||
bool IsCursorBlocked()
|
||||
bool CanDeploy()
|
||||
{
|
||||
if (IsTraitPaused)
|
||||
return true;
|
||||
if (IsTraitPaused || IsTraitDisabled)
|
||||
return false;
|
||||
|
||||
return !IsValidTerrain(self.Location) && (deployState != DeployState.Deployed);
|
||||
return IsValidTerrain(self.Location) || (deployState == DeployState.Deployed);
|
||||
}
|
||||
|
||||
public bool IsValidTerrain(CPos location)
|
||||
|
||||
@@ -157,6 +157,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
INotifyVisualPositionChanged[] notifyVisualPositionChanged;
|
||||
INotifyMoving[] notifyMoving;
|
||||
INotifyFinishedMoving[] notifyFinishedMoving;
|
||||
IWrapMove[] moveWrappers;
|
||||
|
||||
#region IFacing
|
||||
[Sync]
|
||||
@@ -227,6 +228,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
notifyVisualPositionChanged = self.TraitsImplementing<INotifyVisualPositionChanged>().ToArray();
|
||||
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
|
||||
notifyFinishedMoving = self.TraitsImplementing<INotifyFinishedMoving>().ToArray();
|
||||
moveWrappers = self.TraitsImplementing<IWrapMove>().ToArray();
|
||||
|
||||
base.Created(self);
|
||||
}
|
||||
@@ -499,32 +501,41 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
#region IMove
|
||||
|
||||
Activity WrapMove(Activity inner)
|
||||
{
|
||||
var moveWrapper = moveWrappers.FirstOrDefault(Exts.IsTraitEnabled);
|
||||
if (moveWrapper != null)
|
||||
return moveWrapper.WrapMove(inner);
|
||||
|
||||
return inner;
|
||||
}
|
||||
|
||||
public Activity MoveTo(CPos cell, int nearEnough)
|
||||
{
|
||||
return new Move(self, cell, WDist.FromCells(nearEnough));
|
||||
return WrapMove(new Move(self, cell, WDist.FromCells(nearEnough), null));
|
||||
}
|
||||
|
||||
public Activity MoveTo(CPos cell, Actor ignoreActor)
|
||||
{
|
||||
return new Move(self, cell, WDist.Zero, ignoreActor);
|
||||
return WrapMove(new Move(self, cell, WDist.Zero, ignoreActor));
|
||||
}
|
||||
|
||||
public Activity MoveWithinRange(Target target, WDist range,
|
||||
WPos? initialTargetPosition = null, Color? targetLineColor = null)
|
||||
{
|
||||
return new MoveWithinRange(self, target, WDist.Zero, range, initialTargetPosition, targetLineColor);
|
||||
return WrapMove(new MoveWithinRange(self, target, WDist.Zero, range, initialTargetPosition, targetLineColor));
|
||||
}
|
||||
|
||||
public Activity MoveWithinRange(Target target, WDist minRange, WDist maxRange,
|
||||
WPos? initialTargetPosition = null, Color? targetLineColor = null)
|
||||
{
|
||||
return new MoveWithinRange(self, target, minRange, maxRange, initialTargetPosition, targetLineColor);
|
||||
return WrapMove(new MoveWithinRange(self, target, minRange, maxRange, initialTargetPosition, targetLineColor));
|
||||
}
|
||||
|
||||
public Activity MoveFollow(Actor self, Target target, WDist minRange, WDist maxRange,
|
||||
WPos? initialTargetPosition = null, Color? targetLineColor = null)
|
||||
{
|
||||
return new Follow(self, target, minRange, maxRange, initialTargetPosition, targetLineColor);
|
||||
return WrapMove(new Follow(self, target, minRange, maxRange, initialTargetPosition, targetLineColor));
|
||||
}
|
||||
|
||||
public Activity MoveIntoWorld(Actor self, CPos cell, SubCell subCell = SubCell.Any)
|
||||
@@ -542,7 +553,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
SetPosition(self, cell, subCell);
|
||||
SetVisualPosition(self, pos);
|
||||
|
||||
return VisualMove(self, pos, self.World.Map.CenterOfSubCell(cell, subCell), cell);
|
||||
return WrapMove(VisualMove(self, pos, self.World.Map.CenterOfSubCell(cell, subCell), cell));
|
||||
}
|
||||
|
||||
public Activity MoveToTarget(Actor self, Target target,
|
||||
@@ -551,7 +562,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (target.Type == TargetType.Invalid)
|
||||
return null;
|
||||
|
||||
return new MoveAdjacentTo(self, target, initialTargetPosition, targetLineColor);
|
||||
return WrapMove(new MoveAdjacentTo(self, target, initialTargetPosition, targetLineColor));
|
||||
}
|
||||
|
||||
public Activity MoveIntoTarget(Actor self, Target target)
|
||||
@@ -561,12 +572,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
// Activity cancels if the target moves by more than half a cell
|
||||
// to avoid problems with the cell grid
|
||||
return new VisualMoveIntoTarget(self, target, new WDist(512));
|
||||
return WrapMove(new VisualMoveIntoTarget(self, target, new WDist(512)));
|
||||
}
|
||||
|
||||
public Activity VisualMove(Actor self, WPos fromPos, WPos toPos)
|
||||
{
|
||||
return VisualMove(self, fromPos, toPos, self.Location);
|
||||
return WrapMove(VisualMove(self, fromPos, toPos, self.Location));
|
||||
}
|
||||
|
||||
public int EstimatedMoveDuration(Actor self, WPos fromPos, WPos toPos)
|
||||
@@ -768,7 +779,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
self.CancelActivity();
|
||||
|
||||
self.SetTargetLine(Target.FromCell(self.World, cell), Color.Green);
|
||||
self.QueueActivity(order.Queued, new Move(self, cell, WDist.FromCells(8), null, true));
|
||||
self.QueueActivity(order.Queued, WrapMove(new Move(self, cell, WDist.FromCells(8), null, true)));
|
||||
}
|
||||
|
||||
if (order.OrderString == "Stop")
|
||||
|
||||
@@ -437,6 +437,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
bool CanEnterTargetNow(Actor self, Target target);
|
||||
}
|
||||
|
||||
public interface IWrapMove
|
||||
{
|
||||
Activity WrapMove(Activity moveInner);
|
||||
}
|
||||
|
||||
public interface IRadarSignature
|
||||
{
|
||||
void PopulateRadarSignatureCells(Actor self, List<Pair<CPos, Color>> destinationBuffer);
|
||||
|
||||
@@ -61,7 +61,7 @@ Container@PLAYER_WIDGETS:
|
||||
Background:
|
||||
DisableKeySound: true
|
||||
TooltipText: Force Move
|
||||
TooltipDesc: Selected units will move to the desired location\n - Default activity for the target is suppressed\n - Vehicles will attempt to crush enemies at the target location\n - Units entering transports will consider nearby alternatives\n - Carryalls will not release their cargo at the target location\n\nLeft-click icon then right-click on target.\nHold {(Alt)} to activate temporarily while commanding units.
|
||||
TooltipDesc: Selected units will move to the desired location\n - Default activity for the target is suppressed\n - Vehicles will attempt to crush enemies at the target location\n - Deployed units will undeploy and move to the target location\n - Units entering transports will consider nearby alternatives\n - Carryalls will not release their cargo at the target location\n\nLeft-click icon then right-click on target.\nHold {(Alt)} to activate temporarily while commanding units.
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipTemplate: BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP
|
||||
Children:
|
||||
|
||||
@@ -330,7 +330,6 @@ JUGG:
|
||||
Mobile:
|
||||
Speed: 71
|
||||
TurnSpeed: 5
|
||||
RequiresCondition: undeployed
|
||||
PauseOnCondition: empdisable || being-captured
|
||||
RevealsShroud:
|
||||
RequiresCondition: !inside-tunnel
|
||||
@@ -352,6 +351,7 @@ JUGG:
|
||||
PauseOnCondition: empdisable || being-captured
|
||||
DeployedCondition: deployed
|
||||
UndeployedCondition: undeployed
|
||||
UndeployOnMove: true
|
||||
Facing: 96
|
||||
AllowedTerrainTypes: Clear, Road, DirtRoad, Rough
|
||||
DeploySounds: place2.aud
|
||||
|
||||
@@ -104,7 +104,6 @@ TTNK:
|
||||
Mobile:
|
||||
TurnSpeed: 5
|
||||
Speed: 85
|
||||
RequiresCondition: undeployed
|
||||
PauseOnCondition: empdisable || being-captured
|
||||
Health:
|
||||
HP: 35000
|
||||
@@ -135,6 +134,7 @@ TTNK:
|
||||
PauseOnCondition: empdisable || being-captured
|
||||
DeployedCondition: deployed
|
||||
UndeployedCondition: undeployed
|
||||
UndeployOnMove: true
|
||||
Facing: 160
|
||||
AllowedTerrainTypes: Clear, Road, DirtRoad, Rough
|
||||
DeploySounds: place2.aud
|
||||
@@ -226,7 +226,6 @@ ART2:
|
||||
Mobile:
|
||||
Speed: 71
|
||||
TurnSpeed: 2
|
||||
RequiresCondition: undeployed
|
||||
PauseOnCondition: empdisable || being-captured
|
||||
RevealsShroud:
|
||||
RequiresCondition: !inside-tunnel
|
||||
@@ -241,6 +240,7 @@ ART2:
|
||||
PauseOnCondition: empdisable || being-captured
|
||||
DeployedCondition: deployed
|
||||
UndeployedCondition: undeployed
|
||||
UndeployOnMove: true
|
||||
Facing: 96
|
||||
AllowedTerrainTypes: Clear, Road, DirtRoad, Rough
|
||||
DeploySounds: place2.aud
|
||||
|
||||
@@ -126,7 +126,6 @@ LPST:
|
||||
Mobile:
|
||||
Speed: 85
|
||||
TurnSpeed: 5
|
||||
RequiresCondition: undeployed
|
||||
PauseOnCondition: empdisable || being-captured
|
||||
RevealsShroud:
|
||||
RequiresCondition: !inside-tunnel && undeployed
|
||||
@@ -148,6 +147,7 @@ LPST:
|
||||
PauseOnCondition: empdisable || being-captured
|
||||
DeployedCondition: deployed
|
||||
UndeployedCondition: undeployed
|
||||
UndeployOnMove: true
|
||||
Facing: 160
|
||||
AllowedTerrainTypes: Clear, Road, DirtRoad, Rough
|
||||
DeploySounds: place2.aud
|
||||
|
||||
Reference in New Issue
Block a user