diff --git a/OpenRA.Mods.Common/Traits/Carryable.cs b/OpenRA.Mods.Common/Traits/Carryable.cs index 8ddfbcad8a..91373ffb5a 100644 --- a/OpenRA.Mods.Common/Traits/Carryable.cs +++ b/OpenRA.Mods.Common/Traits/Carryable.cs @@ -9,7 +9,7 @@ */ #endregion -using OpenRA.Mods.Common.Activities; +using System.Linq; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits @@ -37,6 +37,11 @@ namespace OpenRA.Mods.Common.Traits public enum LockResponse { Success, Pending, Failed } + public interface IDelayCarryallPickup + { + bool TryLockForPickup(Actor self, Actor carrier); + } + public class Carryable : ConditionalTrait { ConditionManager conditionManager; @@ -45,6 +50,7 @@ namespace OpenRA.Mods.Common.Traits int lockedToken = ConditionManager.InvalidConditionToken; Mobile mobile; + IDelayCarryallPickup[] delayPickups; public Actor Carrier { get; private set; } public bool Reserved { get { return state != State.Free; } } @@ -62,6 +68,7 @@ namespace OpenRA.Mods.Common.Traits { conditionManager = self.Trait(); mobile = self.TraitOrDefault(); + delayPickups = self.TraitsImplementing().ToArray(); base.Created(self); } @@ -121,6 +128,9 @@ namespace OpenRA.Mods.Common.Traits if (state == State.Locked && Carrier != carrier) return LockResponse.Failed; + if (delayPickups.Any(d => d.IsTraitEnabled() && !d.TryLockForPickup(self, carrier))) + return LockResponse.Pending; + if (state != State.Locked) { state = State.Locked; diff --git a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs index 792c7ce23f..8fb6bd56ab 100644 --- a/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs +++ b/OpenRA.Mods.Common/Traits/Conditions/GrantConditionOnDeploy.cs @@ -58,6 +58,9 @@ namespace OpenRA.Mods.Common.Traits [Desc("Undeploy before the actor tries to move?")] public readonly bool UndeployOnMove = false; + [Desc("Undeploy before the actor is picked up by a Carryall?")] + public readonly bool UndeployOnPickup = false; + [VoiceReference] public readonly string Voice = "Action"; @@ -87,7 +90,7 @@ namespace OpenRA.Mods.Common.Traits public enum DeployState { Undeployed, Deploying, Deployed, Undeploying } public class GrantConditionOnDeploy : PausableConditionalTrait, IResolveOrder, IIssueOrder, - INotifyDeployComplete, IIssueDeployOrder, IOrderVoice, IWrapMove + INotifyDeployComplete, IIssueDeployOrder, IOrderVoice, IWrapMove, IDelayCarryallPickup { readonly Actor self; readonly bool checkTerrainType; @@ -157,6 +160,17 @@ namespace OpenRA.Mods.Common.Traits return activity; } + bool IDelayCarryallPickup.TryLockForPickup(Actor self, Actor carrier) + { + if (!Info.UndeployOnPickup || deployState == DeployState.Undeployed || IsTraitDisabled) + return true; + + if (deployState == DeployState.Deployed && !IsTraitPaused) + Undeploy(); + + return false; + } + IEnumerable IIssueOrder.Orders { get