diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 57c74ffc8b..da4ca11ed3 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -114,6 +114,8 @@ + + diff --git a/OpenRa.Game/Traits/Activities/HeliFly.cs b/OpenRa.Game/Traits/Activities/HeliFly.cs new file mode 100644 index 0000000000..c27de496f1 --- /dev/null +++ b/OpenRa.Game/Traits/Activities/HeliFly.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.Traits.Activities +{ + class HeliFly : IActivity + { + const int CruiseAltitude = 20; + readonly float2 Dest; + public HeliFly(float2 dest) + { + Dest = dest; + } + + public IActivity NextActivity { get; set; } + bool isCanceled; + + public IActivity Tick(Actor self) + { + if (isCanceled) + return NextActivity; + + var unit = self.traits.Get(); + + if (unit.Altitude != CruiseAltitude) + { + unit.Altitude += Math.Sign(CruiseAltitude - unit.Altitude); + return this; + } + + var dist = Dest - self.CenterLocation; + if (float2.WithinEpsilon(float2.Zero, dist, 10)) + return NextActivity; + + var desiredFacing = Util.GetFacing(dist, unit.Facing); + Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.ROT); + + var rawSpeed = .2f * Util.GetEffectiveSpeed(self); + self.CenterLocation += (rawSpeed / dist.Length) * dist; + self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); + + return this; + } + + public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } + } +} diff --git a/OpenRa.Game/Traits/Activities/HeliLand.cs b/OpenRa.Game/Traits/Activities/HeliLand.cs new file mode 100644 index 0000000000..eea8171415 --- /dev/null +++ b/OpenRa.Game/Traits/Activities/HeliLand.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.Traits.Activities +{ + class HeliLand : IActivity + { + public HeliLand(bool requireSpace) { this.requireSpace = requireSpace; } + + bool requireSpace; + bool isCanceled; + public IActivity NextActivity { get; set; } + + public IActivity Tick(Actor self) + { + if (isCanceled) return NextActivity; + var unit = self.traits.Get(); + if (unit.Altitude == 0) + return NextActivity; + + if (requireSpace && !Game.IsCellBuildable(self.Location, UnitMovementType.Foot)) + return this; // fail to land if no space + + --unit.Altitude; + return this; + } + + public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } + } +} diff --git a/OpenRa.Game/Traits/Helicopter.cs b/OpenRa.Game/Traits/Helicopter.cs index 400456f832..0c1d5b1a82 100644 --- a/OpenRa.Game/Traits/Helicopter.cs +++ b/OpenRa.Game/Traits/Helicopter.cs @@ -1,19 +1,13 @@ using System; using System.Linq; using OpenRa.Game.GameRules; +using OpenRa.Game.Traits.Activities; namespace OpenRa.Game.Traits { - class Helicopter : ITick, IOrder, IMovement + class Helicopter : IOrder, IMovement { - public int2 targetLocation; - - const int CruiseAltitude = 20; - - public Helicopter(Actor self) - { - targetLocation = self.Location; - } + public Helicopter(Actor self) {} public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { @@ -27,61 +21,15 @@ namespace OpenRa.Game.Traits public void ResolveOrder( Actor self, Order order ) { - if( order.OrderString == "Move" ) + if (order.OrderString == "Move") { - targetLocation = order.TargetLocation; - - var attackBase = self.traits.WithInterface().FirstOrDefault(); - if( attackBase != null ) - attackBase.target = null; /* move cancels attack order */ + self.CancelActivity(); + self.QueueActivity(new HeliFly(Util.CenterOfCell(order.TargetLocation))); + self.QueueActivity(new HeliLand(true)); } } - public void Tick(Actor self) - { - var unit = self.traits.Get(); - - if (self.Location != targetLocation) - { - var dist = Util.CenterOfCell(targetLocation) - self.CenterLocation; - var desiredFacing = Util.GetFacing(dist, unit.Facing); - Util.TickFacing(ref unit.Facing, desiredFacing, - self.Info.ROT); - - var rawSpeed = .2f * Util.GetEffectiveSpeed(self); - var angle = (unit.Facing - desiredFacing) / 128f * Math.PI; - var scale = .4f + .6f * (float)Math.Cos(angle); - - if (unit.Altitude > CruiseAltitude / 2) // do some movement. - { - self.CenterLocation += (rawSpeed * scale / dist.Length) * dist; - self.CenterLocation += (1f - scale) * rawSpeed - * float2.FromAngle((float)angle); - self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); - } - - if (unit.Altitude < CruiseAltitude) - { - ++unit.Altitude; - return; - } - } - else if (unit.Altitude > 0 && - Game.IsCellBuildable( self.Location, UnitMovementType.Foot )) - { - --unit.Altitude; - } - - /* todo: bob slightly when hovering */ - } - public UnitMovementType GetMovementType() - { - return UnitMovementType.Fly; - } - - public bool CanEnterCell(int2 location) - { - return true; // Planes can go anywhere (?) - } + public UnitMovementType GetMovementType() { return UnitMovementType.Fly; } + public bool CanEnterCell(int2 location) { return true; } } } diff --git a/OpenRa.Game/Traits/Production.cs b/OpenRa.Game/Traits/Production.cs index f916f05dc5..c4d1413f39 100755 --- a/OpenRa.Game/Traits/Production.cs +++ b/OpenRa.Game/Traits/Production.cs @@ -33,10 +33,6 @@ namespace OpenRa.Game.Traits var mobile = newUnit.traits.GetOrDefault(); if( mobile != null ) newUnit.QueueActivity( new Activities.Move( rp.rallyPoint, 1 ) ); - - var heli = newUnit.traits.GetOrDefault(); - if (heli != null) - heli.targetLocation = rp.rallyPoint; // TODO: make Activity.Move work for helis. } var bi = self.Info as BuildingInfo;