Replace map type with a category list.
This commit is contained in:
@@ -153,7 +153,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
public class Map : IReadOnlyFileSystem
|
public class Map : IReadOnlyFileSystem
|
||||||
{
|
{
|
||||||
public const int SupportedMapFormat = 10;
|
public const int SupportedMapFormat = 11;
|
||||||
|
|
||||||
/// <summary>Defines the order of the fields in map.yaml</summary>
|
/// <summary>Defines the order of the fields in map.yaml</summary>
|
||||||
static readonly MapField[] YamlFields =
|
static readonly MapField[] YamlFields =
|
||||||
@@ -166,7 +166,7 @@ namespace OpenRA
|
|||||||
new MapField("MapSize"),
|
new MapField("MapSize"),
|
||||||
new MapField("Bounds"),
|
new MapField("Bounds"),
|
||||||
new MapField("Visibility"),
|
new MapField("Visibility"),
|
||||||
new MapField("Type"),
|
new MapField("Categories"),
|
||||||
new MapField("LockPreview", required: false, ignoreIfValue: "False"),
|
new MapField("LockPreview", required: false, ignoreIfValue: "False"),
|
||||||
new MapField("Players", "PlayerDefinitions"),
|
new MapField("Players", "PlayerDefinitions"),
|
||||||
new MapField("Actors", "ActorDefinitions"),
|
new MapField("Actors", "ActorDefinitions"),
|
||||||
@@ -192,7 +192,7 @@ namespace OpenRA
|
|||||||
public bool LockPreview;
|
public bool LockPreview;
|
||||||
public Rectangle Bounds;
|
public Rectangle Bounds;
|
||||||
public MapVisibility Visibility = MapVisibility.Lobby;
|
public MapVisibility Visibility = MapVisibility.Lobby;
|
||||||
public string Type = "Conquest";
|
public string[] Categories = { "Conquest" };
|
||||||
|
|
||||||
public int2 MapSize { get; private set; }
|
public int2 MapSize { get; private set; }
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public readonly string title;
|
public readonly string title;
|
||||||
public readonly string author;
|
public readonly string author;
|
||||||
public readonly string map_type;
|
public readonly string[] categories;
|
||||||
public readonly int players;
|
public readonly int players;
|
||||||
public readonly Rectangle bounds;
|
public readonly Rectangle bounds;
|
||||||
public readonly int[] spawnpoints = { };
|
public readonly int[] spawnpoints = { };
|
||||||
@@ -64,7 +64,7 @@ namespace OpenRA
|
|||||||
IReadOnlyPackage parentPackage;
|
IReadOnlyPackage parentPackage;
|
||||||
|
|
||||||
public string Title { get; private set; }
|
public string Title { get; private set; }
|
||||||
public string Type { get; private set; }
|
public string[] Categories { get; private set; }
|
||||||
public string Author { get; private set; }
|
public string Author { get; private set; }
|
||||||
public string TileSet { get; private set; }
|
public string TileSet { get; private set; }
|
||||||
public MapPlayers Players { get; private set; }
|
public MapPlayers Players { get; private set; }
|
||||||
@@ -116,7 +116,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
Uid = uid;
|
Uid = uid;
|
||||||
Title = "Unknown Map";
|
Title = "Unknown Map";
|
||||||
Type = "Unknown";
|
Categories = new[] { "Unknown" };
|
||||||
Author = "Unknown Author";
|
Author = "Unknown Author";
|
||||||
PlayerCount = 0;
|
PlayerCount = 0;
|
||||||
Bounds = Rectangle.Empty;
|
Bounds = Rectangle.Empty;
|
||||||
@@ -153,8 +153,8 @@ namespace OpenRA
|
|||||||
|
|
||||||
if (yaml.TryGetValue("Title", out temp))
|
if (yaml.TryGetValue("Title", out temp))
|
||||||
Title = temp.Value;
|
Title = temp.Value;
|
||||||
if (yaml.TryGetValue("Type", out temp))
|
if (yaml.TryGetValue("Categories", out temp))
|
||||||
Type = temp.Value;
|
Categories = FieldLoader.GetValue<string[]>("Categories", temp.Value);
|
||||||
if (yaml.TryGetValue("Tileset", out temp))
|
if (yaml.TryGetValue("Tileset", out temp))
|
||||||
TileSet = temp.Value;
|
TileSet = temp.Value;
|
||||||
if (yaml.TryGetValue("Author", out temp))
|
if (yaml.TryGetValue("Author", out temp))
|
||||||
@@ -257,7 +257,7 @@ namespace OpenRA
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Other map types may have confusing settings or gameplay
|
// Other map types may have confusing settings or gameplay
|
||||||
if (Type != "Conquest")
|
if (!Categories.Contains("Conquest"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Maps with bots disabled confuse new players
|
// Maps with bots disabled confuse new players
|
||||||
@@ -290,7 +290,7 @@ namespace OpenRA
|
|||||||
}
|
}
|
||||||
|
|
||||||
Title = r.title;
|
Title = r.title;
|
||||||
Type = r.map_type;
|
Categories = r.categories;
|
||||||
Author = r.author;
|
Author = r.author;
|
||||||
PlayerCount = r.players;
|
PlayerCount = r.players;
|
||||||
Bounds = r.bounds;
|
Bounds = r.bounds;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Lint
|
namespace OpenRA.Mods.Common.Lint
|
||||||
@@ -28,8 +29,8 @@ namespace OpenRA.Mods.Common.Lint
|
|||||||
if (map.Title == null)
|
if (map.Title == null)
|
||||||
emitError("Map does not define a valid title.");
|
emitError("Map does not define a valid title.");
|
||||||
|
|
||||||
if (map.Type == null)
|
if (!map.Categories.Any())
|
||||||
emitError("Map does not define a valid type.");
|
emitError("Map does not define any categories.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -994,6 +994,14 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
|||||||
yaml.Nodes.Add(new MiniYamlNode("LockPreview", new MiniYaml("True")));
|
yaml.Nodes.Add(new MiniYamlNode("LockPreview", new MiniYaml("True")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format 10 -> 11 replaced the single map type field with a list of categories
|
||||||
|
if (mapFormat < 11)
|
||||||
|
{
|
||||||
|
var type = yaml.Nodes.First(n => n.Key == "Type");
|
||||||
|
yaml.Nodes.Add(new MiniYamlNode("Categories", type.Value));
|
||||||
|
yaml.Nodes.Remove(type);
|
||||||
|
}
|
||||||
|
|
||||||
if (mapFormat < Map.SupportedMapFormat)
|
if (mapFormat < Map.SupportedMapFormat)
|
||||||
{
|
{
|
||||||
yaml.Nodes.First(n => n.Key == "MapFormat").Value = new MiniYaml(Map.SupportedMapFormat.ToString());
|
yaml.Nodes.First(n => n.Key == "MapFormat").Value = new MiniYaml(Map.SupportedMapFormat.ToString());
|
||||||
|
|||||||
@@ -96,12 +96,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
var titleText = widget.Get<LabelWidget>("TITLE");
|
var titleText = widget.Get<LabelWidget>("TITLE");
|
||||||
var titleTextNoTabs = widget.GetOrNull<LabelWidget>("TITLE_NO_TABS");
|
var titleTextNoTabs = widget.GetOrNull<LabelWidget>("TITLE_NO_TABS");
|
||||||
|
|
||||||
|
var mapTitle = world.Map.Title;
|
||||||
|
var firstCategory = world.Map.Categories.FirstOrDefault();
|
||||||
|
if (firstCategory != null)
|
||||||
|
mapTitle = firstCategory + ": " + mapTitle;
|
||||||
|
|
||||||
titleText.IsVisible = () => numTabs > 1 || (numTabs == 1 && titleTextNoTabs == null);
|
titleText.IsVisible = () => numTabs > 1 || (numTabs == 1 && titleTextNoTabs == null);
|
||||||
titleText.GetText = () => string.Concat(world.Map.Type, ": ", world.Map.Title);
|
titleText.GetText = () => mapTitle;
|
||||||
if (titleTextNoTabs != null)
|
if (titleTextNoTabs != null)
|
||||||
{
|
{
|
||||||
titleTextNoTabs.IsVisible = () => numTabs == 1;
|
titleTextNoTabs.IsVisible = () => numTabs == 1;
|
||||||
titleTextNoTabs.GetText = () => string.Concat(world.Map.Type, ": ", world.Map.Title);
|
titleTextNoTabs.GetText = () => mapTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bg = widget.Get<BackgroundWidget>("BACKGROUND");
|
var bg = widget.Get<BackgroundWidget>("BACKGROUND");
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Network;
|
using OpenRA.Network;
|
||||||
using OpenRA.Widgets;
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
@@ -43,7 +44,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
var typeLabel = available.GetOrNull<LabelWidget>("MAP_TYPE");
|
var typeLabel = available.GetOrNull<LabelWidget>("MAP_TYPE");
|
||||||
if (typeLabel != null)
|
if (typeLabel != null)
|
||||||
typeLabel.GetText = () => lobby.Map.Type;
|
{
|
||||||
|
var type = new CachedTransform<MapPreview, string>(m => lobby.Map.Categories.FirstOrDefault() ?? "");
|
||||||
|
typeLabel.GetText = () => type.Update(lobby.Map);
|
||||||
|
}
|
||||||
|
|
||||||
var authorLabel = available.GetOrNull<LabelWidget>("MAP_AUTHOR");
|
var authorLabel = available.GetOrNull<LabelWidget>("MAP_AUTHOR");
|
||||||
if (authorLabel != null)
|
if (authorLabel != null)
|
||||||
@@ -65,13 +69,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
|
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
|
||||||
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);
|
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);
|
||||||
|
|
||||||
var title = invalid.GetOrNull<LabelWidget>("MAP_TITLE");
|
var titleLabel = invalid.GetOrNull<LabelWidget>("MAP_TITLE");
|
||||||
if (title != null)
|
if (titleLabel != null)
|
||||||
title.GetText = () => lobby.Map.Title;
|
titleLabel.GetText = () => lobby.Map.Title;
|
||||||
|
|
||||||
var type = invalid.GetOrNull<LabelWidget>("MAP_TYPE");
|
var typeLabel = invalid.GetOrNull<LabelWidget>("MAP_TYPE");
|
||||||
if (type != null)
|
if (typeLabel != null)
|
||||||
type.GetText = () => lobby.Map.Type;
|
{
|
||||||
|
var type = new CachedTransform<MapPreview, string>(m => lobby.Map.Categories.FirstOrDefault() ?? "");
|
||||||
|
typeLabel.GetText = () => type.Update(lobby.Map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var download = widget.GetOrNull("MAP_DOWNLOADABLE");
|
var download = widget.GetOrNull("MAP_DOWNLOADABLE");
|
||||||
@@ -84,17 +91,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
|
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
|
||||||
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);
|
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);
|
||||||
|
|
||||||
var title = download.GetOrNull<LabelWidget>("MAP_TITLE");
|
var titleLabel = download.GetOrNull<LabelWidget>("MAP_TITLE");
|
||||||
if (title != null)
|
if (titleLabel != null)
|
||||||
title.GetText = () => lobby.Map.Title;
|
titleLabel.GetText = () => lobby.Map.Title;
|
||||||
|
|
||||||
var type = download.GetOrNull<LabelWidget>("MAP_TYPE");
|
var typeLabel = download.GetOrNull<LabelWidget>("MAP_TYPE");
|
||||||
if (type != null)
|
if (typeLabel != null)
|
||||||
type.GetText = () => lobby.Map.Type;
|
{
|
||||||
|
var type = new CachedTransform<MapPreview, string>(m => lobby.Map.Categories.FirstOrDefault() ?? "");
|
||||||
|
typeLabel.GetText = () => type.Update(lobby.Map);
|
||||||
|
}
|
||||||
|
|
||||||
var author = download.GetOrNull<LabelWidget>("MAP_AUTHOR");
|
var authorLabel = download.GetOrNull<LabelWidget>("MAP_AUTHOR");
|
||||||
if (author != null)
|
if (authorLabel != null)
|
||||||
author.GetText = () => "Created by {0}".F(lobby.Map.Author);
|
authorLabel.GetText = () => "Created by {0}".F(lobby.Map.Author);
|
||||||
|
|
||||||
var install = download.GetOrNull<ButtonWidget>("MAP_INSTALL");
|
var install = download.GetOrNull<ButtonWidget>("MAP_INSTALL");
|
||||||
if (install != null)
|
if (install != null)
|
||||||
@@ -116,13 +126,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
|
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
|
||||||
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);
|
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);
|
||||||
|
|
||||||
var title = progress.GetOrNull<LabelWidget>("MAP_TITLE");
|
var titleLabel = progress.GetOrNull<LabelWidget>("MAP_TITLE");
|
||||||
if (title != null)
|
if (titleLabel != null)
|
||||||
title.GetText = () => lobby.Map.Title;
|
titleLabel.GetText = () => lobby.Map.Title;
|
||||||
|
|
||||||
var type = progress.GetOrNull<LabelWidget>("MAP_TYPE");
|
var typeLabel = progress.GetOrNull<LabelWidget>("MAP_TYPE");
|
||||||
if (type != null)
|
if (typeLabel != null)
|
||||||
type.GetText = () => lobby.Map.Type;
|
if (typeLabel != null)
|
||||||
|
{
|
||||||
|
var type = new CachedTransform<MapPreview, string>(m => lobby.Map.Categories.FirstOrDefault() ?? "");
|
||||||
|
typeLabel.GetText = () => type.Update(lobby.Map);
|
||||||
|
}
|
||||||
|
|
||||||
var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING");
|
var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING");
|
||||||
if (statusSearching != null)
|
if (statusSearching != null)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
string selectedUid;
|
string selectedUid;
|
||||||
Action<string> onSelect;
|
Action<string> onSelect;
|
||||||
|
|
||||||
string gameMode;
|
string category;
|
||||||
string mapFilter;
|
string mapFilter;
|
||||||
|
|
||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
@@ -170,30 +170,43 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
{
|
{
|
||||||
if (gameModeDropdown != null)
|
if (gameModeDropdown != null)
|
||||||
{
|
{
|
||||||
var gameModes = tabMaps[tab]
|
var categoryDict = new Dictionary<string, int>();
|
||||||
.GroupBy(m => m.Type)
|
foreach (var map in tabMaps[tab])
|
||||||
.Select(g => Pair.New(g.Key, g.Count())).ToList();
|
{
|
||||||
|
foreach (var category in map.Categories)
|
||||||
|
{
|
||||||
|
var count = 0;
|
||||||
|
categoryDict.TryGetValue(category, out count);
|
||||||
|
categoryDict[category] = count + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order categories alphabetically
|
||||||
|
var categories = categoryDict
|
||||||
|
.Select(kv => Pair.New(kv.Key, kv.Value))
|
||||||
|
.OrderBy(p => p.First)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
// 'all game types' extra item
|
// 'all game types' extra item
|
||||||
gameModes.Insert(0, Pair.New(null as string, tabMaps[tab].Count()));
|
categories.Insert(0, Pair.New(null as string, tabMaps[tab].Count()));
|
||||||
|
|
||||||
Func<Pair<string, int>, string> showItem = x => "{0} ({1})".F(x.First ?? "All Game Types", x.Second);
|
Func<Pair<string, int>, string> showItem = x => "{0} ({1})".F(x.First ?? "All Maps", x.Second);
|
||||||
|
|
||||||
Func<Pair<string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
|
Func<Pair<string, int>, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
|
||||||
{
|
{
|
||||||
var item = ScrollItemWidget.Setup(template,
|
var item = ScrollItemWidget.Setup(template,
|
||||||
() => gameMode == ii.First,
|
() => category == ii.First,
|
||||||
() => { gameMode = ii.First; EnumerateMaps(tab, itemTemplate); });
|
() => { category = ii.First; EnumerateMaps(tab, itemTemplate); });
|
||||||
item.Get<LabelWidget>("LABEL").GetText = () => showItem(ii);
|
item.Get<LabelWidget>("LABEL").GetText = () => showItem(ii);
|
||||||
return item;
|
return item;
|
||||||
};
|
};
|
||||||
|
|
||||||
gameModeDropdown.OnClick = () =>
|
gameModeDropdown.OnClick = () =>
|
||||||
gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, gameModes, setupItem);
|
gameModeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, categories, setupItem);
|
||||||
|
|
||||||
gameModeDropdown.GetText = () =>
|
gameModeDropdown.GetText = () =>
|
||||||
{
|
{
|
||||||
var item = gameModes.FirstOrDefault(m => m.First == gameMode);
|
var item = categories.FirstOrDefault(m => m.First == category);
|
||||||
if (item == default(Pair<string, int>))
|
if (item == default(Pair<string, int>))
|
||||||
item.First = "No matches";
|
item.First = "No matches";
|
||||||
|
|
||||||
@@ -209,7 +222,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
playerCountFilter = -1;
|
playerCountFilter = -1;
|
||||||
|
|
||||||
var maps = tabMaps[tab]
|
var maps = tabMaps[tab]
|
||||||
.Where(m => gameMode == null || m.Type == gameMode)
|
.Where(m => category == null || m.Categories.Contains(category))
|
||||||
.Where(m => mapFilter == null ||
|
.Where(m => mapFilter == null ||
|
||||||
(m.Title != null && m.Title.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) ||
|
(m.Title != null && m.Title.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||||
(m.Author != null && m.Author.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) ||
|
(m.Author != null && m.Author.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||||
@@ -251,7 +264,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
var detailsWidget = item.GetOrNull<LabelWidget>("DETAILS");
|
var detailsWidget = item.GetOrNull<LabelWidget>("DETAILS");
|
||||||
if (detailsWidget != null)
|
if (detailsWidget != null)
|
||||||
detailsWidget.GetText = () => "{0} ({1} players)".F(preview.Type, preview.PlayerCount);
|
{
|
||||||
|
var type = preview.Categories.FirstOrDefault();
|
||||||
|
var details = "";
|
||||||
|
if (type != null)
|
||||||
|
details = type + " ";
|
||||||
|
|
||||||
|
details += "({0} players)".F(preview.PlayerCount);
|
||||||
|
detailsWidget.GetText = () => details;
|
||||||
|
}
|
||||||
|
|
||||||
var authorWidget = item.GetOrNull<LabelWidget>("AUTHOR");
|
var authorWidget = item.GetOrNull<LabelWidget>("AUTHOR");
|
||||||
if (authorWidget != null)
|
if (authorWidget != null)
|
||||||
|
|||||||
@@ -83,7 +83,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
var type = panel.GetOrNull<LabelWidget>("MAP_TYPE");
|
var type = panel.GetOrNull<LabelWidget>("MAP_TYPE");
|
||||||
if (type != null)
|
if (type != null)
|
||||||
type.GetText = () => selectedReplay.GameInfo.MapPreview.Type;
|
{
|
||||||
|
var mapType = new CachedTransform<MapPreview, string>(m => m.Categories.FirstOrDefault() ?? "");
|
||||||
|
type.GetText = () => mapType.Update(selectedReplay.GameInfo.MapPreview);
|
||||||
|
}
|
||||||
|
|
||||||
panel.Get<LabelWidget>("DURATION").GetText = () => WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds);
|
panel.Get<LabelWidget>("DURATION").GetText = () => WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user