diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 0cb4d73f1a..4c7b5b8eb9 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -83,8 +83,9 @@ namespace OpenRA } } - readonly IRenderModifier[] traitsImplementingRenderModifier; - readonly IRender[] traitsImplementingRender; + readonly IRenderModifier[] renderModifiers; + readonly IRender[] renders; + readonly IDisable[] disables; internal Actor(World world, string name, TypeDictionary initDict) { @@ -126,8 +127,9 @@ namespace OpenRA return new Rectangle(offset.X, offset.Y, size.X, size.Y); }); - traitsImplementingRenderModifier = TraitsImplementing().ToArray(); - traitsImplementingRender = TraitsImplementing().ToArray(); + renderModifiers = TraitsImplementing().ToArray(); + renders = TraitsImplementing().ToArray(); + disables = TraitsImplementing().ToArray(); } public void Tick() @@ -143,14 +145,14 @@ namespace OpenRA public IEnumerable Render(WorldRenderer wr) { var renderables = Renderables(wr); - foreach (var modifier in traitsImplementingRenderModifier) + foreach (var modifier in renderModifiers) renderables = modifier.ModifyRender(this, wr, renderables); return renderables; } IEnumerable Renderables(WorldRenderer wr) { - foreach (var render in traitsImplementingRender) + foreach (var render in renders) foreach (var renderable in render.Render(this, wr)) yield return renderable; } @@ -277,6 +279,14 @@ namespace OpenRA health.Value.InflictDamage(this, attacker, health.Value.MaxHP, null, true); } + public bool IsDisabled() + { + foreach (var disable in disables) + if (disable.Disabled) + return true; + return false; + } + #region Scripting interface Lazy luaInterface; diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 83e96eae68..448c5f8ec7 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -19,8 +19,8 @@ namespace OpenRA.GameRules public class ProjectileArgs { public WeaponInfo Weapon; - public IEnumerable DamageModifiers; - public IEnumerable InaccuracyModifiers; + public int[] DamageModifiers; + public int[] InaccuracyModifiers; public int Facing; public WPos Source; public Actor SourceActor; diff --git a/OpenRA.Game/Traits/CreatesShroud.cs b/OpenRA.Game/Traits/CreatesShroud.cs index 6adcb682aa..2b6a28b5fc 100644 --- a/OpenRA.Game/Traits/CreatesShroud.cs +++ b/OpenRA.Game/Traits/CreatesShroud.cs @@ -37,7 +37,7 @@ namespace OpenRA.Traits if (lobbyShroudFogDisabled) return; - var disabled = self.TraitsImplementing().Any(d => d.Disabled); + var disabled = self.IsDisabled(); if (cachedLocation != self.Location || cachedDisabled != disabled) { cachedLocation = self.Location; diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 015632cef0..253ddc38dc 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -329,14 +329,6 @@ namespace OpenRA.Traits void OnObjectiveFailed(Player player, int objectiveID); } - public static class DisableExts - { - public static bool IsDisabled(this Actor a) - { - return a.TraitsImplementing().Any(d => d.Disabled); - } - } - public interface ILegacyEditorRenderInfo { string EditorPalette { get; } diff --git a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs index ef20515a01..806efaba29 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Activities { readonly Target target; readonly AttackPlane attackPlane; - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; Activity inner; int ticksUntilTurn; @@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Activities { this.target = target; attackPlane = self.TraitOrDefault(); - ammoPools = self.TraitsImplementing(); + ammoPools = self.TraitsImplementing().ToArray(); ticksUntilTurn = attackPlane.AttackPlaneInfo.AttackTurnDelay; } @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Activities // Move to the next activity only if all ammo pools are depleted and none reload automatically // TODO: This should check whether there is ammo left that is actually suitable for the target - if (ammoPools != null && ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo())) + if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo())) return NextActivity; if (attackPlane != null) diff --git a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs index 0e2839bd6f..e9155ecf9f 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs @@ -22,14 +22,14 @@ namespace OpenRA.Mods.Common.Activities readonly Target target; readonly Helicopter helicopter; readonly AttackHeli attackHeli; - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; public HeliAttack(Actor self, Target target) { this.target = target; helicopter = self.Trait(); attackHeli = self.Trait(); - ammoPools = self.TraitsImplementing(); + ammoPools = self.TraitsImplementing().ToArray(); } public override Activity Tick(Actor self) @@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Activities // If all ammo pools are depleted and none reload automatically, return to helipad to reload and then move to next activity // TODO: This should check whether there is ammo left that is actually suitable for the target - if (ammoPools != null && ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo())) + if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo())) return Util.SequenceActivities(new HeliReturn(self), NextActivity); var dist = target.CenterPosition - self.CenterPosition; diff --git a/OpenRA.Mods.Common/Activities/Demolish.cs b/OpenRA.Mods.Common/Activities/Demolish.cs index 1ce0282d2a..c72b89290b 100644 --- a/OpenRA.Mods.Common/Activities/Demolish.cs +++ b/OpenRA.Mods.Common/Activities/Demolish.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities class Demolish : Enter { readonly Actor target; - readonly IEnumerable demolishables; + readonly IDemolishable[] demolishables; readonly int delay; readonly int flashes; readonly int flashesDelay; @@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Activities : base(self, target) { this.target = target; - demolishables = target.TraitsImplementing(); + demolishables = target.TraitsImplementing().ToArray(); this.delay = delay; this.flashes = flashes; this.flashesDelay = flashesDelay; diff --git a/OpenRA.Mods.Common/Activities/Move/Drag.cs b/OpenRA.Mods.Common/Activities/Move/Drag.cs index b4174169c2..0095b9d6c7 100644 --- a/OpenRA.Mods.Common/Activities/Move/Drag.cs +++ b/OpenRA.Mods.Common/Activities/Move/Drag.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities { readonly IPositionable positionable; readonly IMove movement; - readonly IEnumerable moveDisablers; + readonly IDisableMove[] moveDisablers; WPos start, end; int length; int ticks = 0; @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Activities { positionable = self.Trait(); movement = self.TraitOrDefault(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); this.start = start; this.end = end; this.length = length; diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index 53fbaa5998..9092a14af7 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Activities static readonly List NoPath = new List(); readonly Mobile mobile; - readonly IEnumerable moveDisablers; + readonly IDisableMove[] moveDisablers; readonly WRange nearEnough; readonly Func> getPath; readonly Actor ignoredActor; @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, CPos destination) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => self.World.WorldActor.Trait().FindPath( @@ -60,7 +60,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, CPos destination, WRange nearEnough) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => self.World.WorldActor.Trait() .FindUnitPath(mobile.ToCell, destination, self); @@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, CPos destination, SubCell subCell, WRange nearEnough) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => self.World.WorldActor.Trait() .FindUnitPathToRange(mobile.FromCell, subCell, self.World.Map.CenterOfSubCell(destination, subCell), nearEnough, self); @@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, CPos destination, Actor ignoredActor) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => self.World.WorldActor.Trait().FindPath( @@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, Target target, WRange range) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); getPath = () => { @@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Activities public Move(Actor self, Func> getPath) { mobile = self.Trait(); - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); this.getPath = getPath; @@ -315,13 +315,12 @@ namespace OpenRA.Mods.Common.Activities public override Activity Tick(Actor self) { - var mobile = self.Trait(); var ret = InnerTick(self, Move.mobile); - mobile.IsMoving = ret is MovePart; + Move.mobile.IsMoving = ret is MovePart; if (moveFraction > MoveFractionTotal) moveFraction = MoveFractionTotal; - UpdateCenterLocation(self, mobile); + UpdateCenterLocation(self, Move.mobile); return ret; } diff --git a/OpenRA.Mods.Common/Activities/Rearm.cs b/OpenRA.Mods.Common/Activities/Rearm.cs index 3a63d52d94..6c4bace567 100644 --- a/OpenRA.Mods.Common/Activities/Rearm.cs +++ b/OpenRA.Mods.Common/Activities/Rearm.cs @@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities { public class Rearm : Activity { - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; readonly Dictionary ammoPoolsReloadTimes; public Rearm(Actor self) { - ammoPools = self.TraitsImplementing().Where(p => !p.Info.SelfReloads); + ammoPools = self.TraitsImplementing().Where(p => !p.Info.SelfReloads).ToArray(); if (ammoPools == null) return; diff --git a/OpenRA.Mods.Common/Activities/Turn.cs b/OpenRA.Mods.Common/Activities/Turn.cs index bbfc01d302..fe5d986edd 100644 --- a/OpenRA.Mods.Common/Activities/Turn.cs +++ b/OpenRA.Mods.Common/Activities/Turn.cs @@ -17,12 +17,12 @@ namespace OpenRA.Mods.Common.Activities { public class Turn : Activity { - readonly IEnumerable moveDisablers; + readonly IDisableMove[] moveDisablers; readonly int desiredFacing; public Turn(Actor self, int desiredFacing) { - moveDisablers = self.TraitsImplementing(); + moveDisablers = self.TraitsImplementing().ToArray(); this.desiredFacing = desiredFacing; } diff --git a/OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs index a942f8809d..450ec40076 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/PowerProperties.cs @@ -59,12 +59,12 @@ namespace OpenRA.Mods.Common.Scripting [ScriptPropertyGroup("Power")] public class ActorPowerProperties : ScriptActorProperties, Requires { - readonly IEnumerable power; + readonly PowerTrait[] power; public ActorPowerProperties(ScriptContext context, Actor self) : base(context, self) { - power = self.TraitsImplementing(); + power = self.TraitsImplementing().ToArray(); } [Desc("Returns the power drained/provided by this actor.")] diff --git a/OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs index abc5f73f8b..06d4f607f0 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/ProductionProperties.cs @@ -84,13 +84,13 @@ namespace OpenRA.Mods.Common.Scripting [ScriptPropertyGroup("Production")] public class ProductionQueueProperties : ScriptActorProperties, Requires, Requires { - readonly List queues; + readonly ProductionQueue[] queues; readonly ScriptTriggers triggers; public ProductionQueueProperties(ScriptContext context, Actor self) : base(context, self) { - queues = self.TraitsImplementing().Where(q => q.Enabled).ToList(); + queues = self.TraitsImplementing().Where(q => q.Enabled).ToArray(); triggers = TriggerGlobal.GetScriptTriggers(self); } diff --git a/OpenRA.Mods.Common/Traits/Armament.cs b/OpenRA.Mods.Common/Traits/Armament.cs index c28b6453c2..4afb573f11 100644 --- a/OpenRA.Mods.Common/Traits/Armament.cs +++ b/OpenRA.Mods.Common/Traits/Armament.cs @@ -167,10 +167,10 @@ namespace OpenRA.Mods.Common.Traits Facing = legacyFacing, DamageModifiers = self.TraitsImplementing() - .Select(a => a.GetFirepowerModifier()), + .Select(a => a.GetFirepowerModifier()).ToArray(), InaccuracyModifiers = self.TraitsImplementing() - .Select(a => a.GetInaccuracyModifier()), + .Select(a => a.GetInaccuracyModifier()).ToArray(), Source = muzzlePosition, SourceActor = self, diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs index a76bccee40..83057ff250 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs @@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Traits this.self = self; var armaments = Exts.Lazy(() => self.TraitsImplementing() - .Where(a => info.Armaments.Contains(a.Info.Name))); + .Where(a => info.Armaments.Contains(a.Info.Name)).ToArray()); getArmaments = () => armaments.Value; diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs b/OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs index 0badcb0b29..aca0f97111 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackTurreted.cs @@ -9,6 +9,7 @@ #endregion using System.Collections.Generic; +using System.Linq; using OpenRA.Activities; using OpenRA.Traits; @@ -22,12 +23,12 @@ namespace OpenRA.Mods.Common.Traits public class AttackTurreted : AttackFollow, ITick, ISync { - protected IEnumerable turrets; + protected Turreted[] turrets; public AttackTurreted(Actor self, AttackTurretedInfo info) : base(self, info) { - turrets = self.TraitsImplementing(); + turrets = self.TraitsImplementing().ToArray(); } protected override bool CanAttack(Actor self, Target target) diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index 0d0000c387..78dc552ee2 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -312,6 +312,7 @@ namespace OpenRA.Mods.Common.Traits internal int TicksBeforePathing = 0; readonly Actor self; + readonly ISpeedModifier[] speedModifiers; public readonly MobileInfo Info; public bool IsMoving { get; set; } @@ -351,6 +352,8 @@ namespace OpenRA.Mods.Common.Traits self = init.Self; Info = info; + speedModifiers = self.TraitsImplementing().ToArray(); + ToSubCell = FromSubCell = info.SharesCell ? init.World.Map.DefaultSubCell : SubCell.FullCell; if (init.Contains()) FromSubCell = ToSubCell = init.Get(); @@ -597,7 +600,7 @@ namespace OpenRA.Mods.Common.Traits return 0; speed *= Info.Speed; - foreach (var t in self.TraitsImplementing()) + foreach (var t in speedModifiers) speed *= t.GetSpeedModifier() / 100m; return (int)(speed / 100); diff --git a/OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs b/OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs index fce74db005..f5a36c0daf 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderBuilding.cs @@ -54,11 +54,8 @@ namespace OpenRA.Mods.Common.Traits DefaultAnimation.PlayRepeating(NormalizeSequence(self, info.Sequence)); if (info.PauseOnLowPower) - { - var disabled = self.TraitsImplementing(); - DefaultAnimation.Paused = () => disabled.Any(d => d.Disabled) - && DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, info.Sequence); - } + DefaultAnimation.Paused = () => + self.IsDisabled() && DefaultAnimation.CurrentSequence.Name == NormalizeSequence(self, info.Sequence); } public void PlayCustomAnimThen(Actor self, string name, Action a) diff --git a/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs index a372ee24d9..6a4d93cd75 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithActiveAnimation.cs @@ -30,13 +30,11 @@ namespace OpenRA.Mods.Common.Traits public class WithActiveAnimation : ITick, INotifyBuildComplete, INotifySold { - readonly IEnumerable disabled; readonly WithActiveAnimationInfo info; readonly RenderBuilding renderBuilding; public WithActiveAnimation(Actor self, WithActiveAnimationInfo info) { - disabled = self.TraitsImplementing(); renderBuilding = self.Trait(); this.info = info; } @@ -49,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits if (--ticks <= 0) { - if (!(info.PauseOnLowPower && disabled.Any(d => d.Disabled))) + if (!(info.PauseOnLowPower && self.IsDisabled())) renderBuilding.PlayCustomAnim(self, info.Sequence); ticks = info.Interval; } diff --git a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs index 41d427f999..75b381cdd8 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithIdleOverlay.cs @@ -61,7 +61,6 @@ namespace OpenRA.Mods.Common.Traits { var rs = self.Trait(); var body = self.Trait(); - var disabled = self.TraitsImplementing(); buildComplete = !self.HasTrait(); // always render instantly for units overlay = new Animation(self.World, rs.GetImage(self)); @@ -70,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits new AnimationWithOffset(overlay, () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => IsTraitDisabled || !buildComplete, - () => info.PauseOnLowPower && disabled.Any(d => d.Disabled), + () => info.PauseOnLowPower && self.IsDisabled(), p => WithTurret.ZOffsetFromCenter(self, p, 1)), info.Palette, info.IsPlayerPalette); } diff --git a/OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs b/OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs index 253739ce95..e768b56f03 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithMuzzleFlash.cs @@ -27,9 +27,10 @@ namespace OpenRA.Mods.Common.Traits class WithMuzzleFlash : UpgradableTrait, INotifyAttack, IRender, ITick { - Dictionary visible = new Dictionary(); - Dictionary anims = new Dictionary(); - Func getFacing; + readonly Dictionary visible = new Dictionary(); + readonly Dictionary anims = new Dictionary(); + readonly Func getFacing; + readonly Armament[] armaments; public WithMuzzleFlash(Actor self, WithMuzzleFlashInfo info) : base(info) @@ -37,7 +38,9 @@ namespace OpenRA.Mods.Common.Traits var render = self.Trait(); var facing = self.TraitOrDefault(); - foreach (var arm in self.TraitsImplementing()) + armaments = self.TraitsImplementing().ToArray(); + + foreach (var arm in armaments) { var armClosure = arm; // closure hazard in AnimationWithOffset @@ -87,7 +90,7 @@ namespace OpenRA.Mods.Common.Traits public IEnumerable Render(Actor self, WorldRenderer wr) { - foreach (var arm in self.TraitsImplementing()) + foreach (var arm in armaments) { var palette = wr.Palette(arm.Info.MuzzlePalette); foreach (var kv in anims) diff --git a/OpenRA.Mods.Common/Traits/Render/WithRepairAnimation.cs b/OpenRA.Mods.Common/Traits/Render/WithRepairAnimation.cs index 7acfa409fa..d38612c4f6 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithRepairAnimation.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithRepairAnimation.cs @@ -27,19 +27,17 @@ namespace OpenRA.Mods.Common.Traits public class WithRepairAnimation : INotifyRepair { - IEnumerable disabled; WithRepairAnimationInfo info; public WithRepairAnimation(Actor self, WithRepairAnimationInfo info) { - disabled = self.TraitsImplementing(); this.info = info; } public void Repairing(Actor self, Actor host) { var building = host.TraitOrDefault(); - if (building != null && !(info.PauseOnLowPower && disabled.Any(d => d.Disabled))) + if (building != null && !(info.PauseOnLowPower && self.IsDisabled())) building.PlayCustomAnim(host, info.Sequence); } } diff --git a/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs b/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs index 205ed29758..92746f31f1 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithRepairOverlay.cs @@ -44,7 +44,6 @@ namespace OpenRA.Mods.Common.Traits { var rs = self.Trait(); var body = self.Trait(); - var disabled = self.TraitsImplementing(); buildComplete = !self.HasTrait(); // always render instantly for units overlay = new Animation(self.World, rs.GetImage(self)); @@ -53,7 +52,7 @@ namespace OpenRA.Mods.Common.Traits new AnimationWithOffset(overlay, () => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))), () => !buildComplete, - () => info.PauseOnLowPower && disabled.Any(d => d.Disabled), + () => info.PauseOnLowPower && self.IsDisabled(), p => WithTurret.ZOffsetFromCenter(self, p, 1)), info.Palette, info.IsPlayerPalette); } diff --git a/OpenRA.Mods.Common/Traits/Render/WithTurret.cs b/OpenRA.Mods.Common/Traits/Render/WithTurret.cs index e13708d5f0..a5c254ee2c 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithTurret.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithTurret.cs @@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.Traits IBodyOrientation body; AttackBase ab; Turreted t; - IEnumerable arms; + Armament[] arms; Animation anim; public WithTurret(Actor self, WithTurretInfo info) @@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits t = self.TraitsImplementing() .First(tt => tt.Name == info.Turret); arms = self.TraitsImplementing() - .Where(w => w.Info.Turret == info.Turret); + .Where(w => w.Info.Turret == info.Turret).ToArray(); anim = new Animation(self.World, rs.GetImage(self), () => t.TurretFacing); anim.Play(info.Sequence); diff --git a/OpenRA.Mods.Common/Traits/Repairable.cs b/OpenRA.Mods.Common/Traits/Repairable.cs index e3df40b5c5..b275311bfa 100644 --- a/OpenRA.Mods.Common/Traits/Repairable.cs +++ b/OpenRA.Mods.Common/Traits/Repairable.cs @@ -29,13 +29,13 @@ namespace OpenRA.Mods.Common.Traits { readonly RepairableInfo info; readonly Health health; - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; public Repairable(Actor self, RepairableInfo info) { this.info = info; health = self.Trait(); - ammoPools = self.TraitsImplementing(); + ammoPools = self.TraitsImplementing().ToArray(); } public IEnumerable Orders @@ -72,10 +72,7 @@ namespace OpenRA.Mods.Common.Traits bool CanRearm() { - if (ammoPools != null) - return ammoPools.Any(x => !x.Info.SelfReloads && !x.FullAmmo()); - else - return false; + return ammoPools.Any(x => !x.Info.SelfReloads && !x.FullAmmo()); } public string VoicePhraseForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs index 6f49b1c926..7c9dafe0c4 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/SupportPowerManager.cs @@ -179,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits static bool InstanceDisabled(SupportPower sp) { - return sp.Self.TraitsImplementing().Any(d => d.Disabled); + return sp.Self.IsDisabled(); } bool notifiedCharging; diff --git a/OpenRA.Mods.Common/Traits/Turreted.cs b/OpenRA.Mods.Common/Traits/Turreted.cs index ad78fa147e..1035cea8e5 100644 --- a/OpenRA.Mods.Common/Traits/Turreted.cs +++ b/OpenRA.Mods.Common/Traits/Turreted.cs @@ -13,7 +13,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - public class TurretedInfo : ITraitInfo, UsesInit + public class TurretedInfo : ITraitInfo, UsesInit, Requires { public readonly string Turret = "primary"; [Desc("Rate of Turning")] @@ -34,6 +34,7 @@ namespace OpenRA.Mods.Common.Traits readonly TurretedInfo info; AttackTurreted attack; IFacing facing; + IBodyOrientation body; [Sync] public int QuantizedFacings = 0; [Sync] public int TurretFacing = 0; @@ -67,6 +68,7 @@ namespace OpenRA.Mods.Common.Traits { attack = self.TraitOrDefault(); facing = self.TraitOrDefault(); + body = self.Trait(); } public virtual void Tick(Actor self) @@ -94,7 +96,6 @@ namespace OpenRA.Mods.Common.Traits // Turret offset in world-space public WVec Position(Actor self) { - var body = self.Trait(); var bodyOrientation = body.QuantizeOrientation(self, self.Orientation); return body.LocalToWorld(Offset.Rotate(bodyOrientation)); } diff --git a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs index eb32bd562a..dbd83528dd 100644 --- a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Widgets public WorldTooltipType TooltipType { get; private set; } public IToolTip ActorTooltip { get; private set; } - public IEnumerable ActorTooltipExtra { get; private set; } + public IProvideTooltipInfo[] ActorTooltipExtra { get; private set; } public FrozenActor FrozenActorTooltip { get; private set; } public int EdgeScrollThreshold = 15; @@ -112,7 +112,7 @@ namespace OpenRA.Mods.Common.Widgets if (underCursor != null) { ActorTooltip = underCursor.TraitsImplementing().First(); - ActorTooltipExtra = underCursor.TraitsImplementing(); + ActorTooltipExtra = underCursor.TraitsImplementing().ToArray(); TooltipType = WorldTooltipType.Actor; return; } @@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.Widgets { FrozenActorTooltip = frozen; if (frozen.Actor != null) - ActorTooltipExtra = frozen.Actor.TraitsImplementing(); + ActorTooltipExtra = frozen.Actor.TraitsImplementing().ToArray(); TooltipType = WorldTooltipType.FrozenActor; } } diff --git a/OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs b/OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs index c1d7a4abe7..8d024c5efc 100644 --- a/OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs +++ b/OpenRA.Mods.D2k/Traits/ThrowsShrapnel.cs @@ -50,10 +50,10 @@ namespace OpenRA.Mods.D2k.Traits Facing = self.World.SharedRandom.Next(-1, 255), DamageModifiers = self.TraitsImplementing() - .Select(a => a.GetFirepowerModifier()), + .Select(a => a.GetFirepowerModifier()).ToArray(), InaccuracyModifiers = self.TraitsImplementing() - .Select(a => a.GetInaccuracyModifier()), + .Select(a => a.GetInaccuracyModifier()).ToArray(), Source = self.CenterPosition, SourceActor = self, diff --git a/OpenRA.Mods.RA/Activities/LayMines.cs b/OpenRA.Mods.RA/Activities/LayMines.cs index bff5105113..be26ed2fe9 100644 --- a/OpenRA.Mods.RA/Activities/LayMines.cs +++ b/OpenRA.Mods.RA/Activities/LayMines.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Activities { readonly Minelayer minelayer; readonly MinelayerInfo info; - readonly IEnumerable ammoPools; + readonly AmmoPool[] ammoPools; readonly IMove movement; readonly string[] rearmBuildings; @@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA.Activities { minelayer = self.TraitOrDefault(); info = self.Info.Traits.Get(); - ammoPools = self.TraitsImplementing(); + ammoPools = self.TraitsImplementing().ToArray(); movement = self.Trait(); rearmBuildings = info.RearmBuildings; }