diff --git a/OpenRA.Mods.Common/Activities/CaptureActor.cs b/OpenRA.Mods.Common/Activities/CaptureActor.cs index ca9b6e7cf8..a8bec859a4 100644 --- a/OpenRA.Mods.Common/Activities/CaptureActor.cs +++ b/OpenRA.Mods.Common/Activities/CaptureActor.cs @@ -16,15 +16,19 @@ namespace OpenRA.Mods.Common.Activities public class CaptureActor : Enter { readonly Actor actor; + readonly Building building; readonly Capturable capturable; readonly CapturesInfo capturesInfo; + readonly Health health; public CaptureActor(Actor self, Actor target) : base(self, target) { actor = target; + building = actor.TraitOrDefault(); capturesInfo = self.Info.Traits.Get(); capturable = target.Trait(); + health = actor.Trait(); } protected override bool CanReserve(Actor self) @@ -37,20 +41,17 @@ namespace OpenRA.Mods.Common.Activities if (actor.IsDead || capturable.BeingCaptured) return; - var b = actor.TraitOrDefault(); - if (b != null && !b.Lock()) + if (building != null && !building.Lock()) return; self.World.AddFrameEndTask(w => { - if (b != null && b.Locked) - b.Unlock(); + if (building != null && building.Locked) + building.Unlock(); if (actor.IsDead || capturable.BeingCaptured) return; - var health = actor.Trait(); - var lowEnoughHealth = health.HP <= capturable.Info.CaptureThreshold * health.MaxHP; if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant) { @@ -61,8 +62,8 @@ namespace OpenRA.Mods.Common.Activities foreach (var t in actor.TraitsImplementing()) t.OnCapture(actor, self, oldOwner, self.Owner); - if (b != null && b.Locked) - b.Unlock(); + if (building != null && building.Locked) + building.Unlock(); } else { diff --git a/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs b/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs index ace8a01f15..ae290c3d96 100644 --- a/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs +++ b/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs @@ -17,17 +17,24 @@ namespace OpenRA.Mods.Common.Activities { class ExternalCaptureActor : Activity { - Target target; + readonly ExternalCapturable capturable; + readonly ExternalCapturesInfo capturesInfo; + readonly Mobile mobile; + readonly Target target; - public ExternalCaptureActor(Target target) { this.target = target; } + public ExternalCaptureActor(Actor self, Target target) + { + this.target = target; + capturable = target.Actor.Trait(); + capturesInfo = self.Info.Traits.Get(); + mobile = self.Trait(); + } public override Activity Tick(Actor self) { if (target.Type != TargetType.Actor) return NextActivity; - var capturable = target.Actor.Trait(); - if (IsCanceled || !self.IsInWorld || self.IsDead || !target.IsValidFor(self)) { if (capturable.CaptureInProgress) @@ -36,7 +43,6 @@ namespace OpenRA.Mods.Common.Activities return NextActivity; } - var mobile = self.Trait(); var nearest = target.Actor.OccupiesSpace.NearestCellTo(mobile.ToCell); if ((nearest - mobile.ToCell).LengthSquared > 2) @@ -56,8 +62,6 @@ namespace OpenRA.Mods.Common.Activities if (capturable.CaptureProgressTime == capturable.Info.CaptureCompleteTime * 25) { - var capturesInfo = self.Info.Traits.Get(); - self.World.AddFrameEndTask(w => { if (target.Actor.IsDead) diff --git a/OpenRA.Mods.Common/Activities/Sell.cs b/OpenRA.Mods.Common/Activities/Sell.cs index c44127726c..edfafa3a72 100644 --- a/OpenRA.Mods.Common/Activities/Sell.cs +++ b/OpenRA.Mods.Common/Activities/Sell.cs @@ -17,16 +17,23 @@ namespace OpenRA.Mods.Common.Activities { class Sell : Activity { + readonly Health health; + readonly SellableInfo sellableInfo; + readonly PlayerResources playerResources; + + public Sell(Actor self) + { + health = self.TraitOrDefault(); + sellableInfo = self.Info.Traits.Get(); + playerResources = self.Owner.PlayerActor.Trait(); + } + public override Activity Tick(Actor self) { - var h = self.TraitOrDefault(); - var si = self.Info.Traits.Get(); - var pr = self.Owner.PlayerActor.Trait(); - var cost = self.GetSellValue(); - var refund = (cost * si.RefundPercent * (h == null ? 1 : h.HP)) / (100 * (h == null ? 1 : h.MaxHP)); - pr.GiveCash(refund); + var refund = (cost * sellableInfo.RefundPercent * (health == null ? 1 : health.HP)) / (100 * (health == null ? 1 : health.MaxHP)); + playerResources.GiveCash(refund); foreach (var ns in self.TraitsImplementing()) ns.Sold(self); diff --git a/OpenRA.Mods.Common/Traits/Burns.cs b/OpenRA.Mods.Common/Traits/Burns.cs index f464239555..a68c54497b 100644 --- a/OpenRA.Mods.Common/Traits/Burns.cs +++ b/OpenRA.Mods.Common/Traits/Burns.cs @@ -25,8 +25,8 @@ namespace OpenRA.Mods.Common.Traits class Burns : ITick, ISync { + readonly BurnsInfo info; [Sync] int ticks; - BurnsInfo info; public Burns(Actor self, BurnsInfo info) { diff --git a/OpenRA.Mods.Common/Traits/ExternalCapturable.cs b/OpenRA.Mods.Common/Traits/ExternalCapturable.cs index f046deaecd..7160af26e7 100644 --- a/OpenRA.Mods.Common/Traits/ExternalCapturable.cs +++ b/OpenRA.Mods.Common/Traits/ExternalCapturable.cs @@ -51,21 +51,20 @@ namespace OpenRA.Mods.Common.Traits public class ExternalCapturable : ITick { + readonly Building building; [Sync] public int CaptureProgressTime = 0; [Sync] public Actor Captor; - private Actor self; public ExternalCapturableInfo Info; public bool CaptureInProgress { get { return Captor != null; } } public ExternalCapturable(Actor self, ExternalCapturableInfo info) { - this.self = self; Info = info; + building = self.TraitOrDefault(); } public void BeginCapture(Actor captor) { - var building = self.TraitOrDefault(); if (building != null) building.Lock(); @@ -74,7 +73,6 @@ namespace OpenRA.Mods.Common.Traits public void EndCapture() { - var building = self.TraitOrDefault(); if (building != null) building.Unlock(); diff --git a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs index a40523393a..cd5302fe97 100644 --- a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs +++ b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs @@ -99,7 +99,7 @@ namespace OpenRA.Mods.Common.Traits self.CancelActivity(); self.SetTargetLine(target, Color.Red); - self.QueueActivity(new ExternalCaptureActor(target)); + self.QueueActivity(new ExternalCaptureActor(self, target)); } } diff --git a/OpenRA.Mods.Common/Traits/Infantry/ScaredyCat.cs b/OpenRA.Mods.Common/Traits/Infantry/ScaredyCat.cs index 9caf2bece6..d52ddeed22 100644 --- a/OpenRA.Mods.Common/Traits/Infantry/ScaredyCat.cs +++ b/OpenRA.Mods.Common/Traits/Infantry/ScaredyCat.cs @@ -30,6 +30,7 @@ namespace OpenRA.Mods.Common.Traits class ScaredyCat : ITick, INotifyIdle, INotifyDamage, INotifyAttack, ISpeedModifier, ISync, IRenderInfantrySequenceModifier { readonly ScaredyCatInfo info; + readonly Mobile mobile; [Sync] readonly Actor self; [Sync] int panicStartedTick; bool Panicking { get { return panicStartedTick > 0; } } @@ -41,6 +42,7 @@ namespace OpenRA.Mods.Common.Traits { this.self = self; this.info = info; + mobile = self.Trait(); } public void Panic() @@ -68,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits if (!Panicking) return; - self.Trait().Nudge(self, self, true); + mobile.Nudge(self, self, true); } public void Damaged(Actor self, AttackInfo e) diff --git a/OpenRA.Mods.Common/Traits/Render/WithBuildingExplosion.cs b/OpenRA.Mods.Common/Traits/Render/WithBuildingExplosion.cs index 262263375a..3e76028aa4 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithBuildingExplosion.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithBuildingExplosion.cs @@ -27,21 +27,22 @@ namespace OpenRA.Mods.Common.Traits [Desc("Custom palette name")] public readonly string Palette = "effect"; - public object Create(ActorInitializer init) { return new WithBuildingExplosion(this); } + public object Create(ActorInitializer init) { return new WithBuildingExplosion(init.Self, this); } } class WithBuildingExplosion : INotifyKilled { WithBuildingExplosionInfo info; + BuildingInfo buildingInfo; - public WithBuildingExplosion(WithBuildingExplosionInfo info) + public WithBuildingExplosion(Actor self, WithBuildingExplosionInfo info) { this.info = info; + buildingInfo = self.Info.Traits.Get(); } public void Killed(Actor self, AttackInfo e) { - var buildingInfo = self.Info.Traits.Get(); var cells = FootprintUtils.UnpathableTiles(self.Info.Name, buildingInfo, self.Location); if (info.Delay > 0) diff --git a/OpenRA.Mods.Common/Traits/RepairableNear.cs b/OpenRA.Mods.Common/Traits/RepairableNear.cs index d066bd4355..99ff27c40e 100644 --- a/OpenRA.Mods.Common/Traits/RepairableNear.cs +++ b/OpenRA.Mods.Common/Traits/RepairableNear.cs @@ -29,8 +29,14 @@ namespace OpenRA.Mods.Common.Traits { readonly Actor self; readonly RepairableNearInfo info; + readonly IMove movement; - public RepairableNear(Actor self, RepairableNearInfo info) { this.self = self; this.info = info; } + public RepairableNear(Actor self, RepairableNearInfo info) + { + this.self = self; + this.info = info; + movement = self.Trait(); + } public IEnumerable Orders { @@ -63,7 +69,6 @@ namespace OpenRA.Mods.Common.Traits { if (order.OrderString == "RepairNear" && CanRepairAt(order.TargetActor) && ShouldRepair()) { - var movement = self.Trait(); var target = Target.FromOrder(self.World, order); self.CancelActivity(); diff --git a/OpenRA.Mods.Common/Traits/Sellable.cs b/OpenRA.Mods.Common/Traits/Sellable.cs index c2af65272f..393ab5e6ad 100644 --- a/OpenRA.Mods.Common/Traits/Sellable.cs +++ b/OpenRA.Mods.Common/Traits/Sellable.cs @@ -29,12 +29,18 @@ namespace OpenRA.Mods.Common.Traits { readonly Actor self; readonly Lazy health; + readonly SellableInfo info; + readonly Building building; + readonly WithMakeAnimation makeAnimation; public Sellable(Actor self, SellableInfo info) : base(info) { this.self = self; + this.info = info; health = Exts.Lazy(() => self.TraitOrDefault()); + building = self.TraitOrDefault(); + makeAnimation = self.TraitOrDefault(); } public void ResolveOrder(Actor self, Order order) @@ -48,23 +54,21 @@ namespace OpenRA.Mods.Common.Traits if (IsTraitDisabled) return; - var building = self.TraitOrDefault(); if (building != null && !building.Lock()) return; self.CancelActivity(); - foreach (var s in Info.SellSounds) + foreach (var s in info.SellSounds) Sound.PlayToPlayer(self.Owner, s, self.CenterPosition); foreach (var ns in self.TraitsImplementing()) ns.Selling(self); - var makeAnimation = self.TraitOrDefault(); if (makeAnimation != null) - makeAnimation.Reverse(self, new Sell(), false); + makeAnimation.Reverse(self, new Sell(self), false); else - self.QueueActivity(false, new Sell()); + self.QueueActivity(false, new Sell(self)); } public bool IsTooltipVisible(Player forPlayer) @@ -78,7 +82,7 @@ namespace OpenRA.Mods.Common.Traits { get { - var sellValue = self.GetSellValue() * Info.RefundPercent / 100; + var sellValue = self.GetSellValue() * info.RefundPercent / 100; if (health.Value != null) { sellValue *= health.Value.HP; diff --git a/OpenRA.Mods.Common/Traits/Transforms.cs b/OpenRA.Mods.Common/Traits/Transforms.cs index 79faf49afc..9ad74b49cf 100644 --- a/OpenRA.Mods.Common/Traits/Transforms.cs +++ b/OpenRA.Mods.Common/Traits/Transforms.cs @@ -46,14 +46,18 @@ namespace OpenRA.Mods.Common.Traits { readonly Actor self; readonly TransformsInfo info; - readonly BuildingInfo bi; + readonly Building building; + readonly BuildingInfo buildingInfo; readonly string race; + readonly WithMakeAnimation makeAnimation; public Transforms(ActorInitializer init, TransformsInfo info) { self = init.Self; this.info = info; - bi = self.World.Map.Rules.Actors[info.IntoActor].Traits.GetOrDefault(); + buildingInfo = self.World.Map.Rules.Actors[info.IntoActor].Traits.GetOrDefault(); + building = self.TraitOrDefault(); + makeAnimation = self.TraitOrDefault(); race = init.Contains() ? init.Get() : self.Owner.Country.Race; } @@ -64,11 +68,10 @@ namespace OpenRA.Mods.Common.Traits bool CanDeploy() { - var b = self.TraitOrDefault(); - if (b != null && b.Locked) + if (building != null && building.Locked) return false; - return bi == null || self.World.CanPlaceBuilding(info.IntoActor, bi, self.Location + info.Offset, self); + return buildingInfo == null || self.World.CanPlaceBuilding(info.IntoActor, buildingInfo, self.Location + info.Offset, self); } public IEnumerable Orders @@ -86,9 +89,7 @@ namespace OpenRA.Mods.Common.Traits public void DeployTransform(bool queued) { - var b = self.TraitOrDefault(); - - if (!CanDeploy() || (b != null && !b.Lock())) + if (!CanDeploy() || (building != null && !building.Lock())) { foreach (var s in info.NoTransformSounds) Sound.PlayToPlayer(self.Owner, s); @@ -116,7 +117,6 @@ namespace OpenRA.Mods.Common.Traits Race = race }; - var makeAnimation = self.TraitOrDefault(); if (makeAnimation != null) makeAnimation.Reverse(self, transform); else