diff --git a/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs b/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs index abdd00a0e9..9397d17ef5 100644 --- a/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs +++ b/OpenRA.Mods.Cnc/Traits/Buildings/ProductionAirdrop.cs @@ -59,16 +59,16 @@ namespace OpenRA.Mods.Cnc.Traits return; var altitude = self.World.Map.Rules.Actors[actorType].Traits.Get().CruiseAltitude; - var a = w.CreateActor(actorType, new TypeDictionary + var actor = w.CreateActor(actorType, new TypeDictionary { new CenterPositionInit(w.Map.CenterOfCell(startPos) + new WVec(WRange.Zero, WRange.Zero, altitude)), new OwnerInit(owner), new FacingInit(64) }); - a.QueueActivity(new Fly(a, Target.FromCell(w, self.Location + new CVec(9, 0)))); - a.QueueActivity(new Land(Target.FromActor(self))); - a.QueueActivity(new CallFunc(() => + actor.QueueActivity(new Fly(actor, Target.FromCell(w, self.Location + new CVec(9, 0)))); + actor.QueueActivity(new Land(actor, Target.FromActor(self))); + actor.QueueActivity(new CallFunc(() => { if (!self.IsInWorld || self.IsDead) return; @@ -80,8 +80,8 @@ namespace OpenRA.Mods.Cnc.Traits Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Country.Race); })); - a.QueueActivity(new Fly(a, Target.FromCell(w, endPos))); - a.QueueActivity(new RemoveSelf()); + actor.QueueActivity(new Fly(actor, Target.FromCell(w, endPos))); + actor.QueueActivity(new RemoveSelf()); }); return true; diff --git a/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs b/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs index 4935e46b9e..ee9c2274b3 100644 --- a/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs +++ b/OpenRA.Mods.Common/Activities/Air/FallToEarth.cs @@ -18,20 +18,21 @@ namespace OpenRA.Mods.Common.Activities { public class FallToEarth : Activity { + readonly Aircraft aircraft; + readonly FallsToEarthInfo info; int acceleration = 0; int spin = 0; - FallsToEarthInfo info; public FallToEarth(Actor self, FallsToEarthInfo info) { this.info = info; + aircraft = self.Trait(); if (info.Spins) acceleration = self.World.SharedRandom.Next(2) * 2 - 1; } public override Activity Tick(Actor self) { - var aircraft = self.Trait(); if (self.CenterPosition.Z <= 0) { if (info.Explosion != null) diff --git a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs index 3e204f419b..ade6867341 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyAttack.cs @@ -52,9 +52,9 @@ namespace OpenRA.Mods.Common.Activities // TODO: This should fire each weapon at its maximum range if (target.IsInRange(self.CenterPosition, attackPlane.Armaments.Select(a => a.Weapon.MinRange).Min())) - inner = Util.SequenceActivities(new FlyTimed(ticksUntilTurn), new Fly(self, target), new FlyTimed(ticksUntilTurn)); + inner = Util.SequenceActivities(new FlyTimed(ticksUntilTurn, self), new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); else - inner = Util.SequenceActivities(new Fly(self, target), new FlyTimed(ticksUntilTurn)); + inner = Util.SequenceActivities(new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } inner = Util.RunActivity(self, inner); diff --git a/OpenRA.Mods.Common/Activities/Air/FlyCircle.cs b/OpenRA.Mods.Common/Activities/Air/FlyCircle.cs index eb044f302a..600cf2d63b 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyCircle.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyCircle.cs @@ -16,16 +16,23 @@ namespace OpenRA.Mods.Common.Activities { public class FlyCircle : Activity { + readonly Plane plane; + readonly WRange cruiseAltitude; + + public FlyCircle(Actor self) + { + plane = self.Trait(); + cruiseAltitude = plane.Info.CruiseAltitude; + } + public override Activity Tick(Actor self) { if (IsCanceled) return NextActivity; - var plane = self.Trait(); - // We can't possibly turn this fast var desiredFacing = plane.Facing + 64; - Fly.FlyToward(self, plane, desiredFacing, plane.Info.CruiseAltitude); + Fly.FlyToward(self, plane, desiredFacing, cruiseAltitude); return this; } diff --git a/OpenRA.Mods.Common/Activities/Air/FlyOffMap.cs b/OpenRA.Mods.Common/Activities/Air/FlyOffMap.cs new file mode 100644 index 0000000000..ae14d90ee5 --- /dev/null +++ b/OpenRA.Mods.Common/Activities/Air/FlyOffMap.cs @@ -0,0 +1,35 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using OpenRA.Activities; +using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Activities +{ + public class FlyOffMap : Activity + { + readonly Plane plane; + + public FlyOffMap(Actor self) + { + plane = self.Trait(); + } + + public override Activity Tick(Actor self) + { + if (IsCanceled || !self.World.Map.Contains(self.Location)) + return NextActivity; + + Fly.FlyToward(self, plane, plane.Facing, plane.Info.CruiseAltitude); + return this; + } + } +} diff --git a/OpenRA.Mods.Common/Activities/Air/FlyTimed.cs b/OpenRA.Mods.Common/Activities/Air/FlyTimed.cs index ec9568b627..ef226696bb 100644 --- a/OpenRA.Mods.Common/Activities/Air/FlyTimed.cs +++ b/OpenRA.Mods.Common/Activities/Air/FlyTimed.cs @@ -16,37 +16,25 @@ namespace OpenRA.Mods.Common.Activities { public class FlyTimed : Activity { + readonly Plane plane; + readonly WRange cruiseAltitude; int remainingTicks; - public FlyTimed(int ticks) { remainingTicks = ticks; } + public FlyTimed(int ticks, Actor self) + { + remainingTicks = ticks; + plane = self.Trait(); + cruiseAltitude = plane.Info.CruiseAltitude; + } public override Activity Tick(Actor self) { if (IsCanceled || remainingTicks-- == 0) return NextActivity; - var plane = self.Trait(); - Fly.FlyToward(self, plane, plane.Facing, plane.Info.CruiseAltitude); + Fly.FlyToward(self, plane, plane.Facing, cruiseAltitude); return this; } } - - public class FlyOffMap : Activity - { - public override Activity Tick(Actor self) - { - if (IsCanceled || !self.World.Map.Contains(self.Location)) - return NextActivity; - - var plane = self.Trait(); - Fly.FlyToward(self, plane, plane.Facing, plane.Info.CruiseAltitude); - return this; - } - - public override void Cancel(Actor self) - { - base.Cancel(self); - } - } } diff --git a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs index c420365531..576fc75edc 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliAttack.cs @@ -40,7 +40,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())) - return Util.SequenceActivities(new HeliReturn(), NextActivity); + return Util.SequenceActivities(new HeliReturn(self), NextActivity); var dist = target.CenterPosition - self.CenterPosition; diff --git a/OpenRA.Mods.Common/Activities/Air/HeliLand.cs b/OpenRA.Mods.Common/Activities/Air/HeliLand.cs index 85cd469acc..a0ca4756cc 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliLand.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliLand.cs @@ -15,11 +15,15 @@ namespace OpenRA.Mods.Common.Activities { public class HeliLand : Activity { + readonly Helicopter helicopter; + readonly WRange landAltitude; bool requireSpace; - public HeliLand(bool requireSpace) + public HeliLand(Actor self, bool requireSpace) { this.requireSpace = requireSpace; + helicopter = self.Trait(); + landAltitude = helicopter.Info.LandAltitude; } public override Activity Tick(Actor self) @@ -27,12 +31,10 @@ namespace OpenRA.Mods.Common.Activities if (IsCanceled) return NextActivity; - var helicopter = self.Trait(); - if (requireSpace && !helicopter.CanLand(self.Location)) return this; - if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.LandAltitude)) + if (HeliFly.AdjustAltitude(self, helicopter, landAltitude)) return this; return NextActivity; diff --git a/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs b/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs index 059acc7cae..24a0c7896d 100644 --- a/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs +++ b/OpenRA.Mods.Common/Activities/Air/HeliReturn.cs @@ -17,7 +17,18 @@ namespace OpenRA.Mods.Common.Activities { public class HeliReturn : Activity { - static Actor ChooseHelipad(Actor self) + readonly AircraftInfo aircraftInfo; + readonly Helicopter heli; + readonly HelicopterInfo heliInfo; + + public HeliReturn(Actor self) + { + aircraftInfo = self.Info.Traits.Get(); + heli = self.Trait(); + heliInfo = self.Info.Traits.Get(); + } + + public static Actor ChooseHelipad(Actor self) { var rearmBuildings = self.Info.Traits.Get().RearmBuildings; return self.World.Actors.Where(a => a.Owner == self.Owner).FirstOrDefault( @@ -30,24 +41,23 @@ namespace OpenRA.Mods.Common.Activities return NextActivity; var dest = ChooseHelipad(self); - var initialFacing = self.Info.Traits.Get().InitialFacing; + var initialFacing = aircraftInfo.InitialFacing; if (dest == null) { - var rearmBuildings = self.Info.Traits.Get().RearmBuildings; + var rearmBuildings = heliInfo.RearmBuildings; var nearestHpad = self.World.ActorsWithTrait() .Where(a => a.Actor.Owner == self.Owner && rearmBuildings.Contains(a.Actor.Info.Name)) .Select(a => a.Actor) .ClosestTo(self); if (nearestHpad == null) - return Util.SequenceActivities(new Turn(self, initialFacing), new HeliLand(true), NextActivity); + return Util.SequenceActivities(new Turn(self, initialFacing), new HeliLand(self, true), NextActivity); else return Util.SequenceActivities(new HeliFly(self, Target.FromActor(nearestHpad))); } var res = dest.TraitOrDefault(); - var heli = self.Trait(); if (res != null) { @@ -61,8 +71,8 @@ namespace OpenRA.Mods.Common.Activities return Util.SequenceActivities( new HeliFly(self, Target.FromPos(dest.CenterPosition + offset)), new Turn(self, initialFacing), - new HeliLand(false), - new ResupplyAircraft()); + new HeliLand(self, false), + new ResupplyAircraft(self)); } } } diff --git a/OpenRA.Mods.Common/Activities/Air/Land.cs b/OpenRA.Mods.Common/Activities/Air/Land.cs index 44eed7aa2d..9f5abb4f5e 100644 --- a/OpenRA.Mods.Common/Activities/Air/Land.cs +++ b/OpenRA.Mods.Common/Activities/Air/Land.cs @@ -16,9 +16,14 @@ namespace OpenRA.Mods.Common.Activities { public class Land : Activity { - Target target; + readonly Target target; + readonly Plane plane; - public Land(Target t) { target = t; } + public Land(Actor self, Target t) + { + target = t; + plane = self.Trait(); + } public override Activity Tick(Actor self) { @@ -28,7 +33,6 @@ namespace OpenRA.Mods.Common.Activities if (IsCanceled) return NextActivity; - var plane = self.Trait(); var d = target.CenterPosition - self.CenterPosition; // The next move would overshoot, so just set the final position diff --git a/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs b/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs index 84ddb97574..324d041dfd 100644 --- a/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs +++ b/OpenRA.Mods.Common/Activities/Air/ResupplyAircraft.cs @@ -20,9 +20,15 @@ namespace OpenRA.Mods.Common.Activities { public class ResupplyAircraft : Activity { + readonly Aircraft aircraft; + + public ResupplyAircraft(Actor self) + { + aircraft = self.Trait(); + } + public override Activity Tick(Actor self) { - var aircraft = self.Trait(); var host = aircraft.GetActorBelow(); if (host == null) diff --git a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs index fffc65ecd6..d342661e34 100644 --- a/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs +++ b/OpenRA.Mods.Common/Activities/Air/ReturnToBase.cs @@ -18,10 +18,19 @@ namespace OpenRA.Mods.Common.Activities { public class ReturnToBase : Activity { + readonly Plane plane; + readonly PlaneInfo planeInfo; bool isCalculated; Actor dest; WPos w1, w2, w3; + public ReturnToBase(Actor self, Actor dest) + { + this.dest = dest; + plane = self.Trait(); + planeInfo = self.Info.Traits.Get(); + } + public static Actor ChooseAirfield(Actor self, bool unreservedOnly) { var rearmBuildings = self.Info.Traits.Get().RearmBuildings; @@ -41,8 +50,6 @@ namespace OpenRA.Mods.Common.Activities if (dest == null) return; - var plane = self.Trait(); - var planeInfo = self.Info.Traits.Get(); var res = dest.TraitOrDefault(); if (res != null) { @@ -54,7 +61,7 @@ namespace OpenRA.Mods.Common.Activities var altitude = planeInfo.CruiseAltitude.Range; // Distance required for descent. - var landDistance = altitude * 1024 / plane.Info.MaximumPitch.Tan(); + var landDistance = altitude * 1024 / planeInfo.MaximumPitch.Tan(); // Land towards the east var approachStart = landPos + new WVec(-landDistance, 0, altitude); @@ -92,11 +99,6 @@ namespace OpenRA.Mods.Common.Activities isCalculated = true; } - public ReturnToBase(Actor self, Actor dest) - { - this.dest = dest; - } - public override Activity Tick(Actor self) { if (IsCanceled || self.IsDead) @@ -111,16 +113,16 @@ namespace OpenRA.Mods.Common.Activities self.CancelActivity(); if (nearestAfld != null) - return Util.SequenceActivities(new Fly(self, Target.FromActor(nearestAfld)), new FlyCircle()); + return Util.SequenceActivities(new Fly(self, Target.FromActor(nearestAfld)), new FlyCircle(self)); else - return new FlyCircle(); + return new FlyCircle(self); } return Util.SequenceActivities( new Fly(self, Target.FromPos(w1)), new Fly(self, Target.FromPos(w2)), new Fly(self, Target.FromPos(w3)), - new Land(Target.FromActor(dest)), + new Land(self, Target.FromActor(dest)), NextActivity); } } diff --git a/OpenRA.Mods.Common/Activities/Air/TakeOff.cs b/OpenRA.Mods.Common/Activities/Air/TakeOff.cs index 450205d950..e12e259b27 100644 --- a/OpenRA.Mods.Common/Activities/Air/TakeOff.cs +++ b/OpenRA.Mods.Common/Activities/Air/TakeOff.cs @@ -16,10 +16,17 @@ namespace OpenRA.Mods.Common.Activities { public class TakeOff : Activity { + readonly Aircraft aircraft; + readonly IMove move; + + public TakeOff(Actor self) + { + aircraft = self.Trait(); + move = self.Trait(); + } + public override Activity Tick(Actor self) { - var aircraft = self.Trait(); - self.CancelActivity(); var reservation = aircraft.Reservation; @@ -36,7 +43,7 @@ namespace OpenRA.Mods.Common.Activities var destination = rp != null ? rp.Location : (hasHost ? self.World.Map.CellContaining(host.CenterPosition) : self.Location); - return new AttackMoveActivity(self, self.Trait().MoveTo(destination, 1)); + return new AttackMoveActivity(self, move.MoveTo(destination, 1)); } } } 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/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index b3636ec285..b4ca63d1aa 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -81,6 +81,7 @@ + diff --git a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs index 1f02271e6d..90b1fac341 100644 --- a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs @@ -141,7 +141,7 @@ namespace OpenRA.Mods.Common.Scripting if (heli != null) { transport.QueueActivity(new Turn(transport, heli.Info.InitialFacing)); - transport.QueueActivity(new HeliLand(true)); + transport.QueueActivity(new HeliLand(transport, true)); transport.QueueActivity(new Wait(15)); } diff --git a/OpenRA.Mods.Common/Traits/Air/FlyAwayOnIdle.cs b/OpenRA.Mods.Common/Traits/Air/FlyAwayOnIdle.cs index ecaed00034..a38bd18098 100644 --- a/OpenRA.Mods.Common/Traits/Air/FlyAwayOnIdle.cs +++ b/OpenRA.Mods.Common/Traits/Air/FlyAwayOnIdle.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits { public void TickIdle(Actor self) { - self.QueueActivity(new FlyOffMap()); + self.QueueActivity(new FlyOffMap(self)); self.QueueActivity(new RemoveSelf()); } } diff --git a/OpenRA.Mods.Common/Traits/Air/Helicopter.cs b/OpenRA.Mods.Common/Traits/Air/Helicopter.cs index 7c9e588b19..ee5cc8eafb 100644 --- a/OpenRA.Mods.Common/Traits/Air/Helicopter.cs +++ b/OpenRA.Mods.Common/Traits/Air/Helicopter.cs @@ -35,7 +35,8 @@ namespace OpenRA.Mods.Common.Traits public class Helicopter : Aircraft, ITick, IResolveOrder, IMove { - public HelicopterInfo Info; + public readonly HelicopterInfo Info; + readonly bool fallsToEarth; Actor self; bool firstTick = true; public bool IsMoving { get { return self.CenterPosition.Z > 0; } set { } } @@ -45,6 +46,7 @@ namespace OpenRA.Mods.Common.Traits { self = init.Self; Info = info; + fallsToEarth = self.HasTrait(); } public void ResolveOrder(Actor self, Order order) @@ -74,7 +76,7 @@ namespace OpenRA.Mods.Common.Traits if (Info.TurnToLand) self.QueueActivity(new Turn(self, Info.InitialFacing)); - self.QueueActivity(new HeliLand(true)); + self.QueueActivity(new HeliLand(self, true)); } } @@ -83,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits if (Reservable.IsReserved(order.TargetActor)) { self.CancelActivity(); - self.QueueActivity(new HeliReturn()); + self.QueueActivity(new HeliReturn(self)); } else { @@ -99,16 +101,16 @@ namespace OpenRA.Mods.Common.Traits self.CancelActivity(); self.QueueActivity(new HeliFly(self, Target.FromPos(order.TargetActor.CenterPosition + offset))); self.QueueActivity(new Turn(self, Info.InitialFacing)); - self.QueueActivity(new HeliLand(false)); - self.QueueActivity(new ResupplyAircraft()); - self.QueueActivity(new TakeOff()); + self.QueueActivity(new HeliLand(self, false)); + self.QueueActivity(new ResupplyAircraft(self)); + self.QueueActivity(new TakeOff(self)); } } if (order.OrderString == "ReturnToBase") { self.CancelActivity(); - self.QueueActivity(new HeliReturn()); + self.QueueActivity(new HeliReturn(self)); } if (order.OrderString == "Stop") @@ -120,7 +122,7 @@ namespace OpenRA.Mods.Common.Traits if (Info.TurnToLand) self.QueueActivity(new Turn(self, Info.InitialFacing)); - self.QueueActivity(new HeliLand(true)); + self.QueueActivity(new HeliLand(self, true)); } } } @@ -130,14 +132,14 @@ namespace OpenRA.Mods.Common.Traits if (firstTick) { firstTick = false; - if (!self.HasTrait()) // TODO: Aircraft husks don't properly unreserve. + if (!fallsToEarth) // TODO: Aircraft husks don't properly unreserve. ReserveSpawnBuilding(); var host = GetActorBelow(); if (host == null) return; - self.QueueActivity(new TakeOff()); + self.QueueActivity(new TakeOff(self)); } Repulse(); @@ -155,7 +157,7 @@ namespace OpenRA.Mods.Common.Traits return new HeliFly(self, Target.FromCell(self.World, cell, subCell)); } - public Activity MoveIntoTarget(Actor self, Target target) { return new HeliLand(false); } + public Activity MoveIntoTarget(Actor self, Target target) { return new HeliLand(self, false); } public Activity MoveToTarget(Actor self, Target target) { return Util.SequenceActivities(new HeliFly(self, target), new Turn(self, Info.InitialFacing)); diff --git a/OpenRA.Mods.Common/Traits/Air/Plane.cs b/OpenRA.Mods.Common/Traits/Air/Plane.cs index 2ff0f34e6c..a9ac2f6be3 100644 --- a/OpenRA.Mods.Common/Traits/Air/Plane.cs +++ b/OpenRA.Mods.Common/Traits/Air/Plane.cs @@ -26,6 +26,7 @@ namespace OpenRA.Mods.Common.Traits public class Plane : Aircraft, IResolveOrder, IMove, ITick, ISync { public readonly PlaneInfo Info; + readonly bool fallsToEarth; [Sync] public WPos RTBPathHash; Actor self; public bool IsMoving { get { return self.CenterPosition.Z > 0; } set { } } @@ -35,6 +36,7 @@ namespace OpenRA.Mods.Common.Traits { self = init.Self; Info = info; + fallsToEarth = self.HasTrait(); } bool firstTick = true; @@ -43,14 +45,14 @@ namespace OpenRA.Mods.Common.Traits if (firstTick) { firstTick = false; - if (!self.HasTrait()) // TODO: Aircraft husks don't properly unreserve. + if (!fallsToEarth) // TODO: Aircraft husks don't properly unreserve. ReserveSpawnBuilding(); var host = GetActorBelow(); if (host == null) return; - self.QueueActivity(new TakeOff()); + self.QueueActivity(new TakeOff(self)); } Repulse(); @@ -89,7 +91,7 @@ namespace OpenRA.Mods.Common.Traits self.SetTargetLine(target, Color.Green); self.CancelActivity(); self.QueueActivity(new Fly(self, target)); - self.QueueActivity(new FlyCircle()); + self.QueueActivity(new FlyCircle(self)); } else if (order.OrderString == "Enter") { @@ -101,7 +103,7 @@ namespace OpenRA.Mods.Common.Traits self.CancelActivity(); self.QueueActivity(new ReturnToBase(self, order.TargetActor)); - self.QueueActivity(new ResupplyAircraft()); + self.QueueActivity(new ResupplyAircraft(self)); } else if (order.OrderString == "Stop") { @@ -117,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits self.CancelActivity(); self.SetTargetLine(Target.FromActor(airfield), Color.Green); self.QueueActivity(new ReturnToBase(self, airfield)); - self.QueueActivity(new ResupplyAircraft()); + self.QueueActivity(new ResupplyAircraft(self)); } else { @@ -126,12 +128,12 @@ namespace OpenRA.Mods.Common.Traits } } - public Activity MoveTo(CPos cell, int nearEnough) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell)), new FlyCircle()); } - public Activity MoveTo(CPos cell, Actor ignoredActor) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell)), new FlyCircle()); } - public Activity MoveWithinRange(Target target, WRange range) { return Util.SequenceActivities(new Fly(self, target, WRange.Zero, range), new FlyCircle()); } + public Activity MoveTo(CPos cell, int nearEnough) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell)), new FlyCircle(self)); } + public Activity MoveTo(CPos cell, Actor ignoredActor) { return Util.SequenceActivities(new Fly(self, Target.FromCell(self.World, cell)), new FlyCircle(self)); } + public Activity MoveWithinRange(Target target, WRange range) { return Util.SequenceActivities(new Fly(self, target, WRange.Zero, range), new FlyCircle(self)); } public Activity MoveWithinRange(Target target, WRange minRange, WRange maxRange) { - return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle()); + return Util.SequenceActivities(new Fly(self, target, minRange, maxRange), new FlyCircle(self)); } public Activity MoveFollow(Actor self, Target target, WRange minRange, WRange maxRange) { return new FlyFollow(self, target, minRange, maxRange); } @@ -144,6 +146,6 @@ namespace OpenRA.Mods.Common.Traits } public Activity MoveToTarget(Actor self, Target target) { return new Fly(self, target, WRange.FromCells(3), WRange.FromCells(5)); } - public Activity MoveIntoTarget(Actor self, Target target) { return new Land(target); } + public Activity MoveIntoTarget(Actor self, Target target) { return new Land(self, target); } } } diff --git a/OpenRA.Mods.Common/Traits/Air/ReturnOnIdle.cs b/OpenRA.Mods.Common/Traits/Air/ReturnOnIdle.cs index cf5ff734ec..64c8de885b 100644 --- a/OpenRA.Mods.Common/Traits/Air/ReturnOnIdle.cs +++ b/OpenRA.Mods.Common/Traits/Air/ReturnOnIdle.cs @@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits if (airfield != null) { self.QueueActivity(new ReturnToBase(self, airfield)); - self.QueueActivity(new ResupplyAircraft()); + self.QueueActivity(new ResupplyAircraft(self)); } else { @@ -49,13 +49,13 @@ namespace OpenRA.Mods.Common.Traits if (someBuilding == null) { // ... going down the garden to eat worms ... - self.QueueActivity(new FlyOffMap()); + self.QueueActivity(new FlyOffMap(self)); self.QueueActivity(new RemoveSelf()); return; } self.QueueActivity(new Fly(self, Target.FromActor(someBuilding))); - self.QueueActivity(new FlyCircle()); + self.QueueActivity(new FlyCircle(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/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index b48ed43340..cae349598b 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.Traits Unloading = true; self.CancelActivity(); if (helicopter != null) - self.QueueActivity(new HeliLand(true)); + self.QueueActivity(new HeliLand(self, true)); self.QueueActivity(new UnloadCargo(self, true)); } } 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 diff --git a/OpenRA.Mods.D2k/Activities/PickupUnit.cs b/OpenRA.Mods.D2k/Activities/PickupUnit.cs index e7ac69f65a..c7de52305c 100644 --- a/OpenRA.Mods.D2k/Activities/PickupUnit.cs +++ b/OpenRA.Mods.D2k/Activities/PickupUnit.cs @@ -81,7 +81,7 @@ namespace OpenRA.Mods.D2k.Activities if (selfFacing.Facing != cargoFacing.Facing) return Util.SequenceActivities(new Turn(self, cargoFacing.Facing), this); state = State.Pickup; - return Util.SequenceActivities(new HeliLand(false), new Wait(10), this); + return Util.SequenceActivities(new HeliLand(self, false), new Wait(10), this); case State.Pickup: // Remove our carryable from world diff --git a/OpenRA.Mods.RA/Scripting/Properties/ParadropProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/ParadropProperties.cs index a15add80a3..dfc5d77b77 100644 --- a/OpenRA.Mods.RA/Scripting/Properties/ParadropProperties.cs +++ b/OpenRA.Mods.RA/Scripting/Properties/ParadropProperties.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Scripting { paradrop.SetLZ(cell, true); Self.QueueActivity(new Fly(Self, Target.FromCell(Self.World, cell))); - Self.QueueActivity(new FlyOffMap()); + Self.QueueActivity(new FlyOffMap(Self)); Self.QueueActivity(new RemoveSelf()); } }