Unhardcode voice/order interaction; reimplement for move and attack

This commit is contained in:
Paul Chote
2010-07-23 18:40:39 +12:00
parent 1186d40fda
commit 55e59e0b53
8 changed files with 57 additions and 23 deletions

View File

@@ -45,19 +45,19 @@ 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<IMove>().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<IOrderVoice>())
{
if (Sound.PlayVoice(v.VoicePhraseForOrder(o.Subject, o), o.Subject))
{
done = true;
break;
}
}
if (done) break;
}
}

View File

@@ -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<SelectableInfo>();
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;
}
}

View File

@@ -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))));
}
}
}
@@ -120,6 +123,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; } }
public virtual IEnumerable<int2> OccupiedCells()

View File

@@ -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); }

View File

@@ -216,5 +216,12 @@ namespace OpenRA
{
return a.Info.Traits.Contains<SelectableInfo>() && a.Info.Traits.Get<SelectableInfo>().Voice != null;
}
public static VoiceInfo GetVoice(this Actor a)
{
if (!a.Info.Traits.Contains<SelectableInfo>()) return null;
var v = a.Info.Traits.Get<SelectableInfo>().Voice;
return (v == null) ? null : Rules.Voices[v];
}
}
}

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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)