Merge pull request #8017 from pchote/map-definitions

Remove magic ActorReference/SmudgeReference parsing
This commit is contained in:
Chris Forbes
2015-04-30 10:46:27 +12:00
17 changed files with 112 additions and 132 deletions

View File

@@ -26,12 +26,12 @@ namespace OpenRA.Editor
public void Apply(Surface surface)
{
if (surface.Map.Actors.Value.Any(a => a.Value.Location() == surface.GetBrushLocation()))
if (surface.Actors.Any(a => a.Value.Location() == surface.GetBrushLocation()))
return;
var owner = surface.NewActorOwner;
var id = NextActorName(surface);
surface.Map.Actors.Value[id] = new ActorReference(actorTemplate.Info.Name.ToLowerInvariant())
surface.Actors[id] = new ActorReference(actorTemplate.Info.Name.ToLowerInvariant())
{
new LocationInit(surface.GetBrushLocation()),
new OwnerInit(owner)
@@ -44,7 +44,7 @@ namespace OpenRA.Editor
for (;;)
{
var possible = "Actor{0}".F(id++);
if (!surface.Map.Actors.Value.ContainsKey(possible)) return possible;
if (!surface.Actors.ContainsKey(possible)) return possible;
}
}
}

View File

@@ -128,7 +128,7 @@ namespace OpenRA.Editor
// but this breaks the game pretty badly.
if (map.PlayerDefinitions.Count == 0)
{
var players = new MapPlayers(map.Rules, map.GetSpawnPoints().Length);
var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
map.PlayerDefinitions = players.ToMiniYaml();
}
@@ -415,7 +415,7 @@ namespace OpenRA.Editor
map.ResizeCordon((int)nmd.CordonLeft.Value, (int)nmd.CordonTop.Value,
(int)nmd.CordonRight.Value, (int)nmd.CordonBottom.Value);
var players = new MapPlayers(map.Rules, map.GetSpawnPoints().Length);
var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
map.PlayerDefinitions = players.ToMiniYaml();
map.FixOpenAreas(Program.Rules);
@@ -506,7 +506,7 @@ namespace OpenRA.Editor
void SetupDefaultPlayers(object sender, EventArgs e)
{
dirty = true;
var players = new MapPlayers(surface1.Map.Rules, surface1.Map.GetSpawnPoints().Length);
var players = new MapPlayers(surface1.Map.Rules, surface1.Map.SpawnPoints.Value.Length);
surface1.Map.PlayerDefinitions = players.ToMiniYaml();
surface1.Chunks.Clear();

View File

@@ -43,6 +43,7 @@ namespace OpenRA.Editor
class Surface : Control
{
public Map Map { get; private set; }
public Dictionary<string, ActorReference> Actors { get; private set; }
public TileSet TileSet { get; private set; }
public TileSetRenderer TileSetRenderer { get; private set; }
public IPalette Palette { get; private set; }
@@ -84,6 +85,9 @@ namespace OpenRA.Editor
public void Bind(Map m, TileSet ts, TileSetRenderer tsr, IPalette p, IPalette pp)
{
Map = m;
if (m != null)
Actors = m.ActorDefinitions.ToDictionary(n => n.Key, n => new ActorReference(n.Value.Value, n.Value.ToDictionary()));
TileSet = ts;
TileSetRenderer = tsr;
Palette = p;
@@ -132,7 +136,7 @@ namespace OpenRA.Editor
{
base.OnDoubleClick(e);
var x = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == GetBrushLocation());
var x = Actors.FirstOrDefault(a => a.Value.Location() == GetBrushLocation());
if (x.Key != null)
ActorDoubleClicked(x);
}
@@ -203,8 +207,8 @@ namespace OpenRA.Editor
currentTool = null;
var key = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == brushLocation);
if (key.Key != null) Map.Actors.Value.Remove(key.Key);
var key = Actors.FirstOrDefault(a => a.Value.Location() == brushLocation);
if (key.Key != null) Actors.Remove(key.Key);
if (Map.MapResources.Value[brushLocation].Type != 0)
{
@@ -456,7 +460,7 @@ namespace OpenRA.Editor
height * (TileSetRenderer.TileSize * Zoom));
}
foreach (var ar in Map.Actors.Value)
foreach (var ar in Actors)
{
if (actorTemplates.ContainsKey(ar.Value.Type))
DrawActor(e.Graphics, ar.Value.Location(), actorTemplates[ar.Value.Type],
@@ -466,7 +470,7 @@ namespace OpenRA.Editor
}
if (ShowActorNames)
foreach (var ar in Map.Actors.Value)
foreach (var ar in Actors)
if (!ar.Key.StartsWith("Actor")) // if it has a custom name
e.Graphics.DrawStringContrast(Font, ar.Key,
(int)(ar.Value.Location().X * TileSetRenderer.TileSize * Zoom + Offset.X),
@@ -500,7 +504,7 @@ namespace OpenRA.Editor
if (currentTool == null)
{
var x = Map.Actors.Value.FirstOrDefault(a => a.Value.Location() == GetBrushLocation());
var x = Actors.FirstOrDefault(a => a.Value.Location() == GetBrushLocation());
if (x.Key != null && actorTemplates.ContainsKey(x.Value.Type))
DrawActorBorder(e.Graphics, x.Value.Location(), actorTemplates[x.Value.Type]);
}

View File

@@ -221,13 +221,11 @@ namespace OpenRA
return videos;
}
[FieldLoader.Ignore] public Lazy<Dictionary<string, ActorReference>> Actors;
public Rectangle Bounds;
// Yaml map data
[FieldLoader.Ignore] public Lazy<List<SmudgeReference>> Smudges;
public Lazy<CPos[]> SpawnPoints;
// Yaml map data
[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>();
@@ -237,6 +235,9 @@ namespace OpenRA
[FieldLoader.Ignore] public List<MiniYamlNode> TranslationDefinitions = new List<MiniYamlNode>();
[FieldLoader.Ignore] public List<MiniYamlNode> PlayerDefinitions = new List<MiniYamlNode>();
[FieldLoader.Ignore] public List<MiniYamlNode> ActorDefinitions = new List<MiniYamlNode>();
[FieldLoader.Ignore] public List<MiniYamlNode> SmudgeDefinitions = new List<MiniYamlNode>();
// Binary map data
[FieldLoader.Ignore] public byte TileFormat = 2;
@@ -294,8 +295,8 @@ namespace OpenRA
MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(tileShape, size)),
MapTiles = makeMapTiles,
MapHeight = makeMapHeight,
Actors = Exts.Lazy(() => new Dictionary<string, ActorReference>()),
Smudges = Exts.Lazy(() => new List<SmudgeReference>())
SpawnPoints = Exts.Lazy(() => new CPos[0])
};
map.PostInit();
@@ -345,29 +346,17 @@ namespace OpenRA
Visibility = MapVisibility.MissionSelector;
}
Actors = Exts.Lazy(() =>
SpawnPoints = Exts.Lazy(() =>
{
var ret = new Dictionary<string, ActorReference>();
foreach (var kv in nd["Actors"].ToDictionary())
ret.Add(kv.Key, new ActorReference(kv.Value.Value, kv.Value.ToDictionary()));
return ret;
});
var spawns = new List<CPos>();
foreach (var kv in ActorDefinitions.Where(d => d.Value.Value == "mpspawn"))
{
var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
// Smudges
Smudges = Exts.Lazy(() =>
{
var ret = new List<SmudgeReference>();
foreach (var name in nd["Smudges"].ToDictionary().Keys)
{
var vals = name.Split(' ');
var loc = vals[1].Split(',');
ret.Add(new SmudgeReference(vals[0], new int2(
Exts.ParseIntegerInvariant(loc[0]),
Exts.ParseIntegerInvariant(loc[1])),
Exts.ParseIntegerInvariant(vals[2])));
spawns.Add(s.InitDict.Get<LocationInit>().Value(null));
}
return ret;
return spawns.ToArray();
});
RuleDefinitions = MiniYaml.NodesOrEmpty(yaml, "Rules");
@@ -379,6 +368,9 @@ namespace OpenRA
TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations");
PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors");
SmudgeDefinitions = MiniYaml.NodesOrEmpty(yaml, "Smudges");
MapTiles = Exts.Lazy(LoadMapTiles);
MapResources = Exts.Lazy(LoadResourceTiles);
MapHeight = Exts.Lazy(LoadMapHeight);
@@ -448,14 +440,6 @@ namespace OpenRA
return rules.Value;
}
public CPos[] GetSpawnPoints()
{
return Actors.Value.Values
.Where(a => a.Type == "mpspawn")
.Select(a => (CPos)a.InitDict.Get<LocationInit>().Value(null))
.ToArray();
}
public void Save(string toPath)
{
MapFormat = 7;
@@ -489,10 +473,8 @@ namespace OpenRA
root.Add(new MiniYamlNode("Players", null, PlayerDefinitions));
root.Add(new MiniYamlNode("Actors", null,
Actors.Value.Select(x => new MiniYamlNode(x.Key, x.Value.Save())).ToList()));
root.Add(new MiniYamlNode("Smudges", MiniYaml.FromList<SmudgeReference>(Smudges.Value)));
root.Add(new MiniYamlNode("Actors", null, ActorDefinitions));
root.Add(new MiniYamlNode("Smudges", null, SmudgeDefinitions));
root.Add(new MiniYamlNode("Rules", null, RuleDefinitions));
root.Add(new MiniYamlNode("Sequences", null, SequenceDefinitions));
root.Add(new MiniYamlNode("VoxelSequences", null, VoxelSequenceDefinitions));

View File

@@ -119,7 +119,7 @@ namespace OpenRA
Type = m.Type;
Author = m.Author;
Bounds = m.Bounds;
SpawnPoints = m.GetSpawnPoints();
SpawnPoints = m.SpawnPoints.Value;
CustomPreview = m.CustomPreview;
Status = MapStatus.Available;
Class = classification;

View File

@@ -1,31 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
namespace OpenRA
{
public struct SmudgeReference
{
public readonly string Type;
public readonly int2 Location;
public readonly int Depth;
public SmudgeReference(string type, int2 location, int depth)
{
Type = type;
Location = location;
Depth = depth;
}
public override string ToString()
{
return "{0} {1},{2} {3}".F(Type, Location.X, Location.Y, Depth);
}
}
}

View File

@@ -249,7 +249,6 @@
<Compile Include="FileSystem\ZipFile.cs" />
<Compile Include="FileSystem\BigFile.cs" />
<Compile Include="Map\PlayerReference.cs" />
<Compile Include="Map\SmudgeReference.cs" />
<Compile Include="Map\TileReference.cs" />
<Compile Include="Map\TileSet.cs" />
<Compile Include="FieldLoader.cs" />

View File

@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Lint
{
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
{
var actorTypes = map.Actors.Value.Values.Select(a => a.Type);
var actorTypes = map.ActorDefinitions.Select(a => a.Value.Value);
foreach (var actor in actorTypes)
if (!map.Rules.Actors.Keys.Contains(actor.ToLowerInvariant()))
emitError("Actor {0} is not defined by any rule.".F(actor));

View File

@@ -789,7 +789,7 @@ namespace OpenRA.Mods.Common.Server
int spawnPoint;
if (!Exts.TryParseIntegerInvariant(parts[1], out spawnPoint)
|| spawnPoint < 0 || spawnPoint > server.Map.GetSpawnPoints().Length)
|| spawnPoint < 0 || spawnPoint > server.Map.SpawnPoints.Value.Length)
{
Log.Write("server", "Invalid spawn point: {0}", parts[1]);
return true;

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
public void WorldLoaded(World world, WorldRenderer wr)
{
var spawns = world.Map.GetSpawnPoints();
var spawns = world.Map.SpawnPoints.Value;
var taken = world.LobbyInfo.Clients.Where(c => c.SpawnPoint != 0 && c.Slot != null)
.Select(c => spawns[c.SpawnPoint - 1]).ToList();
var available = spawns.Except(taken).ToList();

View File

@@ -72,16 +72,27 @@ namespace OpenRA.Mods.Common.Traits
}
// Add map smudges
foreach (var s in w.Map.Smudges.Value.Where(s => smudges.ContainsKey(s.Type)))
foreach (var s in w.Map.SmudgeDefinitions)
{
var name = s.Key;
var vals = name.Split(' ');
var type = vals[0];
if (!smudges.ContainsKey(type))
continue;
var loc = vals[1].Split(',');
var cell = new CPos(Exts.ParseIntegerInvariant(loc[0]), Exts.ParseIntegerInvariant(loc[1]));
var depth = Exts.ParseIntegerInvariant(vals[2]);
var smudge = new Smudge
{
Type = s.Type,
Depth = s.Depth,
Sprite = smudges[s.Type][s.Depth]
Type = type,
Depth = depth,
Sprite = smudges[type][depth]
};
tiles.Add((CPos)s.Location, smudge);
tiles.Add(cell, smudge);
}
}

View File

@@ -25,17 +25,19 @@ namespace OpenRA.Mods.Common.Traits
public void WorldLoaded(World world, WorldRenderer wr)
{
foreach (var actorReference in world.Map.Actors.Value)
foreach (var kv in world.Map.ActorDefinitions)
{
var actorReference = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
// if there is no real player associated, dont spawn it.
var ownerName = actorReference.Value.InitDict.Get<OwnerInit>().PlayerName;
var ownerName = actorReference.InitDict.Get<OwnerInit>().PlayerName;
if (!world.Players.Any(p => p.InternalName == ownerName))
continue;
var initDict = actorReference.Value.InitDict;
var initDict = actorReference.InitDict;
initDict.Add(new SkipMakeAnimsInit());
var actor = world.CreateActor(actorReference.Value.Type, initDict);
Actors[actorReference.Key] = actor;
var actor = world.CreateActor(actorReference.Type, initDict);
Actors[kv.Key] = actor;
LastMapActorID = actor.ActorID;
}
}

View File

@@ -150,8 +150,6 @@ namespace OpenRA.Mods.Common.UtilityCommands
map.MapSize = new int2(mapSize, mapSize);
map.Bounds = Rectangle.FromLTRB(offsetX, offsetY, offsetX + width, offsetY + height);
map.Smudges = Exts.Lazy(() => new List<SmudgeReference>());
map.Actors = Exts.Lazy(() => new Dictionary<string, ActorReference>());
map.MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(TileShape.Rectangle, size));
map.MapTiles = Exts.Lazy(() => new CellLayer<TerrainTile>(TileShape.Rectangle, size));
@@ -190,26 +188,28 @@ namespace OpenRA.Mods.Common.UtilityCommands
{
if (kv.First <= 7)
{
var a = new ActorReference("mpspawn")
var ar = new ActorReference("mpspawn")
{
new LocationInit((CPos)kv.Second),
new OwnerInit("Neutral")
};
map.Actors.Value.Add("Actor" + map.Actors.Value.Count.ToString(), a);
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
}
else
{
var a = new ActorReference("waypoint")
var ar = new ActorReference("waypoint")
{
new LocationInit((CPos)kv.Second),
new OwnerInit("Neutral")
};
map.Actors.Value.Add("waypoint" + kv.First, a);
map.ActorDefinitions.Add(new MiniYamlNode("waypoint" + kv.First, ar.Save()));
}
}
// Create default player definitions only if there are no players to import
mapPlayers = new MapPlayers(map.Rules, (players.Count == 0) ? map.GetSpawnPoints().Length : 0);
mapPlayers = new MapPlayers(map.Rules, (players.Count == 0) ? map.SpawnPoints.Value.Length : 0);
foreach (var p in players)
LoadPlayer(file, p, legacyMapFormat == IniMapFormat.RedAlert);
map.PlayerDefinitions = mapPlayers.ToMiniYaml();
@@ -295,12 +295,13 @@ namespace OpenRA.Mods.Common.UtilityCommands
if (o != 255 && overlayActorMapping.ContainsKey(redAlertOverlayNames[o]))
{
map.Actors.Value.Add("Actor" + actorCount++,
new ActorReference(overlayActorMapping[redAlertOverlayNames[o]])
var ar = new ActorReference(overlayActorMapping[redAlertOverlayNames[o]])
{
new LocationInit(cell),
new OwnerInit("Neutral")
});
};
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
}
}
}
@@ -315,12 +316,13 @@ namespace OpenRA.Mods.Common.UtilityCommands
foreach (var kv in terrain)
{
var loc = Exts.ParseIntegerInvariant(kv.Key);
map.Actors.Value.Add("Actor" + actorCount++,
new ActorReference(kv.Value.ToLowerInvariant())
var ar = new ActorReference(kv.Value.ToLowerInvariant())
{
new LocationInit(new CPos(loc % mapSize, loc / mapSize)),
new OwnerInit("Neutral")
});
};
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
}
}
@@ -355,12 +357,15 @@ namespace OpenRA.Mods.Common.UtilityCommands
map.MapResources.Value[cell] = new ResourceTile(res.First, res.Second);
if (overlayActorMapping.ContainsKey(kv.Value.ToLower()))
map.Actors.Value.Add("Actor" + actorCount++,
new ActorReference(overlayActorMapping[kv.Value.ToLower()])
{
var ar = new ActorReference(overlayActorMapping[kv.Value.ToLower()])
{
new LocationInit(cell),
new OwnerInit("Neutral")
});
};
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
}
}
}
@@ -373,12 +378,13 @@ namespace OpenRA.Mods.Common.UtilityCommands
foreach (var kv in terrain)
{
var loc = Exts.ParseIntegerInvariant(kv.Key);
map.Actors.Value.Add("Actor" + actorCount++,
new ActorReference(kv.Value.Split(',')[0].ToLowerInvariant())
var ar = new ActorReference(kv.Value.Split(',')[0].ToLowerInvariant())
{
new LocationInit(new CPos(loc % mapSize, loc / mapSize)),
new OwnerInit("Neutral")
});
};
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, ar.Save()));
}
}
@@ -420,7 +426,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
if (!rules.Actors.ContainsKey(parts[1].ToLowerInvariant()))
errorHandler("Ignoring unknown actor type: `{0}`".F(parts[1].ToLowerInvariant()));
else
map.Actors.Value.Add("Actor" + actorCount++, actor);
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + actorCount++, actor.Save()));
}
catch (Exception)
{
@@ -436,7 +442,8 @@ namespace OpenRA.Mods.Common.UtilityCommands
// loc=type,loc,depth
var parts = s.Value.Split(',');
var loc = Exts.ParseIntegerInvariant(parts[1]);
map.Smudges.Value.Add(new SmudgeReference(parts[0].ToLowerInvariant(), new int2(loc % mapSize, loc / mapSize), Exts.ParseIntegerInvariant(parts[2])));
var key = "{0} {1},{2} {3}".F(parts[0].ToLowerInvariant(), loc % mapSize, loc / mapSize, Exts.ParseIntegerInvariant(parts[2]));
map.SmudgeDefinitions.Add(new MiniYamlNode(key, ""));
}
}

View File

@@ -31,6 +31,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0);
UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0);
UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0);
UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0);
map.Save(args[1]);
}
}

View File

@@ -84,6 +84,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
UpgradeRules.UpgradeActorRules(engineDate, ref map.RuleDefinitions, null, 0);
UpgradeRules.UpgradeWeaponRules(engineDate, ref map.WeaponDefinitions, null, 0);
UpgradeRules.UpgradePlayers(engineDate, ref map.PlayerDefinitions, null, 0);
UpgradeRules.UpgradeActors(engineDate, ref map.ActorDefinitions, null, 0);
map.Save(map.Path);
}
}

View File

@@ -1365,5 +1365,11 @@ namespace OpenRA.Mods.Common.UtilityCommands
foreach (var node in nodes)
UpgradePlayers(engineVersion, ref node.Value.Nodes, node, depth + 1);
}
internal static void UpgradeActors(int engineVersion, ref List<MiniYamlNode> nodes, MiniYamlNode parent, int depth)
{
foreach (var node in nodes)
UpgradeActors(engineVersion, ref node.Value.Nodes, node, depth + 1);
}
}
}

View File

@@ -297,7 +297,7 @@ namespace OpenRA.Mods.D2k.UtilityCommands
return null;
map.RequiresMod = mod;
var players = new MapPlayers(map.Rules, map.GetSpawnPoints().Length);
var players = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length);
map.PlayerDefinitions = players.ToMiniYaml();
return map;
@@ -314,8 +314,6 @@ namespace OpenRA.Mods.D2k.UtilityCommands
map.MapSize = new int2(mapSize.Width + 2 * MapCordonWidth, mapSize.Height + 2 * MapCordonWidth);
map.Bounds = new Rectangle(MapCordonWidth, MapCordonWidth, mapSize.Width, mapSize.Height);
map.Smudges = Exts.Lazy(() => new List<SmudgeReference>());
map.Actors = Exts.Lazy(() => new Dictionary<string, ActorReference>());
map.MapResources = Exts.Lazy(() => new CellLayer<ResourceTile>(TileShape.Rectangle, new Size(map.MapSize.X, map.MapSize.Y)));
map.MapTiles = Exts.Lazy(() => new CellLayer<TerrainTile>(TileShape.Rectangle, new Size(map.MapSize.X, map.MapSize.Y)));
@@ -357,7 +355,7 @@ namespace OpenRA.Mods.D2k.UtilityCommands
new LocationInit(locationOnMap),
new OwnerInit(kvp.Second)
};
map.Actors.Value.Add("Actor" + map.Actors.Value.Count, a);
map.ActorDefinitions.Add(new MiniYamlNode("Actor" + map.ActorDefinitions.Count, a.Save()));
}
}
}