diff --git a/OpenRA.Mods.RA/Air/ReservableProduction.cs b/OpenRA.Mods.RA/Air/ReservableProduction.cs deleted file mode 100755 index a82d9a1220..0000000000 --- a/OpenRA.Mods.RA/Air/ReservableProduction.cs +++ /dev/null @@ -1,62 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2010 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 LICENSE. - */ -#endregion - -using System.Linq; -using OpenRA.FileFormats; -using OpenRA.Traits; - -namespace OpenRA.Mods.RA.Air -{ - // a small hack to teach Production about Reservable. - - public class ReservableProductionInfo : ProductionInfo, ITraitPrerequisite - { - public override object Create(ActorInitializer init) { return new ReservableProduction(this); } - } - - class ReservableProduction : Production - { - public ReservableProduction(ReservableProductionInfo info) : base(info) {} - - public override bool Produce(Actor self, ActorInfo producee) - { - if (Reservable.IsReserved(self)) - return false; - - // Pick a spawn/exit point - // Todo: Reorder in a synced random way - foreach (var s in self.Info.Traits.WithInterface()) - { - var exit = self.Location + s.ExitCell; - if (!self.World.WorldActor.Trait().GetUnitsAt( exit ).Any( x => x != self )) - { - var newUnit = self.World.CreateActor( producee.Name, new TypeDictionary - { - new LocationInit( exit ), - new OwnerInit( self.Owner ), - }); - - var rp = self.TraitOrDefault(); - if( rp != null ) - { - newUnit.QueueActivity( new HeliFly( Util.CenterOfCell(rp.rallyPoint)) ); - } - - foreach (var t in self.TraitsImplementing()) - t.UnitProduced(self, newUnit, exit); - - //Log.Write("debug", "{0} #{1} produced by {2} #{3}", newUnit.Info.Name, newUnit.ActorID, self.Info.Name, self.ActorID); - return true; - } - } - return false; - } - } -} diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 5a720977f7..9dabe345d1 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -151,7 +151,6 @@ - @@ -353,8 +352,4 @@ copy "$(TargetPath)" "$(SolutionDir)mods/ra/" cd "$(SolutionDir)" - - - - \ No newline at end of file diff --git a/OpenRA.Mods.RA/Production.cs b/OpenRA.Mods.RA/Production.cs index b3e470609d..3ee7cc57fe 100755 --- a/OpenRA.Mods.RA/Production.cs +++ b/OpenRA.Mods.RA/Production.cs @@ -9,10 +9,12 @@ #endregion using System.Drawing; +using System.Linq; using OpenRA.FileFormats; using OpenRA.Traits; using OpenRA.Traits.Activities; using OpenRA.Mods.RA.Move; +using OpenRA.Mods.RA.Air; namespace OpenRA.Mods.RA { @@ -49,54 +51,82 @@ namespace OpenRA.Mods.RA var exit = self.Location + exitinfo.ExitCell; var spawn = self.Trait().PxPosition + exitinfo.SpawnOffset; - var mobile = newUnit.Trait(); + var teleportable = newUnit.Trait(); var facing = newUnit.TraitOrDefault(); // Set the physical position of the unit as the exit cell - mobile.SetPosition(newUnit,exit); + teleportable.SetPosition(newUnit,exit); var to = Util.CenterOfCell(exit); - mobile.PxPosition = spawn; + teleportable.SetPxPosition(newUnit, spawn); if (facing != null) facing.Facing = exitinfo.Facing < 0 ? Util.GetFacing(to - spawn, facing.Facing) : exitinfo.Facing; self.World.Add(newUnit); - // Animate the spawn -> exit transition - var speed = mobile.MovementSpeedForCell(self, exit); - var length = speed > 0 ? (int)( ( to - spawn ).Length*3 / speed ) : 0; - newUnit.QueueActivity(new Drag(spawn, to, length)); + var mobile = newUnit.TraitOrDefault(); + if (mobile != null) + { + // Animate the spawn -> exit transition + var speed = mobile.MovementSpeedForCell(newUnit, exit); + var length = speed > 0 ? (int)((to - spawn).Length * 3 / speed) : 0; + newUnit.QueueActivity(new Drag(spawn, to, length)); + } -// Log.Write("debug", "length={0} facing={1} exit={2} spawn={3}", length, facing.Facing, exit, spawn); - - // For the target line - var target = exit; - var rp = self.TraitOrDefault(); - if (rp != null) - { - target = rp.rallyPoint; - newUnit.QueueActivity(mobile.MoveTo(target, 1)); - } + 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); - - //Log.Write("debug", "{0} #{1} produced by {2} #{3}", newUnit.Info.Name, newUnit.ActorID, self.Info.Name, self.ActorID); } + static int2 MoveToRallyPoint(Actor self, Actor newUnit, int2 exitLocation) + { + var rp = self.TraitOrDefault(); + if (rp == null) + return exitLocation; + + var mobile = self.TraitOrDefault(); + if (mobile != null) + { + newUnit.QueueActivity(mobile.MoveTo(rp.rallyPoint, 1)); + return rp.rallyPoint; + } + + // todo: don't talk about HeliFly here. + var helicopter = self.TraitOrDefault(); + if (helicopter != null) + { + newUnit.QueueActivity(new HeliFly(Util.CenterOfCell(rp.rallyPoint))); + return rp.rallyPoint; + } + + return exitLocation; + } + public virtual bool Produce(Actor self, ActorInfo producee) { - // todo: remove Mobile requirement. - var mobileInfo = producee.Traits.Get(); - var uim = self.World.WorldActor.Trait(); + if (Reservable.IsReserved(self)) + return false; // pick a spawn/exit point pair - foreach (var s in self.Info.Traits.WithInterface().Shuffle(self.World.SharedRandom)) - if (mobileInfo.CanEnterCell(self.World, uim, self.Location + s.ExitCell, self, true)) - { - DoProduction(self, producee, s); - return true; - } + var exit = self.Info.Traits.WithInterface().Shuffle(self.World.SharedRandom) + .FirstOrDefault(e => CanUseExit(self, producee, e)); + + if (exit != null) + { + DoProduction(self, producee, exit); + return true; + } + return false; } + + static bool CanUseExit(Actor self, ActorInfo producee, ExitInfo s) + { + var uim = self.World.WorldActor.Trait(); + var mobileInfo = producee.Traits.GetOrDefault(); + + return mobileInfo == null || + mobileInfo.CanEnterCell(self.World, uim, self.Location + s.ExitCell, self, true); + } } } diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index 8c0a5dafe0..4bfdd9db5d 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -388,7 +388,7 @@ HPAD: Bib: Exit@1: SpawnOffset: 0,-6 - ReservableProduction: + Production: Produces: Plane BelowUnits: Reservable: diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 6c92f1fd30..1bf328adad 100755 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -698,7 +698,7 @@ HPAD: Exit@1: SpawnOffset: 0,-6 ExitCell: 0,0 - ReservableProduction: + Production: Produces: Plane PrimaryBuilding: BelowUnits: @@ -732,7 +732,7 @@ AFLD: Exit@1: SpawnOffset: 0,-4 ExitCell: 1,1 - ReservableProduction: + Production: Produces: Plane PrimaryBuilding: BelowUnits: