diff --git a/OpenRA.Mods.Common/Activities/RepairBuilding.cs b/OpenRA.Mods.Common/Activities/RepairBuilding.cs index 3a88543503..e364f832ad 100644 --- a/OpenRA.Mods.Common/Activities/RepairBuilding.cs +++ b/OpenRA.Mods.Common/Activities/RepairBuilding.cs @@ -21,6 +21,7 @@ namespace OpenRA.Mods.Common.Activities Actor enterActor; IHealth enterHealth; + EngineerRepairable enterEngineerRepariable; public RepairBuilding(Actor self, Target target, EngineerRepairInfo info) : base(self, target, Color.Yellow) @@ -32,11 +33,12 @@ namespace OpenRA.Mods.Common.Activities { enterActor = targetActor; enterHealth = targetActor.TraitOrDefault(); + enterEngineerRepariable = targetActor.TraitOrDefault(); // Make sure we can still repair the target before entering // (but not before, because this may stop the actor in the middle of nowhere) var stance = self.Owner.Stances[enterActor.Owner]; - if (enterHealth == null || enterHealth.DamageState == DamageState.Undamaged || !info.ValidStances.HasStance(stance)) + if (enterHealth == null || enterHealth.DamageState == DamageState.Undamaged || enterEngineerRepariable == null || enterEngineerRepariable.IsTraitDisabled || !info.ValidStances.HasStance(stance)) { Cancel(self, true); return false; @@ -52,6 +54,9 @@ namespace OpenRA.Mods.Common.Activities if (targetActor != enterActor) return; + if (enterEngineerRepariable.IsTraitDisabled) + return; + if (enterHealth.DamageState == DamageState.Undamaged) return; diff --git a/OpenRA.Mods.Common/Traits/EngineerRepair.cs b/OpenRA.Mods.Common/Traits/EngineerRepair.cs index 6e1df7c529..3cf150b3d8 100644 --- a/OpenRA.Mods.Common/Traits/EngineerRepair.cs +++ b/OpenRA.Mods.Common/Traits/EngineerRepair.cs @@ -108,11 +108,11 @@ namespace OpenRA.Mods.Common.Traits public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) { - var engineerRepairable = target.Info.TraitInfoOrDefault(); - if (engineerRepairable == null) + var engineerRepairable = target.TraitOrDefault(); + if (engineerRepairable == null || engineerRepairable.IsTraitDisabled) return false; - if (!engineerRepairable.Types.IsEmpty && !engineerRepairable.Types.Overlaps(info.Types)) + if (!engineerRepairable.Info.Types.IsEmpty && !engineerRepairable.Info.Types.Overlaps(info.Types)) return false; if (!info.ValidStances.HasStance(self.Owner.Stances[target.Owner])) @@ -126,6 +126,10 @@ namespace OpenRA.Mods.Common.Traits public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) { + // TODO: FrozenActors don't yet have a way of caching conditions, so we can't filter disabled traits + // This therefore assumes that all EngineerRepairable traits are enabled, which is probably wrong. + // Actors with FrozenUnderFog should therefore not disable the EngineerRepairable trait if + // ValidStances includes Enemy actors. var engineerRepairable = target.Info.TraitInfoOrDefault(); if (engineerRepairable == null) return false; diff --git a/OpenRA.Mods.Common/Traits/EngineerRepairable.cs b/OpenRA.Mods.Common/Traits/EngineerRepairable.cs index 6105ceafc7..3d9fcca231 100644 --- a/OpenRA.Mods.Common/Traits/EngineerRepairable.cs +++ b/OpenRA.Mods.Common/Traits/EngineerRepairable.cs @@ -17,11 +17,17 @@ namespace OpenRA.Mods.Common.Traits public class EngineerRepairType { } [Desc("Eligible for instant repair.")] - class EngineerRepairableInfo : TraitInfo + class EngineerRepairableInfo : ConditionalTraitInfo { [Desc("Actors with these Types under EngineerRepair trait can repair me.")] public readonly BitSet Types = default(BitSet); + + public override object Create(ActorInitializer init) { return new EngineerRepairable(init, this); } } - class EngineerRepairable { } + class EngineerRepairable : ConditionalTrait + { + public EngineerRepairable(ActorInitializer init, EngineerRepairableInfo info) + : base(info) { } + } }