notifications (formerly EVAalerts) centralized and race specific

outsourced into notifications.yaml
triggered with PlayNotification(...)

(v2: less redundant code for PlayVoice/Notifications)

added harvester under attack and battlecontrol terminated
This commit is contained in:
Matthias Mailänder
2012-06-28 19:52:25 +02:00
committed by Chris Forbes
parent 5fee165692
commit 7a578a0679
40 changed files with 271 additions and 219 deletions

View File

@@ -20,7 +20,7 @@ namespace OpenRA.FileFormats
public readonly string[] public readonly string[]
Mods, Folders, Packages, Rules, ServerTraits, Mods, Folders, Packages, Rules, ServerTraits,
Sequences, Cursors, Chrome, Assemblies, ChromeLayout, Sequences, Cursors, Chrome, Assemblies, ChromeLayout,
Weapons, Voices, Music, Movies, TileSets, ChromeMetrics; Weapons, Voices, Notifications, Music, Movies, TileSets, ChromeMetrics;
public readonly MiniYaml LoadScreen; public readonly MiniYaml LoadScreen;
public readonly Dictionary<string, Pair<string,int>> Fonts; public readonly Dictionary<string, Pair<string,int>> Fonts;
public readonly int TileSize = 24; public readonly int TileSize = 24;
@@ -44,6 +44,7 @@ namespace OpenRA.FileFormats
ChromeLayout = YamlList(yaml, "ChromeLayout"); ChromeLayout = YamlList(yaml, "ChromeLayout");
Weapons = YamlList(yaml, "Weapons"); Weapons = YamlList(yaml, "Weapons");
Voices = YamlList(yaml, "Voices"); Voices = YamlList(yaml, "Voices");
Notifications = YamlList(yaml, "Notifications");
Music = YamlList(yaml, "Music"); Music = YamlList(yaml, "Music");
Movies = YamlList(yaml, "Movies"); Movies = YamlList(yaml, "Movies");
TileSets = YamlList(yaml, "TileSets"); TileSets = YamlList(yaml, "TileSets");

View File

@@ -20,7 +20,8 @@ namespace OpenRA
{ {
public static Dictionary<string, ActorInfo> Info; public static Dictionary<string, ActorInfo> Info;
public static Dictionary<string, WeaponInfo> Weapons; public static Dictionary<string, WeaponInfo> Weapons;
public static Dictionary<string, VoiceInfo> Voices; public static Dictionary<string, SoundInfo> Voices;
public static Dictionary<string, SoundInfo> Notifications;
public static Dictionary<string, MusicInfo> Music; public static Dictionary<string, MusicInfo> Music;
public static Dictionary<string, string> Movies; public static Dictionary<string, string> Movies;
public static Dictionary<string, TileSet> TileSets; public static Dictionary<string, TileSet> TileSets;
@@ -30,7 +31,8 @@ namespace OpenRA
// Added support to extend the list of rules (add it to m.LocalRules) // Added support to extend the list of rules (add it to m.LocalRules)
Info = LoadYamlRules(m.Rules, map.Rules, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); Info = LoadYamlRules(m.Rules, map.Rules, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y));
Weapons = LoadYamlRules(m.Weapons, map.Weapons, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value)); Weapons = LoadYamlRules(m.Weapons, map.Weapons, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
Voices = LoadYamlRules(m.Voices, map.Voices, (k, _) => new VoiceInfo(k.Value)); Voices = LoadYamlRules(m.Voices, map.Voices, (k, _) => new SoundInfo(k.Value));
Notifications = LoadYamlRules(m.Notifications, map.Notifications, (k, _) => new SoundInfo(k.Value));
Music = LoadYamlRules(m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value)); Music = LoadYamlRules(m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
Movies = LoadYamlRules(m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value); Movies = LoadYamlRules(m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);

View File

@@ -1,4 +1,4 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * This file is part of OpenRA, which is free software. It is made
@@ -15,11 +15,12 @@ using OpenRA.FileFormats;
namespace OpenRA.GameRules namespace OpenRA.GameRules
{ {
public class VoiceInfo public class SoundInfo
{ {
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Variants; [FieldLoader.Ignore] public readonly Dictionary<string,string[]> Variants;
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Prefixes; [FieldLoader.Ignore] public readonly Dictionary<string,string[]> Prefixes;
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Voices; [FieldLoader.Ignore] public readonly Dictionary<string,string[]> Voices;
[FieldLoader.Ignore] public readonly Dictionary<string,string[]> Notifications;
public readonly string DefaultVariant = ".aud" ; public readonly string DefaultVariant = ".aud" ;
public readonly string DefaultPrefix = "" ; public readonly string DefaultPrefix = "" ;
public readonly string[] DisableVariants = { }; public readonly string[] DisableVariants = { };
@@ -34,31 +35,28 @@ namespace OpenRA.GameRules
: new Dictionary<string, string[]>(); : new Dictionary<string, string[]>();
} }
public readonly OpenRA.FileFormats.Lazy<Dictionary<string, VoicePool>> Pools; public readonly OpenRA.FileFormats.Lazy<Dictionary<string, SoundPool>> VoicePools;
public readonly OpenRA.FileFormats.Lazy<Dictionary<string, SoundPool>> NotificationsPools;
public VoiceInfo( MiniYaml y ) public SoundInfo( MiniYaml y )
{ {
FieldLoader.Load( this, y ); FieldLoader.Load( this, y );
Variants = Load(y, "Variants"); Variants = Load(y, "Variants");
Prefixes = Load(y, "Prefixes"); Prefixes = Load(y, "Prefixes");
Voices = Load(y, "Voices"); Voices = Load(y, "Voices");
Notifications = Load(y, "Notifications");
if (!Voices.ContainsKey("Attack")) VoicePools = Lazy.New(() => Voices.ToDictionary( a => a.Key, a => new SoundPool(a.Value) ));
Voices.Add("Attack", Voices["Move"]); NotificationsPools = Lazy.New(() => Notifications.ToDictionary( a => a.Key, a => new SoundPool(a.Value) ));
if (!Voices.ContainsKey("AttackMove"))
Voices.Add("AttackMove", Voices["Move"]);
Pools = Lazy.New(() => Voices.ToDictionary( a => a.Key, a => new VoicePool(a.Value) ));
} }
} }
public class VoicePool public class SoundPool
{ {
readonly string[] clips; readonly string[] clips;
readonly List<string> liveclips = new List<string>(); readonly List<string> liveclips = new List<string>();
public VoicePool(params string[] clips) public SoundPool(params string[] clips)
{ {
this.clips = clips; this.clips = clips;
} }

View File

@@ -60,6 +60,7 @@ namespace OpenRA
[FieldLoader.Ignore] public List<MiniYamlNode> Sequences = new List<MiniYamlNode>(); [FieldLoader.Ignore] public List<MiniYamlNode> Sequences = new List<MiniYamlNode>();
[FieldLoader.Ignore] public List<MiniYamlNode> Weapons = new List<MiniYamlNode>(); [FieldLoader.Ignore] public List<MiniYamlNode> Weapons = new List<MiniYamlNode>();
[FieldLoader.Ignore] public List<MiniYamlNode> Voices = new List<MiniYamlNode>(); [FieldLoader.Ignore] public List<MiniYamlNode> Voices = new List<MiniYamlNode>();
[FieldLoader.Ignore] public List<MiniYamlNode> Notifications = new List<MiniYamlNode>();
// Binary map data // Binary map data
[FieldLoader.Ignore] public byte TileFormat = 1; [FieldLoader.Ignore] public byte TileFormat = 1;
@@ -150,6 +151,7 @@ namespace OpenRA
Sequences = NodesOrEmpty(yaml, "Sequences"); Sequences = NodesOrEmpty(yaml, "Sequences");
Weapons = NodesOrEmpty(yaml, "Weapons"); Weapons = NodesOrEmpty(yaml, "Weapons");
Voices = NodesOrEmpty(yaml, "Voices"); Voices = NodesOrEmpty(yaml, "Voices");
Notifications = NodesOrEmpty(yaml, "Notifications");
CustomTerrain = new string[MapSize.X, MapSize.Y]; CustomTerrain = new string[MapSize.X, MapSize.Y];
@@ -204,6 +206,7 @@ namespace OpenRA
root.Add(new MiniYamlNode("Sequences", null, Sequences)); root.Add(new MiniYamlNode("Sequences", null, Sequences));
root.Add(new MiniYamlNode("Weapons", null, Weapons)); root.Add(new MiniYamlNode("Weapons", null, Weapons));
root.Add(new MiniYamlNode("Voices", null, Voices)); root.Add(new MiniYamlNode("Voices", null, Voices));
root.Add(new MiniYamlNode("Notifications", null, Notifications));
var entries = new Dictionary<string, byte[]>(); var entries = new Dictionary<string, byte[]>();
entries.Add("map.bin", SaveBinaryData()); entries.Add("map.bin", SaveBinaryData());

View File

@@ -94,7 +94,7 @@
<Compile Include="GameRules\MusicInfo.cs" /> <Compile Include="GameRules\MusicInfo.cs" />
<Compile Include="GameRules\Rules.cs" /> <Compile Include="GameRules\Rules.cs" />
<Compile Include="GameRules\Settings.cs" /> <Compile Include="GameRules\Settings.cs" />
<Compile Include="GameRules\VoiceInfo.cs" /> <Compile Include="GameRules\SoundInfo.cs" />
<Compile Include="GameRules\WeaponInfo.cs" /> <Compile Include="GameRules\WeaponInfo.cs" />
<Compile Include="Graphics\Animation.cs" /> <Compile Include="Graphics\Animation.cs" />
<Compile Include="Graphics\AnimationWithOffset.cs" /> <Compile Include="Graphics\AnimationWithOffset.cs" />

View File

@@ -90,11 +90,6 @@ namespace OpenRA
} }
} }
public void GiveAdvice(string advice)
{
Sound.PlayToPlayer(this, advice);
}
public Dictionary<Player, Stance> Stances = new Dictionary<Player, Stance>(); public Dictionary<Player, Stance> Stances = new Dictionary<Player, Stance>();
} }
} }

View File

@@ -246,7 +246,45 @@ namespace OpenRA
get { return (video != null) ? video.SeekPosition : 0; } get { return (video != null) ? video.SeekPosition : 0; }
} }
// Returns true if it played a phrase // Returns true if played successfully
public static bool PlayPredefined(Player p, Actor voicedUnit, string type, string definition, string variant)
{
if (definition == null) return false;
var rules = (voicedUnit != null) ? Rules.Voices[type] : Rules.Notifications[type];
var ID = (voicedUnit != null) ? voicedUnit.ActorID : 0;
var clip = (voicedUnit != null) ? rules.VoicePools.Value[definition].GetNext() : rules.NotificationsPools.Value[definition].GetNext();
if (clip == null) return false;
var suffix = rules.DefaultVariant;
var prefix = rules.DefaultPrefix;
if (voicedUnit != null)
{
if (!rules.VoicePools.Value.ContainsKey("Attack"))
rules.VoicePools.Value.Add("Attack", rules.VoicePools.Value["Move"]);
if (!rules.VoicePools.Value.ContainsKey("AttackMove"))
rules.VoicePools.Value.Add("AttackMove", rules.VoicePools.Value["Move"]);
}
if (variant != null)
{
if (rules.Variants.ContainsKey(variant) && !rules.DisableVariants.Contains(definition))
suffix = rules.Variants[variant][ID % rules.Variants[variant].Length];
if (rules.Prefixes.ContainsKey(variant) && !rules.DisablePrefixes.Contains(definition))
prefix = rules.Prefixes[variant][ID % rules.Prefixes[variant].Length];
}
if (p == null)
Play(prefix + clip + suffix);
else
PlayToPlayer(p, prefix + clip + suffix);
return true;
}
public static bool PlayVoice(string phrase, Actor voicedUnit, string variant) public static bool PlayVoice(string phrase, Actor voicedUnit, string variant)
{ {
if (voicedUnit == null) return false; if (voicedUnit == null) return false;
@@ -256,21 +294,17 @@ namespace OpenRA
if (mi == null) return false; if (mi == null) return false;
if (mi.Voice == null) return false; if (mi.Voice == null) return false;
var vi = Rules.Voices[mi.Voice.ToLowerInvariant()]; var type = mi.Voice.ToLowerInvariant();
if (!vi.Pools.Value.ContainsKey(phrase)) return PlayPredefined(null, voicedUnit, type, phrase, variant);
return false; }
var clip = vi.Pools.Value[phrase].GetNext(); public static bool PlayNotification(Player player, string type, string notification, string variant)
if (clip == null) {
return false; if (type == null) return false;
if (notification == null) return false;
var variantExt = (vi.Variants.ContainsKey(variant) && !vi.DisableVariants.Contains(phrase)) ? return PlayPredefined(player, null, type.ToLowerInvariant(), notification, variant);
vi.Variants[variant][voicedUnit.ActorID % vi.Variants[variant].Length] : vi.DefaultVariant;
var prefix = (vi.Prefixes.ContainsKey(variant) && !vi.DisablePrefixes.Contains(phrase)) ?
vi.Prefixes[variant][voicedUnit.ActorID % vi.Prefixes[variant].Length] : vi.DefaultPrefix;
Play(prefix + clip + variantExt);
return true;
} }
} }

View File

@@ -1,43 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
namespace OpenRA.Traits
{
public class EvaAlertsInfo : TraitInfo<EvaAlerts>
{
// Sound effects
public readonly string RadarUp = "radaron2.aud";
public readonly string RadarDown = "radardn1.aud";
public readonly string CashTickUp = "cashup1.aud";
public readonly string CashTickDown = "cashdn1.aud";
// Build Palette
public readonly string BuildingCannotPlaceAudio = "nodeply1.aud";
public readonly string NewOptions = "newopt1.aud";
// For manual powerup/down in ra-ng
public readonly string DisablePower = "bleep11.aud";
public readonly string EnablePower = "bleep12.aud";
// Eva speech
public readonly string Repairing = "repair1.aud";
public readonly string LowPower = "lopower1.aud";
public readonly string SilosNeeded = "silond1.aud";
public readonly string PrimaryBuildingSelected = "pribldg1.aud";
// Special powers
public readonly string AbilityInsufficientPower = "nopowr1.aud";
public readonly string LevelUp = "hydrod1.aud";
}
public class EvaAlerts {}
}

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -136,8 +136,6 @@ namespace OpenRA.Traits
public void Tick(Actor self) public void Tick(Actor self)
{ {
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
if(cashtickallowed > 0) { if(cashtickallowed > 0) {
cashtickallowed = cashtickallowed - 1; cashtickallowed = cashtickallowed - 1;
} }
@@ -152,7 +150,7 @@ namespace OpenRA.Traits
if (--nextSiloAdviceTime <= 0) if (--nextSiloAdviceTime <= 0)
{ {
if (Ore > 0.8*OreCapacity) if (Ore > 0.8*OreCapacity)
Owner.GiveAdvice(eva.SilosNeeded); Sound.PlayNotification(Owner, "Speech", "SilosNeeded", Owner.Country.Race);
nextSiloAdviceTime = AdviceInterval; nextSiloAdviceTime = AdviceInterval;
} }
@@ -192,21 +190,19 @@ namespace OpenRA.Traits
public void playCashTickUp(Actor self) public void playCashTickUp(Actor self)
{ {
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
if (Game.Settings.Sound.SoundCashTickType != SoundCashTicks.Disabled) if (Game.Settings.Sound.SoundCashTickType != SoundCashTicks.Disabled)
{ {
Sound.PlayToPlayer(self.Owner, eva.CashTickUp); Sound.PlayNotification(self.Owner, "Sounds", "CashTickUp", self.Owner.Country.Race);
} }
} }
public void playCashTickDown(Actor self) public void playCashTickDown(Actor self)
{ {
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
if ( if (
Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Extreme || Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Extreme ||
(Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Normal && cashtickallowed == 0) (Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Normal && cashtickallowed == 0)
) { ) {
Sound.PlayToPlayer(self.Owner, eva.CashTickDown); Sound.PlayNotification(self.Owner, "Sounds", "CashTickDown", self.Owner.Country.Race);
cashtickallowed = 3; cashtickallowed = 3;
} }

View File

@@ -54,6 +54,7 @@ namespace OpenRA.Traits
public interface IResolveOrder { void ResolveOrder(Actor self, Order order); } public interface IResolveOrder { void ResolveOrder(Actor self, Order order); }
public interface IValidateOrder { bool OrderValidation(OrderManager orderManager, World world, int clientId, Order order); } public interface IValidateOrder { bool OrderValidation(OrderManager orderManager, World world, int clientId, Order order); }
public interface IOrderVoice { string VoicePhraseForOrder(Actor self, Order order); } public interface IOrderVoice { string VoicePhraseForOrder(Actor self, Order order); }
public interface INotify { void Play(Player p, string notification); }
public interface INotifySold { void Selling(Actor self); void Sold(Actor self); } public interface INotifySold { void Selling(Actor self); void Sold(Actor self); }
public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); } public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); }
public interface INotifyDamageStateChanged { void DamageStateChanged(Actor self, AttackInfo e); } public interface INotifyDamageStateChanged { void DamageStateChanged(Actor self, AttackInfo e); }

View File

@@ -22,8 +22,6 @@ namespace OpenRA.Widgets
public bool Depressed = false; public bool Depressed = false;
public int VisualHeight = ChromeMetrics.Get<int>("ButtonDepth"); public int VisualHeight = ChromeMetrics.Get<int>("ButtonDepth");
public string Font = ChromeMetrics.Get<string>("ButtonFont"); public string Font = ChromeMetrics.Get<string>("ButtonFont");
public string ClickSound = null;
public string ClickDisabledSound = null;
public bool Disabled = false; public bool Disabled = false;
public Func<string> GetText; public Func<string> GetText;
public Func<bool> IsDisabled; public Func<bool> IsDisabled;
@@ -73,10 +71,10 @@ namespace OpenRA.Widgets
if (!IsDisabled()) if (!IsDisabled())
{ {
OnKeyPress(e); OnKeyPress(e);
Sound.Play(ClickSound); Sound.PlayNotification(null, "Sounds", "ClickSound", null);
} }
else else
Sound.Play(ClickDisabledSound); Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null);
return true; return true;
} }
@@ -105,12 +103,12 @@ namespace OpenRA.Widgets
{ {
OnMouseDown(mi); OnMouseDown(mi);
Depressed = true; Depressed = true;
Sound.Play(ClickSound); Sound.PlayNotification(null, "Sounds", "ClickSound", null);
} }
else else
{ {
LoseFocus(mi); LoseFocus(mi);
Sound.Play(ClickDisabledSound); Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null);
} }
} }
else if (mi.Event == MouseInputEvent.Move && Focused) else if (mi.Event == MouseInputEvent.Move && Focused)

View File

@@ -121,7 +121,7 @@ namespace OpenRA
return selectable != null && selectable.Voice != null; return selectable != null && selectable.Voice != null;
} }
public static VoiceInfo GetVoice(this Actor a) public static SoundInfo GetVoice(this Actor a)
{ {
var selectable = a.Info.Traits.GetOrDefault<SelectableInfo>(); var selectable = a.Info.Traits.GetOrDefault<SelectableInfo>();
if (selectable == null) return null; if (selectable == null) return null;

View File

@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
// TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions // TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions
Action onQuit = () => Action onQuit = () =>
{ {
Sound.Play("batlcon1.aud"); Sound.PlayNotification(null, "Speech", "Leave", null);
resumeDisabled = true; resumeDisabled = true;
Game.RunAfterDelay(1200, () => mpe.Fade(CncMenuPaletteEffect.EffectType.Black)); Game.RunAfterDelay(1200, () => mpe.Fade(CncMenuPaletteEffect.EffectType.Black));
Game.RunAfterDelay(1200 + 40 * mpe.Info.FadeLength, () => Game.RunAfterDelay(1200 + 40 * mpe.Info.FadeLength, () =>

View File

@@ -61,8 +61,6 @@ namespace OpenRA.Mods.Cnc.Widgets
class ProductionTabsWidget : Widget class ProductionTabsWidget : Widget
{ {
public readonly string PaletteWidget = null; public readonly string PaletteWidget = null;
public readonly string ClickSound = null;
public readonly string DisabledClickSound = null;
public readonly float ScrollVelocity = 4f; public readonly float ScrollVelocity = 4f;
public readonly int TabWidth = 30; public readonly int TabWidth = 30;
public readonly int ArrowWidth = 20; public readonly int ArrowWidth = 20;
@@ -248,9 +246,9 @@ namespace OpenRA.Mods.Cnc.Widgets
if (leftPressed || rightPressed) if (leftPressed || rightPressed)
{ {
if ((leftPressed && !leftDisabled) || (rightPressed && !rightDisabled)) if ((leftPressed && !leftDisabled) || (rightPressed && !rightDisabled))
Sound.Play(ClickSound); Sound.PlayNotification(null, "Sounds", "ClickSound", null);
else else
Sound.Play(DisabledClickSound); Sound.PlayNotification(null, "Sounds", "DisabledClickSound", null);
} }
// Check production tabs // Check production tabs
@@ -258,7 +256,7 @@ namespace OpenRA.Mods.Cnc.Widgets
if (offsetloc.X > 0 && offsetloc.X < ContentWidth) if (offsetloc.X > 0 && offsetloc.X < ContentWidth)
{ {
CurrentQueue = Groups[queueGroup].Tabs[offsetloc.X/(TabWidth - 1)].Queue; CurrentQueue = Groups[queueGroup].Tabs[offsetloc.X/(TabWidth - 1)].Queue;
Sound.Play(ClickSound); Sound.PlayNotification(null, "Sounds", "ClickSound", null);
return true; return true;
} }
@@ -270,7 +268,7 @@ namespace OpenRA.Mods.Cnc.Widgets
if (e.Event != KeyInputEvent.Down) return false; if (e.Event != KeyInputEvent.Down) return false;
if (e.KeyName == "tab") if (e.KeyName == "tab")
{ {
Sound.Play(ClickSound); Sound.PlayNotification(null, "Sounds", "ClickSound", null);
SelectNextTab(e.Modifiers.HasModifier(Modifiers.Shift)); SelectNextTab(e.Modifiers.HasModifier(Modifiers.Shift));
return true; return true;
} }

View File

@@ -37,9 +37,7 @@ namespace OpenRA.Mods.RA.Buildings
if (order.OrderString == "PowerDown") if (order.OrderString == "PowerDown")
{ {
disabled = !disabled; disabled = !disabled;
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>(); Sound.PlayNotification(self.Owner, "Sounds", (disabled ? "EnablePower" : "DisablePower"), self.Owner.Country.Race);
Sound.PlayToPlayer(self.Owner, disabled ? eva.EnablePower : eva.DisablePower);
PowerManager.UpdateActor(self, disabled ? 0 : normalPower); PowerManager.UpdateActor(self, disabled ? 0 : normalPower);
if (disabled) if (disabled)

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -108,8 +108,7 @@ namespace OpenRA.Mods.RA.Buildings
if (--nextPowerAdviceTime <= 0) if (--nextPowerAdviceTime <= 0)
{ {
if (lowPower) if (lowPower)
Player.GiveAdvice(Rules.Info["world"].Traits.Get<EvaAlertsInfo>().LowPower); Sound.PlayNotification(self.Owner, "Speech", "LowPower", self.Owner.Country.Race);
nextPowerAdviceTime = Info.AdviceInterval; nextPowerAdviceTime = Info.AdviceInterval;
} }
} }

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Mods.RA.Buildings
else else
{ {
Repairer = p; Repairer = p;
Sound.PlayToPlayer(Repairer, p.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().Repairing); Sound.PlayNotification(Repairer, "Speech", "Repairing", self.Owner.Country.Race);
self.World.AddFrameEndTask( self.World.AddFrameEndTask(
w => w.Add(new RepairIndicator(self, p))); w => w.Add(new RepairIndicator(self, p)));

View File

@@ -15,10 +15,7 @@ namespace OpenRA.Mods.RA
{ {
public class ConquestVictoryConditionsInfo : ITraitInfo public class ConquestVictoryConditionsInfo : ITraitInfo
{ {
public string WinNotification = null;
public string LoseNotification = null;
public int NotificationDelay = 1500; // Milliseconds public int NotificationDelay = 1500; // Milliseconds
public readonly string Race = null;
public object Create(ActorInitializer init) { return new ConquestVictoryConditions(this); } public object Create(ActorInitializer init) { return new ConquestVictoryConditions(this); }
} }
@@ -55,7 +52,6 @@ namespace OpenRA.Mods.RA
public void Lose(Actor self) public void Lose(Actor self)
{ {
if (Info.Race != null && Info.Race != self.Owner.Country.Race) return;
if (self.Owner.WinState == WinState.Lost) return; if (self.Owner.WinState == WinState.Lost) return;
self.Owner.WinState = WinState.Lost; self.Owner.WinState = WinState.Lost;
@@ -70,14 +66,13 @@ namespace OpenRA.Mods.RA
Game.RunAfterDelay(Info.NotificationDelay, () => Game.RunAfterDelay(Info.NotificationDelay, () =>
{ {
if (Game.IsCurrentWorld(self.World)) if (Game.IsCurrentWorld(self.World))
Sound.Play(Info.LoseNotification); Sound.PlayNotification(self.Owner, "Speech", "Lose", self.Owner.Country.Race);
}); });
} }
} }
public void Win(Actor self) public void Win(Actor self)
{ {
if (Info.Race != null && Info.Race != self.Owner.Country.Race) return;
if (self.Owner.WinState == WinState.Won) return; if (self.Owner.WinState == WinState.Won) return;
self.Owner.WinState = WinState.Won; self.Owner.WinState = WinState.Won;
@@ -85,7 +80,7 @@ namespace OpenRA.Mods.RA
if (self.Owner == self.World.LocalPlayer) if (self.Owner == self.World.LocalPlayer)
{ {
self.World.LocalShroud.Disabled = true; self.World.LocalShroud.Disabled = true;
Game.RunAfterDelay(Info.NotificationDelay, () => Sound.Play(Info.WinNotification)); Game.RunAfterDelay(Info.NotificationDelay, () => Sound.PlayNotification(self.Owner, "Speech", "Win", self.Owner.Country.Race));
} }
} }
} }

View File

@@ -77,8 +77,7 @@ namespace OpenRA.Mods.RA
while (Level < MaxLevel && Experience >= Levels[Level]) while (Level < MaxLevel && Experience >= Levels[Level])
{ {
Level++; Level++;
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>(); Sound.PlayNotification(self.Owner, "Sounds", "LevelUp", self.Owner.Country.Race);
Sound.PlayToPlayer(self.Owner, eva.LevelUp, self.CenterLocation);
self.World.AddFrameEndTask(w => w.Add(new CrateEffect(self, "levelup", new int2(0,-24)))); self.World.AddFrameEndTask(w => w.Add(new CrateEffect(self, "levelup", new int2(0,-24))));
} }
} }

View File

@@ -58,8 +58,7 @@ namespace OpenRA.Mods.RA.Orders
if (!world.CanPlaceBuilding( Building, BuildingInfo, topLeft, null) if (!world.CanPlaceBuilding( Building, BuildingInfo, topLeft, null)
|| !BuildingInfo.IsCloseEnoughToBase(world, Producer.Owner, Building, topLeft)) || !BuildingInfo.IsCloseEnoughToBase(world, Producer.Owner, Building, topLeft))
{ {
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>(); Sound.PlayNotification(Producer.Owner, "Speech", "BuildingCannotPlaceAudio", Producer.Owner.Country.Race);
Sound.Play(eva.BuildingCannotPlaceAudio);
yield break; yield break;
} }

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information #region Copyright & License Information
/* /*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made * This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License * available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information, * as published by the Free Software Foundation. For more information,
@@ -17,9 +17,7 @@ namespace OpenRA.Mods.RA
{ {
public class BaseAttackNotifierInfo : ITraitInfo public class BaseAttackNotifierInfo : ITraitInfo
{ {
public readonly int NotifyInterval = 30; /* seconds */ public readonly int NotifyInterval = 30; // seconds
public readonly string Audio = "baseatk1.aud";
public readonly string Race = null;
public object Create(ActorInitializer init) { return new BaseAttackNotifier(this); } public object Create(ActorInitializer init) { return new BaseAttackNotifier(this); }
} }
@@ -35,17 +33,16 @@ namespace OpenRA.Mods.RA
public void Damaged(Actor self, AttackInfo e) public void Damaged(Actor self, AttackInfo e)
{ {
if (info.Race != null && info.Race != self.Owner.Country.Race) return; // only track last hit against our base
/* only track last hit against our base */
if (!self.HasTrait<Building>()) if (!self.HasTrait<Building>())
return; return;
/* don't track self-damage */ // don't track self-damage
if (e.Attacker != null && e.Attacker.Owner == self.Owner) if (e.Attacker != null && e.Attacker.Owner == self.Owner)
return; return;
if (self.World.FrameNumber - lastAttackTime > info.NotifyInterval * 25) if (self.World.FrameNumber - lastAttackTime > info.NotifyInterval * 25)
Sound.PlayToPlayer(self.Owner, info.Audio); Sound.PlayNotification(self.Owner, "Speech", "BaseAttack", self.Owner.Country.Race);
lastAttackLocation = self.CenterLocation.ToCPos(); lastAttackLocation = self.CenterLocation.ToCPos();
lastAttackTime = self.World.FrameNumber; lastAttackTime = self.World.FrameNumber;

View File

@@ -0,0 +1,52 @@
#region Copyright & License Information
/*
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Effects;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
public class HarvesterAttackNotifierInfo : ITraitInfo
{
public readonly int NotifyInterval = 30; // seconds
public object Create(ActorInitializer init) { return new HarvesterAttackNotifier(this); }
}
public class HarvesterAttackNotifier : INotifyDamage
{
HarvesterAttackNotifierInfo info;
public int lastAttackTime = -1;
public CPos lastAttackLocation;
public HarvesterAttackNotifier(HarvesterAttackNotifierInfo info) { this.info = info; }
public void Damaged(Actor self, AttackInfo e)
{
// only track last hit against our base
if (!self.HasTrait<Harvester>())
return;
// don't track self-damage
if (e.Attacker != null && e.Attacker.Owner == self.Owner)
return;
if (self.World.FrameNumber - lastAttackTime > info.NotifyInterval * 25)
Sound.PlayNotification(self.Owner, "Speech", "HarvesterAttack", self.Owner.Country.Race);
lastAttackLocation = self.CenterLocation.ToCPos();
lastAttackTime = self.World.FrameNumber;
}
}
}

View File

@@ -82,8 +82,7 @@ namespace OpenRA.Mods.RA
if (GetNumBuildables(self.Owner) > prevItems) if (GetNumBuildables(self.Owner) > prevItems)
w.Add(new DelayedAction(10, w.Add(new DelayedAction(10,
() => Sound.PlayToPlayer(order.Player, () => Sound.PlayNotification(order.Player, "Speech", "NewOptions", order.Player.Country.Race)));
w.WorldActor.Info.Traits.Get<EvaAlertsInfo>().NewOptions)));
}); });
} }
} }

View File

@@ -66,8 +66,7 @@ namespace OpenRA.Mods.RA
isPrimary = true; isPrimary = true;
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>(); Sound.PlayNotification(self.Owner, "Speech", "PrimaryBuildingSelected", self.Owner.Country.Race);
Sound.PlayToPlayer(self.Owner, eva.PrimaryBuildingSelected);
} }
} }

View File

@@ -44,9 +44,6 @@ namespace OpenRA.Mods.RA.Widgets
List<Pair<Rectangle, Action<MouseInput>>> tabs = new List<Pair<Rectangle, Action<MouseInput>>>(); List<Pair<Rectangle, Action<MouseInput>>> tabs = new List<Pair<Rectangle, Action<MouseInput>>>();
Animation cantBuild; Animation cantBuild;
Animation clock; Animation clock;
public readonly string BuildPaletteOpen = "bleep13.aud";
public readonly string BuildPaletteClose = "bleep13.aud";
public readonly string TabClick = "ramenu1.aud";
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly World world; readonly World world;
@@ -118,11 +115,11 @@ namespace OpenRA.Mods.RA.Widgets
// Play palette-open sound at the start of the activate anim (open) // Play palette-open sound at the start of the activate anim (open)
if (paletteAnimationFrame == 1 && paletteOpen) if (paletteAnimationFrame == 1 && paletteOpen)
Sound.Play(BuildPaletteOpen); Sound.PlayNotification(null, "Sounds", "BuildPaletteOpen", null);
// Play palette-close sound at the start of the activate anim (close) // Play palette-close sound at the start of the activate anim (close)
if (paletteAnimationFrame == paletteAnimationLength + -1 && !paletteOpen) if (paletteAnimationFrame == paletteAnimationLength + -1 && !paletteOpen)
Sound.Play(BuildPaletteClose); Sound.PlayNotification(null, "Sounds", "BuildPaletteClose", null);
// Animation is complete // Animation is complete
if ((paletteAnimationFrame == 0 && !paletteOpen) if ((paletteAnimationFrame == 0 && !paletteOpen)
@@ -291,7 +288,7 @@ namespace OpenRA.Mods.RA.Widgets
Action<MouseInput> HandleClick(string name, World world) Action<MouseInput> HandleClick(string name, World world)
{ {
return mi => { return mi => {
Sound.Play(TabClick); Sound.PlayNotification(null, "Sounds", "TabClick", null);
if (name != null) if (name != null)
HandleBuildPalette(world, name, (mi.Button == MouseButton.Left)); HandleBuildPalette(world, name, (mi.Button == MouseButton.Left));
@@ -304,7 +301,7 @@ namespace OpenRA.Mods.RA.Widgets
if (mi.Button != MouseButton.Left) if (mi.Button != MouseButton.Left)
return; return;
Sound.Play(TabClick); Sound.PlayNotification(null, "Sounds", "TabClick", null);
var wasOpen = paletteOpen; var wasOpen = paletteOpen;
paletteOpen = (CurrentQueue == queue && wasOpen) ? false : true; paletteOpen = (CurrentQueue == queue && wasOpen) ? false : true;
CurrentQueue = queue; CurrentQueue = queue;
@@ -496,7 +493,7 @@ namespace OpenRA.Mods.RA.Widgets
if ( toBuild != null ) if ( toBuild != null )
{ {
Sound.Play(TabClick); Sound.PlayNotification(null, "Sounds", "TabClick", null);
HandleBuildPalette(world, toBuild.Name, true); HandleBuildPalette(world, toBuild.Name, true);
return true; return true;
} }

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
}; };
cheatsButton.IsVisible = () => world.LocalPlayer != null && world.LobbyInfo.GlobalSettings.AllowCheats; cheatsButton.IsVisible = () => world.LocalPlayer != null && world.LobbyInfo.GlobalSettings.AllowCheats;
optionsBG.Get<ButtonWidget>("DISCONNECT").OnClick = () => LeaveGame(optionsBG); optionsBG.Get<ButtonWidget>("DISCONNECT").OnClick = () => LeaveGame(optionsBG, world);
optionsBG.Get<ButtonWidget>("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU"); optionsBG.Get<ButtonWidget>("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU");
optionsBG.Get<ButtonWidget>("MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU"); optionsBG.Get<ButtonWidget>("MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU");
@@ -57,7 +57,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
var postGameObserve = postgameBG.Get<ButtonWidget>("POSTGAME_OBSERVE"); var postGameObserve = postgameBG.Get<ButtonWidget>("POSTGAME_OBSERVE");
var postgameQuit = postgameBG.Get<ButtonWidget>("POSTGAME_QUIT"); var postgameQuit = postgameBG.Get<ButtonWidget>("POSTGAME_QUIT");
postgameQuit.OnClick = () => LeaveGame(postgameQuit); postgameQuit.OnClick = () => LeaveGame(postgameQuit, world);
postGameObserve.OnClick = () => postgameQuit.Visible = false; postGameObserve.OnClick = () => postgameQuit.Visible = false;
postGameObserve.IsVisible = () => world.LocalPlayer.WinState != WinState.Won; postGameObserve.IsVisible = () => world.LocalPlayer.WinState != WinState.Won;
@@ -76,8 +76,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
}; };
} }
void LeaveGame(Widget pane) void LeaveGame(Widget pane, World world)
{ {
Sound.PlayNotification(null, "Speech", "Leave", world.LocalPlayer.Country.Race);
pane.Visible = false; pane.Visible = false;
Game.Disconnect(); Game.Disconnect();
Game.LoadShellMap(); Game.LoadShellMap();

View File

@@ -237,7 +237,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
chatPanel.AddChild(template); chatPanel.AddChild(template);
chatPanel.ScrollToBottom(); chatPanel.ScrollToBottom();
Sound.Play("scold1.aud"); Sound.PlayNotification(null, "Sounds", "ChatLine", null);
} }
void UpdateCurrentMap() void UpdateCurrentMap()

View File

@@ -175,8 +175,7 @@ namespace OpenRA.Mods.RA.Widgets
if (hasRadarNew != hasRadar) if (hasRadarNew != hasRadar)
{ {
radarAnimating = true; radarAnimating = true;
var eva = Rules.Info["world"].Traits.Get<EvaAlertsInfo>(); Sound.PlayNotification(null, "Sounds", (hasRadarNew ? "RadarUp" : "RadarDown"), null);
Sound.Play(hasRadarNew ? eva.RadarUp : eva.RadarDown);
} }
hasRadar = hasRadarNew; hasRadar = hasRadarNew;

View File

@@ -103,8 +103,6 @@ Container@PLAYER_WIDGETS:
Font:Bold Font:Bold
TooltipText: Menu TooltipText: Menu
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
ClickSound:button.aud
ClickDisabledSound:scold2.aud
Children: Children:
Image@ICON: Image@ICON:
X:7 X:7
@@ -120,8 +118,6 @@ Container@PLAYER_WIDGETS:
Font:Bold Font:Bold
TooltipText: Sell TooltipText: Sell
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
ClickSound:button.aud
ClickDisabledSound:scold2.aud
Children: Children:
Image@ICON: Image@ICON:
X:7 X:7
@@ -136,8 +132,6 @@ Container@PLAYER_WIDGETS:
Font:Bold Font:Bold
TooltipText: Repair TooltipText: Repair
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
ClickSound:button.aud
ClickDisabledSound:scold2.aud
Children: Children:
Image@ICON: Image@ICON:
X:7 X:7
@@ -200,8 +194,6 @@ Container@PLAYER_WIDGETS:
Key: q Key: q
TooltipText: Buildings TooltipText: Buildings
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
ClickSound:button.aud
ClickDisabledSound:scold2.aud
Children: Children:
Image@ICON: Image@ICON:
X:7 X:7
@@ -214,8 +206,6 @@ Container@PLAYER_WIDGETS:
Key: w Key: w
TooltipText: Defense TooltipText: Defense
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
ClickSound:button.aud
ClickDisabledSound:scold2.aud
Children: Children:
Image@ICON: Image@ICON:
X:7 X:7
@@ -228,8 +218,6 @@ Container@PLAYER_WIDGETS:
Key: e Key: e
TooltipText: Infantry TooltipText: Infantry
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
ClickSound:button.aud
ClickDisabledSound:scold2.aud
Children: Children:
Image@ICON: Image@ICON:
X:7 X:7
@@ -242,8 +230,6 @@ Container@PLAYER_WIDGETS:
Key: r Key: r
TooltipText: Vehicles TooltipText: Vehicles
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
ClickSound:button.aud
ClickDisabledSound:scold2.aud
Children: Children:
Image@ICON: Image@ICON:
X:7 X:7
@@ -256,8 +242,6 @@ Container@PLAYER_WIDGETS:
Key: t Key: t
TooltipText: Aircraft TooltipText: Aircraft
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
ClickSound:button.aud
ClickDisabledSound:scold2.aud
Children: Children:
Image@ICON: Image@ICON:
X:7 X:7
@@ -265,8 +249,6 @@ Container@PLAYER_WIDGETS:
ImageCollection:production-icons ImageCollection:production-icons
ProductionTabs@PRODUCTION_TABS: ProductionTabs@PRODUCTION_TABS:
PaletteWidget:PRODUCTION_PALETTE PaletteWidget:PRODUCTION_PALETTE
ClickSound:button.aud
DisabledClickSound:scold2.aud
X:WINDOW_RIGHT - 204 X:WINDOW_RIGHT - 204
Y:268 Y:268
Width:194 Width:194
@@ -274,8 +256,6 @@ Container@PLAYER_WIDGETS:
ProductionPalette@PRODUCTION_PALETTE: ProductionPalette@PRODUCTION_PALETTE:
X:WINDOW_RIGHT - 204 X:WINDOW_RIGHT - 204
Y:287 Y:287
TabClick: button.aud
DisabledTabClick:scold2.aud
TooltipContainer:TOOLTIP_CONTAINER TooltipContainer:TOOLTIP_CONTAINER
Background@FMVPLAYER: Background@FMVPLAYER:
Width:WINDOW_RIGHT Width:WINDOW_RIGHT

View File

@@ -90,6 +90,9 @@ Movies:
Voices: Voices:
mods/cnc/voices.yaml mods/cnc/voices.yaml
Notifications:
mods/cnc/notifications.yaml
Music: Music:
mods/cnc/music.yaml mods/cnc/music.yaml

View File

@@ -0,0 +1,26 @@
Speech:
Notifications:
Repairing: repair1
LowPower: lopower1
SilosNeeded: silos1
PrimaryBuildingSelected: pribldg1
BuildingCannotPlaceAudio: deploy1
NewOptions: newopt1
AbilityInsufficientPower: nopower1
Win: accom1
Lose: fail1
BaseAttack: baseatk1
HarvesterAttack:
Leave: batlcon1
Sounds:
Notifications:
RadarUp: comcntr1
RadarDown: powrdn1
CashTickUp:
CashTickDown:
LevelUp: text2
ChatLine: scold1
TabClick: button
ClickSound: button
ClickDisabledSound: scold2

View File

@@ -3,8 +3,6 @@ Player:
TechTree: TechTree:
SupportPowerManager: SupportPowerManager:
ConquestVictoryConditions: ConquestVictoryConditions:
WinNotification:accom1.aud
LoseNotification:fail1.aud
PowerManager: PowerManager:
AllyRepair: AllyRepair:
PlayerResources: PlayerResources:
@@ -151,17 +149,6 @@ World:
CreateMPPlayers: CreateMPPlayers:
SpawnMPUnits: SpawnMPUnits:
MPStartLocations: MPStartLocations:
EvaAlerts:
RadarUp: comcntr1.aud
RadarDown: powrdn1.aud
BuildingCannotPlaceAudio: deploy1.aud
CashTickUp:
CashTickDown:
LowPower: lopower1.aud
SilosNeeded: silos1.aud
PrimaryBuildingSelected: pribldg1.aud
AbilityInsufficientPower: nopower1.aud
LevelUp: text2.aud
SpatialBins: SpatialBins:
BinSize: 4 BinSize: 4
Shroud: Shroud:

View File

@@ -13,14 +13,12 @@
# add more spice tiles and make them fit # add more spice tiles and make them fit
# add game logic for concrete plates (use terrain overlay from bridges/ressources) # add game logic for concrete plates (use terrain overlay from bridges/ressources)
# allow placing turrets on walls # allow placing turrets on walls
# R8 converter needs infantry/ornithocopter frame resorter
# add grenade thrower # add grenade thrower
# make sandworm behave like a moving anti-vehicle mine # make sandworm behave like a moving anti-vehicle mine
# add neutral buildings: emperor palace, fremen siech, smugglers factory # add neutral buildings: emperor palace, fremen siech, smugglers factory
# add deathhand missile (nuke) # add deathhand missile (nuke)
# maybe add ornithocopter strikes (they are currently directly contrallable units with non-reloading machine guns as in Dune II) # maybe add ornithocopter strikes (they are currently directly contrallable units with non-reloading machine guns as in Dune II)
# allow upgrades # allow upgrades
# allow different EVA voices for each faction (currently Atreides only)
# add muzzles and explosions (currently falls back to RA) # add muzzles and explosions (currently falls back to RA)
# create a shellmap (currently just a blank placeholder) # create a shellmap (currently just a blank placeholder)
# rework chrome UI, dialoges, tabs # rework chrome UI, dialoges, tabs
@@ -33,3 +31,5 @@
# infantry-only areas (Rough) do not show the dark-green mouse cursor # infantry-only areas (Rough) do not show the dark-green mouse cursor
# put TilesetBuilder.Export into OpenRA.Utility to call the functions directly when extracting game-files (instead of opening a GUI) # put TilesetBuilder.Export into OpenRA.Utility to call the functions directly when extracting game-files (instead of opening a GUI)
# group number metrics are off # group number metrics are off
# add bibs
# building offsets wrong (worst for towers)

View File

@@ -71,6 +71,9 @@ Weapons:
Voices: Voices:
mods/d2k/voices.yaml mods/d2k/voices.yaml
Notifications:
mods/d2k/notifications.yaml
TileSets: TileSets:
mods/d2k/tilesets/arrakis.yaml mods/d2k/tilesets/arrakis.yaml

View File

@@ -0,0 +1,37 @@
# requires Dune 2000/DATA/GAMESFX copied to ~/.openra/Content/d2k
Speech:
DefaultVariant: .AUD
Prefixes:
atreides: AI_
ordos: OI_
harkonnen: HI_
Notifications:
Repairing: MEND
BuildingCannotPlaceAudio: PLACE
LowPower: POWER
SilosNeeded: SILOS
PrimaryBuildingSelected: PRMRY
AbilityInsufficientPower:
NewOptions: NEWOP
Win: MWIN
Lose: MFAIL
BaseAttack: ATACK
HarvesterAttack: HATTK
Leave: ABORT
Sounds:
Notifications:
RadarUp: MULTI1
RadarDown:
DisablePower: POWRDN1
EnablePower: POWRUP1
CashTickUp: CASHTIK1
CashTickDown:CASHTIK1
LevelUp: SCORTIK1
ChatLine: CHAT1
BuildPaletteOpen: BUTTON1
BuildPaletteClose: BUTTON1
TabClick: SIDEBAR1
ClickSound: BUTTON1
ClickDisabledSound: ENDLIST1

View File

@@ -2,18 +2,7 @@ Player:
TechTree: TechTree:
PlaceBuilding: PlaceBuilding:
SupportPowerManager: SupportPowerManager:
ConquestVictoryConditions@Atreides: ConquestVictoryConditions:
Race: atreides
WinNotification: AI_MWIN.AUD
LoseNotification: AI_MFAIL.AUD
ConquestVictoryConditions@Harkonnen:
Race: harkonnen
WinNotification: HI_MWIN.AUD
LoseNotification: HI_MFAIL.AUD
ConquestVictoryConditions@Ordos:
Race: ordos
WinNotification: OI_MWIN.AUD
LoseNotification: OI_MFAIL.AUD
PowerManager: PowerManager:
AllyRepair: AllyRepair:
PlayerResources: PlayerResources:
@@ -65,15 +54,8 @@ Player:
PlayerColorPalette: PlayerColorPalette:
BasePalette: d2k BasePalette: d2k
RemapIndex: 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 RemapIndex: 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
BaseAttackNotifier@Atreides: BaseAttackNotifier:
Race: atreides HarvesterAttackNotifier:
Audio: AI_ATACK.AUD
BaseAttackNotifier@Harkonnen:
Race: harkonnen
Audio: HI_ATACK.AUD
BaseAttackNotifier@Ordos:
Race: ordos
Audio: OI_ATACK.AUD
World: World:
OpenWidgetAtGameStart: OpenWidgetAtGameStart:
@@ -179,25 +161,12 @@ World:
SpawnMPUnits@ordos: SpawnMPUnits@ordos:
InitialUnit: mcvo InitialUnit: mcvo
Faction: ordos Faction: ordos
#TODO: These are just the Atreides sounds.
EvaAlerts:
RadarUp: POWRUP1.aud
RadarDown: POWRDN1.aud
BuildingCannotPlaceAudio: AI_PLACE.AUD
CashTickUp: CASHTIK1.aud
CashTickDown:CASHTIK1.aud
NewOptions: AI_NEWOP.AUD
LowPower: AI_POWER.AUD
SilosNeeded: AI_SILOS.AUD
PrimaryBuildingSelected: AI_PRMRY.AUD
AbilityInsufficientPower:
LevelUp: SCORTIK1.aud
Repairing:
SpatialBins: SpatialBins:
BinSize: 4 BinSize: 4
Shroud: Shroud:
PathFinder: PathFinder:
ValidateOrder: ValidateOrder:
CRATE: CRATE:
Tooltip: Tooltip:
Name: Crate Name: Crate

View File

@@ -46,7 +46,7 @@ HARVESTER:
Capacity: 20 Capacity: 20
Resources: Spice Resources: Spice
UnloadTicksPerBale: 1 UnloadTicksPerBale: 1
# How far away from our linked proc (refinery) to find resources (in cells): # How far away from our linked refinery to find resources (in cells):
SearchFromProcRadius: 24 SearchFromProcRadius: 24
# How far away from last harvest order location to find more resources (in cells): # How far away from last harvest order location to find more resources (in cells):
SearchFromOrderRadius: 12 SearchFromOrderRadius: 12

View File

@@ -71,6 +71,9 @@ Weapons:
Voices: Voices:
mods/ra/voices.yaml mods/ra/voices.yaml
Notifications:
mods/ra/notifications.yaml
TileSets: TileSets:
mods/ra/tilesets/snow.yaml mods/ra/tilesets/snow.yaml
mods/ra/tilesets/interior.yaml mods/ra/tilesets/interior.yaml

View File

@@ -0,0 +1,30 @@
Speech:
Notifications:
Repairing: repair1
LowPower: lopower1
SilosNeeded: silond1
PrimaryBuildingSelected: pribldg1
BuildingCannotPlaceAudio: nodeply1
NewOptions: newopt1
AbilityInsufficientPower: nopowr1
Win: misnwon1
Lose: misnlst1
BaseAttack: baseatk1
HarvesterAttack:
Leave: bct1
Sounds:
Notifications:
RadarUp: radaron2
RadarDown: radardn1
CashTickUp: cashup1
CashTickDown:cashdn1
LevelUp: hydrod1
DisablePower: bleep11
EnablePower: bleep12
ChatLine: scold1
BuildPaletteOpen: bleep13
BuildPaletteClose: bleep13
TabClick: ramenu1
ClickSound:
ClickDisabledSound:

View File

@@ -31,8 +31,6 @@ Player:
PlaceBuilding: PlaceBuilding:
SupportPowerManager: SupportPowerManager:
ConquestVictoryConditions: ConquestVictoryConditions:
WinNotification:misnwon1.aud
LoseNotification:misnlst1.aud
PowerManager: PowerManager:
AllyRepair: AllyRepair:
PlayerResources: PlayerResources:
@@ -293,7 +291,6 @@ World:
CreateMPPlayers: CreateMPPlayers:
MPStartLocations: MPStartLocations:
SpawnMPUnits: SpawnMPUnits:
EvaAlerts:
SpatialBins: SpatialBins:
BinSize: 4 BinSize: 4
Shroud: Shroud: