From 5a4fba43b0a02c38137d45aad2622b8bd61a2475 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sun, 20 Dec 2009 23:04:07 +1300 Subject: [PATCH] what a hack; it mostly works, but there are edge cases. --- OpenRa.Game/Traits/Activities/Fly.cs | 114 ++++++++++++++++++++++++-- OpenRa.Game/Traits/Plane.cs | 8 ++ OpenRa.Game/Traits/RenderUnitPlane.cs | 10 ++- units.ini | 11 ++- 4 files changed, 132 insertions(+), 11 deletions(-) diff --git a/OpenRa.Game/Traits/Activities/Fly.cs b/OpenRa.Game/Traits/Activities/Fly.cs index 62c4ab2ab7..7ff53f9ca1 100644 --- a/OpenRa.Game/Traits/Activities/Fly.cs +++ b/OpenRa.Game/Traits/Activities/Fly.cs @@ -7,10 +7,10 @@ namespace OpenRa.Game.Traits.Activities { class Fly : IActivity { - readonly int2 Cell; + readonly float2 Pos; bool isCanceled; - public Fly(int2 cell) { Cell = cell; } + public Fly(float2 pos) { Pos = pos; } public IActivity NextActivity { get; set; } @@ -20,7 +20,7 @@ namespace OpenRa.Game.Traits.Activities { if (isCanceled) return NextActivity; - var d = Util.CenterOfCell(Cell) - self.CenterLocation; + var d = Pos - self.CenterLocation; if (d.LengthSquared < 50) /* close enough */ return NextActivity; @@ -44,12 +44,49 @@ namespace OpenRa.Game.Traits.Activities public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } + class Land : IActivity + { + readonly float2 Pos; + bool isCanceled; + + public Land(float2 pos) { Pos = pos; } + + public IActivity NextActivity { get; set; } + + public IActivity Tick(Actor self) + { + if (isCanceled) return NextActivity; + + var d = Pos - self.CenterLocation; + if (d.LengthSquared < 50) /* close enough */ + return NextActivity; + + var unit = self.traits.Get(); + + if (unit.Altitude > 0) + --unit.Altitude; + + var desiredFacing = Util.GetFacing(d, unit.Facing); + Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.ROT); + var speed = .2f * Util.GetEffectiveSpeed(self); + var angle = unit.Facing / 128f * Math.PI; + + self.CenterLocation += speed * -float2.FromAngle((float)angle); + self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); + + return null; + } + + public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } + } + class FlyTimed : IActivity { public IActivity NextActivity { get; set; } int remainingTicks; + int targetAltitude; - public FlyTimed(int ticks) { remainingTicks = ticks; } + public FlyTimed(int ticks, int targetAltitude) { remainingTicks = ticks; this.targetAltitude = targetAltitude; } public IActivity Tick(Actor self) { @@ -65,6 +102,7 @@ namespace OpenRa.Game.Traits.Activities self.CenterLocation += speed * -float2.FromAngle((float)angle); self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); + unit.Altitude += Math.Sign(targetAltitude - unit.Altitude); return null; } @@ -82,10 +120,11 @@ namespace OpenRa.Game.Traits.Activities public IActivity Tick(Actor self) { if (isCanceled) return NextActivity; - return new Fly(Cell) + var unit = self.traits.Get(); + return new Fly(Util.CenterOfCell(Cell)) { NextActivity = - new FlyTimed(50) + new FlyTimed(50, 20) { NextActivity = this } @@ -94,4 +133,67 @@ namespace OpenRa.Game.Traits.Activities public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } } + + class ReturnToBase : IActivity + { + public IActivity NextActivity { get; set; } + bool isCanceled; + + readonly float2 w1, w2, w3; /* tangent points to turn circles */ + readonly float2 landPoint; + + public ReturnToBase(Actor self, float2 landPos) + { + var unit = self.traits.Get(); + var speed = .2f * Util.GetEffectiveSpeed(self); + var approachStart = landPos - new float2(unit.Altitude * speed, 0); + var turnRadius = (128f / self.Info.ROT) * speed / (float)Math.PI; + + /* work out the center points */ + var fwd = -float2.FromAngle(unit.Facing / 128f * (float)Math.PI); + var side = new float2(-fwd.Y, fwd.X); /* rotate */ + var sideTowardBase = new [] { side, -side } + .OrderBy( a => float2.Dot( a, self.CenterLocation - approachStart ) ) + .First(); + + var c1 = self.CenterLocation + turnRadius * sideTowardBase; + var c2 = approachStart + new float2(0, + turnRadius * Math.Sign( self.CenterLocation.Y - approachStart.Y )); // above or below start point + + /* work out tangent points */ + var d = c2 - c1; + var e = (turnRadius / d.Length) * d; + var f = new float2(-e.Y, e.X); /* rotate */ + + /* todo: support internal tangents, too! */ + + if (f.X > 0) f = -f; + + w1 = c1 + f; + w2 = c2 + f; + w3 = approachStart; + landPoint = landPos; + + var rup = self.traits.Get(); + rup.wps = new[] { self.CenterLocation, w1, w2, w3, landPoint, c1, c2 }; + } + + public IActivity Tick(Actor self) + { + if (isCanceled) return NextActivity; + var unit = self.traits.Get(); + return new Fly(w1) + { + NextActivity = new Fly(w2) + { + NextActivity = new Fly(w3) + { + NextActivity = new Land(landPoint) + } + } + }; + } + + public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } + } } diff --git a/OpenRa.Game/Traits/Plane.cs b/OpenRa.Game/Traits/Plane.cs index 5398111df3..163e8fea9c 100644 --- a/OpenRa.Game/Traits/Plane.cs +++ b/OpenRa.Game/Traits/Plane.cs @@ -17,6 +17,8 @@ namespace OpenRa.Game.Traits if (mi.Button == MouseButton.Left) return null; if (underCursor == null) return Order.Move(self, xy); + if (underCursor.Info == Rules.UnitInfo["AFLD"]) + return Order.DeliverOre(self, underCursor); /* brutal hack */ return null; } @@ -27,6 +29,12 @@ namespace OpenRa.Game.Traits self.CancelActivity(); self.QueueActivity(new Circle(order.TargetLocation)); } + + if (order.OrderString == "DeliverOre") + { + self.CancelActivity(); + self.QueueActivity(new ReturnToBase(self, order.TargetActor.CenterLocation)); + } } } } diff --git a/OpenRa.Game/Traits/RenderUnitPlane.cs b/OpenRa.Game/Traits/RenderUnitPlane.cs index 88463ee066..3bc981a584 100644 --- a/OpenRa.Game/Traits/RenderUnitPlane.cs +++ b/OpenRa.Game/Traits/RenderUnitPlane.cs @@ -3,13 +3,17 @@ using System.Collections.Generic; using System.Linq; using System.Text; using OpenRa.Game.Graphics; +using OpenRa.Game.Traits.Activities; namespace OpenRa.Game.Traits { class RenderUnitPlane : RenderUnit { + Animation debug = new Animation("litning"); + public float2[] wps; + public RenderUnitPlane(Actor self) - : base(self) {} + : base(self) { debug.PlayRepeating("bright"); debug.Tick(); } public override IEnumerable> Render(Actor self) { @@ -18,6 +22,10 @@ namespace OpenRa.Game.Traits yield return Util.CenteredShadow(self, anim.Image, self.CenterLocation); var p = self.CenterLocation - new float2(0, unit.Altitude); yield return Util.Centered(self, anim.Image, p); + + if (wps != null) + foreach (var w in wps) + yield return Tuple.New(debug.Image, w - .5f * debug.Image.size, 0); } } } diff --git a/units.ini b/units.ini index d08b485d37..26644b46d7 100755 --- a/units.ini +++ b/units.ini @@ -670,6 +670,8 @@ ImpactSound=kaboom15 OreChance=.02 LowPowerSlowdown=3 + + [VoiceTypes] GenericVoice VehicleVoice @@ -683,6 +685,7 @@ CivilianMaleVoice CivilianFemaleVoice EinsteinVoice +;; explicit extension on voice clips overrides the normal `variants` mechanism [GenericVoice] SovietVariants=.r01,.r03 AlliedVariants=.v01,.v03 @@ -699,12 +702,12 @@ Move=ackno,affirm1 [EngineerVoice] Select=eengin1,eyessir1 Move=eaffirm1,emovout1 -Die=dedman1.aud,dedman2.aud,dedman3.aud,dedman4.aud,dedman5.aud,dedman6.aud,dedman7.aud,dedman8.aud,dedman10.aud +Die=dedman1,dedman2,dedman3,dedman4,dedman5,dedman6,dedman7,dedman8,dedman10 [MedicVoice] Select=mrespon1,myessir1 Move=maffirm1,mmovout1 -Die=dedman1.aud,dedman2.aud,dedman3.aud,dedman4.aud,dedman5.aud,dedman6.aud,dedman7.aud,dedman8.aud,dedman10.aud +Die=dedman1,dedman2,dedman3,dedman4,dedman5,dedman6,dedman7,dedman8,dedman10 [TanyaVoice] Select=yo1,yes1,yeah1 @@ -722,12 +725,12 @@ Die=dogw5,dogw6,dogw7 Select=syessir1,scomnd1 Move=sonway1,sindeed1 Attack=sking1 -Die=dedman1.aud,dedman2.aud,dedman3.aud,dedman4.aud,dedman5.aud,dedman6.aud,dedman7.aud,dedman8.aud,dedman10.aud +Die=dedman1,dedman2,dedman3,dedman4,dedman5,dedman6,dedman7,dedman8,dedman10 [ThiefVoice] Select=swhat1,syeah1 Move=saffirm1,smout1,sokay1 -Die=dedman1.aud,dedman2.aud,dedman3.aud,dedman4.aud,dedman5.aud,dedman6.aud,dedman7.aud,dedman8.aud,dedman10.aud +Die=dedman1,dedman2,dedman3,dedman4,dedman5,dedman6,dedman7,dedman8,dedman10 [CivilianMaleVoice] Select=guyyeah1