diff --git a/OpenRA.Game/Traits/Mobile.cs b/OpenRA.Game/Traits/Mobile.cs index f7456b0ae1..19d2097c79 100644 --- a/OpenRA.Game/Traits/Mobile.cs +++ b/OpenRA.Game/Traits/Mobile.cs @@ -76,19 +76,21 @@ namespace OpenRA.Traits { this.self = init.self; this.Info = info; - if (init.Contains()) - this.__fromCell = this.__toCell = init.Get(); - - this.Facing = init.Contains() ? init.Get() : info.InitialFacing; - this.Altitude = init.Contains() ? init.Get() : 0; shroud = self.World.WorldActor.traits.Get(); uim = self.World.WorldActor.traits.Get(); bim = self.World.WorldActor.traits.Get(); canShareCell = self.traits.Contains(); - AddInfluence(); + if (init.Contains()) + { + this.__fromCell = this.__toCell = init.Get(); + AddInfluence(); + } + this.Facing = init.Contains() ? init.Get() : info.InitialFacing; + this.Altitude = init.Contains() ? init.Get() : 0; + TerrainCost = new Dictionary(); TerrainSpeed = new Dictionary(); diff --git a/OpenRA.Game/Traits/Production.cs b/OpenRA.Game/Traits/Production.cs index 85c19cfc58..efce2a5753 100755 --- a/OpenRA.Game/Traits/Production.cs +++ b/OpenRA.Game/Traits/Production.cs @@ -43,22 +43,19 @@ namespace OpenRA.Traits public void DoProduction(Actor self, Actor newUnit, int2 exit, float2 spawn) { - Game.Debug("Creating actor {0}".F(newUnit.Info.Name)); + var move = newUnit.traits.Get(); + var facing = newUnit.traits.GetOrDefault(); - var mobile = newUnit.traits.Get(); - - // 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); + move.SetPosition(newUnit,exit); var to = Util.CenterOfCell(exit); + newUnit.CenterLocation = spawn; + if (facing != null) + facing.Facing = Util.GetFacing(to - spawn, facing.Facing); + self.World.Add(newUnit); // Animate the spawn -> exit transition - newUnit.CenterLocation = spawn; - mobile.Facing = Util.GetFacing(to - spawn, mobile.Facing); - var speed = mobile.MovementSpeedForCell(self, exit); + var speed = move.MovementSpeedForCell(self, exit); var length = speed > 0 ? (int)( ( to - spawn ).Length*3 / speed ) : 0; newUnit.QueueActivity(new Activities.Drag(spawn, to, length)); @@ -68,6 +65,7 @@ namespace OpenRA.Traits if (rp != null) { target = rp.rallyPoint; + // Todo: Move implies unit has Mobile newUnit.QueueActivity(new Activities.Move(target, 1)); } @@ -82,7 +80,7 @@ namespace OpenRA.Traits } foreach (var t in self.traits.WithInterface()) - t.UnitProduced(self, newUnit); + t.UnitProduced(self, newUnit, exit); Log.Write("debug", "{0} #{1} produced by {2} #{3}", newUnit.Info.Name, newUnit.ActorID, self.Info.Name, self.ActorID); } @@ -94,40 +92,26 @@ namespace OpenRA.Traits new OwnerInit( self.Owner ), }); - // Todo: remove assumption on Mobile + // Todo: remove assumption on Mobile; + // required for 3-arg CanEnterCell 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 + // Pick a spawn/exit point pair // Todo: Reorder in a synced random way foreach (var s in Spawns) { - exit = self.Location + s.Value; - spawn = self.CenterLocation + s.Key; + var exit = self.Location + s.Value; + var spawn = self.CenterLocation + s.Key; if (mobile.CanEnterCell(exit,self,true)) { - success = true; - break; + DoProduction(self, newUnit, exit, spawn); + return true; } } - - 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; + return false; } // "primary building" crap - perhaps this should be split? - bool isPrimary = false; public bool IsPrimary { get { return isPrimary; } } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 3e97f6fbbb..af323f0420 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -40,7 +40,7 @@ namespace OpenRA.Traits public interface INotifySold { void Selling( Actor self ); void Sold( Actor self ); } public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); } public interface INotifyBuildComplete { void BuildingComplete(Actor self); } - public interface INotifyProduction { void UnitProduced(Actor self, Actor other); } + public interface INotifyProduction { void UnitProduced(Actor self, Actor other, int2 exit); } public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); } public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); } public interface INotifyEnterCell { void OnEnterCell(Actor self, int2 cell); } diff --git a/OpenRA.Mods.RA/ProducesHelicopters.cs b/OpenRA.Mods.RA/ProducesHelicopters.cs index b0f3c4757a..ebb887acbe 100644 --- a/OpenRA.Mods.RA/ProducesHelicopters.cs +++ b/OpenRA.Mods.RA/ProducesHelicopters.cs @@ -64,7 +64,7 @@ namespace OpenRA.Mods.RA } foreach (var t in self.traits.WithInterface()) - t.UnitProduced(self, newUnit); + t.UnitProduced(self, newUnit, exit); Log.Write("debug", "{0} #{1} produced by {2} #{3}", newUnit.Info.Name, newUnit.ActorID, self.Info.Name, self.ActorID); diff --git a/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs b/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs index 7de2a0d36d..3f1b8774cd 100644 --- a/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs +++ b/OpenRA.Mods.RA/Render/RenderBuildingWarFactory.cs @@ -24,7 +24,9 @@ namespace OpenRA.Mods.RA.Render public Animation roof; [Sync] bool isOpen; - + [Sync] + int2 openExit; + string GetPrefix(Actor self) { return self.GetDamageState() >= DamageState.Heavy ? "damaged-" : ""; @@ -44,7 +46,7 @@ namespace OpenRA.Mods.RA.Render public void Tick(Actor self) { if (isOpen && !self.World.WorldActor.traits.Get() - .GetUnitsAt(((1f/Game.CellSize) * self.CenterLocation).ToInt2()).Any()) + .GetUnitsAt(openExit).Any()) { isOpen = false; roof.PlayBackwardsThen(GetPrefix(self) + "build-top", () => roof.Play(GetPrefix(self) + "idle-top")); @@ -61,9 +63,9 @@ namespace OpenRA.Mods.RA.Render roof.ReplaceAnim(roof.CurrentSequence.Name.Replace("damaged-","")); } - public void UnitProduced(Actor self, Actor other) + public void UnitProduced(Actor self, Actor other, int2 exit) { - roof.PlayThen(GetPrefix(self) + "build-top", () => isOpen = true); + roof.PlayThen(GetPrefix(self) + "build-top", () => {isOpen = true; openExit = exit;}); } public void Selling( Actor self ) diff --git a/mods/cnc/structures.yaml b/mods/cnc/structures.yaml index ee65f68931..334613025f 100644 --- a/mods/cnc/structures.yaml +++ b/mods/cnc/structures.yaml @@ -212,6 +212,7 @@ AFLD: Range: 7 Bib: RallyPoint: + RallyPoint: 4,2 BelowUnits: ProductionAirdrop: Produces: Vehicle @@ -241,9 +242,11 @@ WEAP: Bib: RenderWarFactory: RallyPoint: + RallyPoint: 0,3 Production: -# ExitOffset:-1,1 Produces: Vehicle + SpawnOffsets: -8,-8 + ExitCells: 0,2 HQ: RequiresPower: CanPowerDown: