diff --git a/OpenRA.Game/Traits/Production.cs b/OpenRA.Game/Traits/Production.cs index c21ead443f..85c19cfc58 100755 --- a/OpenRA.Game/Traits/Production.cs +++ b/OpenRA.Game/Traits/Production.cs @@ -41,44 +41,16 @@ namespace OpenRA.Traits Spawns.Add(new float2(info.SpawnOffsets[i],info.SpawnOffsets[i+1]), new int2(info.ExitCells[i], info.ExitCells[i+1])); } - public virtual bool Produce( Actor self, ActorInfo producee ) - { - var newUnit = self.World.CreateActor(false, producee.Name, new TypeDictionary - { - new OwnerInit( self.Owner ), - }); + public void DoProduction(Actor self, Actor newUnit, int2 exit, float2 spawn) + { + Game.Debug("Creating actor {0}".F(newUnit.Info.Name)); - // Todo: remove assumption on Mobile var mobile = newUnit.traits.Get(); - - // Pick an exit that we can move to - var exit = int2.Zero; - var spawn = float2.Zero; - var success = false; - - // Pick a spawn/exit point - // Todo: Reorder in a synced random way - foreach (var s in Spawns) - { - exit = self.Location + s.Value; - spawn = self.CenterLocation + s.Key; - if (mobile.CanEnterCell(exit,self,true)) - { - success = true; - break; - } - } - - if (!success) - { - // Hack around mobile being a tard; remove from UIM (we shouldn't be there in the first place) - newUnit.traits.Get().RemoveInfluence(); - return false; - } // Unit can be built; add to the world self.World.Add(newUnit); - + Game.Debug("Added to world"); + // Set the physical position of the unit as the exit cell mobile.SetPosition(newUnit,exit); var to = Util.CenterOfCell(exit); @@ -113,7 +85,44 @@ namespace OpenRA.Traits t.UnitProduced(self, newUnit); Log.Write("debug", "{0} #{1} produced by {2} #{3}", newUnit.Info.Name, newUnit.ActorID, self.Info.Name, self.ActorID); + } + + public virtual bool Produce( Actor self, ActorInfo producee ) + { + var newUnit = self.World.CreateActor(false, producee.Name, new TypeDictionary + { + new OwnerInit( self.Owner ), + }); + + // Todo: remove assumption on Mobile + var mobile = newUnit.traits.Get(); + + // Pick an exit that we can move to + var exit = int2.Zero; + var spawn = float2.Zero; + var success = false; + + // Pick a spawn/exit point + // Todo: Reorder in a synced random way + foreach (var s in Spawns) + { + exit = self.Location + s.Value; + spawn = self.CenterLocation + s.Key; + if (mobile.CanEnterCell(exit,self,true)) + { + success = true; + break; + } + } + + if (!success) + { + // Hack around mobile being a tard; remove from UIM (we shouldn't be there in the first place) + newUnit.traits.Get().RemoveInfluence(); + return false; + } + DoProduction(self, newUnit, exit, spawn); return true; } diff --git a/OpenRA.Mods.Cnc/ProductionAirdrop.cs b/OpenRA.Mods.Cnc/ProductionAirdrop.cs index f22f93acac..67b19bc705 100644 --- a/OpenRA.Mods.Cnc/ProductionAirdrop.cs +++ b/OpenRA.Mods.Cnc/ProductionAirdrop.cs @@ -33,12 +33,14 @@ namespace OpenRA.Mods.Cnc var owner = self.Owner; // Start and end beyond the edge of the map, to give a finite delay, and ability to land when AFLD is on map edge - var startPos = new int2(owner.World.Map.XOffset + owner.World.Map.Width+15, self.Location.Y); - var endPos = new int2(owner.World.Map.XOffset-15, self.Location.Y); - var unloadOffset = new int2(1,1); - var exitOffset = new int2(3,1); + var startPos = new int2(owner.World.Map.XOffset + owner.World.Map.Width+5, self.Location.Y); + var endPos = new int2(owner.World.Map.XOffset-5, self.Location.Y); + + + // Assume a single exit point for simplicity + var spawn = self.CenterLocation + Spawns.First().Key; + var exit = self.Location + Spawns.First().Value; - var rp = self.traits.GetOrDefault(); owner.World.AddFrameEndTask(w => { var a = w.CreateActor("C17", new TypeDictionary @@ -50,37 +52,20 @@ namespace OpenRA.Mods.Cnc }); var cargo = a.traits.Get(); - - var newUnit = self.World.CreateActor(false, producee.Name, new TypeDictionary{ new OwnerInit( self.Owner ) }); + var newUnit = self.World.CreateActor(false, producee.Name, new TypeDictionary + { + new OwnerInit( self.Owner ), + }); cargo.Load(a, newUnit); - a.CancelActivity(); - a.QueueActivity(new Land(Target.FromActor(self))); a.QueueActivity(new CallFunc(() => { if (self.IsDead()) return; - var actor = cargo.Unload(self); - self.World.AddFrameEndTask(ww => - { - ww.Add(actor); - actor.traits.Get().SetPosition(actor, self.Location + unloadOffset); - newUnit.traits.Get().Facing = 192; - actor.CancelActivity(); - actor.QueueActivity(new Move(self.Location + exitOffset, self)); - actor.QueueActivity(new Move(rp.rallyPoint, 0)); - if (actor.Owner == self.World.LocalPlayer) - { - var line = actor.traits.GetOrDefault(); - if (line != null) - line.SetTargetSilently(actor, Target.FromCell(rp.rallyPoint), Color.Green); - } - - foreach (var t in self.traits.WithInterface()) - t.UnitProduced(self, actor); - }); + Game.Debug("Creating"); + self.World.AddFrameEndTask(ww => DoProduction(self, cargo.Unload(self), exit, spawn)); })); a.QueueActivity(new Fly(endPos)); a.QueueActivity(new RemoveSelf()); diff --git a/OpenRA.Mods.RA/ProducesHelicopters.cs b/OpenRA.Mods.RA/ProducesHelicopters.cs index 0b8a57d77d..b0f3c4757a 100644 --- a/OpenRA.Mods.RA/ProducesHelicopters.cs +++ b/OpenRA.Mods.RA/ProducesHelicopters.cs @@ -45,6 +45,9 @@ namespace OpenRA.Mods.RA break; } } + + if (!success) + return false; // Todo: Once Helicopter supports it, update UIM if its docked/landed var newUnit = self.World.CreateActor( producee.Name, new TypeDictionary diff --git a/mods/cnc/structures.yaml b/mods/cnc/structures.yaml index 3c3a3d5fef..ee65f68931 100644 --- a/mods/cnc/structures.yaml +++ b/mods/cnc/structures.yaml @@ -215,7 +215,8 @@ AFLD: BelowUnits: ProductionAirdrop: Produces: Vehicle - + SpawnOffsets: -24,0 + ExitCells:3,1 WEAP: Inherits: ^Building Buildable: