From 55e59e0b53becdcb7cfce713e1985e4c334f45d5 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 23 Jul 2010 18:40:39 +1200 Subject: [PATCH] Unhardcode voice/order interaction; reimplement for move and attack --- OpenRA.Game/Controller.cs | 26 +++++++++++++------------- OpenRA.Game/Sound.cs | 15 +++++++++------ OpenRA.Game/Traits/Mobile.cs | 10 +++++++++- OpenRA.Game/Traits/TraitsInterfaces.cs | 1 + OpenRA.Game/WorldUtils.cs | 7 +++++++ OpenRA.Mods.RA/AttackBase.cs | 7 ++++++- OpenRA.Mods.RA/Helicopter.cs | 7 ++++++- OpenRA.Mods.RA/Plane.cs | 7 ++++++- 8 files changed, 57 insertions(+), 23 deletions(-) diff --git a/OpenRA.Game/Controller.cs b/OpenRA.Game/Controller.cs index 77de83a27e..7563fe922c 100644 --- a/OpenRA.Game/Controller.cs +++ b/OpenRA.Game/Controller.cs @@ -44,20 +44,20 @@ namespace OpenRA var orders = orderGenerator.Order(world, xy.ToInt2(), mi).ToArray(); Game.orderManager.IssueOrders( orders ); - - var voicedActor = orders.Select(o => o.Subject) - .FirstOrDefault(a => a.Owner == world.LocalPlayer && a.HasVoice()); - - var isMove = orders.Any(o => o.OrderString == "Move"); - var isAttack = orders.Any( o => o.OrderString == "Attack" ); - - if (voicedActor != null) + + // Find an actor with a phrase to say + var done = false; + foreach (var o in orders) { - if(voicedActor.traits.GetOrDefault().CanEnterCell(xy.ToInt2())) - Sound.PlayVoice(isAttack ? "Attack" : "Move", voicedActor); - - if (isMove) - world.Add(new Effects.MoveFlash(world, Game.CellSize * xy)); + foreach (var v in o.Subject.traits.WithInterface()) + { + if (Sound.PlayVoice(v.VoicePhraseForOrder(o.Subject, o), o.Subject)) + { + done = true; + break; + } + } + if (done) break; } } diff --git a/OpenRA.Game/Sound.cs b/OpenRA.Game/Sound.cs index 297d886e21..c139cf0553 100644 --- a/OpenRA.Game/Sound.cs +++ b/OpenRA.Game/Sound.cs @@ -132,24 +132,26 @@ namespace OpenRA } } - public static void PlayVoice(string phrase, Actor voicedUnit) + // Returns true if it played a phrase + public static bool PlayVoice(string phrase, Actor voicedUnit) { - if (voicedUnit == null) return; + if (voicedUnit == null) return false; + if (phrase == null) return false; var mi = voicedUnit.Info.Traits.GetOrDefault(); - if (mi == null) return; - if (mi.Voice == null) return; + if (mi == null) return false; + if (mi.Voice == null) return false; var vi = Rules.Voices[mi.Voice.ToLowerInvariant()]; var clip = vi.Pools.Value[phrase].GetNext(); if (clip == null) - return; + return false; if (clip.Contains(".")) /* no variants! */ { Play(clip); - return; + return true; } // todo: fix this @@ -159,6 +161,7 @@ namespace OpenRA var variant = variants[voicedUnit.ActorID % variants.Length]; Play(clip + variant); + return true; } } diff --git a/OpenRA.Game/Traits/Mobile.cs b/OpenRA.Game/Traits/Mobile.cs index 95b11fafe8..551dba4846 100644 --- a/OpenRA.Game/Traits/Mobile.cs +++ b/OpenRA.Game/Traits/Mobile.cs @@ -27,7 +27,7 @@ namespace OpenRA.Traits public virtual object Create(ActorInitializer init) { return new Mobile(init, this); } } - public class Mobile : IIssueOrder, IResolveOrder, IOccupySpace, IMove, IOrderCursor, INudge + public class Mobile : IIssueOrder, IResolveOrder, IOrderCursor, IOrderVoice, IOccupySpace, IMove, INudge { public readonly Actor self; public readonly MobileInfo Info; @@ -108,6 +108,9 @@ namespace OpenRA.Traits { if( !order.Queued ) self.CancelActivity(); self.QueueActivity(new Activities.Move(order.TargetLocation, 8)); + + if (self.Owner == self.World.LocalPlayer) + self.World.Add(new Effects.MoveFlash(self.World, Game.CellSize * (order.TargetLocation + new float2(0.5f, 0.5f)))); } } } @@ -119,6 +122,11 @@ namespace OpenRA.Traits return (CanEnterCell(order.TargetLocation)) ? "move" : "move-blocked"; } + + public string VoicePhraseForOrder(Actor self, Order order) + { + return (order.OrderString == "Move") ? "Move" : null; + } public int2 TopLeft { get { return toCell; } } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index ff80f9de55..03982fd3da 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -36,6 +36,7 @@ namespace OpenRA.Traits public interface IIssueOrder { Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor ); } public interface IResolveOrder { void ResolveOrder(Actor self, Order order); } public interface IOrderCursor { string CursorForOrder(Actor self, Order order); } + public interface IOrderVoice { string VoicePhraseForOrder(Actor self, Order order); } public interface INotifySold { void Selling( Actor self ); void Sold( Actor self ); } public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); } diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index c7c5521993..964b7c35e9 100755 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -216,5 +216,12 @@ namespace OpenRA { return a.Info.Traits.Contains() && a.Info.Traits.Get().Voice != null; } + + public static VoiceInfo GetVoice(this Actor a) + { + if (!a.Info.Traits.Contains()) return null; + var v = a.Info.Traits.Get().Voice; + return (v == null) ? null : Rules.Voices[v]; + } } } diff --git a/OpenRA.Mods.RA/AttackBase.cs b/OpenRA.Mods.RA/AttackBase.cs index 9cd5ad80e4..c61937462d 100755 --- a/OpenRA.Mods.RA/AttackBase.cs +++ b/OpenRA.Mods.RA/AttackBase.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.RA public virtual object Create(ActorInitializer init) { return new AttackBase(init.self); } } - public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor + public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor, IOrderVoice { public Target target; @@ -263,6 +263,11 @@ namespace OpenRA.Mods.RA } } + public string VoicePhraseForOrder(Actor self, Order order) + { + return (order.OrderString == "Attack" || order.OrderString == "Heal") ? "Attack" : null; + } + protected virtual void QueueAttack(Actor self, Order order) { /* todo: choose the appropriate weapon, when only one works against this target */ diff --git a/OpenRA.Mods.RA/Helicopter.cs b/OpenRA.Mods.RA/Helicopter.cs index 5182ab61cd..b58e990022 100644 --- a/OpenRA.Mods.RA/Helicopter.cs +++ b/OpenRA.Mods.RA/Helicopter.cs @@ -27,7 +27,7 @@ namespace OpenRA.Mods.RA public override object Create( ActorInitializer init ) { return new Helicopter( init ); } } - class Helicopter : Aircraft, ITick, IIssueOrder, IResolveOrder, IOrderCursor + class Helicopter : Aircraft, ITick, IIssueOrder, IResolveOrder, IOrderCursor, IOrderVoice { public IDisposable reservation; @@ -56,6 +56,11 @@ namespace OpenRA.Mods.RA return (order.OrderString == "Enter") ? "enter" : null; } + public string VoicePhraseForOrder(Actor self, Order order) + { + return (order.OrderString == "Move") ? "Move" : null; + } + public void ResolveOrder(Actor self, Order order) { if (reservation != null) diff --git a/OpenRA.Mods.RA/Plane.cs b/OpenRA.Mods.RA/Plane.cs index 305405e84c..e87ab0cbc3 100644 --- a/OpenRA.Mods.RA/Plane.cs +++ b/OpenRA.Mods.RA/Plane.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA public override object Create( ActorInitializer init ) { return new Plane( init ); } } - public class Plane : Aircraft, IIssueOrder, IResolveOrder, IOrderCursor + public class Plane : Aircraft, IIssueOrder, IResolveOrder, IOrderCursor, IOrderVoice { public IDisposable reservation; @@ -46,6 +46,11 @@ namespace OpenRA.Mods.RA return (order.OrderString == "Enter") ? "enter" : null; } + public string VoicePhraseForOrder(Actor self, Order order) + { + return (order.OrderString == "Move") ? "Move" : null; + } + public void ResolveOrder(Actor self, Order order) { if (reservation != null)