@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Editor
|
||||
|
||||
currentMod = args.FirstOrDefault() ?? "ra";
|
||||
|
||||
toolStripComboBox1.Items.AddRange(Mod.AllMods.Keys.ToArray());
|
||||
toolStripComboBox1.Items.AddRange(ModMetadata.AllMods.Keys.ToArray());
|
||||
|
||||
toolStripComboBox1.SelectedIndexChanged += (_, e) =>
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace OpenRA.Editor
|
||||
|
||||
Game.modData = new ModData(currentMod);
|
||||
GlobalFileSystem.LoadFromManifest(Game.modData.Manifest);
|
||||
Rules.LoadRules(Game.modData.Manifest, new Map());
|
||||
Program.Rules = Game.modData.RulesetCache.LoadDefaultRules();
|
||||
|
||||
var mod = Game.modData.Manifest.Mod;
|
||||
Text = "{0} Mod Version: {1} - OpenRA Editor".F(mod.Title, mod.Version);
|
||||
@@ -69,7 +69,8 @@ namespace OpenRA.Editor
|
||||
void OnMapChanged()
|
||||
{
|
||||
MakeDirty();
|
||||
miniMapBox.Image = Minimap.AddStaticResources(surface1.Map, Minimap.TerrainBitmap(surface1.Map, true));
|
||||
var tileSet = Program.Rules.TileSets[surface1.Map.Tileset];
|
||||
miniMapBox.Image = Minimap.RenderMapPreview(tileSet, surface1.Map, true);
|
||||
cashToolStripStatusLabel.Text = CalculateTotalResource().ToString();
|
||||
}
|
||||
|
||||
@@ -84,7 +85,7 @@ namespace OpenRA.Editor
|
||||
var objSaved = kv.Value.Save();
|
||||
|
||||
// TODO: make this work properly
|
||||
foreach (var init in Rules.Info[kv.Value.Type].GetInitKeys())
|
||||
foreach (var init in Program.Rules.Actors[kv.Value.Type].GetInitKeys())
|
||||
apd.AddRow(init.First,
|
||||
apd.MakeEditorControl(init.Second,
|
||||
() => objSaved.NodesDict.ContainsKey(init.First) ? objSaved.NodesDict[init.First].Value : null,
|
||||
@@ -120,7 +121,7 @@ namespace OpenRA.Editor
|
||||
if (map.Players.Count == 0)
|
||||
map.MakeDefaultPlayers();
|
||||
|
||||
PrepareMapResources(Game.modData.Manifest, map);
|
||||
PrepareMapResources(Game.modData, map);
|
||||
|
||||
// Calculate total net worth of resources in cash
|
||||
cashToolStripStatusLabel.Text = CalculateTotalResource().ToString();
|
||||
@@ -135,17 +136,18 @@ namespace OpenRA.Editor
|
||||
resourcePalette.Controls.Clear();
|
||||
|
||||
loadedMapName = null;
|
||||
PrepareMapResources(Game.modData.Manifest, map);
|
||||
PrepareMapResources(Game.modData, map);
|
||||
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
// this code is insanely stupid, and mostly my fault -- chrisf
|
||||
void PrepareMapResources(Manifest manifest, Map map)
|
||||
void PrepareMapResources(ModData modData, Map map)
|
||||
{
|
||||
Rules.LoadRules(manifest, map);
|
||||
tileset = Rules.TileSets[map.Tileset];
|
||||
tilesetRenderer = new TileSetRenderer(tileset, manifest.TileSize);
|
||||
Program.Rules = map.Rules;
|
||||
|
||||
tileset = Program.Rules.TileSets[map.Tileset];
|
||||
tilesetRenderer = new TileSetRenderer(tileset, modData.Manifest.TileSize);
|
||||
var shadowIndex = new int[] { 3, 4 };
|
||||
var palette = new Palette(GlobalFileSystem.Open(tileset.Palette), shadowIndex);
|
||||
|
||||
@@ -208,11 +210,11 @@ namespace OpenRA.Editor
|
||||
|
||||
var actorTemplates = new List<ActorTemplate>();
|
||||
|
||||
foreach (var a in Rules.Info.Keys)
|
||||
foreach (var a in Program.Rules.Actors.Keys)
|
||||
{
|
||||
try
|
||||
{
|
||||
var info = Rules.Info[a];
|
||||
var info = Program.Rules.Actors[a];
|
||||
if (!info.Traits.Contains<RenderSimpleInfo>()) continue;
|
||||
|
||||
var etf = info.Traits.GetOrDefault<EditorTilesetFilterInfo>();
|
||||
@@ -253,7 +255,7 @@ namespace OpenRA.Editor
|
||||
|
||||
var resourceTemplates = new List<ResourceTemplate>();
|
||||
|
||||
foreach (var a in Rules.Info["world"].Traits.WithInterface<ResourceTypeInfo>())
|
||||
foreach (var a in Program.Rules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -286,7 +288,7 @@ namespace OpenRA.Editor
|
||||
p.ResumeLayout();
|
||||
}
|
||||
|
||||
miniMapBox.Image = Minimap.AddStaticResources(surface1.Map, Minimap.TerrainBitmap(surface1.Map, true));
|
||||
miniMapBox.Image = Minimap.RenderMapPreview(tileset, surface1.Map, true);
|
||||
|
||||
propertiesToolStripMenuItem.Enabled = true;
|
||||
toolStripMenuItemProperties.Enabled = true;
|
||||
@@ -388,12 +390,12 @@ namespace OpenRA.Editor
|
||||
using (var nmd = new NewMapDialog())
|
||||
{
|
||||
nmd.TheaterBox.Items.Clear();
|
||||
nmd.TheaterBox.Items.AddRange(Rules.TileSets.Select(a => a.Value.Id).ToArray());
|
||||
nmd.TheaterBox.Items.AddRange(Program.Rules.TileSets.Select(a => a.Value.Id).ToArray());
|
||||
nmd.TheaterBox.SelectedIndex = 0;
|
||||
|
||||
if (DialogResult.OK == nmd.ShowDialog())
|
||||
{
|
||||
var tileset = OpenRA.Rules.TileSets[nmd.TheaterBox.SelectedItem as string];
|
||||
var tileset = Program.Rules.TileSets[nmd.TheaterBox.SelectedItem as string];
|
||||
var map = Map.FromTileset(tileset);
|
||||
|
||||
map.Resize((int)nmd.MapWidth.Value, (int)nmd.MapHeight.Value);
|
||||
@@ -402,7 +404,7 @@ namespace OpenRA.Editor
|
||||
|
||||
map.Players.Clear();
|
||||
map.MakeDefaultPlayers();
|
||||
map.FixOpenAreas();
|
||||
map.FixOpenAreas(Program.Rules);
|
||||
|
||||
NewMap(map);
|
||||
}
|
||||
@@ -485,7 +487,7 @@ namespace OpenRA.Editor
|
||||
void FixOpenAreas(object sender, EventArgs e)
|
||||
{
|
||||
dirty = true;
|
||||
surface1.Map.FixOpenAreas();
|
||||
surface1.Map.FixOpenAreas(Program.Rules);
|
||||
surface1.Chunks.Clear();
|
||||
surface1.Invalidate();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -75,7 +75,8 @@ namespace OpenRA.Editor
|
||||
|
||||
try
|
||||
{
|
||||
MiniMapBox.Image = Minimap.AddStaticResources(map, Minimap.TerrainBitmap(map, true));
|
||||
var tileset = Program.Rules.TileSets[map.Tileset];
|
||||
MiniMapBox.Image = Minimap.RenderMapPreview(tileset, map, true);
|
||||
}
|
||||
catch (Exception ed)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -19,9 +19,13 @@ namespace OpenRA.Editor
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
public static Ruleset Rules;
|
||||
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Log.AddChannel("perf", null);
|
||||
|
||||
Application.CurrentCulture = CultureInfo.InvariantCulture;
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -379,7 +379,7 @@ namespace OpenRA.Editor
|
||||
ColorPalette GetPaletteForPlayerInner(string name)
|
||||
{
|
||||
var pr = Map.Players[name];
|
||||
var pcpi = Rules.Info["player"].Traits.Get<PlayerColorPaletteInfo>();
|
||||
var pcpi = Program.Rules.Actors["player"].Traits.Get<PlayerColorPaletteInfo>();
|
||||
var remap = new PlayerColorRemap(pcpi.RemapIndex, pr.Color, pcpi.Ramp);
|
||||
return new Palette(PlayerPalette, remap).AsSystemPalette();
|
||||
}
|
||||
|
||||
@@ -69,10 +69,10 @@ namespace OpenRA
|
||||
|
||||
if (name != null)
|
||||
{
|
||||
if (!Rules.Info.ContainsKey(name.ToLowerInvariant()))
|
||||
if (!world.Map.Rules.Actors.ContainsKey(name.ToLowerInvariant()))
|
||||
throw new NotImplementedException("No rules definition for unit {0}".F(name.ToLowerInvariant()));
|
||||
|
||||
Info = Rules.Info[name.ToLowerInvariant()];
|
||||
Info = world.Map.Rules.Actors[name.ToLowerInvariant()];
|
||||
foreach (var trait in Info.TraitsInConstructOrder())
|
||||
AddTrait(trait.Create(init));
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenRA.Effects
|
||||
public MoveFlash(WPos pos, World world)
|
||||
{
|
||||
this.pos = pos;
|
||||
anim = new Animation("moveflsh");
|
||||
anim = new Animation(world, "moveflsh");
|
||||
anim.PlayThen("idle", () => world.AddFrameEndTask(w => w.Remove(this)));
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +117,8 @@ namespace OpenRA
|
||||
}, parent, id);
|
||||
}
|
||||
|
||||
// Note: These delayed actions should only be used by widgets or disposing objects
|
||||
// - things that depend on a particular world should be queuing them on the worldactor.
|
||||
static ActionQueue delayedActions = new ActionQueue();
|
||||
public static void RunAfterTick(Action a) { delayedActions.Add(a); }
|
||||
public static void RunAfterDelay(int delay, Action a) { delayedActions.Add(a, delay); }
|
||||
@@ -151,8 +153,11 @@ namespace OpenRA
|
||||
using (new PerfSample("render_widgets"))
|
||||
{
|
||||
Ui.Draw();
|
||||
var cursorName = Ui.Root.GetCursorOuter(Viewport.LastMousePos) ?? "default";
|
||||
CursorProvider.DrawCursor(Renderer, cursorName, Viewport.LastMousePos, (int)cursorFrame);
|
||||
if (modData != null && modData.CursorProvider != null)
|
||||
{
|
||||
var cursorName = Ui.Root.GetCursorOuter(Viewport.LastMousePos) ?? "default";
|
||||
modData.CursorProvider.DrawCursor(Renderer, cursorName, Viewport.LastMousePos, (int)cursorFrame);
|
||||
}
|
||||
}
|
||||
|
||||
using (new PerfSample("render_flip"))
|
||||
@@ -248,11 +253,12 @@ namespace OpenRA
|
||||
BeforeGameStart();
|
||||
|
||||
Map map;
|
||||
|
||||
using (new PerfTimer("PrepareMap"))
|
||||
map = modData.PrepareMap(mapUID);
|
||||
using (new PerfTimer("NewWorld"))
|
||||
{
|
||||
orderManager.world = new World(modData.Manifest, map, orderManager, isShellmap);
|
||||
orderManager.world = new World(map, orderManager, isShellmap);
|
||||
orderManager.world.Timestep = Timestep;
|
||||
}
|
||||
worldRenderer = new WorldRenderer(orderManager.world);
|
||||
@@ -354,7 +360,7 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
Console.WriteLine("Available mods:");
|
||||
foreach (var mod in Mod.AllMods)
|
||||
foreach (var mod in ModMetadata.AllMods)
|
||||
Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version);
|
||||
|
||||
InitializeWithMod(Settings.Game.Mod, args.GetValue("Launch.Replay", null));
|
||||
@@ -379,7 +385,7 @@ namespace OpenRA
|
||||
orderManager.Dispose();
|
||||
|
||||
// Fall back to default if the mod doesn't exist
|
||||
if (!Mod.AllMods.ContainsKey(mod))
|
||||
if (!ModMetadata.AllMods.ContainsKey(mod))
|
||||
mod = new GameSettings().Mod;
|
||||
|
||||
Console.WriteLine("Loading mod: {0}", mod);
|
||||
|
||||
@@ -1,56 +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
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.GameRules;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public static class Rules
|
||||
{
|
||||
public static Dictionary<string, ActorInfo> Info;
|
||||
public static Dictionary<string, WeaponInfo> Weapons;
|
||||
public static Dictionary<string, SoundInfo> Voices;
|
||||
public static Dictionary<string, SoundInfo> Notifications;
|
||||
public static Dictionary<string, MusicInfo> Music;
|
||||
public static Dictionary<string, string> Movies;
|
||||
public static Dictionary<string, TileSet> TileSets;
|
||||
|
||||
public static void LoadRules(Manifest m, Map map)
|
||||
{
|
||||
// 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));
|
||||
Weapons = LoadYamlRules(m.Weapons, map.Weapons, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), 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));
|
||||
Movies = LoadYamlRules(m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
||||
|
||||
TileSets = new Dictionary<string, TileSet>();
|
||||
foreach (var file in m.TileSets)
|
||||
{
|
||||
var t = new TileSet(file);
|
||||
TileSets.Add(t.Id,t);
|
||||
}
|
||||
}
|
||||
|
||||
static Dictionary<string, T> LoadYamlRules<T>(string[] files, List<MiniYamlNode> dict, Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f)
|
||||
{
|
||||
var y = files.Select(MiniYaml.FromFile).Aggregate(dict, MiniYaml.MergeLiberal);
|
||||
var yy = y.ToDictionary(x => x.Key, x => x.Value);
|
||||
return y.ToDictionaryWithConflictLog(kv => kv.Key.ToLowerInvariant(), kv => f(kv, yy), "LoadYamlRules", null, null);
|
||||
}
|
||||
|
||||
public static IEnumerable<KeyValuePair<string, MusicInfo>> InstalledMusic { get { return Music.Where(m => m.Value.Exists); } }
|
||||
}
|
||||
}
|
||||
52
OpenRA.Game/GameRules/Ruleset.cs
Normal file
52
OpenRA.Game/GameRules/Ruleset.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class Ruleset
|
||||
{
|
||||
public readonly IReadOnlyDictionary<string, ActorInfo> Actors;
|
||||
public readonly IReadOnlyDictionary<string, WeaponInfo> Weapons;
|
||||
public readonly IReadOnlyDictionary<string, SoundInfo> Voices;
|
||||
public readonly IReadOnlyDictionary<string, SoundInfo> Notifications;
|
||||
public readonly IReadOnlyDictionary<string, MusicInfo> Music;
|
||||
public readonly IReadOnlyDictionary<string, string> Movies;
|
||||
public readonly IReadOnlyDictionary<string, TileSet> TileSets;
|
||||
public readonly IReadOnlyDictionary<string, SequenceProvider> Sequences;
|
||||
|
||||
public Ruleset(
|
||||
IDictionary<string, ActorInfo> actors,
|
||||
IDictionary<string, WeaponInfo> weapons,
|
||||
IDictionary<string, SoundInfo> voices,
|
||||
IDictionary<string, SoundInfo> notifications,
|
||||
IDictionary<string, MusicInfo> music,
|
||||
IDictionary<string, string> movies,
|
||||
IDictionary<string, TileSet> tileSets,
|
||||
IDictionary<string, SequenceProvider> sequences)
|
||||
{
|
||||
Actors = new ReadOnlyDictionary<string, ActorInfo>(actors);
|
||||
Weapons = new ReadOnlyDictionary<string, WeaponInfo>(weapons);
|
||||
Voices = new ReadOnlyDictionary<string, SoundInfo>(voices);
|
||||
Notifications = new ReadOnlyDictionary<string, SoundInfo>(notifications);
|
||||
Music = new ReadOnlyDictionary<string, MusicInfo>(music);
|
||||
Movies = new ReadOnlyDictionary<string, string>(movies);
|
||||
TileSets = new ReadOnlyDictionary<string, TileSet>(tileSets);
|
||||
Sequences = new ReadOnlyDictionary<string, SequenceProvider>(sequences);
|
||||
}
|
||||
|
||||
public IEnumerable<KeyValuePair<string, MusicInfo>> InstalledMusic { get { return Music.Where(m => m.Value.Exists); } }
|
||||
}
|
||||
}
|
||||
142
OpenRA.Game/GameRules/RulesetCache.cs
Executable file
142
OpenRA.Game/GameRules/RulesetCache.cs
Executable file
@@ -0,0 +1,142 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Support;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class RulesetCache
|
||||
{
|
||||
readonly ModData modData;
|
||||
|
||||
readonly Dictionary<string, ActorInfo> actorCache = new Dictionary<string, ActorInfo>();
|
||||
readonly Dictionary<string, WeaponInfo> weaponCache = new Dictionary<string, WeaponInfo>();
|
||||
readonly Dictionary<string, SoundInfo> voiceCache = new Dictionary<string, SoundInfo>();
|
||||
readonly Dictionary<string, SoundInfo> notificationCache = new Dictionary<string, SoundInfo>();
|
||||
readonly Dictionary<string, MusicInfo> musicCache = new Dictionary<string, MusicInfo>();
|
||||
readonly Dictionary<string, string> movieCache = new Dictionary<string, string>();
|
||||
readonly Dictionary<string, TileSet> tileSetCache = new Dictionary<string, TileSet>();
|
||||
readonly Dictionary<string, SequenceCache> sequenceCaches = new Dictionary<string, SequenceCache>();
|
||||
|
||||
public event EventHandler LoadingProgress;
|
||||
void RaiseProgress()
|
||||
{
|
||||
if (LoadingProgress != null)
|
||||
LoadingProgress(this, new EventArgs());
|
||||
}
|
||||
|
||||
public RulesetCache(ModData modData)
|
||||
{
|
||||
this.modData = modData;
|
||||
}
|
||||
|
||||
public Ruleset LoadDefaultRules()
|
||||
{
|
||||
return LoadMapRules(new Map());
|
||||
}
|
||||
|
||||
public Ruleset LoadMapRules(Map map)
|
||||
{
|
||||
var m = modData.Manifest;
|
||||
|
||||
Dictionary<string, ActorInfo> actors;
|
||||
Dictionary<string, WeaponInfo> weapons;
|
||||
Dictionary<string, SoundInfo> voices;
|
||||
Dictionary<string, SoundInfo> notifications;
|
||||
Dictionary<string, MusicInfo> music;
|
||||
Dictionary<string, string> movies;
|
||||
Dictionary<string, TileSet> tileSets;
|
||||
|
||||
using (new PerfTimer("Actors"))
|
||||
actors = LoadYamlRules(actorCache, m.Rules, map.RuleDefinitions, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y));
|
||||
using (new PerfTimer("Weapons"))
|
||||
weapons = LoadYamlRules(weaponCache, m.Weapons, map.WeaponDefinitions, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
|
||||
using (new PerfTimer("Voices"))
|
||||
voices = LoadYamlRules(voiceCache, m.Voices, map.VoiceDefinitions, (k, _) => new SoundInfo(k.Value));
|
||||
using (new PerfTimer("Notifications"))
|
||||
notifications = LoadYamlRules(notificationCache, m.Notifications, map.NotificationDefinitions, (k, _) => new SoundInfo(k.Value));
|
||||
using (new PerfTimer("Music"))
|
||||
music = LoadYamlRules(musicCache, m.Music, new List<MiniYamlNode>(), (k, _) => new MusicInfo(k.Key, k.Value));
|
||||
using (new PerfTimer("Movies"))
|
||||
movies = LoadYamlRules(movieCache, m.Movies, new List<MiniYamlNode>(), (k, v) => k.Value.Value);
|
||||
using (new PerfTimer("TileSets"))
|
||||
tileSets = LoadTileSets(tileSetCache, sequenceCaches, m.TileSets);
|
||||
|
||||
var sequences = sequenceCaches.ToDictionary(kvp => kvp.Key, kvp => new SequenceProvider(kvp.Value, map));
|
||||
|
||||
return new Ruleset(actors, weapons, voices, notifications, music, movies, tileSets, sequences);
|
||||
}
|
||||
|
||||
Dictionary<string, T> LoadYamlRules<T>(
|
||||
Dictionary<string, T> itemCache,
|
||||
string[] files, List<MiniYamlNode> nodes,
|
||||
Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f)
|
||||
{
|
||||
RaiseProgress();
|
||||
|
||||
var inputKey = string.Concat(string.Join("|", files), "|", nodes.WriteToString());
|
||||
|
||||
var mergedNodes = files
|
||||
.Select(s => MiniYaml.FromFile(s))
|
||||
.Aggregate(nodes, MiniYaml.MergeLiberal);
|
||||
|
||||
Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> wrap = (wkv, wyy) =>
|
||||
{
|
||||
var key = inputKey + wkv.Value.ToLines(wkv.Key).JoinWith("|");
|
||||
T t;
|
||||
if (itemCache.TryGetValue(key, out t))
|
||||
return t;
|
||||
|
||||
t = f(wkv, wyy);
|
||||
itemCache.Add(key, t);
|
||||
|
||||
RaiseProgress();
|
||||
return t;
|
||||
};
|
||||
|
||||
var yy = mergedNodes.ToDictionary(x => x.Key, x => x.Value);
|
||||
var itemSet = mergedNodes.ToDictionaryWithConflictLog(kv => kv.Key.ToLowerInvariant(), kv => wrap(kv, yy), "LoadYamlRules", null, null);
|
||||
|
||||
RaiseProgress();
|
||||
return itemSet;
|
||||
}
|
||||
|
||||
Dictionary<string, TileSet> LoadTileSets(Dictionary<string, TileSet> itemCache, Dictionary<string, SequenceCache> sequenceCaches, string[] files)
|
||||
{
|
||||
var items = new Dictionary<string, TileSet>();
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
TileSet t;
|
||||
if (itemCache.TryGetValue(file, out t))
|
||||
items.Add(t.Id, t);
|
||||
else
|
||||
{
|
||||
t = new TileSet(modData, file);
|
||||
itemCache.Add(file, t);
|
||||
|
||||
// every time we load a tile set, we create a sequence cache for it
|
||||
var sc = new SequenceCache(modData, t);
|
||||
sequenceCaches.Add(t.Id, sc);
|
||||
|
||||
items.Add(t.Id, t);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA.Graphics
|
||||
public bool IsDecoration = false;
|
||||
public Func<bool> Paused;
|
||||
|
||||
Func<int> facingFunc;
|
||||
readonly Func<int> facingFunc;
|
||||
|
||||
int frame = 0;
|
||||
bool backwards = false;
|
||||
@@ -28,11 +28,17 @@ namespace OpenRA.Graphics
|
||||
|
||||
public string Name { get { return name; } }
|
||||
|
||||
public Animation(string name)
|
||||
: this(name, () => 0) {}
|
||||
readonly SequenceProvider sequenceProvider;
|
||||
|
||||
public Animation(string name, Func<int> facingFunc)
|
||||
public Animation(World world, string name)
|
||||
: this(world, name, () => 0) { }
|
||||
|
||||
public Animation(World world, string name, Func<int> facingFunc)
|
||||
: this(world.Map.SequenceProvider, name, facingFunc) { }
|
||||
|
||||
public Animation(SequenceProvider sequenceProvider, string name, Func<int> facingFunc)
|
||||
{
|
||||
this.sequenceProvider = sequenceProvider;
|
||||
this.name = name.ToLowerInvariant();
|
||||
this.tickFunc = () => {};
|
||||
this.facingFunc = facingFunc;
|
||||
@@ -66,7 +72,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
backwards = false;
|
||||
tickAlways = false;
|
||||
CurrentSequence = SequenceProvider.GetSequence(name, sequenceName);
|
||||
CurrentSequence = sequenceProvider.GetSequence(name, sequenceName);
|
||||
frame = 0;
|
||||
tickFunc = () =>
|
||||
{
|
||||
@@ -81,7 +87,7 @@ namespace OpenRA.Graphics
|
||||
if (!HasSequence(sequenceName))
|
||||
return false;
|
||||
|
||||
CurrentSequence = SequenceProvider.GetSequence(name, sequenceName);
|
||||
CurrentSequence = sequenceProvider.GetSequence(name, sequenceName);
|
||||
frame %= CurrentSequence.Length;
|
||||
return true;
|
||||
}
|
||||
@@ -90,7 +96,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
backwards = false;
|
||||
tickAlways = false;
|
||||
CurrentSequence = SequenceProvider.GetSequence(name, sequenceName);
|
||||
CurrentSequence = sequenceProvider.GetSequence(name, sequenceName);
|
||||
frame = 0;
|
||||
tickFunc = () =>
|
||||
{
|
||||
@@ -114,7 +120,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
backwards = false;
|
||||
tickAlways = true;
|
||||
CurrentSequence = SequenceProvider.GetSequence(name, sequenceName);
|
||||
CurrentSequence = sequenceProvider.GetSequence(name, sequenceName);
|
||||
frame = func();
|
||||
tickFunc = () => frame = func();
|
||||
}
|
||||
@@ -128,7 +134,7 @@ namespace OpenRA.Graphics
|
||||
Tick(40); // tick one frame
|
||||
}
|
||||
|
||||
public bool HasSequence(string seq) { return SequenceProvider.HasSequence(name, seq); }
|
||||
public bool HasSequence(string seq) { return sequenceProvider.HasSequence(name, seq); }
|
||||
|
||||
public void Tick(int t)
|
||||
{
|
||||
@@ -159,7 +165,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
public Sequence GetSequence(string sequenceName)
|
||||
{
|
||||
return SequenceProvider.GetSequence(name, sequenceName);
|
||||
return sequenceProvider.GetSequence(name, sequenceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,23 +16,16 @@ using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
{
|
||||
public static class CursorProvider
|
||||
public class CursorProvider
|
||||
{
|
||||
static HardwarePalette palette;
|
||||
static Dictionary<string, CursorSequence> cursors;
|
||||
static Cache<string, PaletteReference> palettes;
|
||||
HardwarePalette palette;
|
||||
Dictionary<string, CursorSequence> cursors;
|
||||
Cache<string, PaletteReference> palettes;
|
||||
|
||||
static PaletteReference CreatePaletteReference(string name)
|
||||
public CursorProvider(ModData modData)
|
||||
{
|
||||
var pal = palette.GetPalette(name);
|
||||
if (pal == null)
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
var sequenceFiles = modData.Manifest.Cursors;
|
||||
|
||||
return new PaletteReference(name, palette.GetPaletteIndex(name), pal);
|
||||
}
|
||||
|
||||
public static void Initialize(string[] sequenceFiles)
|
||||
{
|
||||
cursors = new Dictionary<string, CursorSequence>();
|
||||
palettes = new Cache<string, PaletteReference>(CreatePaletteReference);
|
||||
var sequences = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal));
|
||||
@@ -49,26 +42,35 @@ namespace OpenRA.Graphics
|
||||
foreach (var p in sequences.NodesDict["Palettes"].Nodes)
|
||||
palette.AddPalette(p.Key, new Palette(GlobalFileSystem.Open(p.Value.Value), shadowIndex), false);
|
||||
|
||||
|
||||
var spriteLoader = new SpriteLoader(new string[0], new SheetBuilder(SheetType.Indexed));
|
||||
foreach (var s in sequences.NodesDict["Cursors"].Nodes)
|
||||
LoadSequencesForCursor(s.Key, s.Value);
|
||||
LoadSequencesForCursor(spriteLoader, s.Key, s.Value);
|
||||
|
||||
palette.Initialize();
|
||||
}
|
||||
|
||||
static void LoadSequencesForCursor(string cursorSrc, MiniYaml cursor)
|
||||
PaletteReference CreatePaletteReference(string name)
|
||||
{
|
||||
Game.modData.LoadScreen.Display();
|
||||
var pal = palette.GetPalette(name);
|
||||
if (pal == null)
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
|
||||
foreach (var sequence in cursor.Nodes)
|
||||
cursors.Add(sequence.Key, new CursorSequence(cursorSrc, cursor.Value, sequence.Value));
|
||||
return new PaletteReference(name, palette.GetPaletteIndex(name), pal);
|
||||
}
|
||||
|
||||
public static bool HasCursorSequence(string cursor)
|
||||
void LoadSequencesForCursor(SpriteLoader loader, string cursorSrc, MiniYaml cursor)
|
||||
{
|
||||
foreach (var sequence in cursor.Nodes)
|
||||
cursors.Add(sequence.Key, new CursorSequence(loader, cursorSrc, cursor.Value, sequence.Value));
|
||||
}
|
||||
|
||||
public bool HasCursorSequence(string cursor)
|
||||
{
|
||||
return cursors.ContainsKey(cursor);
|
||||
}
|
||||
|
||||
public static void DrawCursor(Renderer renderer, string cursorName, int2 lastMousePos, int cursorFrame)
|
||||
public void DrawCursor(Renderer renderer, string cursorName, int2 lastMousePos, int cursorFrame)
|
||||
{
|
||||
var cursorSequence = GetCursorSequence(cursorName);
|
||||
var cursorSprite = cursorSequence.GetSprite(cursorFrame);
|
||||
@@ -80,13 +82,12 @@ namespace OpenRA.Graphics
|
||||
cursorSprite.size);
|
||||
}
|
||||
|
||||
public static CursorSequence GetCursorSequence(string cursor)
|
||||
public CursorSequence GetCursorSequence(string cursor)
|
||||
{
|
||||
try { return cursors[cursor]; }
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Cursor does not have a sequence `{0}`".F(cursor));
|
||||
throw new InvalidOperationException("Cursor does not have a sequence `{0}`".F(cursor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace OpenRA.Graphics
|
||||
|
||||
Sprite[] sprites;
|
||||
|
||||
public CursorSequence(string cursorSrc, string palette, MiniYaml info)
|
||||
public CursorSequence(SpriteLoader loader, string cursorSrc, string palette, MiniYaml info)
|
||||
{
|
||||
sprites = Game.modData.SpriteLoader.LoadAllSprites(cursorSrc);
|
||||
sprites = loader.LoadAllSprites(cursorSrc);
|
||||
var d = info.NodesDict;
|
||||
|
||||
start = Exts.ParseIntegerInvariant(d["start"].Value);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -19,14 +19,8 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
public class Minimap
|
||||
{
|
||||
public static Bitmap TerrainBitmap(Map map)
|
||||
public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false)
|
||||
{
|
||||
return TerrainBitmap(map, false);
|
||||
}
|
||||
|
||||
public static Bitmap TerrainBitmap(Map map, bool actualSize)
|
||||
{
|
||||
var tileset = Rules.TileSets[map.Tileset];
|
||||
var width = map.Bounds.Width;
|
||||
var height = map.Bounds.Height;
|
||||
|
||||
@@ -61,10 +55,9 @@ namespace OpenRA.Graphics
|
||||
|
||||
// Add the static resources defined in the map; if the map lives
|
||||
// in a world use AddCustomTerrain instead
|
||||
public static Bitmap AddStaticResources(Map map, Bitmap terrainBitmap)
|
||||
static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap)
|
||||
{
|
||||
Bitmap terrain = new Bitmap(terrainBitmap);
|
||||
var tileset = Rules.TileSets[map.Tileset];
|
||||
|
||||
var bitmapData = terrain.LockBits(terrain.Bounds(),
|
||||
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
@@ -81,7 +74,7 @@ namespace OpenRA.Graphics
|
||||
if (map.MapResources.Value[mapX, mapY].Type == 0)
|
||||
continue;
|
||||
|
||||
var res = Rules.Info["world"].Traits.WithInterface<ResourceTypeInfo>()
|
||||
var res = resourceRules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>()
|
||||
.Where(t => t.ResourceType == map.MapResources.Value[mapX, mapY].Type)
|
||||
.Select(t => t.TerrainType).FirstOrDefault();
|
||||
if (res == null)
|
||||
@@ -185,10 +178,15 @@ namespace OpenRA.Graphics
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Bitmap RenderMapPreview(Map map, bool actualSize)
|
||||
public static Bitmap RenderMapPreview(TileSet tileset, Map map, bool actualSize)
|
||||
{
|
||||
Bitmap terrain = TerrainBitmap(map, actualSize);
|
||||
return AddStaticResources(map, terrain);
|
||||
return RenderMapPreview(tileset, map, map.Rules, actualSize);
|
||||
}
|
||||
|
||||
public static Bitmap RenderMapPreview(TileSet tileset, Map map, Ruleset resourceRules, bool actualSize)
|
||||
{
|
||||
Bitmap terrain = TerrainBitmap(tileset, map, actualSize);
|
||||
return AddStaticResources(tileset, map, resourceRules, terrain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Graphics
|
||||
public readonly int ShadowZOffset;
|
||||
public readonly int[] Frames;
|
||||
|
||||
public Sequence(string unit, string name, MiniYaml info)
|
||||
public Sequence(SpriteLoader loader, string unit, string name, MiniYaml info)
|
||||
{
|
||||
var srcOverride = info.Value;
|
||||
Name = name;
|
||||
@@ -50,7 +50,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
// Apply offset to each sprite in the sequence
|
||||
// Different sequences may apply different offsets to the same frame
|
||||
sprites = Game.modData.SpriteLoader.LoadAllSprites(srcOverride ?? unit).Select(
|
||||
sprites = loader.LoadAllSprites(srcOverride ?? unit).Select(
|
||||
s => new Sprite(s.sheet, s.bounds, s.offset + offset, s.channel, blendMode)).ToArray();
|
||||
|
||||
if (!d.ContainsKey("Length"))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -13,69 +13,101 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
{
|
||||
public static class SequenceProvider
|
||||
public class SequenceProvider
|
||||
{
|
||||
static Dictionary<string, Dictionary<string, Sequence>> units;
|
||||
readonly Lazy<IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>> sequences;
|
||||
public readonly SpriteLoader SpriteLoader;
|
||||
|
||||
public static void Initialize(string[] sequenceFiles, List<MiniYamlNode> sequenceNodes)
|
||||
public SequenceProvider(SequenceCache cache, Map map)
|
||||
{
|
||||
units = new Dictionary<string, Dictionary<string, Sequence>>();
|
||||
this.sequences = Exts.Lazy(() => cache.LoadSequences(map));
|
||||
this.SpriteLoader = cache.SpriteLoader;
|
||||
}
|
||||
|
||||
var sequences = sequenceFiles
|
||||
public Sequence GetSequence(string unitName, string sequenceName)
|
||||
{
|
||||
Lazy<IReadOnlyDictionary<string, Sequence>> unitSeq;
|
||||
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
|
||||
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
|
||||
|
||||
Sequence seq;
|
||||
if (!unitSeq.Value.TryGetValue(sequenceName, out seq))
|
||||
throw new InvalidOperationException("Unit `{0}` does not have a sequence named `{1}`".F(unitName, sequenceName));
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
public bool HasSequence(string unitName, string sequenceName)
|
||||
{
|
||||
Lazy<IReadOnlyDictionary<string, Sequence>> unitSeq;
|
||||
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
|
||||
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
|
||||
|
||||
return unitSeq.Value.ContainsKey(sequenceName);
|
||||
}
|
||||
|
||||
public IEnumerable<string> Sequences(string unitName)
|
||||
{
|
||||
Lazy<IReadOnlyDictionary<string, Sequence>> unitSeq;
|
||||
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
|
||||
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
|
||||
|
||||
return unitSeq.Value.Keys;
|
||||
}
|
||||
}
|
||||
|
||||
public class SequenceCache
|
||||
{
|
||||
readonly ModData modData;
|
||||
readonly Lazy<SpriteLoader> spriteLoader;
|
||||
public SpriteLoader SpriteLoader { get { return spriteLoader.Value; } }
|
||||
|
||||
readonly Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> sequenceCache = new Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>();
|
||||
|
||||
public SequenceCache(ModData modData, TileSet tileSet)
|
||||
{
|
||||
this.modData = modData;
|
||||
|
||||
spriteLoader = Exts.Lazy(() => new SpriteLoader(tileSet.Extensions, new SheetBuilder(SheetType.Indexed)));
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> LoadSequences(Map map)
|
||||
{
|
||||
using (new Support.PerfTimer("LoadSequences"))
|
||||
return Load(map.SequenceDefinitions);
|
||||
}
|
||||
|
||||
IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> Load(List<MiniYamlNode> sequenceNodes)
|
||||
{
|
||||
var sequenceFiles = modData.Manifest.Sequences;
|
||||
|
||||
var nodes = sequenceFiles
|
||||
.Select(s => MiniYaml.FromFile(s))
|
||||
.Aggregate(sequenceNodes, MiniYaml.MergeLiberal);
|
||||
|
||||
foreach (var s in sequences)
|
||||
LoadSequencesForUnit(s.Key, s.Value);
|
||||
}
|
||||
var items = new Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>();
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
var key = node.Value.ToLines(node.Key).JoinWith("|");
|
||||
|
||||
static void LoadSequencesForUnit(string unit, MiniYaml sequences)
|
||||
{
|
||||
Game.modData.LoadScreen.Display();
|
||||
try
|
||||
{
|
||||
var seq = sequences.NodesDict.ToDictionary(x => x.Key, x => new Sequence(unit,x.Key,x.Value));
|
||||
units.Add(unit, seq);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// Do nothing; we can crash later if we actually wanted art
|
||||
}
|
||||
}
|
||||
|
||||
public static Sequence GetSequence(string unitName, string sequenceName)
|
||||
{
|
||||
try { return units[unitName][sequenceName]; }
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
if (units.ContainsKey(unitName))
|
||||
throw new InvalidOperationException(
|
||||
"Unit `{0}` does not have a sequence `{1}`".F(unitName, sequenceName));
|
||||
Lazy<IReadOnlyDictionary<string, Sequence>> t;
|
||||
if (sequenceCache.TryGetValue(key, out t))
|
||||
items.Add(node.Key, t);
|
||||
else
|
||||
throw new InvalidOperationException(
|
||||
"Unit `{0}` does not have all sequences defined.".F(unitName));
|
||||
{
|
||||
t = Exts.Lazy(() => (IReadOnlyDictionary<string, Sequence>)new ReadOnlyDictionary<string, Sequence>(
|
||||
node.Value.NodesDict.ToDictionary(x => x.Key, x =>
|
||||
new Sequence(spriteLoader.Value, node.Key, x.Key, x.Value))));
|
||||
sequenceCache.Add(key, t);
|
||||
items.Add(node.Key, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasSequence(string unit, string seq)
|
||||
{
|
||||
if (!units.ContainsKey(unit))
|
||||
throw new InvalidOperationException(
|
||||
"Unit `{0}` does not have sequence `{1}` defined.".F(unit, seq));
|
||||
|
||||
return units[unit].ContainsKey(seq);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> Sequences(string unit)
|
||||
{
|
||||
if (!units.ContainsKey(unit))
|
||||
throw new InvalidOperationException(
|
||||
"Unit `{0}` does not have all sequences defined.".F(unit));
|
||||
|
||||
return units[unit].Keys;
|
||||
return new ReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>(items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
public class SpriteLoader
|
||||
{
|
||||
readonly SheetBuilder SheetBuilder;
|
||||
public readonly SheetBuilder SheetBuilder;
|
||||
readonly Cache<string, Sprite[]> sprites;
|
||||
readonly string[] exts;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA
|
||||
// Describes what is to be loaded in order to run a mod
|
||||
public class Manifest
|
||||
{
|
||||
public readonly Mod Mod;
|
||||
public readonly ModMetadata Mod;
|
||||
public readonly string[]
|
||||
Folders, MapFolders, Rules, ServerTraits,
|
||||
Sequences, VoxelSequences, Cursors, Chrome, Assemblies, ChromeLayout,
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA
|
||||
var path = new[] { "mods", mod, "mod.yaml" }.Aggregate(Path.Combine);
|
||||
var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).NodesDict;
|
||||
|
||||
Mod = FieldLoader.Load<Mod>(yaml["Metadata"]);
|
||||
Mod = FieldLoader.Load<ModMetadata>(yaml["Metadata"]);
|
||||
Mod.Id = mod;
|
||||
|
||||
// TODO: Use fieldloader
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Primitives;
|
||||
@@ -17,16 +18,24 @@ namespace OpenRA
|
||||
public class ActorReference : IEnumerable
|
||||
{
|
||||
public string Type;
|
||||
public TypeDictionary InitDict;
|
||||
public TypeDictionary InitDict
|
||||
{
|
||||
get { return initDict.Value; }
|
||||
}
|
||||
Lazy<TypeDictionary> initDict;
|
||||
|
||||
public ActorReference( string type ) : this( type, new Dictionary<string, MiniYaml>() ) { }
|
||||
|
||||
public ActorReference( string type, Dictionary<string, MiniYaml> inits )
|
||||
{
|
||||
Type = type;
|
||||
InitDict = new TypeDictionary();
|
||||
foreach( var i in inits )
|
||||
InitDict.Add( LoadInit( i.Key, i.Value ) );
|
||||
initDict = Exts.Lazy(() =>
|
||||
{
|
||||
var dict = new TypeDictionary();
|
||||
foreach (var i in inits)
|
||||
dict.Add(LoadInit(i.Key, i.Value));
|
||||
return dict;
|
||||
});
|
||||
}
|
||||
|
||||
static IActorInit LoadInit(string traitName, MiniYaml my)
|
||||
|
||||
@@ -18,6 +18,7 @@ using System.Text;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
@@ -94,13 +95,13 @@ namespace OpenRA
|
||||
[FieldLoader.Ignore] public Dictionary<string, PlayerReference> Players = new Dictionary<string, PlayerReference>();
|
||||
[FieldLoader.Ignore] public Lazy<List<SmudgeReference>> Smudges;
|
||||
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Rules = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Sequences = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> VoxelSequences = 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> Notifications = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> Translations = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> RuleDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> SequenceDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> VoxelSequenceDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> WeaponDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> VoiceDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> NotificationDefinitions = new List<MiniYamlNode>();
|
||||
[FieldLoader.Ignore] public List<MiniYamlNode> TranslationDefinitions = new List<MiniYamlNode>();
|
||||
|
||||
// Binary map data
|
||||
[FieldLoader.Ignore] public byte TileFormat = 1;
|
||||
@@ -110,6 +111,10 @@ namespace OpenRA
|
||||
[FieldLoader.Ignore] public Lazy<TileReference<byte, byte>[,]> MapResources;
|
||||
[FieldLoader.Ignore] public string[,] CustomTerrain;
|
||||
|
||||
[FieldLoader.Ignore] Lazy<Ruleset> rules;
|
||||
public Ruleset Rules { get { return rules != null ? rules.Value : null; } }
|
||||
public SequenceProvider SequenceProvider { get { return Rules.Sequences[Tileset]; } }
|
||||
|
||||
public static Map FromTileset(TileSet tileset)
|
||||
{
|
||||
var tile = tileset.Templates.First();
|
||||
@@ -128,6 +133,7 @@ namespace OpenRA
|
||||
Actors = Exts.Lazy(() => new Dictionary<string, ActorReference>()),
|
||||
Smudges = Exts.Lazy(() => new List<SmudgeReference>())
|
||||
};
|
||||
map.PostInit();
|
||||
|
||||
return map;
|
||||
}
|
||||
@@ -210,13 +216,13 @@ namespace OpenRA
|
||||
return ret;
|
||||
});
|
||||
|
||||
Rules = MiniYaml.NodesOrEmpty(yaml, "Rules");
|
||||
Sequences = MiniYaml.NodesOrEmpty(yaml, "Sequences");
|
||||
VoxelSequences = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
|
||||
Weapons = MiniYaml.NodesOrEmpty(yaml, "Weapons");
|
||||
Voices = MiniYaml.NodesOrEmpty(yaml, "Voices");
|
||||
Notifications = MiniYaml.NodesOrEmpty(yaml, "Notifications");
|
||||
Translations = MiniYaml.NodesOrEmpty(yaml, "Translations");
|
||||
RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules");
|
||||
SequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Sequences");
|
||||
VoxelSequenceDefinitions = MiniYaml.NodesOrEmpty(yaml, "VoxelSequences");
|
||||
WeaponDefinitions = MiniYaml.NodesOrEmpty(yaml, "Weapons");
|
||||
VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices");
|
||||
NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications");
|
||||
TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations");
|
||||
|
||||
CustomTerrain = new string[MapSize.X, MapSize.Y];
|
||||
|
||||
@@ -233,6 +239,18 @@ namespace OpenRA
|
||||
|
||||
if (Container.Exists("map.png"))
|
||||
CustomPreview = new Bitmap(Container.GetContent("map.png"));
|
||||
|
||||
PostInit();
|
||||
}
|
||||
|
||||
void PostInit()
|
||||
{
|
||||
rules = Exts.Lazy(() => Game.modData.RulesetCache.LoadMapRules(this));
|
||||
}
|
||||
|
||||
public Ruleset PreloadRules()
|
||||
{
|
||||
return rules.Value;
|
||||
}
|
||||
|
||||
public CPos[] GetSpawnPoints()
|
||||
@@ -282,13 +300,13 @@ namespace OpenRA
|
||||
);
|
||||
|
||||
root.Add(new MiniYamlNode("Smudges", MiniYaml.FromList<SmudgeReference>(Smudges.Value)));
|
||||
root.Add(new MiniYamlNode("Rules", null, Rules));
|
||||
root.Add(new MiniYamlNode("Sequences", null, Sequences));
|
||||
root.Add(new MiniYamlNode("VoxelSequences", null, VoxelSequences));
|
||||
root.Add(new MiniYamlNode("Weapons", null, Weapons));
|
||||
root.Add(new MiniYamlNode("Voices", null, Voices));
|
||||
root.Add(new MiniYamlNode("Notifications", null, Notifications));
|
||||
root.Add(new MiniYamlNode("Translations", null, Translations));
|
||||
root.Add(new MiniYamlNode("Rules", null, RuleDefinitions));
|
||||
root.Add(new MiniYamlNode("Sequences", null, SequenceDefinitions));
|
||||
root.Add(new MiniYamlNode("VoxelSequences", null, VoxelSequenceDefinitions));
|
||||
root.Add(new MiniYamlNode("Weapons", null, WeaponDefinitions));
|
||||
root.Add(new MiniYamlNode("Voices", null, VoiceDefinitions));
|
||||
root.Add(new MiniYamlNode("Notifications", null, NotificationDefinitions));
|
||||
root.Add(new MiniYamlNode("Translations", null, TranslationDefinitions));
|
||||
|
||||
var entries = new Dictionary<string, byte[]>();
|
||||
entries.Add("map.bin", SaveBinaryData());
|
||||
@@ -452,7 +470,7 @@ namespace OpenRA
|
||||
|
||||
public void MakeDefaultPlayers()
|
||||
{
|
||||
var firstRace = OpenRA.Rules.Info["world"].Traits
|
||||
var firstRace = Rules.Actors["world"].Traits
|
||||
.WithInterface<CountryInfo>().First(c => c.Selectable).Race;
|
||||
|
||||
if (!Players.ContainsKey("Neutral"))
|
||||
@@ -489,10 +507,10 @@ namespace OpenRA
|
||||
});
|
||||
}
|
||||
|
||||
public void FixOpenAreas()
|
||||
public void FixOpenAreas(Ruleset rules)
|
||||
{
|
||||
var r = new Random();
|
||||
var tileset = OpenRA.Rules.TileSets[Tileset];
|
||||
var tileset = rules.TileSets[Tileset];
|
||||
|
||||
for (var j = Bounds.Top; j < Bounds.Bottom; j++)
|
||||
{
|
||||
|
||||
14
OpenRA.Game/Map/MapCache.cs
Executable file → Normal file
14
OpenRA.Game/Map/MapCache.cs
Executable file → Normal file
@@ -27,30 +27,30 @@ namespace OpenRA
|
||||
{
|
||||
public static readonly MapPreview UnknownMap = new MapPreview(null, null);
|
||||
readonly Cache<string, MapPreview> previews;
|
||||
readonly Manifest manifest;
|
||||
readonly ModData modData;
|
||||
readonly SheetBuilder sheetBuilder;
|
||||
Thread previewLoaderThread;
|
||||
object syncRoot = new object();
|
||||
Queue<MapPreview> generateMinimap = new Queue<MapPreview>();
|
||||
|
||||
public MapCache(Manifest m)
|
||||
public MapCache(ModData modData)
|
||||
{
|
||||
manifest = m;
|
||||
this.modData = modData;
|
||||
previews = new Cache<string, MapPreview>(uid => new MapPreview(uid, this));
|
||||
sheetBuilder = new SheetBuilder(SheetType.BGRA);
|
||||
}
|
||||
|
||||
public void LoadMaps()
|
||||
{
|
||||
var paths = manifest.MapFolders.SelectMany(f => FindMapsIn(f));
|
||||
var paths = modData.Manifest.MapFolders.SelectMany(f => FindMapsIn(f));
|
||||
foreach (var path in paths)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (new Support.PerfTimer(path))
|
||||
{
|
||||
var map = new Map(path, manifest.Mod.Id);
|
||||
if (manifest.MapCompatibility.Contains(map.RequiresMod))
|
||||
var map = new Map(path, modData.Manifest.Mod.Id);
|
||||
if (modData.Manifest.MapCompatibility.Contains(map.RequiresMod))
|
||||
previews[map.Uid].UpdateFromMap(map);
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ namespace OpenRA
|
||||
// the next render cycle.
|
||||
// (d) Any partially written bytes from the next minimap is in an
|
||||
// unallocated area, and will be committed in the next cycle.
|
||||
var bitmap = p.CustomPreview ?? Minimap.RenderMapPreview(p.Map, true);
|
||||
var bitmap = p.CustomPreview ?? Minimap.RenderMapPreview(modData.DefaultRules.TileSets[p.Map.Tileset], p.Map, modData.DefaultRules, true);
|
||||
p.Minimap = sheetBuilder.Add(bitmap);
|
||||
|
||||
lock (syncRoot)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -8,21 +8,23 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class TerrainTypeInfo
|
||||
{
|
||||
public string Type;
|
||||
public string[] TargetTypes = { };
|
||||
public string[] AcceptsSmudgeType = { };
|
||||
public bool IsWater = false; // TODO: Remove this
|
||||
public Color Color;
|
||||
public string CustomCursor;
|
||||
public readonly string Type;
|
||||
public readonly string[] TargetTypes = { };
|
||||
public readonly string[] AcceptsSmudgeType = { };
|
||||
public readonly bool IsWater = false; // TODO: Remove this
|
||||
public readonly Color Color;
|
||||
public readonly string CustomCursor;
|
||||
|
||||
public TerrainTypeInfo() { }
|
||||
public TerrainTypeInfo(MiniYaml my) { FieldLoader.Load(this, my); }
|
||||
@@ -32,19 +34,26 @@ namespace OpenRA
|
||||
|
||||
public class TileTemplate
|
||||
{
|
||||
public ushort Id;
|
||||
public string Image;
|
||||
public int[] Frames;
|
||||
public int2 Size;
|
||||
public bool PickAny;
|
||||
public string Category;
|
||||
public readonly ushort Id;
|
||||
public readonly string Image;
|
||||
public readonly int[] Frames;
|
||||
public readonly int2 Size;
|
||||
public readonly bool PickAny;
|
||||
public readonly string Category;
|
||||
|
||||
[FieldLoader.LoadUsing("LoadTiles")]
|
||||
public Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
|
||||
public readonly Dictionary<byte, string> Tiles = new Dictionary<byte, string>();
|
||||
|
||||
public TileTemplate() { }
|
||||
public TileTemplate(MiniYaml my) { FieldLoader.Load(this, my); }
|
||||
|
||||
public TileTemplate(ushort id, string image, int2 size)
|
||||
{
|
||||
this.Id = id;
|
||||
this.Image = image;
|
||||
this.Size = size;
|
||||
}
|
||||
|
||||
static object LoadTiles(MiniYaml y)
|
||||
{
|
||||
return y.NodesDict["Tiles"].NodesDict.ToDictionary(
|
||||
@@ -75,22 +84,20 @@ namespace OpenRA
|
||||
|
||||
public class TileSet
|
||||
{
|
||||
public string Name;
|
||||
public string Id;
|
||||
public int SheetSize = 512;
|
||||
public string Palette;
|
||||
public string PlayerPalette;
|
||||
public string[] Extensions;
|
||||
public int WaterPaletteRotationBase = 0x60;
|
||||
public Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
|
||||
public Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
||||
public string[] EditorTemplateOrder;
|
||||
public readonly string Name;
|
||||
public readonly string Id;
|
||||
public readonly int SheetSize = 512;
|
||||
public readonly string Palette;
|
||||
public readonly string PlayerPalette;
|
||||
public readonly string[] Extensions;
|
||||
public readonly int WaterPaletteRotationBase = 0x60;
|
||||
public readonly Dictionary<string, TerrainTypeInfo> Terrain = new Dictionary<string, TerrainTypeInfo>();
|
||||
public readonly Dictionary<ushort, TileTemplate> Templates = new Dictionary<ushort, TileTemplate>();
|
||||
public readonly string[] EditorTemplateOrder;
|
||||
|
||||
static readonly string[] Fields = { "Name", "Id", "SheetSize", "Palette", "Extensions" };
|
||||
|
||||
public TileSet() { }
|
||||
|
||||
public TileSet(string filepath)
|
||||
public TileSet(ModData modData, string filepath)
|
||||
{
|
||||
var yaml = MiniYaml.DictFromFile(filepath);
|
||||
|
||||
@@ -106,6 +113,14 @@ namespace OpenRA
|
||||
.Select(y => new TileTemplate(y)).ToDictionary(t => t.Id);
|
||||
}
|
||||
|
||||
public TileSet(string name, string id, string palette, string[] extensions)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Id = id;
|
||||
this.Palette = palette;
|
||||
this.Extensions = extensions;
|
||||
}
|
||||
|
||||
public void Save(string filepath)
|
||||
{
|
||||
var root = new List<MiniYamlNode>();
|
||||
|
||||
45
OpenRA.Game/ModData.cs
Executable file → Normal file
45
OpenRA.Game/ModData.cs
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -25,9 +25,12 @@ namespace OpenRA
|
||||
public readonly WidgetLoader WidgetLoader;
|
||||
public readonly MapCache MapCache;
|
||||
public ILoadScreen LoadScreen = null;
|
||||
public SheetBuilder SheetBuilder;
|
||||
public SpriteLoader SpriteLoader;
|
||||
public VoxelLoader VoxelLoader;
|
||||
public readonly RulesetCache RulesetCache;
|
||||
public CursorProvider CursorProvider { get; private set; }
|
||||
|
||||
Lazy<Ruleset> defaultRules;
|
||||
public Ruleset DefaultRules { get { return defaultRules.Value; } }
|
||||
|
||||
public ModData(string mod)
|
||||
{
|
||||
@@ -38,12 +41,26 @@ namespace OpenRA
|
||||
LoadScreen.Init(Manifest, Manifest.LoadScreen.NodesDict.ToDictionary(x => x.Key, x => x.Value.Value));
|
||||
LoadScreen.Display();
|
||||
WidgetLoader = new WidgetLoader(this);
|
||||
MapCache = new MapCache(Manifest);
|
||||
RulesetCache = new RulesetCache(this);
|
||||
RulesetCache.LoadingProgress += HandleLoadingProgress;
|
||||
MapCache = new MapCache(this);
|
||||
|
||||
// HACK: Mount only local folders so we have a half-working environment for the asset installer
|
||||
GlobalFileSystem.UnmountAll();
|
||||
foreach (var dir in Manifest.Folders)
|
||||
GlobalFileSystem.Mount(dir);
|
||||
|
||||
defaultRules = Exts.Lazy(() => RulesetCache.LoadDefaultRules());
|
||||
|
||||
initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
|
||||
}
|
||||
|
||||
// HACK: Only update the loading screen if we're in the main thread.
|
||||
int initialThreadId;
|
||||
void HandleLoadingProgress(object sender, EventArgs e)
|
||||
{
|
||||
if (LoadScreen != null && System.Threading.Thread.CurrentThread.ManagedThreadId == initialThreadId)
|
||||
LoadScreen.Display();
|
||||
}
|
||||
|
||||
public void InitializeLoaders()
|
||||
@@ -52,10 +69,9 @@ namespace OpenRA
|
||||
// horribly when you use ModData in unexpected ways.
|
||||
ChromeMetrics.Initialize(Manifest.ChromeMetrics);
|
||||
ChromeProvider.Initialize(Manifest.Chrome);
|
||||
SheetBuilder = new SheetBuilder(SheetType.Indexed);
|
||||
SpriteLoader = new SpriteLoader(new string[0], SheetBuilder);
|
||||
VoxelLoader = new VoxelLoader();
|
||||
CursorProvider.Initialize(Manifest.Cursors);
|
||||
|
||||
CursorProvider = new CursorProvider(this);
|
||||
}
|
||||
|
||||
public IEnumerable<string> Languages { get; private set; }
|
||||
@@ -75,7 +91,7 @@ namespace OpenRA
|
||||
var yaml = Manifest.Translations.Select(MiniYaml.FromFile).Aggregate(MiniYaml.MergeLiberal);
|
||||
Languages = yaml.Select(t => t.Key).ToArray();
|
||||
|
||||
yaml = MiniYaml.MergeLiberal(map.Translations, yaml);
|
||||
yaml = MiniYaml.MergeLiberal(map.TranslationDefinitions, yaml);
|
||||
|
||||
foreach (var y in yaml)
|
||||
{
|
||||
@@ -118,16 +134,11 @@ namespace OpenRA
|
||||
// Mount map package so custom assets can be used. TODO: check priority.
|
||||
GlobalFileSystem.Mount(GlobalFileSystem.OpenPackage(map.Path, null, int.MaxValue));
|
||||
|
||||
using (new Support.PerfTimer("LoadRules"))
|
||||
Rules.LoadRules(Manifest, map);
|
||||
SpriteLoader = new SpriteLoader(Rules.TileSets[map.Tileset].Extensions, SheetBuilder);
|
||||
using (new Support.PerfTimer("Map.LoadRules"))
|
||||
map.PreloadRules();
|
||||
|
||||
VoxelProvider.Initialize(Manifest.VoxelSequences, map.VoxelSequenceDefinitions);
|
||||
|
||||
using (new Support.PerfTimer("SequenceProvider.Initialize"))
|
||||
{
|
||||
// TODO: Don't load the sequences for assets that are not used in this tileset. Maybe use the existing EditorTilesetFilters.
|
||||
SequenceProvider.Initialize(Manifest.Sequences, map.Sequences);
|
||||
}
|
||||
VoxelProvider.Initialize(Manifest.VoxelSequences, map.VoxelSequences);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -14,9 +14,9 @@ using System.Linq;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public class Mod
|
||||
public class ModMetadata
|
||||
{
|
||||
public static readonly Dictionary<string, Mod> AllMods = ValidateMods(Directory.GetDirectories("mods").Select(x => x.Substring(5)).ToArray());
|
||||
public static readonly Dictionary<string, ModMetadata> AllMods = ValidateMods(Directory.GetDirectories("mods").Select(x => x.Substring(5)).ToArray());
|
||||
|
||||
public string Id;
|
||||
public string Title;
|
||||
@@ -24,9 +24,9 @@ namespace OpenRA
|
||||
public string Version;
|
||||
public string Author;
|
||||
|
||||
public static Dictionary<string, Mod> ValidateMods(string[] mods)
|
||||
public static Dictionary<string, ModMetadata> ValidateMods(string[] mods)
|
||||
{
|
||||
var ret = new Dictionary<string, Mod>();
|
||||
var ret = new Dictionary<string, ModMetadata>();
|
||||
foreach (var m in mods)
|
||||
{
|
||||
var yamlPath = new[] { "mods", m, "mod.yaml" }.Aggregate(Path.Combine);
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA
|
||||
if (!yaml.NodesDict.ContainsKey("Metadata"))
|
||||
continue;
|
||||
|
||||
var mod = FieldLoader.Load<Mod>(yaml.NodesDict["Metadata"]);
|
||||
var mod = FieldLoader.Load<ModMetadata>(yaml.NodesDict["Metadata"]);
|
||||
mod.Id = m;
|
||||
|
||||
ret.Add(m, mod);
|
||||
@@ -99,7 +99,6 @@
|
||||
<Compile Include="Game.cs" />
|
||||
<Compile Include="GameRules\ActorInfo.cs" />
|
||||
<Compile Include="GameRules\MusicInfo.cs" />
|
||||
<Compile Include="GameRules\Rules.cs" />
|
||||
<Compile Include="GameRules\SoundInfo.cs" />
|
||||
<Compile Include="GameRules\WeaponInfo.cs" />
|
||||
<Compile Include="Graphics\Animation.cs" />
|
||||
@@ -244,6 +243,10 @@
|
||||
<Compile Include="Scripting\ScriptMemberExts.cs" />
|
||||
<Compile Include="Scripting\ScriptPlayerInterface.cs" />
|
||||
<Compile Include="Traits\Player\FixedColorPalette.cs" />
|
||||
<Compile Include="Primitives\ReadOnlyDictionary.cs" />
|
||||
<Compile Include="ModMetadata.cs" />
|
||||
<Compile Include="GameRules\Ruleset.cs" />
|
||||
<Compile Include="GameRules\RulesetCache.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FileSystem\D2kSoundResources.cs" />
|
||||
@@ -303,7 +306,6 @@
|
||||
<Compile Include="Hotkey.cs" />
|
||||
<Compile Include="Keycode.cs" />
|
||||
<Compile Include="MiniYaml.cs" />
|
||||
<Compile Include="Mod.cs" />
|
||||
<Compile Include="Platform.cs" />
|
||||
<Compile Include="StreamExts.cs" />
|
||||
<Compile Include="Map\Map.cs" />
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA
|
||||
|
||||
static CountryInfo ChooseCountry(World world, string name)
|
||||
{
|
||||
var selectableCountries = Rules.Info["world"].Traits
|
||||
var selectableCountries = world.Map.Rules.Actors["world"].Traits
|
||||
.WithInterface<CountryInfo>().Where( c => c.Selectable )
|
||||
.ToArray();
|
||||
|
||||
|
||||
90
OpenRA.Game/Primitives/ReadOnlyDictionary.cs
Normal file
90
OpenRA.Game/Primitives/ReadOnlyDictionary.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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 System.Collections.Generic;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
/// <summary>
|
||||
/// A minimal read only dictionary interface for .NET 4
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// .NET 4.5 has an implementation built-in, this code is not meant to
|
||||
/// duplicate it but provide a compatible interface that can be replaced
|
||||
/// when we switch to .NET 4.5 or higher.
|
||||
/// </remarks>
|
||||
public interface IReadOnlyDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
|
||||
{
|
||||
int Count { get; }
|
||||
TValue this[TKey key] { get; }
|
||||
IEnumerable<TKey> Keys { get; }
|
||||
IEnumerable<TValue> Values { get; }
|
||||
|
||||
bool ContainsKey(TKey key);
|
||||
bool TryGetValue(TKey key, out TValue value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A minimal read only dictionary for .NET 4 implemented as a wrapper
|
||||
/// around an IDictionary.
|
||||
/// </summary>
|
||||
public class ReadOnlyDictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>
|
||||
{
|
||||
private readonly IDictionary<TKey, TValue> dict;
|
||||
|
||||
public ReadOnlyDictionary()
|
||||
: this(new Dictionary<TKey, TValue>())
|
||||
{
|
||||
}
|
||||
|
||||
public ReadOnlyDictionary(IDictionary<TKey, TValue> dict)
|
||||
{
|
||||
if (dict == null)
|
||||
throw new ArgumentNullException("dict");
|
||||
|
||||
this.dict = dict;
|
||||
}
|
||||
|
||||
#region IReadOnlyDictionary implementation
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return dict.ContainsKey(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
return dict.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public int Count { get { return dict.Count; } }
|
||||
|
||||
public TValue this[TKey key] { get { return dict[key]; } }
|
||||
|
||||
public IEnumerable<TKey> Keys { get { return dict.Keys; } }
|
||||
|
||||
public IEnumerable<TValue> Values { get { return dict.Values; } }
|
||||
#endregion
|
||||
|
||||
#region IEnumerable implementation
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
return dict.GetEnumerator();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEnumerable implementation
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return dict.GetEnumerator();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -296,15 +296,18 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
// Returns true if played successfully
|
||||
public static bool PlayPredefined(Player p, Actor voicedUnit, string type, string definition, string variant, bool relative, WPos pos, float volumeModifier, bool attenuateVolume)
|
||||
public static bool PlayPredefined(Ruleset ruleset, Player p, Actor voicedUnit, string type, string definition, string variant, bool relative, WPos pos, float volumeModifier, bool attenuateVolume)
|
||||
{
|
||||
if (ruleset == null)
|
||||
throw new ArgumentNullException("ruleset");
|
||||
|
||||
if (definition == null)
|
||||
return false;
|
||||
|
||||
if (Rules.Voices == null || Rules.Notifications == null)
|
||||
if (ruleset.Voices == null || ruleset.Notifications == null)
|
||||
return false;
|
||||
|
||||
var rules = (voicedUnit != null) ? Rules.Voices[type] : Rules.Notifications[type];
|
||||
var rules = (voicedUnit != null) ? ruleset.Voices[type] : ruleset.Notifications[type];
|
||||
if (rules == null)
|
||||
return false;
|
||||
|
||||
@@ -366,7 +369,7 @@ namespace OpenRA
|
||||
return false;
|
||||
|
||||
var type = mi.Voice.ToLowerInvariant();
|
||||
return PlayPredefined(null, voicedUnit, type, phrase, variant, true, WPos.Zero, 1f, true);
|
||||
return PlayPredefined(voicedUnit.World.Map.Rules, null, voicedUnit, type, phrase, variant, true, WPos.Zero, 1f, true);
|
||||
}
|
||||
|
||||
public static bool PlayVoiceLocal(string phrase, Actor voicedUnit, string variant, WPos pos, float volume)
|
||||
@@ -379,15 +382,18 @@ namespace OpenRA
|
||||
return false;
|
||||
|
||||
var type = mi.Voice.ToLowerInvariant();
|
||||
return PlayPredefined(null, voicedUnit, type, phrase, variant, false, pos, volume, true);
|
||||
return PlayPredefined(voicedUnit.World.Map.Rules, null, voicedUnit, type, phrase, variant, false, pos, volume, true);
|
||||
}
|
||||
|
||||
public static bool PlayNotification(Player player, string type, string notification, string variant)
|
||||
public static bool PlayNotification(Ruleset rules, Player player, string type, string notification, string variant)
|
||||
{
|
||||
if (rules == null)
|
||||
throw new ArgumentNullException("rules");
|
||||
|
||||
if (type == null || notification == null)
|
||||
return false;
|
||||
|
||||
return PlayPredefined(player, null, type.ToLowerInvariant(), notification, variant, true, WPos.Zero, 1f, false);
|
||||
return PlayPredefined(rules, player, null, type.ToLowerInvariant(), notification, variant, true, WPos.Zero, 1f, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -118,7 +118,7 @@ namespace OpenRA.Traits
|
||||
{
|
||||
if (Ore > 0.8 * OreCapacity)
|
||||
{
|
||||
Sound.PlayNotification(Owner, "Speech", "SilosNeeded", Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, Owner, "Speech", "SilosNeeded", Owner.Country.Race);
|
||||
AlertSilo = true;
|
||||
}
|
||||
else
|
||||
@@ -163,14 +163,14 @@ namespace OpenRA.Traits
|
||||
public void playCashTickUp(Actor self)
|
||||
{
|
||||
if (Game.Settings.Sound.CashTicks)
|
||||
Sound.PlayNotification(self.Owner, "Sounds", "CashTickUp", self.Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", "CashTickUp", self.Owner.Country.Race);
|
||||
}
|
||||
|
||||
public void playCashTickDown(Actor self)
|
||||
{
|
||||
if (Game.Settings.Sound.CashTicks && nextCashTickTime == 0)
|
||||
{
|
||||
Sound.PlayNotification(self.Owner, "Sounds", "CashTickDown", self.Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", "CashTickDown", self.Owner.Country.Race);
|
||||
nextCashTickTime = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ namespace OpenRA.Traits
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new RenderSimple(init.self); }
|
||||
|
||||
public virtual IEnumerable<IRenderable> RenderPreview(ActorInfo ai, PaletteReference pr)
|
||||
public virtual IEnumerable<IRenderable> RenderPreview(World world, ActorInfo ai, PaletteReference pr)
|
||||
{
|
||||
var anim = new Animation(RenderSimple.GetImage(ai), () => 0);
|
||||
var anim = new Animation(world, RenderSimple.GetImage(ai), () => 0);
|
||||
anim.PlayRepeating("idle");
|
||||
|
||||
return anim.Render(WPos.Zero, WVec.Zero, 0, pr, Scale);
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Traits
|
||||
public RenderSimple(Actor self, Func<int> baseFacing)
|
||||
: base(self)
|
||||
{
|
||||
anims.Add("", new Animation(GetImage(self), baseFacing));
|
||||
anims.Add("", new Animation(self.World, GetImage(self), baseFacing));
|
||||
Info = self.Info.Traits.Get<RenderSimpleInfo>();
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace OpenRA.Traits
|
||||
var group = self.World.Selection.GetControlGroupForActor(self);
|
||||
if (group == null) return;
|
||||
|
||||
var pipImages = new Animation("pips");
|
||||
var pipImages = new Animation(self.World, "pips");
|
||||
var pal = wr.Palette(Info.Palette);
|
||||
pipImages.PlayFetchIndex("groups", () => (int)group);
|
||||
pipImages.Tick();
|
||||
@@ -75,7 +75,7 @@ namespace OpenRA.Traits
|
||||
if (!pipSources.Any())
|
||||
return;
|
||||
|
||||
var pipImages = new Animation("pips");
|
||||
var pipImages = new Animation(self.World, "pips");
|
||||
pipImages.PlayRepeating(pipStrings[0]);
|
||||
|
||||
var pipSize = pipImages.Image.size.ToInt2();
|
||||
@@ -115,7 +115,7 @@ namespace OpenRA.Traits
|
||||
if (!self.Owner.IsAlliedWith(self.World.RenderPlayer))
|
||||
return;
|
||||
|
||||
var tagImages = new Animation("pips");
|
||||
var tagImages = new Animation(self.World, "pips");
|
||||
var pal = wr.Palette(Info.Palette);
|
||||
var tagxyOffset = new int2(0, 6);
|
||||
var tagBase = wr.Viewport.WorldToViewPx(basePosition);
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Traits
|
||||
|
||||
public PipType PipColor = PipType.Yellow;
|
||||
|
||||
public object Create(ActorInitializer init) { return new ResourceType(this); }
|
||||
public object Create(ActorInitializer init) { return new ResourceType(this, init.world); }
|
||||
}
|
||||
|
||||
public class ResourceType : IWorldLoaded
|
||||
@@ -41,13 +41,13 @@ namespace OpenRA.Traits
|
||||
public PaletteReference Palette { get; private set; }
|
||||
public readonly Dictionary<string, Sprite[]> Variants;
|
||||
|
||||
public ResourceType(ResourceTypeInfo info)
|
||||
public ResourceType(ResourceTypeInfo info, World world)
|
||||
{
|
||||
this.Info = info;
|
||||
Variants = new Dictionary<string, Sprite[]>();
|
||||
foreach (var v in info.Variants)
|
||||
{
|
||||
var seq = SequenceProvider.GetSequence("resources", v);
|
||||
var seq = world.Map.SequenceProvider.GetSequence("resources", v);
|
||||
var sprites = Exts.MakeArray(seq.Length, x => seq.GetSprite(x));
|
||||
Variants.Add(v, sprites);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -53,8 +53,13 @@ namespace OpenRA.Widgets
|
||||
public Action OnDoubleClick = () => {};
|
||||
public Action<KeyInput> OnKeyPress = _ => {};
|
||||
|
||||
public ButtonWidget()
|
||||
readonly Ruleset modRules;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ButtonWidget(Ruleset modRules)
|
||||
{
|
||||
this.modRules = modRules;
|
||||
|
||||
GetText = () => { return Text; };
|
||||
GetColor = () => TextColor;
|
||||
GetColorDisabled = () => TextColorDisabled;
|
||||
@@ -70,6 +75,8 @@ namespace OpenRA.Widgets
|
||||
protected ButtonWidget(ButtonWidget other)
|
||||
: base(other)
|
||||
{
|
||||
this.modRules = other.modRules;
|
||||
|
||||
Text = other.Text;
|
||||
Font = other.Font;
|
||||
TextColor = other.TextColor;
|
||||
@@ -113,10 +120,10 @@ namespace OpenRA.Widgets
|
||||
if (!IsDisabled())
|
||||
{
|
||||
OnKeyPress(e);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
Sound.PlayNotification(modRules, null, "Sounds", "ClickSound", null);
|
||||
}
|
||||
else
|
||||
Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null);
|
||||
Sound.PlayNotification(modRules, null, "Sounds", "ClickDisabledSound", null);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -153,12 +160,12 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
OnMouseDown(mi);
|
||||
Depressed = true;
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
Sound.PlayNotification(modRules, null, "Sounds", "ClickSound", null);
|
||||
}
|
||||
else
|
||||
{
|
||||
YieldMouseFocus(mi);
|
||||
Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null);
|
||||
Sound.PlayNotification(modRules, null, "Sounds", "ClickDisabledSound", null);
|
||||
}
|
||||
}
|
||||
else if (mi.Event == MouseInputEvent.Move && HasMouseFocus)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -11,6 +11,7 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Network;
|
||||
|
||||
namespace OpenRA.Widgets
|
||||
{
|
||||
@@ -23,7 +24,9 @@ namespace OpenRA.Widgets
|
||||
public int CheckOffset = 2;
|
||||
public bool HasPressedState = ChromeMetrics.Get<bool>("CheckboxPressedState");
|
||||
|
||||
public CheckboxWidget()
|
||||
[ObjectCreator.UseCtor]
|
||||
public CheckboxWidget(Ruleset modRules)
|
||||
: base(modRules)
|
||||
{
|
||||
GetCheckType = () => CheckType;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -12,6 +12,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Network;
|
||||
|
||||
namespace OpenRA.Widgets
|
||||
{
|
||||
@@ -20,7 +21,9 @@ namespace OpenRA.Widgets
|
||||
Widget panel;
|
||||
MaskWidget fullscreenMask;
|
||||
|
||||
public DropDownButtonWidget() { }
|
||||
[ObjectCreator.UseCtor]
|
||||
public DropDownButtonWidget(Ruleset modRules)
|
||||
: base(modRules) { }
|
||||
|
||||
protected DropDownButtonWidget(DropDownButtonWidget widget) : base(widget) { }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -9,6 +9,8 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Network;
|
||||
|
||||
namespace OpenRA.Widgets
|
||||
{
|
||||
@@ -17,7 +19,9 @@ namespace OpenRA.Widgets
|
||||
public string ItemKey;
|
||||
public string BaseName = "scrollitem";
|
||||
|
||||
public ScrollItemWidget()
|
||||
[ObjectCreator.UseCtor]
|
||||
public ScrollItemWidget(Ruleset modRules)
|
||||
: base(modRules)
|
||||
{
|
||||
IsVisible = () => false;
|
||||
VisualHeight = 0;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Widgets
|
||||
|
||||
if (Unit != null && Sequence != null)
|
||||
{
|
||||
var anim = new Animation(Unit, () => Facing);
|
||||
var anim = new Animation(worldRenderer.world, Unit, () => Facing);
|
||||
anim.PlayFetchIndex(Sequence, () => Frame);
|
||||
GetAnimation = () => anim;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA.Widgets
|
||||
public Func<string> GetPalette;
|
||||
public Func<Sprite> GetSprite;
|
||||
|
||||
readonly WorldRenderer worldRenderer;
|
||||
protected readonly WorldRenderer worldRenderer;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public SpriteWidget(WorldRenderer worldRenderer)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -18,10 +18,13 @@ namespace OpenRA
|
||||
{
|
||||
public class WidgetLoader
|
||||
{
|
||||
Dictionary<string, MiniYamlNode> widgets = new Dictionary<string, MiniYamlNode>();
|
||||
readonly Dictionary<string, MiniYamlNode> widgets = new Dictionary<string, MiniYamlNode>();
|
||||
readonly ModData modData;
|
||||
|
||||
public WidgetLoader(ModData modData)
|
||||
{
|
||||
this.modData = modData;
|
||||
|
||||
foreach (var file in modData.Manifest.ChromeLayout.Select(a => MiniYaml.FromFile(a)))
|
||||
foreach( var w in file )
|
||||
{
|
||||
@@ -55,6 +58,8 @@ namespace OpenRA
|
||||
if (child.Key != "Children")
|
||||
FieldLoader.LoadField(widget, child.Key, child.Value.Value);
|
||||
|
||||
if (!args.ContainsKey("modRules"))
|
||||
args = new WidgetArgs(args) { { "modRules", modData.DefaultRules } };
|
||||
widget.Initialize(args);
|
||||
|
||||
foreach (var child in node.Value.Nodes)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -118,14 +118,14 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
internal World(Manifest manifest, Map map, OrderManager orderManager, bool isShellmap)
|
||||
internal World(Map map, OrderManager orderManager, bool isShellmap)
|
||||
{
|
||||
IsShellmap = isShellmap;
|
||||
this.orderManager = orderManager;
|
||||
orderGenerator_ = new UnitOrderGenerator();
|
||||
Map = map;
|
||||
|
||||
TileSet = Rules.TileSets[Map.Tileset];
|
||||
TileSet = map.Rules.TileSets[Map.Tileset];
|
||||
SharedRandom = new XRandom(orderManager.LobbyInfo.GlobalSettings.RandomSeed);
|
||||
|
||||
WorldActor = CreateActor("World", new TypeDictionary());
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace OpenRA
|
||||
var selectable = a.Info.Traits.GetOrDefault<SelectableInfo>();
|
||||
if (selectable == null) return null;
|
||||
var v = selectable.Voice;
|
||||
return (v == null) ? null : Rules.Voices[v.ToLowerInvariant()];
|
||||
return (v == null) ? null : a.World.Map.Rules.Voices[v.ToLowerInvariant()];
|
||||
}
|
||||
|
||||
public static void PlayVoiceForOrders(this World w, Order[] orders)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -69,7 +69,7 @@ namespace OpenRA.Lint
|
||||
|
||||
foreach (var testMap in maps)
|
||||
{
|
||||
if (testMap.Rules.Count < 1)
|
||||
if (testMap.RuleDefinitions.Count < 1)
|
||||
{
|
||||
if (verbose)
|
||||
Console.WriteLine("No custom rules detected. Omitting Map: {0}".F(testMap.Title));
|
||||
@@ -79,7 +79,7 @@ namespace OpenRA.Lint
|
||||
|
||||
if (verbose)
|
||||
Console.WriteLine("Map: {0}".F(testMap.Title));
|
||||
Rules.LoadRules(Game.modData.Manifest, testMap);
|
||||
testMap.PreloadRules();
|
||||
|
||||
foreach (var customPassType in Game.modData.ObjectCreator
|
||||
.GetTypesImplementing<ILintPass>())
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace OpenRA.Mods.Cnc.Effects
|
||||
{
|
||||
public class IonCannon : IEffect
|
||||
{
|
||||
Target target;
|
||||
Animation anim;
|
||||
Player firedBy;
|
||||
string palette;
|
||||
string weapon;
|
||||
readonly Target target;
|
||||
readonly Animation anim;
|
||||
readonly Player firedBy;
|
||||
readonly string palette;
|
||||
readonly string weapon;
|
||||
|
||||
public IonCannon(Player firedBy, string weapon, World world, CPos location, string effect, string palette)
|
||||
{
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Cnc.Effects
|
||||
this.weapon = weapon;
|
||||
this.palette = palette;
|
||||
target = Target.FromCell(location);
|
||||
anim = new Animation(effect);
|
||||
anim = new Animation(world, effect);
|
||||
anim.PlayThen("idle", () => Finish(world));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Cnc
|
||||
if (r == null) return;
|
||||
if (!info.Resources.Contains(r.Info.Name)) return;
|
||||
|
||||
var weapon = Rules.Weapons[info.Weapon.ToLowerInvariant()];
|
||||
var weapon = self.World.Map.Rules.Weapons[info.Weapon.ToLowerInvariant()];
|
||||
|
||||
self.InflictDamage(self.World.WorldActor, weapon.Warheads[0].Damage, weapon.Warheads[0]);
|
||||
poisonTicks = weapon.ROF;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -52,7 +52,7 @@ namespace OpenRA.Mods.Cnc
|
||||
|
||||
owner.World.AddFrameEndTask(w =>
|
||||
{
|
||||
var altitude = Rules.Info[actorType].Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
var altitude = self.World.Map.Rules.Actors[actorType].Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
var a = w.CreateActor(actorType, new TypeDictionary
|
||||
{
|
||||
new CenterPositionInit(startPos.CenterPosition + new WVec(WRange.Zero, WRange.Zero, altitude)),
|
||||
@@ -69,7 +69,7 @@ namespace OpenRA.Mods.Cnc
|
||||
|
||||
rb.PlayCustomAnimRepeating(self, "idle");
|
||||
self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit));
|
||||
Sound.PlayNotification(self.Owner, "Speech", (Info as ProductionAirdropInfo).ReadyAudio, self.Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", (Info as ProductionAirdropInfo).ReadyAudio, self.Owner.Country.Race);
|
||||
}));
|
||||
|
||||
a.QueueActivity(new Fly(a, Target.FromCell(endPos)));
|
||||
|
||||
@@ -35,19 +35,19 @@ namespace OpenRA.Mods.RA.Render
|
||||
var turret = self.TraitsImplementing<Turreted>()
|
||||
.First(t => t.Name == info.Turret);
|
||||
|
||||
left = new Animation(name, () => turret.turretFacing);
|
||||
left = new Animation(self.World, name, () => turret.turretFacing);
|
||||
left.Play("left");
|
||||
anims.Add("left", new AnimationWithOffset(left, null, () => facing.Facing > 128, 0));
|
||||
|
||||
right = new Animation(name, () => turret.turretFacing);
|
||||
right = new Animation(self.World, name, () => turret.turretFacing);
|
||||
right.Play("right");
|
||||
anims.Add("right", new AnimationWithOffset(right, null, () => facing.Facing <= 128, 0));
|
||||
|
||||
var leftWake = new Animation(name);
|
||||
var leftWake = new Animation(self.World, name);
|
||||
leftWake.Play("wake-left");
|
||||
anims.Add("wake-left", new AnimationWithOffset(leftWake, null, () => facing.Facing > 128, -87));
|
||||
|
||||
var rightWake = new Animation(name);
|
||||
var rightWake = new Animation(self.World, name);
|
||||
rightWake.Play("wake-right");
|
||||
anims.Add("wake-right", new AnimationWithOffset(rightWake, null, () => facing.Facing <= 128, -87));
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
public class CncIngameChromeLogic
|
||||
{
|
||||
Widget ingameRoot;
|
||||
World world;
|
||||
readonly World world;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public CncIngameChromeLogic(Widget widget, World world)
|
||||
@@ -95,7 +95,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
.Any(a => a.Actor.Owner == world.LocalPlayer && a.Trait.IsActive);
|
||||
|
||||
if (radarEnabled != cachedRadarEnabled)
|
||||
Sound.PlayNotification(null, "Sounds", radarEnabled ? "RadarUp" : "RadarDown", null);
|
||||
Sound.PlayNotification(world.Map.Rules, null, "Sounds", radarEnabled ? "RadarUp" : "RadarDown", null);
|
||||
cachedRadarEnabled = radarEnabled;
|
||||
|
||||
// Switch to observer mode after win/loss
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
// TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions
|
||||
Action onQuit = () =>
|
||||
{
|
||||
Sound.PlayNotification(null, "Speech", "Leave", null);
|
||||
Sound.PlayNotification(world.Map.Rules, null, "Speech", "Leave", null);
|
||||
resumeDisabled = true;
|
||||
Game.RunAfterDelay(1200, () => mpe.Fade(MenuPaletteEffect.EffectType.Black));
|
||||
Game.RunAfterDelay(1200 + 40 * mpe.Info.FadeLength, () =>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
public class CncInstallMusicLogic
|
||||
{
|
||||
[ObjectCreator.UseCtor]
|
||||
public CncInstallMusicLogic(Widget widget, Action onExit)
|
||||
public CncInstallMusicLogic(Widget widget, Ruleset modRules, Action onExit)
|
||||
{
|
||||
var installButton = widget.GetOrNull<ButtonWidget>("INSTALL_BUTTON");
|
||||
if (installButton != null)
|
||||
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
GlobalFileSystem.Mount(Path.Combine(path, "scores.mix"));
|
||||
GlobalFileSystem.Mount(Path.Combine(path, "transit.mix"));
|
||||
|
||||
Rules.Music.Do(m => m.Value.Reload());
|
||||
modRules.Music.Do(m => m.Value.Reload());
|
||||
|
||||
var musicPlayerLogic = (MusicPlayerLogic)installButton.Parent.LogicObject;
|
||||
musicPlayerLogic.BuildMusicTable();
|
||||
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
{ "filesToCopy", new[] { "SCORES.MIX" } },
|
||||
{ "filesToExtract", new[] { "transit.mix" } },
|
||||
});
|
||||
installButton.IsVisible = () => Rules.InstalledMusic.ToArray().Length < 3; // HACK around music being split between transit.mix and scores.mix
|
||||
installButton.IsVisible = () => modRules.InstalledMusic.ToArray().Length < 3; // HACK around music being split between transit.mix and scores.mix
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
public class ProductionTabsLogic
|
||||
{
|
||||
ProductionTabsWidget tabs;
|
||||
World world;
|
||||
readonly World world;
|
||||
|
||||
void SetupProductionGroupButton(ProductionTypeButtonWidget button)
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
[ObjectCreator.UseCtor]
|
||||
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ProductionPaletteWidget palette)
|
||||
{
|
||||
var mapRules = palette.World.Map.Rules;
|
||||
var pm = palette.World.LocalPlayer.PlayerActor.Trait<PowerManager>();
|
||||
var pr = palette.World.LocalPlayer.PlayerActor.Trait<PlayerResources>();
|
||||
|
||||
@@ -45,7 +46,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
if (actor == null || actor == lastActor)
|
||||
return;
|
||||
|
||||
var info = Rules.Info[actor];
|
||||
var info = mapRules.Actors[actor];
|
||||
var tooltip = info.Traits.Get<TooltipInfo>();
|
||||
var buildable = info.Traits.Get<BuildableInfo>();
|
||||
var cost = info.Traits.Get<ValuedInfo>().Cost;
|
||||
@@ -53,7 +54,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
|
||||
nameLabel.GetText = () => tooltip.Name;
|
||||
|
||||
var prereqs = buildable.Prerequisites.Select(a => ActorName(a));
|
||||
var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a));
|
||||
var requiresString = prereqs.Any() ? requiresLabel.Text.F(prereqs.JoinWith(", ")) : "";
|
||||
requiresLabel.GetText = () => requiresString;
|
||||
|
||||
@@ -92,11 +93,10 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||
};
|
||||
}
|
||||
|
||||
static string ActorName(string a)
|
||||
static string ActorName(Ruleset rules, string a)
|
||||
{
|
||||
ActorInfo ai;
|
||||
Rules.Info.TryGetValue(a.ToLowerInvariant(), out ai);
|
||||
if (ai != null && ai.Traits.Contains<TooltipInfo>())
|
||||
if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai) && ai.Traits.Contains<TooltipInfo>())
|
||||
return ai.Traits.Get<TooltipInfo>().Name;
|
||||
|
||||
return a;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -72,9 +72,9 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
tooltipContainer = Exts.Lazy(() =>
|
||||
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
|
||||
|
||||
cantBuild = new Animation("clock");
|
||||
cantBuild = new Animation(world, "clock");
|
||||
cantBuild.PlayFetchIndex("idle", () => 0);
|
||||
clock = new Animation("clock");
|
||||
clock = new Animation(world, "clock");
|
||||
}
|
||||
|
||||
public override void Tick()
|
||||
@@ -114,7 +114,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
if (mi.Event != MouseInputEvent.Down)
|
||||
return true;
|
||||
|
||||
var actor = Rules.Info[icon.Name];
|
||||
var actor = World.Map.Rules.Actors[icon.Name];
|
||||
var first = icon.Queued.FirstOrDefault();
|
||||
|
||||
if (mi.Button == MouseButton.Left)
|
||||
@@ -135,7 +135,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
{
|
||||
// Queue a new item
|
||||
Sound.Play(TabClick);
|
||||
Sound.PlayNotification(World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Country.Race);
|
||||
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Country.Race);
|
||||
World.IssueOrder(Order.StartProduction(CurrentQueue.self, icon.Name,
|
||||
Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1));
|
||||
}
|
||||
@@ -152,13 +152,13 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
// instant cancel of things we havent started yet and things that are finished
|
||||
if (first.Paused || first.Done || first.TotalCost == first.RemainingCost)
|
||||
{
|
||||
Sound.PlayNotification(World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Country.Race);
|
||||
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Country.Race);
|
||||
World.IssueOrder(Order.CancelProduction(CurrentQueue.self, icon.Name,
|
||||
Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound.PlayNotification(World.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, World.LocalPlayer.Country.Race);
|
||||
Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, World.LocalPlayer.Country.Race);
|
||||
World.IssueOrder(Order.PauseProduction(CurrentQueue.self, icon.Name, true));
|
||||
}
|
||||
}
|
||||
@@ -183,7 +183,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
var x = i % Columns;
|
||||
var y = i / Columns;
|
||||
var rect = new Rectangle(rb.X + x * 64 + 1, rb.Y + y * 48 + 1, 64, 48);
|
||||
var icon = new Animation(RenderSimple.GetImage(item));
|
||||
var icon = new Animation(World, RenderSimple.GetImage(item));
|
||||
icon.Play(item.Traits.Get<TooltipInfo>().Icon);
|
||||
var pi = new ProductionIcon()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -60,6 +60,8 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
|
||||
class ProductionTabsWidget : Widget
|
||||
{
|
||||
readonly World world;
|
||||
|
||||
public readonly string PaletteWidget = null;
|
||||
public readonly string TypesContainer = null;
|
||||
|
||||
@@ -79,7 +81,9 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
[ObjectCreator.UseCtor]
|
||||
public ProductionTabsWidget(World world)
|
||||
{
|
||||
Groups = Rules.Info.Values.SelectMany(a => a.Traits.WithInterface<ProductionQueueInfo>())
|
||||
this.world = world;
|
||||
|
||||
Groups = world.Map.Rules.Actors.Values.SelectMany(a => a.Traits.WithInterface<ProductionQueueInfo>())
|
||||
.Select(q => q.Group).Distinct().ToDictionary(g => g, g => new ProductionTabGroup() { Group = g });
|
||||
|
||||
// Only visible if the production palette has icons to display
|
||||
@@ -93,7 +97,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
if (queueGroup == null)
|
||||
return true;
|
||||
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
|
||||
|
||||
// Prioritize alerted queues
|
||||
var queues = Groups[queueGroup].Tabs.Select(t => t.Queue)
|
||||
@@ -253,9 +257,9 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
if (leftPressed || rightPressed)
|
||||
{
|
||||
if ((leftPressed && !leftDisabled) || (rightPressed && !rightDisabled))
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
|
||||
else
|
||||
Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null);
|
||||
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickDisabledSound", null);
|
||||
}
|
||||
|
||||
// Check production tabs
|
||||
@@ -263,7 +267,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
if (offsetloc.X > 0 && offsetloc.X < contentWidth)
|
||||
{
|
||||
CurrentQueue = Groups[queueGroup].Tabs[offsetloc.X / (TabWidth - 1)].Queue;
|
||||
Sound.PlayNotification(null, "Sounds", "ClickSound", null);
|
||||
Sound.PlayNotification(world.Map.Rules, null, "Sounds", "ClickSound", null);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -16,7 +16,10 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
{
|
||||
public readonly string ProductionGroup;
|
||||
|
||||
public ProductionTypeButtonWidget() { }
|
||||
[ObjectCreator.UseCtor]
|
||||
public ProductionTypeButtonWidget(Ruleset modRules)
|
||||
: base(modRules) { }
|
||||
|
||||
protected ProductionTypeButtonWidget(ProductionTypeButtonWidget other)
|
||||
: base(other)
|
||||
{
|
||||
|
||||
@@ -52,8 +52,8 @@ namespace OpenRA.Mods.Cnc.Widgets
|
||||
tooltipContainer = Exts.Lazy(() =>
|
||||
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
|
||||
|
||||
icon = new Animation("icon");
|
||||
clock = new Animation("clock");
|
||||
icon = new Animation(world, "icon");
|
||||
clock = new Animation(world, "clock");
|
||||
}
|
||||
|
||||
public class SupportPowerIcon
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Cnc
|
||||
public WithFire(Actor self, WithFireInfo info)
|
||||
{
|
||||
var rs = self.Trait<RenderSprites>();
|
||||
var roof = new Animation(rs.GetImage(self));
|
||||
var roof = new Animation(self.World, rs.GetImage(self));
|
||||
roof.PlayThen("fire-start", () => roof.PlayRepeating("fire-loop"));
|
||||
rs.anims.Add("fire", new AnimationWithOffset(roof, null, null, 1024));
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Cnc
|
||||
public WithRoof(Actor self)
|
||||
{
|
||||
var rs = self.Trait<RenderSprites>();
|
||||
var roof = new Animation(rs.GetImage(self), () => self.Trait<IFacing>().Facing);
|
||||
var roof = new Animation(self.World, rs.GetImage(self), () => self.Trait<IFacing>().Facing);
|
||||
roof.Play("roof");
|
||||
rs.anims.Add("roof", new AnimationWithOffset(roof, null, null, 1024));
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Cnc
|
||||
{
|
||||
this.info = info;
|
||||
health = self.Trait<Health>();
|
||||
weapon = Rules.Weapons[info.Weapon.ToLowerInvariant()];
|
||||
weapon = self.World.Map.Rules.Weapons[info.Weapon.ToLowerInvariant()];
|
||||
}
|
||||
|
||||
public void AddedToWorld(Actor self)
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA.Render
|
||||
|
||||
buildComplete = !self.HasTrait<Building>(); // always render instantly for units
|
||||
|
||||
overlay = new Animation(rs.GetImage(self));
|
||||
overlay = new Animation(self.World, rs.GetImage(self));
|
||||
overlay.Play(info.Sequence);
|
||||
rs.anims.Add("crane_overlay_{0}".F(info.Sequence),
|
||||
new AnimationWithOffset(overlay,
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.RA.Render
|
||||
|
||||
if (!init.Contains<SkipMakeAnimsInit>())
|
||||
{
|
||||
var overlay = new Animation(rs.GetImage(init.self));
|
||||
var overlay = new Animation(init.world, rs.GetImage(init.self));
|
||||
overlay.PlayThen(info.Sequence, () => buildComplete = false);
|
||||
rs.anims.Add("make_overlay_{0}".F(info.Sequence),
|
||||
new AnimationWithOffset(overlay, null, () => !buildComplete));
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace OpenRA.Mods.RA.Render
|
||||
|
||||
buildComplete = !self.HasTrait<Building>(); // always render instantly for units
|
||||
|
||||
overlay = new Animation(rs.GetImage(self));
|
||||
overlay = new Animation(self.World, rs.GetImage(self));
|
||||
overlay.Play(info.Sequence);
|
||||
rs.anims.Add("docking_overlay_{0}".F(info.Sequence),
|
||||
new AnimationWithOffset(overlay,
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Render
|
||||
|
||||
buildComplete = !self.HasTrait<Building>(); // always render instantly for units
|
||||
|
||||
overlay = new Animation(rs.GetImage(self));
|
||||
overlay = new Animation(self.World, rs.GetImage(self));
|
||||
overlay.PlayRepeating(info.Sequence);
|
||||
rs.anims.Add("production_overlay_{0}".F(info.Sequence),
|
||||
new AnimationWithOffset(overlay,
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.D2k
|
||||
{
|
||||
foreach (var name in info.Weapons)
|
||||
{
|
||||
var wep = Rules.Weapons[name];
|
||||
var wep = self.World.Map.Rules.Weapons[name];
|
||||
var pieces = self.World.SharedRandom.Next(info.Pieces[0], info.Pieces[1]);
|
||||
var range = self.World.SharedRandom.Next(info.Range[0].Range, info.Range[1].Range);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -68,9 +68,9 @@ namespace OpenRA.Mods.RA.AI
|
||||
|
||||
// Place the building
|
||||
var type = BuildingType.Building;
|
||||
if (Rules.Info[currentBuilding.Item].Traits.Contains<AttackBaseInfo>())
|
||||
if (ai.Map.Rules.Actors[currentBuilding.Item].Traits.Contains<AttackBaseInfo>())
|
||||
type = BuildingType.Defense;
|
||||
else if (Rules.Info[currentBuilding.Item].Traits.Contains<OreRefineryInfo>())
|
||||
else if (ai.Map.Rules.Actors[currentBuilding.Item].Traits.Contains<OreRefineryInfo>())
|
||||
type = BuildingType.Refinery;
|
||||
|
||||
var location = ai.ChooseBuildLocation(currentBuilding.Item, type);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -83,7 +83,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
|
||||
static object LoadBuildingLimits(MiniYaml y) { return LoadList<int>(y, "BuildingLimits"); }
|
||||
|
||||
public object Create(ActorInitializer init) { return new HackyAI(this); }
|
||||
public object Create(ActorInitializer init) { return new HackyAI(this, init); }
|
||||
}
|
||||
|
||||
public class Enemy { public int Aggro; }
|
||||
@@ -119,15 +119,17 @@ namespace OpenRA.Mods.RA.AI
|
||||
const int MaxBaseDistance = 40;
|
||||
public const int feedbackTime = 30; // ticks; = a bit over 1s. must be >= netlag.
|
||||
|
||||
public World world { get { return p.PlayerActor.World; } }
|
||||
public readonly World world;
|
||||
public Map Map { get { return world.Map; } }
|
||||
IBotInfo IBot.Info { get { return this.Info; } }
|
||||
|
||||
public HackyAI(HackyAIInfo info)
|
||||
public HackyAI(HackyAIInfo info, ActorInitializer init)
|
||||
{
|
||||
Info = info;
|
||||
world = init.world;
|
||||
|
||||
// Temporary hack.
|
||||
rallypointTestBuilding = Rules.Info[Info.RallypointTestBuilding].Traits.Get<BuildingInfo>();
|
||||
rallypointTestBuilding = Map.Rules.Actors[Info.RallypointTestBuilding].Traits.Get<BuildingInfo>();
|
||||
}
|
||||
|
||||
public static void BotDebug(string s, params object[] args)
|
||||
@@ -151,7 +153,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
|
||||
random = new XRandom((int)p.PlayerActor.ActorID);
|
||||
|
||||
resourceTypes = Rules.Info["world"].Traits.WithInterface<ResourceTypeInfo>()
|
||||
resourceTypes = Map.Rules.Actors["world"].Traits.WithInterface<ResourceTypeInfo>()
|
||||
.Select(t => t.TerrainType).ToArray();
|
||||
}
|
||||
|
||||
@@ -185,8 +187,8 @@ namespace OpenRA.Mods.RA.AI
|
||||
foreach (var unit in Info.UnitsToBuild)
|
||||
if (buildableThings.Any(b => b.Name == unit.Key))
|
||||
if (myUnits.Count(a => a == unit.Key) < unit.Value * myUnits.Length)
|
||||
if (HasAdequateAirUnits(Rules.Info[unit.Key]))
|
||||
return Rules.Info[unit.Key];
|
||||
if (HasAdequateAirUnits(Map.Rules.Actors[unit.Key]))
|
||||
return Map.Rules.Actors[unit.Key];
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -215,7 +217,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
ActorInfo GetBuildingInfoByCommonName(string commonName, Player owner)
|
||||
{
|
||||
if (commonName == "ConstructionYard")
|
||||
return Rules.Info.Where(k => Info.BuildingCommonNames[commonName].Contains(k.Key)).Random(random).Value;
|
||||
return Map.Rules.Actors.Where(k => Info.BuildingCommonNames[commonName].Contains(k.Key)).Random(random).Value;
|
||||
|
||||
return GetInfoByCommonName(Info.BuildingCommonNames, commonName, owner);
|
||||
}
|
||||
@@ -230,7 +232,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
if (!names.Any() || !names.ContainsKey(commonName))
|
||||
return null;
|
||||
|
||||
return Rules.Info.Where(k => names[commonName].Contains(k.Key) &&
|
||||
return Map.Rules.Actors.Where(k => names[commonName].Contains(k.Key) &&
|
||||
k.Value.Traits.Get<BuildableInfo>().Owner.Contains(owner.Country.Race)).Random(random).Value;
|
||||
}
|
||||
|
||||
@@ -314,8 +316,8 @@ namespace OpenRA.Mods.RA.AI
|
||||
foreach (var frac in Info.BuildingFractions)
|
||||
if (buildableThings.Any(b => b.Name == frac.Key))
|
||||
if (myBuildings.Count(a => a == frac.Key) < frac.Value * myBuildings.Length && HasAdequateNumber(frac.Key, p) &&
|
||||
playerPower.ExcessPower >= Rules.Info[frac.Key].Traits.Get<BuildingInfo>().Power)
|
||||
return Rules.Info[frac.Key];
|
||||
playerPower.ExcessPower >= Map.Rules.Actors[frac.Key].Traits.Get<BuildingInfo>().Power)
|
||||
return Map.Rules.Actors[frac.Key];
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -334,7 +336,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
|
||||
public CPos? ChooseBuildLocation(string actorType, bool distanceToBaseIsImportant, int maxBaseDistance, BuildingType type)
|
||||
{
|
||||
var bi = Rules.Info[actorType].Traits.GetOrDefault<BuildingInfo>();
|
||||
var bi = Map.Rules.Actors[actorType].Traits.GetOrDefault<BuildingInfo>();
|
||||
if (bi == null)
|
||||
return null;
|
||||
|
||||
@@ -348,7 +350,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
foreach (var t in tlist)
|
||||
if (world.CanPlaceBuilding(actorType, bi, t, null))
|
||||
if (bi.IsCloseEnoughToBase(world, p, actorType, t))
|
||||
if (NoBuildingsUnder(Util.ExpandFootprint(FootprintUtils.Tiles(actorType, bi, t), false)))
|
||||
if (NoBuildingsUnder(Util.ExpandFootprint(FootprintUtils.Tiles(Map.Rules, actorType, bi, t), false)))
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -377,7 +379,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
if (distanceToBaseIsImportant && !bi.IsCloseEnoughToBase(world, p, actorType, t))
|
||||
continue;
|
||||
|
||||
if (NoBuildingsUnder(Util.ExpandFootprint(FootprintUtils.Tiles(actorType, bi, t), false)))
|
||||
if (NoBuildingsUnder(Util.ExpandFootprint(FootprintUtils.Tiles(Map.Rules, actorType, bi, t), false)))
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@@ -850,7 +852,7 @@ namespace OpenRA.Mods.RA.AI
|
||||
if (queue == null)
|
||||
return;
|
||||
|
||||
if (Rules.Info[name] != null)
|
||||
if (Map.Rules.Actors[name] != null)
|
||||
world.IssueOrder(Order.StartProduction(queue.self, name, 1));
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA
|
||||
public void Killed(Actor self, AttackInfo e)
|
||||
{
|
||||
var player = (info.NotifyAll) ? self.World.LocalPlayer : self.Owner;
|
||||
Sound.PlayNotification(player, "Speech", info.Notification, self.Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, player, "Speech", info.Notification, self.Owner.Country.Race);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace OpenRA.Mods.RA
|
||||
Coords = Exts.Lazy(() => self.Trait<IBodyOrientation>());
|
||||
limitedAmmo = Exts.Lazy(() => self.TraitOrDefault<LimitedAmmo>());
|
||||
|
||||
Weapon = Rules.Weapons[info.Weapon.ToLowerInvariant()];
|
||||
Weapon = self.World.Map.Rules.Weapons[info.Weapon.ToLowerInvariant()];
|
||||
Burst = Weapon.Burst;
|
||||
|
||||
if (info.LocalOffset.Length % 3 != 0)
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace OpenRA.Mods.RA
|
||||
if (barrel != null && a.Info.MuzzleSequence != null)
|
||||
{
|
||||
// Muzzle facing is fixed once the firing starts
|
||||
var muzzleAnim = new Animation(paxRender[a.Actor].GetImage(a.Actor), () => muzzleFacing);
|
||||
var muzzleAnim = new Animation(self.World, paxRender[a.Actor].GetImage(a.Actor), () => muzzleFacing);
|
||||
var sequence = a.Info.MuzzleSequence;
|
||||
|
||||
if (a.Info.MuzzleSplitFacings > 0)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -44,7 +44,7 @@ namespace OpenRA.Mods.RA
|
||||
// Build a list of templates that should be overlayed with bridges
|
||||
foreach(var bridge in Info.Bridges)
|
||||
{
|
||||
var bi = Rules.Info[bridge].Traits.Get<BridgeInfo>();
|
||||
var bi = w.Map.Rules.Actors[bridge].Traits.Get<BridgeInfo>();
|
||||
foreach (var template in bi.Templates)
|
||||
BridgeTypes.Add(template.First, Pair.New(bridge, template.Second));
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
for (var i = 0; i < rows * width; i++)
|
||||
{
|
||||
var index = i;
|
||||
var anim = new Animation(rs.GetImage(self));
|
||||
var anim = new Animation(self.World, rs.GetImage(self));
|
||||
var cellOffset = new CVec(i % width, i / width + bibOffset);
|
||||
|
||||
// Some mods may define terrain-specific bibs
|
||||
|
||||
6
OpenRA.Mods.RA/Buildings/Building.cs
Executable file → Normal file
6
OpenRA.Mods.RA/Buildings/Building.cs
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -65,7 +65,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
return false;
|
||||
|
||||
var buildingMaxBounds = (CVec)Dimensions;
|
||||
var buildingTraits = Rules.Info[buildingName].Traits;
|
||||
var buildingTraits = world.Map.Rules.Actors[buildingName].Traits;
|
||||
if (buildingTraits.Contains<BibInfo>() && !(buildingTraits.Get<BibInfo>().HasMinibib))
|
||||
buildingMaxBounds += new CVec(0, 1);
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
}
|
||||
}
|
||||
|
||||
var buildingTiles = FootprintUtils.Tiles(buildingName, this, topLeft).ToList();
|
||||
var buildingTiles = FootprintUtils.Tiles(world.Map.Rules, buildingName, this, topLeft).ToList();
|
||||
return nearnessCandidates
|
||||
.Any(a => buildingTiles
|
||||
.Any(b => Math.Abs(a.X - b.X) <= Adjacent
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
if (b == null)
|
||||
return;
|
||||
|
||||
foreach (var u in FootprintUtils.Tiles(a.Info.Name, b.Info, a.Location))
|
||||
foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b.Info, a.Location))
|
||||
if (map.IsInMap(u) && influence[u.X, u.Y] == null)
|
||||
influence[u.X, u.Y] = a;
|
||||
};
|
||||
@@ -45,7 +45,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
if (b == null)
|
||||
return;
|
||||
|
||||
foreach (var u in FootprintUtils.Tiles(a.Info.Name, b.Info, a.Location))
|
||||
foreach (var u in FootprintUtils.Tiles(map.Rules, a.Info.Name, b.Info, a.Location))
|
||||
if (map.IsInMap(u) && influence[u.X, u.Y] == a)
|
||||
influence[u.X, u.Y] = null;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
if (order.OrderString == "PowerDown")
|
||||
{
|
||||
disabled = !disabled;
|
||||
Sound.PlayNotification(self.Owner, "Sounds", (disabled ? "EnablePower" : "DisablePower"), self.Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", (disabled ? "EnablePower" : "DisablePower"), self.Owner.Country.Race);
|
||||
PowerManager.UpdateActor(self, disabled ? 0 : normalPower);
|
||||
|
||||
if (disabled)
|
||||
|
||||
8
OpenRA.Mods.RA/Buildings/FootprintUtils.cs
Executable file → Normal file
8
OpenRA.Mods.RA/Buildings/FootprintUtils.cs
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -16,13 +16,13 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
{
|
||||
public static class FootprintUtils
|
||||
{
|
||||
public static IEnumerable<CPos> Tiles(string name, BuildingInfo buildingInfo, CPos topLeft)
|
||||
public static IEnumerable<CPos> Tiles(Ruleset rules, string name, BuildingInfo buildingInfo, CPos topLeft)
|
||||
{
|
||||
var dim = (CVec)buildingInfo.Dimensions;
|
||||
|
||||
var footprint = buildingInfo.Footprint.Where(x => !char.IsWhiteSpace(x));
|
||||
|
||||
var buildingTraits = Rules.Info[name].Traits;
|
||||
var buildingTraits = rules.Actors[name].Traits;
|
||||
if (buildingTraits.Contains<BibInfo>() && !(buildingTraits.Get<BibInfo>().HasMinibib))
|
||||
{
|
||||
dim += new CVec(0, 1);
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
|
||||
public static IEnumerable<CPos> Tiles(Actor a)
|
||||
{
|
||||
return Tiles( a.Info.Name, a.Info.Traits.Get<BuildingInfo>(), a.Location );
|
||||
return Tiles(a.World.Map.Rules, a.Info.Name, a.Info.Traits.Get<BuildingInfo>(), a.Location);
|
||||
}
|
||||
|
||||
public static IEnumerable<CPos> UnpathableTiles(string name, BuildingInfo buildingInfo, CPos position)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -108,7 +108,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
if (--nextPowerAdviceTime <= 0)
|
||||
{
|
||||
if (lowPower)
|
||||
Sound.PlayNotification(self.Owner, "Speech", "LowPower", self.Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", "LowPower", self.Owner.Country.Race);
|
||||
nextPowerAdviceTime = Info.AdviceInterval;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
else
|
||||
{
|
||||
Repairer = p;
|
||||
Sound.PlayNotification(Repairer, "Speech", "Repairing", self.Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, Repairer, "Speech", "Repairing", self.Owner.Country.Race);
|
||||
|
||||
self.World.AddFrameEndTask(
|
||||
w => w.Add(new RepairIndicator(self, Info.IndicatorPalettePrefix, p)));
|
||||
|
||||
6
OpenRA.Mods.RA/Buildings/Util.cs
Executable file → Normal file
6
OpenRA.Mods.RA/Buildings/Util.cs
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -35,14 +35,14 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
return true;
|
||||
|
||||
var res = world.WorldActor.Trait<ResourceLayer>();
|
||||
return FootprintUtils.Tiles(name, building, topLeft).All(
|
||||
return FootprintUtils.Tiles(world.Map.Rules, name, building, topLeft).All(
|
||||
t => world.Map.IsInMap(t.X, t.Y) && res.GetResource(t) == null &&
|
||||
world.IsCellBuildable(t, building, toIgnore));
|
||||
}
|
||||
|
||||
public static IEnumerable<CPos> GetLineBuildCells(World world, CPos location, string name, BuildingInfo bi)
|
||||
{
|
||||
var lbi = Rules.Info[name].Traits.Get<LineBuildInfo>();
|
||||
var lbi = world.Map.Rules.Actors[name].Traits.Get<LineBuildInfo>();
|
||||
var topLeft = location; // 1x1 assumption!
|
||||
|
||||
if (world.IsCellBuildable(topLeft, bi))
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
Info = info;
|
||||
|
||||
var anim = new Animation("fire", () => 0);
|
||||
var anim = new Animation(self.World, "fire", () => 0);
|
||||
anim.IsDecoration = true;
|
||||
anim.PlayRepeating(Info.Anim);
|
||||
self.Trait<RenderSprites>().anims.Add("fire", anim);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA
|
||||
return;
|
||||
|
||||
var race = info.NewOwnerVoice ? newOwner.Country.Race : oldOwner.Country.Race;
|
||||
Sound.PlayNotification(captor.World.LocalPlayer, "Speech", info.Notification, race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, captor.World.LocalPlayer, "Speech", info.Notification, race);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public static void DoExplosion(Actor attacker, string weapontype, WPos pos)
|
||||
{
|
||||
var weapon = Rules.Weapons[weapontype.ToLowerInvariant()];
|
||||
var weapon = attacker.World.Map.Rules.Weapons[weapontype.ToLowerInvariant()];
|
||||
if (weapon.Report != null && weapon.Report.Any())
|
||||
Sound.Play(weapon.Report.Random(attacker.World.SharedRandom), pos);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA
|
||||
Game.RunAfterDelay(Info.NotificationDelay, () =>
|
||||
{
|
||||
if (Game.IsCurrentWorld(self.World))
|
||||
Sound.PlayNotification(self.Owner, "Speech", "Lose", self.Owner.Country.Race);
|
||||
Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", "Lose", self.Owner.Country.Race);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
Game.Debug("{0} is victorious.".F(self.Owner.PlayerName));
|
||||
if (self.Owner == self.World.LocalPlayer)
|
||||
Game.RunAfterDelay(Info.NotificationDelay, () => Sound.PlayNotification(self.Owner, "Speech", "Win", self.Owner.Country.Race));
|
||||
Game.RunAfterDelay(Info.NotificationDelay, () => Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", "Win", self.Owner.Country.Race));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -90,7 +90,7 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
var crate = w.CreateActor(false, crateActor, new TypeDictionary { new OwnerInit(w.WorldActor.Owner) });
|
||||
var startPos = w.ChooseRandomEdgeCell();
|
||||
var altitude = Rules.Info[info.DeliveryAircraft].Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
var altitude = self.World.Map.Rules.Actors[info.DeliveryAircraft].Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
var plane = w.CreateActor(info.DeliveryAircraft, new TypeDictionary
|
||||
{
|
||||
new CenterPositionInit(startPos.CenterPosition + new WVec(WRange.Zero, WRange.Zero, altitude)),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA.Crates
|
||||
|
||||
public bool CanGiveTo(Actor collector)
|
||||
{
|
||||
var bi = Rules.Info[Info.Unit].Traits.GetOrDefault<BuildableInfo>();
|
||||
var bi = self.World.Map.Rules.Actors[Info.Unit].Traits.GetOrDefault<BuildableInfo>();
|
||||
|
||||
// this unit is not buildable by the collector's country, so
|
||||
// don't give them free ones either.
|
||||
@@ -68,7 +68,7 @@ namespace OpenRA.Mods.RA.Crates
|
||||
|
||||
IEnumerable<CPos> GetSuitableCells(CPos near)
|
||||
{
|
||||
var mi = Rules.Info[Info.Unit].Traits.Get<MobileInfo>();
|
||||
var mi = self.World.Map.Rules.Actors[Info.Unit].Traits.Get<MobileInfo>();
|
||||
|
||||
for (var i = -1; i < 2; i++)
|
||||
for (var j = -1; j < 2; j++)
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace OpenRA.Mods.RA.Effects
|
||||
readonly WPos position;
|
||||
readonly string palettePrefix;
|
||||
readonly string posterPalette;
|
||||
readonly Animation arrow = new Animation("beacon");
|
||||
readonly Animation circles = new Animation("beacon");
|
||||
readonly Animation arrow;
|
||||
readonly Animation circles;
|
||||
readonly Animation poster;
|
||||
static readonly int maxArrowHeight = 512;
|
||||
int arrowHeight = maxArrowHeight;
|
||||
@@ -35,12 +35,15 @@ namespace OpenRA.Mods.RA.Effects
|
||||
this.palettePrefix = palettePrefix;
|
||||
this.posterPalette = posterPalette;
|
||||
|
||||
arrow = new Animation(owner.World, "beacon");
|
||||
circles = new Animation(owner.World, "beacon");
|
||||
|
||||
arrow.Play("arrow");
|
||||
circles.Play("circles");
|
||||
|
||||
if (posterType != null)
|
||||
{
|
||||
poster = new Animation("beacon");
|
||||
poster = new Animation(owner.World, "beacon");
|
||||
poster.Play(posterType);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@ namespace OpenRA.Mods.RA.Effects
|
||||
this.args = args;
|
||||
this.pos = args.Source;
|
||||
|
||||
var world = args.SourceActor.World;
|
||||
|
||||
if (info.Angle.Length > 1 && info.Speed.Length > 1)
|
||||
{
|
||||
angle = new WAngle(args.SourceActor.World.SharedRandom.Next(info.Angle[0].Angle, info.Angle[1].Angle));
|
||||
@@ -89,7 +91,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
if (info.Image != null)
|
||||
{
|
||||
anim = new Animation(info.Image, GetEffectiveFacing);
|
||||
anim = new Animation(world, info.Image, GetEffectiveFacing);
|
||||
anim.PlayRepeating("idle");
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
this.pos = pos;
|
||||
this.cell = pos.ToCPos();
|
||||
this.paletteName = paletteName;
|
||||
anim = new Animation(image);
|
||||
anim = new Animation(world, image);
|
||||
anim.PlayThen(sequence, () => world.AddFrameEndTask(w => w.Remove(this)));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,15 @@ namespace OpenRA.Mods.RA.Effects
|
||||
class CrateEffect : IEffect
|
||||
{
|
||||
readonly string palette;
|
||||
Actor a;
|
||||
Animation anim = new Animation("crate-effects");
|
||||
readonly Actor a;
|
||||
readonly Animation anim;
|
||||
|
||||
public CrateEffect(Actor a, string seq, string palette)
|
||||
{
|
||||
this.a = a;
|
||||
this.palette = palette;
|
||||
|
||||
anim = new Animation(a.World, "crate-effects");
|
||||
anim.PlayThen(seq, () => a.World.AddFrameEndTask(w => w.Remove(this)));
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
this.pos = pos;
|
||||
this.cell = pos.ToCPos();
|
||||
this.palette = palette;
|
||||
anim = new Animation("explosion");
|
||||
anim = new Animation(world, "explosion");
|
||||
anim.PlayThen(sequence, () => world.AddFrameEndTask(w => w.Remove(this)));
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
this.self = self;
|
||||
this.info = info;
|
||||
anim = new Animation("gpsdot");
|
||||
anim = new Animation(self.World, "gpsdot");
|
||||
anim.PlayRepeating(info.String);
|
||||
|
||||
self.World.AddFrameEndTask(w => w.Add(this));
|
||||
|
||||
@@ -16,27 +16,29 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class GpsSatellite : IEffect
|
||||
{
|
||||
WPos Pos;
|
||||
Animation Anim = new Animation("sputnik");
|
||||
WPos pos;
|
||||
readonly Animation anim;
|
||||
|
||||
public GpsSatellite(WPos pos)
|
||||
public GpsSatellite(World world, WPos pos)
|
||||
{
|
||||
Pos = pos;
|
||||
Anim.PlayRepeating("idle");
|
||||
this.pos = pos;
|
||||
|
||||
anim = new Animation(world, "sputnik");
|
||||
anim.PlayRepeating("idle");
|
||||
}
|
||||
|
||||
public void Tick( World world )
|
||||
{
|
||||
Anim.Tick();
|
||||
Pos += new WVec(0, 0, 427);
|
||||
anim.Tick();
|
||||
pos += new WVec(0, 0, 427);
|
||||
|
||||
if (Pos.Z > Pos.Y)
|
||||
if (pos.Z > pos.Y)
|
||||
world.AddFrameEndTask(w => w.Remove(this));
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
return Anim.Render(Pos, wr.Palette("effect"));
|
||||
return anim.Render(pos, wr.Palette("effect"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
pos = args.Source;
|
||||
velocity = new WVec(WRange.Zero, WRange.Zero, -info.Velocity);
|
||||
|
||||
anim = new Animation(info.Image);
|
||||
anim = new Animation(args.SourceActor.World, info.Image);
|
||||
if (anim.HasSequence("open"))
|
||||
anim.PlayThen("open", () => anim.PlayRepeating("idle"));
|
||||
else
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
this.target = args.PassiveTarget;
|
||||
|
||||
if (info.HitAnim != null)
|
||||
this.hitanim = new Animation(info.HitAnim);
|
||||
this.hitanim = new Animation(args.SourceActor.World, info.HitAnim);
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
if (info.Image != null)
|
||||
{
|
||||
anim = new Animation(info.Image, () => facing);
|
||||
anim = new Animation(args.SourceActor.World, info.Image, () => facing);
|
||||
anim.PlayRepeating("idle");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 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,
|
||||
@@ -45,11 +45,11 @@ namespace OpenRA.Mods.RA.Effects
|
||||
descendSource = targetPos + offset;
|
||||
descendTarget = targetPos;
|
||||
|
||||
anim = new Animation(weapon);
|
||||
anim = new Animation(firedBy.World, weapon);
|
||||
anim.PlayRepeating("up");
|
||||
|
||||
pos = launchPos;
|
||||
var weaponRules = Rules.Weapons[weapon.ToLowerInvariant()];
|
||||
var weaponRules = firedBy.World.Map.Rules.Weapons[weapon.ToLowerInvariant()];
|
||||
if (weaponRules.Report != null && weaponRules.Report.Any())
|
||||
Sound.Play(weaponRules.Report.Random(firedBy.World.SharedRandom), pos);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
this.cargo = cargo;
|
||||
|
||||
var pai = cargo.Info.Traits.GetOrDefault<ParachuteAttachmentInfo>();
|
||||
paraAnim = new Animation(pai != null ? pai.ParachuteSprite : "parach");
|
||||
paraAnim = new Animation(cargo.World, pai != null ? pai.ParachuteSprite : "parach");
|
||||
paraAnim.PlayThen("open", () => paraAnim.PlayRepeating("idle"));
|
||||
|
||||
if (pai != null)
|
||||
|
||||
@@ -18,12 +18,15 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class PowerdownIndicator : IEffect
|
||||
{
|
||||
Actor a;
|
||||
Animation anim = new Animation("poweroff");
|
||||
readonly Actor a;
|
||||
readonly Animation anim;
|
||||
|
||||
public PowerdownIndicator(Actor a)
|
||||
{
|
||||
this.a = a; anim.PlayRepeating("offline");
|
||||
this.a = a;
|
||||
|
||||
anim = new Animation(a.World, "poweroff");
|
||||
anim.PlayRepeating("offline");
|
||||
}
|
||||
|
||||
public void Tick(World world)
|
||||
|
||||
@@ -21,14 +21,19 @@ namespace OpenRA.Mods.RA.Effects
|
||||
readonly Actor building;
|
||||
readonly RA.RallyPoint rp;
|
||||
readonly string palettePrefix;
|
||||
public Animation flag = new Animation("rallypoint");
|
||||
public Animation circles = new Animation("rallypoint");
|
||||
readonly Animation flag;
|
||||
readonly Animation circles;
|
||||
|
||||
public RallyPoint(Actor building, string palettePrefix)
|
||||
{
|
||||
this.building = building;
|
||||
rp = building.Trait<RA.RallyPoint>();
|
||||
this.palettePrefix = palettePrefix;
|
||||
|
||||
rp = building.Trait<RA.RallyPoint>();
|
||||
|
||||
flag = new Animation(building.World, "rallypoint");
|
||||
circles = new Animation(building.World, "rallypoint");
|
||||
|
||||
flag.PlayRepeating("flag");
|
||||
circles.Play("circles");
|
||||
}
|
||||
|
||||
@@ -17,16 +17,17 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class Rank : IEffect
|
||||
{
|
||||
Actor self;
|
||||
Animation anim = new Animation("rank");
|
||||
readonly Actor self;
|
||||
readonly Animation anim;
|
||||
readonly string paletteName;
|
||||
|
||||
public Rank(Actor self, string paletteName)
|
||||
{
|
||||
this.self = self;
|
||||
this.paletteName = paletteName;
|
||||
var xp = self.Trait<GainsExperience>();
|
||||
|
||||
var xp = self.Trait<GainsExperience>();
|
||||
anim = new Animation(self.World, "rank");
|
||||
anim.PlayRepeating("rank");
|
||||
anim.PlayFetchIndex("rank", () => xp.Level == 0 ? 0 : xp.Level - 1);
|
||||
}
|
||||
|
||||
@@ -18,18 +18,20 @@ namespace OpenRA.Mods.RA.Effects
|
||||
{
|
||||
class RepairIndicator : IEffect
|
||||
{
|
||||
Actor building;
|
||||
Player player;
|
||||
string palettePrefix;
|
||||
Animation anim = new Animation("allyrepair");
|
||||
RepairableBuilding rb;
|
||||
readonly Actor building;
|
||||
readonly Player player;
|
||||
readonly string palettePrefix;
|
||||
readonly Animation anim;
|
||||
readonly RepairableBuilding rb;
|
||||
|
||||
public RepairIndicator(Actor building, string palettePrefix, Player player)
|
||||
{
|
||||
this.building = building;
|
||||
this.player = player;
|
||||
this.palettePrefix = palettePrefix;
|
||||
|
||||
rb = building.Trait<RepairableBuilding>();
|
||||
anim = new Animation(building.World, "allyrepair");
|
||||
anim.PlayRepeating("repair");
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,13 @@ namespace OpenRA.Mods.RA.Effects
|
||||
class SatelliteLaunch : IEffect
|
||||
{
|
||||
int frame = 0;
|
||||
Animation doors = new Animation("atek");
|
||||
WPos pos;
|
||||
readonly Animation doors;
|
||||
readonly WPos pos;
|
||||
|
||||
public SatelliteLaunch(Actor a)
|
||||
{
|
||||
doors = new Animation(a.World, "atek");
|
||||
|
||||
doors.PlayThen("active",
|
||||
() => a.World.AddFrameEndTask(w => w.Remove(this)));
|
||||
|
||||
@@ -33,7 +35,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
doors.Tick();
|
||||
|
||||
if (++frame == 19)
|
||||
world.AddFrameEndTask(w => w.Add(new GpsSatellite(pos)));
|
||||
world.AddFrameEndTask(w => w.Add(new GpsSatellite(world, pos)));
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user