From 7ccb2aa9ee1e228b9132c62d67db3e16405d2050 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 23 Nov 2009 21:05:51 +1300 Subject: [PATCH] heli flight sortof ok --- OpenRa.Game/Game.cs | 17 +++++-- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/Helicopter.cs | 70 +++++++++++++++++++++++++++ OpenRa.Game/Traits/RenderUnit.cs | 5 +- OpenRa.Game/Traits/RenderUnitRotor.cs | 26 ++++------ OpenRa.Game/Traits/Util.cs | 2 +- OpenRa.Game/UnitOrders.cs | 13 +++-- units.ini | 7 +-- 8 files changed, 112 insertions(+), 29 deletions(-) create mode 100644 OpenRa.Game/Traits/Helicopter.cs diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 9a6e81e44f..97e4a8566c 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -373,13 +373,22 @@ namespace OpenRa.Game return; unit = new Actor(name, (1 / 24f * producer.CenterLocation).ToInt2(), player); - var mobile = unit.traits.Get(); - mobile.facing = 128; - var rp = producer.traits.GetOrDefault(); var dest = rp != null ? rp.rallyPoint : (unit.Location + new int2(0, 3)); - mobile.QueueActivity(new Traits.Activities.Move(dest, 1)); + var mobile = unit.traits.GetOrDefault(); + if (mobile != null) + { + mobile.facing = 128; + mobile.QueueActivity(new Traits.Activities.Move(dest, 1)); + } + + var heli = unit.traits.GetOrDefault(); + if (heli != null) + { + heli.facing = 20; + heli.targetLocation = dest; + } } world.Add(unit); diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 4dc2262e62..5066fefc11 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -142,6 +142,7 @@ + diff --git a/OpenRa.Game/Traits/Helicopter.cs b/OpenRa.Game/Traits/Helicopter.cs new file mode 100644 index 0000000000..c54d007113 --- /dev/null +++ b/OpenRa.Game/Traits/Helicopter.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.GameRules; + +namespace OpenRa.Game.Traits +{ + class Helicopter : ITick, IOrder + { + public int facing; + public int altitude; + public int2 targetLocation; + + const int CruiseAltitude = 20; + + public Helicopter(Actor self) + { + targetLocation = self.Location; + } + + public Order Order(Actor self, int2 xy, bool lmb, Actor underCursor) + { + if (lmb) return null; + + if (underCursor == null) + return OpenRa.Game.Order.Move(self, xy, + !Game.IsCellBuildable(xy, UnitMovementType.Foot)); + + return null; + } + + public void Tick(Actor self) + { + if (self.Location != targetLocation) + { + var dist = Game.CellSize * (targetLocation + new float2(.5f,.5f)) - self.CenterLocation; + var desiredFacing = Util.GetFacing(dist, facing); + Util.TickFacing(ref facing, desiredFacing, + self.unitInfo.ROT); + + // .6f going the wrong way; .8f going sideways, 1f going forward. + var rawSpeed = .2f * (self.unitInfo as UnitInfo.VehicleInfo).Speed; + var angle = (facing - desiredFacing) / 128f * Math.PI; + var scale = .4f + .6f * (float)Math.Cos(angle); + + if (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 (altitude < CruiseAltitude) + { + ++altitude; + return; + } + } + else if (altitude > 0 && + Game.IsCellBuildable( self.Location, UnitMovementType.Foot )) + { + --altitude; + } + + /* todo: bob slightly when hovering */ + } + } +} diff --git a/OpenRa.Game/Traits/RenderUnit.cs b/OpenRa.Game/Traits/RenderUnit.cs index 18f43284fb..98e2be0c74 100644 --- a/OpenRa.Game/Traits/RenderUnit.cs +++ b/OpenRa.Game/Traits/RenderUnit.cs @@ -18,9 +18,12 @@ namespace OpenRa.Game.Traits void PlayFacingAnim(Actor self) { + var mobile = self.traits.GetOrDefault(); + var heli = self.traits.GetOrDefault(); + anim.PlayFetchIndex("idle", () => Util.QuantizeFacing( - self.traits.Get().facing, + mobile != null ? mobile.facing : heli.facing, anim.CurrentSequence.Length )); } diff --git a/OpenRa.Game/Traits/RenderUnitRotor.cs b/OpenRa.Game/Traits/RenderUnitRotor.cs index 090b84ee60..7dcd0ef412 100755 --- a/OpenRa.Game/Traits/RenderUnitRotor.cs +++ b/OpenRa.Game/Traits/RenderUnitRotor.cs @@ -25,8 +25,6 @@ namespace OpenRa.Game.Traits public override IEnumerable> Render(Actor self) { - var mobile = self.traits.Get(); - yield return Util.CenteredShadow(self, anim.Image, self.CenterLocation); yield return Util.CenteredShadow(self, rotorAnim.Image, self.CenterLocation + Util.GetTurretPosition(self, self.unitInfo.PrimaryOffset, 0)); @@ -34,7 +32,8 @@ namespace OpenRa.Game.Traits yield return Util.CenteredShadow(self, (secondRotorAnim ?? rotorAnim).Image, self.CenterLocation + Util.GetTurretPosition(self, self.unitInfo.SecondaryOffset, 0)); - var p = self.CenterLocation - new float2( 0, altitude ); + var heli = self.traits.Get(); + var p = self.CenterLocation - new float2( 0, heli.altitude ); yield return Util.Centered(self, anim.Image, p); yield return Util.Centered(self, rotorAnim.Image, p @@ -44,10 +43,6 @@ namespace OpenRa.Game.Traits + Util.GetTurretPosition(self, self.unitInfo.SecondaryOffset, 0)); } - int altitude = 0; - const int climbRate = 1; - const int cruiseAltitude = 20; - public override void Tick(Actor self) { base.Tick(self); @@ -55,20 +50,17 @@ namespace OpenRa.Game.Traits if (secondRotorAnim != null) secondRotorAnim.Tick(); - var mobile = self.traits.Get(); - var isFlying = mobile.HasActivity; + var heli = self.traits.GetOrDefault(); + if (heli == null) return; + + var isFlying = heli.altitude > 0; - if (isFlying && altitude < cruiseAltitude) - altitude = Math.Min(altitude + climbRate, cruiseAltitude); - else if (!isFlying && altitude > 0) - altitude = Math.Max(altitude - climbRate, 0); - - if ((altitude >0) ^ (rotorAnim.CurrentSequence.Name != "rotor")) + if (isFlying ^ (rotorAnim.CurrentSequence.Name != "rotor")) return; - rotorAnim.PlayRepeatingPreservingPosition((altitude>0) ? "rotor" : "slow-rotor"); + rotorAnim.PlayRepeatingPreservingPosition(isFlying ? "rotor" : "slow-rotor"); if (secondRotorAnim != null) - secondRotorAnim.PlayRepeatingPreservingPosition((altitude>0) ? "rotor2" : "slow-rotor2"); + secondRotorAnim.PlayRepeatingPreservingPosition(isFlying ? "rotor2" : "slow-rotor2"); } } } diff --git a/OpenRa.Game/Traits/Util.cs b/OpenRa.Game/Traits/Util.cs index c7b3507869..7e823ad347 100755 --- a/OpenRa.Game/Traits/Util.cs +++ b/OpenRa.Game/Traits/Util.cs @@ -91,7 +91,7 @@ namespace OpenRa.Game.Traits var ru = self.traits.WithInterface().FirstOrDefault(); if (ru == null) return int2.Zero; /* things that don't have a rotating base don't need the turrets repositioned */ - var bodyFacing = self.traits.Get().facing; + var bodyFacing = self.traits.Contains() ? self.traits.Get().facing : self.traits.Get().facing; var quantizedFacing = QuantizeFacing(bodyFacing, ru.anim.CurrentSequence.Length) * (256 / ru.anim.CurrentSequence.Length); return (RotateVectorByFacing(new float2(offset[0], offset[1]), quantizedFacing, .7f) + GetRecoil(self, recoil)) diff --git a/OpenRa.Game/UnitOrders.cs b/OpenRa.Game/UnitOrders.cs index b1e745bd0a..af26a56ff9 100755 --- a/OpenRa.Game/UnitOrders.cs +++ b/OpenRa.Game/UnitOrders.cs @@ -15,9 +15,16 @@ namespace OpenRa.Game { case "Move": { - var mobile = order.Subject.traits.Get(); - mobile.Cancel( order.Subject ); - mobile.QueueActivity( new Traits.Activities.Move( order.TargetLocation, 8 ) ); + var mobile = order.Subject.traits.GetOrDefault(); + if (mobile != null) + { + mobile.Cancel(order.Subject); + mobile.QueueActivity(new Traits.Activities.Move(order.TargetLocation, 8)); + } + + var heli = order.Subject.traits.GetOrDefault(); + if (heli != null) + heli.targetLocation = order.TargetLocation; var attackBase = order.Subject.traits.WithInterface().FirstOrDefault(); if( attackBase != null ) diff --git a/units.ini b/units.ini index 160d40ec4b..97d71908b4 100755 --- a/units.ini +++ b/units.ini @@ -128,16 +128,17 @@ Description=Transport Helicopter PrimaryOffset=0,14,0,-4 SecondaryOffset=0,-14,0,-2 BuiltAt=hpad -Traits=Mobile, RenderUnitRotor +Traits=Helicopter, RenderUnitRotor SecondaryAnim=rotor2 [HELI] Description=Longbow BuiltAt=hpad -Traits=Mobile, RenderUnitRotor +Traits=Helicopter, RenderUnitRotor +PrimaryOffset=0,0,0,-2 [HIND] Description=Hind BuiltAt=hpad -Traits=Mobile, RenderUnitRotor +Traits=Helicopter, RenderUnitRotor