diff --git a/OpenRA.Mods.Cnc/Traits/Disguise.cs b/OpenRA.Mods.Cnc/Traits/Disguise.cs index 0cd137827d..4f243286f3 100644 --- a/OpenRA.Mods.Cnc/Traits/Disguise.cs +++ b/OpenRA.Mods.Cnc/Traits/Disguise.cs @@ -90,12 +90,20 @@ namespace OpenRA.Mods.Cnc.Traits "Unload, Infiltrate, Demolish, Move.")] public readonly RevealDisguiseType RevealDisguiseOn = RevealDisguiseType.Attack; + [Desc("Conditions to grant when disguised as specified actor.", + "A dictionary of [actor id]: [condition].")] + public readonly Dictionary DisguisedAsConditions = new Dictionary(); + + [GrantedConditionReference] + public IEnumerable LinterConditions { get { return DisguisedAsConditions.Values; } } + public object Create(ActorInitializer init) { return new Disguise(init.Self, this); } } class Disguise : INotifyCreated, IEffectiveOwner, IIssueOrder, IResolveOrder, IOrderVoice, IRadarColorModifier, INotifyAttack, INotifyDamage, INotifyUnload, INotifyDemolition, INotifyInfiltration, ITick { + public ActorInfo AsActor { get; private set; } public Player AsPlayer { get; private set; } public string AsSprite { get; private set; } public ITooltipInfo AsTooltipInfo { get; private set; } @@ -108,6 +116,7 @@ namespace OpenRA.Mods.Cnc.Traits ConditionManager conditionManager; int disguisedToken = ConditionManager.InvalidConditionToken; + int disguisedAsToken = ConditionManager.InvalidConditionToken; CPos? lastPos; public Disguise(Actor self, DisguiseInfo info) @@ -161,8 +170,9 @@ namespace OpenRA.Mods.Cnc.Traits public void DisguiseAs(Actor target) { - var oldDisguiseSetting = Disguised; + var oldEffectiveActor = AsActor; var oldEffectiveOwner = AsPlayer; + var oldDisguiseSetting = Disguised; if (target != null) { @@ -173,6 +183,7 @@ namespace OpenRA.Mods.Cnc.Traits { AsSprite = targetDisguise.AsSprite; AsPlayer = targetDisguise.AsPlayer; + AsActor = targetDisguise.AsActor; AsTooltipInfo = targetDisguise.AsTooltipInfo; } else @@ -180,6 +191,7 @@ namespace OpenRA.Mods.Cnc.Traits AsSprite = target.Trait().GetImage(target); var tooltip = target.TraitsImplementing().FirstOrDefault(); AsPlayer = tooltip.Owner; + AsActor = target.Info; AsTooltipInfo = tooltip.TooltipInfo; } } @@ -187,36 +199,52 @@ namespace OpenRA.Mods.Cnc.Traits { AsTooltipInfo = null; AsPlayer = null; + AsActor = self.Info; AsSprite = null; } - HandleDisguise(oldEffectiveOwner, oldDisguiseSetting); + HandleDisguise(oldEffectiveActor, oldEffectiveOwner, oldDisguiseSetting); } public void DisguiseAs(ActorInfo actorInfo, Player newOwner) { - var oldDisguiseSetting = Disguised; + var oldEffectiveActor = AsActor; var oldEffectiveOwner = AsPlayer; + var oldDisguiseSetting = Disguised; var renderSprites = actorInfo.TraitInfoOrDefault(); AsSprite = renderSprites == null ? null : renderSprites.GetImage(actorInfo, self.World.Map.Rules.Sequences, newOwner.Faction.InternalName); AsPlayer = newOwner; + AsActor = actorInfo; AsTooltipInfo = actorInfo.TraitInfos().FirstOrDefault(); - HandleDisguise(oldEffectiveOwner, oldDisguiseSetting); + HandleDisguise(oldEffectiveActor, oldEffectiveOwner, oldDisguiseSetting); } - void HandleDisguise(Player oldEffectiveOwner, bool oldDisguiseSetting) + void HandleDisguise(ActorInfo oldEffectiveActor, Player oldEffectiveOwner, bool oldDisguiseSetting) { foreach (var t in self.TraitsImplementing()) t.OnEffectiveOwnerChanged(self, oldEffectiveOwner, AsPlayer); - if (Disguised != oldDisguiseSetting && conditionManager != null) + if (conditionManager != null) { - if (Disguised && disguisedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(info.DisguisedCondition)) - disguisedToken = conditionManager.GrantCondition(self, info.DisguisedCondition); - else if (!Disguised && disguisedToken != ConditionManager.InvalidConditionToken) - disguisedToken = conditionManager.RevokeCondition(self, disguisedToken); + if (Disguised != oldDisguiseSetting) + { + if (Disguised && disguisedToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(info.DisguisedCondition)) + disguisedToken = conditionManager.GrantCondition(self, info.DisguisedCondition); + else if (!Disguised && disguisedToken != ConditionManager.InvalidConditionToken) + disguisedToken = conditionManager.RevokeCondition(self, disguisedToken); + } + + if (AsActor != oldEffectiveActor) + { + if (disguisedAsToken != ConditionManager.InvalidConditionToken) + disguisedAsToken = conditionManager.RevokeCondition(self, disguisedAsToken); + + string disguisedAsCondition; + if (info.DisguisedAsConditions.TryGetValue(AsActor.Name, out disguisedAsCondition)) + disguisedAsToken = conditionManager.GrantCondition(self, disguisedAsCondition); + } } }