diff --git a/OpenRA.Mods.RA/Helicopter.cs b/OpenRA.Mods.RA/Helicopter.cs index 2f4883c821..d85dcad5f2 100644 --- a/OpenRA.Mods.RA/Helicopter.cs +++ b/OpenRA.Mods.RA/Helicopter.cs @@ -28,7 +28,9 @@ using OpenRA.Mods.RA.Activities; namespace OpenRA.Mods.RA { class HelicopterInfo : AircraftInfo - { + { + public readonly float InstabilityMagnitude = 2.0f; + public readonly int InstabilityTicks = 5; public readonly int IdealSeparation = 40; public readonly bool LandWhenIdle = true; @@ -99,10 +101,16 @@ namespace OpenRA.Mods.RA } } + int offsetTicks = 0; public void Tick(Actor self) { + var unit = self.traits.Get(); + if (unit.Altitude <= 0) + return; + + var Info = self.Info.Traits.Get(); var rawSpeed = .2f * Util.GetEffectiveSpeed(self, UnitMovementType.Fly); - var otherHelis = self.World.FindUnitsInCircle(self.CenterLocation, self.Info.Traits.Get().IdealSeparation) + var otherHelis = self.World.FindUnitsInCircle(self.CenterLocation, Info.IdealSeparation) .Where(a => a.traits.Contains()); var f = otherHelis @@ -110,7 +118,15 @@ namespace OpenRA.Mods.RA .Aggregate(float2.Zero, (a, b) => a + b); self.CenterLocation += rawSpeed * f; - Location = ((1 / 24f) * self.CenterLocation).ToInt2(); + + if (--offsetTicks <= 0) + { + self.CenterLocation += Info.InstabilityMagnitude * self.World.SharedRandom.Gauss2D(5); + unit.Altitude += (int)(Info.InstabilityMagnitude * self.World.SharedRandom.Gauss1D(5)); + offsetTicks = Info.InstabilityTicks; + } + + Location = ((1 / 24f) * self.CenterLocation).ToInt2(); } const float Epsilon = .5f; diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 6d73bc7a2c..da3c62eace 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -183,6 +183,7 @@ + diff --git a/OpenRA.Mods.RA/ProducesHelicopters.cs b/OpenRA.Mods.RA/ProducesHelicopters.cs new file mode 100644 index 0000000000..0467533a7b --- /dev/null +++ b/OpenRA.Mods.RA/ProducesHelicopters.cs @@ -0,0 +1,73 @@ +#region Copyright & License Information +/* + * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. + * This file is part of OpenRA. + * + * OpenRA is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenRA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenRA. If not, see . + */ +#endregion + +using System.Collections.Generic; +using System.Linq; +using OpenRA.GameRules; +using OpenRA.Traits; +using OpenRA.Traits.Activities; +using OpenRA.Mods.RA.Activities; + +namespace OpenRA.Mods.RA +{ + public class ProducesHelicoptersInfo : ProductionInfo + { + public override object Create(ActorInitializer init) { return new ProducesHelicopters(); } + } + + class ProducesHelicopters : Production + { + // Hack around visibility bullshit in Production + public override bool Produce( Actor self, ActorInfo producee ) + { + var location = CreationLocation( self, producee ); + if( location == null || self.World.WorldActor.traits.Get().GetUnitsAt( location.Value ).Any() ) + return false; + + var newUnit = self.World.CreateActor( producee.Name, location.Value, self.Owner ); + newUnit.traits.Get().Facing = CreationFacing( self, newUnit ); ; + + var pi = self.Info.Traits.Get(); + var rp = self.traits.GetOrDefault(); + if( rp != null || pi.ExitOffset != null) + { + if( newUnit.traits.Contains() ) + { + if (pi.ExitOffset != null) + newUnit.QueueActivity(new Activities.HeliFly(Util.CenterOfCell(ExitLocation( self, producee ).Value))); + + if (rp != null) + newUnit.QueueActivity( new Activities.HeliFly( Util.CenterOfCell(rp.rallyPoint)) ); + } + } + + if (pi != null && pi.SpawnOffset != null) + newUnit.CenterLocation = self.CenterLocation + + new float2(pi.SpawnOffset[0], pi.SpawnOffset[1]); + + foreach (var t in self.traits.WithInterface()) + t.UnitProduced(self, newUnit); + + Log.Write("debug", "{0} #{1} produced by {2} #{3}", newUnit.Info.Name, newUnit.ActorID, self.Info.Name, self.ActorID); + + return true; + } + } +} diff --git a/mods/cnc/structures.yaml b/mods/cnc/structures.yaml index 96bdaba3cf..bec2827142 100644 --- a/mods/cnc/structures.yaml +++ b/mods/cnc/structures.yaml @@ -293,6 +293,7 @@ FIX: BelowUnits: Reservable: RepairsUnits: + RallyPoint: HPAD: Inherits: ^Building @@ -314,11 +315,13 @@ HPAD: Crewed: yes Sight: 5 Bib: - Production: + ProducesHelicopters: SpawnOffset: 0,-4 Produces: Plane BelowUnits: Reservable: + RepairsUnits: + RallyPoint: EYE: RequiresPower: diff --git a/mods/cnc/vehicles.yaml b/mods/cnc/vehicles.yaml index 9a32690e7e..e80c0a7871 100644 --- a/mods/cnc/vehicles.yaml +++ b/mods/cnc/vehicles.yaml @@ -440,6 +440,8 @@ HELI: PrimaryOffset: -5,0,0,2 SecondaryOffset: 5,0,0,2 Helicopter: + RearmBuildings: + RepairBuildings: hpad LandWhenIdle: no RenderUnitRotor: PrimaryOffset: 0,0,0,-2 @@ -470,6 +472,8 @@ ORCA: PrimaryOffset: -5,0,0,2 SecondaryOffset: 5,0,0,2 Helicopter: + RearmBuildings: + RepairBuildings: hpad LandWhenIdle: no RenderUnit: WithShadow: