diff --git a/OpenRA.Mods.Cnc/ProductionAirdrop.cs b/OpenRA.Mods.Cnc/ProductionAirdrop.cs index 39bbfd6f54..61db327831 100644 --- a/OpenRA.Mods.Cnc/ProductionAirdrop.cs +++ b/OpenRA.Mods.Cnc/ProductionAirdrop.cs @@ -25,13 +25,13 @@ namespace OpenRA.Mods.Cnc [Desc("Cargo aircraft used.")] [ActorReference] public readonly string ActorType = "c17"; - public override object Create(ActorInitializer init) { return new ProductionAirdrop(this); } + public override object Create(ActorInitializer init) { return new ProductionAirdrop(this, init.self); } } class ProductionAirdrop : Production { - public ProductionAirdrop(ProductionAirdropInfo info) - : base(info) { } + public ProductionAirdrop(ProductionAirdropInfo info, Actor self) + : base(info, self) { } public override bool Produce(Actor self, ActorInfo producee) { diff --git a/OpenRA.Mods.RA/Production.cs b/OpenRA.Mods.RA/Production.cs index 8a03489bec..af5abf263e 100755 --- a/OpenRA.Mods.RA/Production.cs +++ b/OpenRA.Mods.RA/Production.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Drawing; using System.Linq; using OpenRA.Mods.RA.Move; @@ -22,7 +23,7 @@ namespace OpenRA.Mods.RA [Desc("e.g. Infantry, Vehicles, Aircraft, Buildings")] public readonly string[] Produces = { }; - public virtual object Create(ActorInitializer init) { return new Production(this); } + public virtual object Create(ActorInitializer init) { return new Production(this, init.self); } } [Desc("Where the unit should leave the building. Multiples are allowed if IDs are added: Exit@2, ...")] @@ -41,10 +42,13 @@ namespace OpenRA.Mods.RA public class Production { + Lazy rp; + public ProductionInfo Info; - public Production(ProductionInfo info) + public Production(ProductionInfo info, Actor self) { Info = info; + rp = Exts.Lazy(() => self.IsDead() ? null : self.TraitOrDefault()); } public void DoProduction(Actor self, ActorInfo producee, ExitInfo exitinfo) @@ -56,6 +60,10 @@ namespace OpenRA.Mods.RA var fi = producee.Traits.Get(); var initialFacing = exitinfo.Facing < 0 ? Util.GetFacing(to - spawn, fi.GetInitialFacing()) : exitinfo.Facing; + var exitLocation = rp.Value != null ? rp.Value.rallyPoint : exit; + var target = Target.FromCell(exitLocation); + var nearEnough = rp.Value != null ? WRange.FromCells(rp.Value.nearEnough) : WRange.Zero; + self.World.AddFrameEndTask(w => { var newUnit = self.World.CreateActor(producee.Name, new TypeDictionary @@ -66,34 +74,24 @@ namespace OpenRA.Mods.RA new FacingInit(initialFacing) }); - var move = newUnit.Trait(); - if (exitinfo.MoveIntoWorld) - newUnit.QueueActivity(move.MoveIntoWorld(newUnit, exit)); + var move = newUnit.TraitOrDefault(); + if (move != null) + { + if (exitinfo.MoveIntoWorld) + newUnit.QueueActivity(move.MoveIntoWorld(newUnit, exit)); - var target = MoveToRallyPoint(self, newUnit, exit); - newUnit.SetTargetLine(Target.FromCell(target), Color.Green, false); - foreach (var t in self.TraitsImplementing()) - t.UnitProduced(self, newUnit, exit); + newUnit.QueueActivity(new AttackMove.AttackMoveActivity( + newUnit, move.MoveWithinRange(target, nearEnough))); + } + + newUnit.SetTargetLine(target, Color.Green, false); + + if (!self.IsDead()) + foreach (var t in self.TraitsImplementing()) + t.UnitProduced(self, newUnit, exit); }); } - static CPos MoveToRallyPoint(Actor self, Actor newUnit, CPos exitLocation) - { - var rp = self.TraitOrDefault(); - if (rp == null) - return exitLocation; - - var move = newUnit.TraitOrDefault(); - if (move != null) - { - newUnit.QueueActivity(new AttackMove.AttackMoveActivity( - newUnit, move.MoveTo(rp.rallyPoint, rp.nearEnough))); - return rp.rallyPoint; - } - - return exitLocation; - } - public virtual bool Produce(Actor self, ActorInfo producee) { if (Reservable.IsReserved(self))