diff --git a/OpenRA.Mods.Cnc/Traits/SupportPowers/IonCannonPower.cs b/OpenRA.Mods.Cnc/Traits/SupportPowers/IonCannonPower.cs index ebdd6a346d..03cc029aaf 100644 --- a/OpenRA.Mods.Cnc/Traits/SupportPowers/IonCannonPower.cs +++ b/OpenRA.Mods.Cnc/Traits/SupportPowers/IonCannonPower.cs @@ -47,7 +47,11 @@ namespace OpenRA.Mods.Cnc.Traits public readonly string OnFireSound = null; public override object Create(ActorInitializer init) { return new IonCannonPower(init.Self, this); } - public void RulesetLoaded(Ruleset rules, ActorInfo ai) { WeaponInfo = rules.Weapons[Weapon.ToLowerInvariant()]; } + public override void RulesetLoaded(Ruleset rules, ActorInfo ai) + { + WeaponInfo = rules.Weapons[Weapon.ToLowerInvariant()]; + base.RulesetLoaded(rules, ai); + } } class IonCannonPower : SupportPower diff --git a/OpenRA.Mods.Common/AI/BaseBuilder.cs b/OpenRA.Mods.Common/AI/BaseBuilder.cs index 4f4ac164f7..92c7b711c5 100644 --- a/OpenRA.Mods.Common/AI/BaseBuilder.cs +++ b/OpenRA.Mods.Common/AI/BaseBuilder.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Mods.Common.Traits; +using OpenRA.Support; using OpenRA.Traits; namespace OpenRA.Mods.Common.AI @@ -193,7 +194,7 @@ namespace OpenRA.Mods.Common.AI bool HasSufficientPowerForActor(ActorInfo actorInfo) { - return (actorInfo.TraitInfos().Where(i => i.UpgradeMinEnabledLevel < 1) + return (actorInfo.TraitInfos().Where(i => i.EnabledByDefault) .Sum(p => p.Amount) + playerPower.ExcessPower) >= ai.Info.MinimumExcessPower; } @@ -203,12 +204,12 @@ namespace OpenRA.Mods.Common.AI // This gets used quite a bit, so let's cache it here var power = GetProducibleBuilding(ai.Info.BuildingCommonNames.Power, buildableThings, - a => a.TraitInfos().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(p => p.Amount)); + a => a.TraitInfos().Where(i => i.EnabledByDefault).Sum(p => p.Amount)); // First priority is to get out of a low power situation if (playerPower.ExcessPower < ai.Info.MinimumExcessPower) { - if (power != null && power.TraitInfos().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(p => p.Amount) > 0) + if (power != null && power.TraitInfos().Where(i => i.EnabledByDefault).Sum(p => p.Amount) > 0) { HackyAI.BotDebug("AI: {0} decided to build {1}: Priority override (low power)", queue.Actor.Owner, power.Name); return power; @@ -314,7 +315,7 @@ namespace OpenRA.Mods.Common.AI if (playerPower.ExcessPower < ai.Info.MinimumExcessPower || !HasSufficientPowerForActor(actor)) { // Try building a power plant instead - if (power != null && power.TraitInfos().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(pi => pi.Amount) > 0) + if (power != null && power.TraitInfos().Where(i => i.EnabledByDefault).Sum(pi => pi.Amount) > 0) { if (playerPower.PowerOutageRemainingTicks > 0) HackyAI.BotDebug("{0} decided to build {1}: Priority override (is low power)", queue.Actor.Owner, power.Name); diff --git a/OpenRA.Mods.Common/Traits/Armament.cs b/OpenRA.Mods.Common/Traits/Armament.cs index fc09205ed1..53423f4e25 100644 --- a/OpenRA.Mods.Common/Traits/Armament.cs +++ b/OpenRA.Mods.Common/Traits/Armament.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits } [Desc("Allows you to attach weapons to the unit (use @IdentifierSuffix for > 1)")] - public class ArmamentInfo : UpgradableTraitInfo, IRulesetLoaded, Requires + public class ArmamentInfo : UpgradableTraitInfo, Requires { public readonly string Name = "primary"; @@ -79,7 +79,7 @@ namespace OpenRA.Mods.Common.Traits public override object Create(ActorInitializer init) { return new Armament(init.Self, this); } - public void RulesetLoaded(Ruleset rules, ActorInfo ai) + public override void RulesetLoaded(Ruleset rules, ActorInfo ai) { WeaponInfo weaponInfo; @@ -91,6 +91,8 @@ namespace OpenRA.Mods.Common.Traits ModifiedRange = new WDist(Util.ApplyPercentageModifiers( WeaponInfo.Range.Length, ai.TraitInfos().Select(m => m.GetRangeModifierDefault()))); + + base.RulesetLoaded(rules, ai); } } diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs b/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs index ddf2ed53b6..5e314d50e8 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackGarrisoned.cs @@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits [PaletteReference] public readonly string MuzzlePalette = "effect"; public override object Create(ActorInitializer init) { return new AttackGarrisoned(init.Self, this); } - public void RulesetLoaded(Ruleset rules, ActorInfo ai) + public override void RulesetLoaded(Ruleset rules, ActorInfo ai) { if (PortOffsets.Length == 0) throw new YamlException("PortOffsets must have at least one entry."); @@ -67,6 +67,8 @@ namespace OpenRA.Mods.Common.Traits Cone = PortCones[i], }; } + + base.RulesetLoaded(rules, ai); } } diff --git a/OpenRA.Mods.Common/Traits/Render/RenderRangeCircle.cs b/OpenRA.Mods.Common/Traits/Render/RenderRangeCircle.cs index f2a919b486..10d9d5e7b2 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderRangeCircle.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderRangeCircle.cs @@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits.Render // Defer this lookup until we really need it to ensure we get the correct value. range = Exts.Lazy(() => { - var armaments = ai.TraitInfos().Where(a => a.UpgradeMinEnabledLevel == 0); + var armaments = ai.TraitInfos().Where(a => a.EnabledByDefault); if (!armaments.Any()) return FallbackRange; diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs index 520ef26767..ec779e2cc7 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs @@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits.Render public IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { - if (UpgradeMinEnabledLevel > 0) + if (!EnabledByDefault) yield break; if (Palette != null) diff --git a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs index 2c5ae38056..08e8095ddd 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs @@ -59,7 +59,7 @@ namespace OpenRA.Mods.Common.Traits.Render public IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { - if (UpgradeMinEnabledLevel > 0) + if (!EnabledByDefault) yield break; if (image == null) diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs index 25236c18ef..894ed089c7 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteBarrel.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Traits.Render public IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { - if (UpgradeMinEnabledLevel > 0) + if (!EnabledByDefault) yield break; var body = init.Actor.TraitInfo(); diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs index 2be28793f0..26bc9af9cc 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteBody.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits.Render public virtual IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { - if (UpgradeMinEnabledLevel > 0) + if (!EnabledByDefault) yield break; var anim = new Animation(init.World, image); diff --git a/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs index 17b5603b2b..9bc4e41e79 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithSpriteTurret.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Traits.Render public IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { - if (UpgradeMinEnabledLevel > 0) + if (!EnabledByDefault) yield break; var body = init.Actor.TraitInfo(); diff --git a/OpenRA.Mods.Common/Traits/Render/WithTextDecoration.cs b/OpenRA.Mods.Common/Traits/Render/WithTextDecoration.cs index 6f6c242225..d78a144fd7 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithTextDecoration.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithTextDecoration.cs @@ -20,7 +20,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits.Render { [Desc("Displays a text overlay relative to the selection box.")] - public class WithTextDecorationInfo : UpgradableTraitInfo, IRulesetLoaded + public class WithTextDecorationInfo : UpgradableTraitInfo { [FieldLoader.Require] [Translate] public readonly string Text = null; @@ -47,10 +47,12 @@ namespace OpenRA.Mods.Common.Traits.Render public override object Create(ActorInitializer init) { return new WithTextDecoration(init.Self, this); } - void IRulesetLoaded.RulesetLoaded(Ruleset rules, ActorInfo info) + public override void RulesetLoaded(Ruleset rules, ActorInfo ai) { if (!Game.ModData.Manifest.Fonts.ContainsKey(Font)) throw new YamlException("Font '{0}' is not listed in the mod.yaml's Fonts section".F(Font)); + + base.RulesetLoaded(rules, ai); } } diff --git a/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs b/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs index edfc419ce2..d531e6fa99 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithVoxelBarrel.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits.Render public IEnumerable RenderPreviewVoxels( ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, Func orientation, int facings, PaletteReference p) { - if (UpgradeMinEnabledLevel > 0) + if (!EnabledByDefault) yield break; var body = init.Actor.TraitInfo(); diff --git a/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs index 5a85056013..421e833665 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithVoxelTurret.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits.Render public IEnumerable RenderPreviewVoxels( ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, Func orientation, int facings, PaletteReference p) { - if (UpgradeMinEnabledLevel > 0) + if (!EnabledByDefault) yield break; var body = init.Actor.TraitInfo(); diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs index 2d3423b689..5630466860 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/NukePower.cs @@ -74,7 +74,11 @@ namespace OpenRA.Mods.Common.Traits public WeaponInfo WeaponInfo { get; private set; } public override object Create(ActorInitializer init) { return new NukePower(init.Self, this); } - public void RulesetLoaded(Ruleset rules, ActorInfo ai) { WeaponInfo = rules.Weapons[MissileWeapon.ToLowerInvariant()]; } + public override void RulesetLoaded(Ruleset rules, ActorInfo ai) + { + WeaponInfo = rules.Weapons[MissileWeapon.ToLowerInvariant()]; + base.RulesetLoaded(rules, ai); + } } class NukePower : SupportPower diff --git a/OpenRA.Mods.Common/Traits/Upgrades/UpgradableTrait.cs b/OpenRA.Mods.Common/Traits/Upgrades/UpgradableTrait.cs index 02d94da697..584586a56b 100644 --- a/OpenRA.Mods.Common/Traits/Upgrades/UpgradableTrait.cs +++ b/OpenRA.Mods.Common/Traits/Upgrades/UpgradableTrait.cs @@ -10,12 +10,14 @@ #endregion using System.Collections.Generic; +using System.Linq; +using OpenRA.Support; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { /// Use as base class for *Info to subclass of UpgradableTrait. (See UpgradableTrait.) - public abstract class UpgradableTraitInfo : IUpgradableInfo + public abstract class UpgradableTraitInfo : IUpgradableInfo, IRulesetLoaded { [UpgradeUsedReference] [Desc("The upgrade types which can enable or disable this trait.")] @@ -34,6 +36,16 @@ namespace OpenRA.Mods.Common.Traits public readonly int UpgradeMaxAcceptedLevel = 1; public abstract object Create(ActorInitializer init); + + // HACK: A shim for all the ActorPreview code that used to query UpgradeMinEnabledLevel directly + // This can go away after we introduce an InitialUpgrades ActorInit and have the traits query the + // condition directly + public bool EnabledByDefault { get; private set; } + + public virtual void RulesetLoaded(Ruleset rules, ActorInfo ai) + { + EnabledByDefault = UpgradeMinEnabledLevel < 1; + } } /// diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs index 9a7243ca9d..bcd799f00b 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs @@ -13,6 +13,7 @@ using System; using System.Drawing; using System.Linq; using OpenRA.Mods.Common.Traits; +using OpenRA.Support; using OpenRA.Traits; using OpenRA.Widgets; @@ -74,7 +75,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var requiresString = prereqs.Any() ? requiresLabel.Text.F(prereqs.JoinWith(", ")) : ""; requiresLabel.GetText = () => requiresString; - var power = actor.TraitInfos().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(i => i.Amount); + var power = actor.TraitInfos().Where(i => i.EnabledByDefault).Sum(i => i.Amount); var powerString = power.ToString(); powerLabel.GetText = () => powerString; powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0)