Merge pull request #10901 from pchote/server-maps
Remove Map usage from the server and mission browser.
This commit is contained in:
@@ -148,7 +148,9 @@ namespace OpenRA
|
|||||||
return new Ruleset(dr.Actors, dr.Weapons, dr.Voices, dr.Notifications, dr.Music, ts, sequences);
|
return new Ruleset(dr.Actors, dr.Weapons, dr.Voices, dr.Notifications, dr.Music, ts, sequences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Ruleset LoadFromMap(ModData modData, Map map)
|
public static Ruleset Load(ModData modData, IReadOnlyFileSystem fileSystem, string tileSet,
|
||||||
|
MiniYaml mapRules, MiniYaml mapWeapons, MiniYaml mapVoices, MiniYaml mapNotifications,
|
||||||
|
MiniYaml mapMusic, MiniYaml mapSequences)
|
||||||
{
|
{
|
||||||
var m = modData.Manifest;
|
var m = modData.Manifest;
|
||||||
var dr = modData.DefaultRules;
|
var dr = modData.DefaultRules;
|
||||||
@@ -156,27 +158,27 @@ namespace OpenRA
|
|||||||
Ruleset ruleset = null;
|
Ruleset ruleset = null;
|
||||||
Action f = () =>
|
Action f = () =>
|
||||||
{
|
{
|
||||||
var actors = MergeOrDefault("Manifest,Rules", map, m.Rules, map.RuleDefinitions, dr.Actors,
|
var actors = MergeOrDefault("Rules", fileSystem, m.Rules, mapRules, dr.Actors,
|
||||||
k => new ActorInfo(modData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value));
|
k => new ActorInfo(modData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value));
|
||||||
|
|
||||||
var weapons = MergeOrDefault("Manifest,Weapons", map, m.Weapons, map.WeaponDefinitions, dr.Weapons,
|
var weapons = MergeOrDefault("Weapons", fileSystem, m.Weapons, mapWeapons, dr.Weapons,
|
||||||
k => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
|
k => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
|
||||||
|
|
||||||
var voices = MergeOrDefault("Manifest,Voices", map, m.Voices, map.VoiceDefinitions, dr.Voices,
|
var voices = MergeOrDefault("Voices", fileSystem, m.Voices, mapVoices, dr.Voices,
|
||||||
k => new SoundInfo(k.Value));
|
k => new SoundInfo(k.Value));
|
||||||
|
|
||||||
var notifications = MergeOrDefault("Manifest,Notifications", map, m.Notifications, map.NotificationDefinitions, dr.Notifications,
|
var notifications = MergeOrDefault("Notifications", fileSystem, m.Notifications, mapNotifications, dr.Notifications,
|
||||||
k => new SoundInfo(k.Value));
|
k => new SoundInfo(k.Value));
|
||||||
|
|
||||||
var music = MergeOrDefault("Manifest,Music", map, m.Music, map.NotificationDefinitions, dr.Music,
|
var music = MergeOrDefault("Music", fileSystem, m.Music, mapMusic, dr.Music,
|
||||||
k => new MusicInfo(k.Key, k.Value));
|
k => new MusicInfo(k.Key, k.Value));
|
||||||
|
|
||||||
// TODO: Add support for merging custom tileset modifications
|
// TODO: Add support for merging custom tileset modifications
|
||||||
var ts = modData.DefaultTileSets[map.Tileset];
|
var ts = modData.DefaultTileSets[tileSet];
|
||||||
|
|
||||||
// TODO: Top-level dictionary should be moved into the Ruleset instead of in its own object
|
// TODO: Top-level dictionary should be moved into the Ruleset instead of in its own object
|
||||||
var sequences = map.SequenceDefinitions == null ? modData.DefaultSequences[map.Tileset] :
|
var sequences = mapSequences == null ? modData.DefaultSequences[tileSet] :
|
||||||
new SequenceProvider(map, modData, ts, map.SequenceDefinitions);
|
new SequenceProvider(fileSystem, modData, ts, mapSequences);
|
||||||
|
|
||||||
// TODO: Add support for custom voxel sequences
|
// TODO: Add support for custom voxel sequences
|
||||||
ruleset = new Ruleset(actors, weapons, voices, notifications, music, ts, sequences);
|
ruleset = new Ruleset(actors, weapons, voices, notifications, music, ts, sequences);
|
||||||
|
|||||||
@@ -295,7 +295,8 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Ruleset.LoadFromMap(modData, this);
|
return Ruleset.Load(modData, this, Tileset, RuleDefinitions, WeaponDefinitions,
|
||||||
|
VoiceDefinitions, NotificationDefinitions, MusicDefinitions, SequenceDefinitions);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -1190,7 +1191,6 @@ namespace OpenRA
|
|||||||
return FindTilesInAnnulus(center, 0, maxRange, allowOutsideBounds);
|
return FindTilesInAnnulus(center, 0, maxRange, allowOutsideBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Placeholders for future implementation
|
|
||||||
public Stream Open(string filename)
|
public Stream Open(string filename)
|
||||||
{
|
{
|
||||||
// Explicit package paths never refer to a map
|
// Explicit package paths never refer to a map
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public sealed class MapCache : IEnumerable<MapPreview>, IDisposable
|
public sealed class MapCache : IEnumerable<MapPreview>, IDisposable
|
||||||
{
|
{
|
||||||
public static readonly MapPreview UnknownMap = new MapPreview(null, MapGridType.Rectangular, null);
|
public static readonly MapPreview UnknownMap = new MapPreview(null, null, MapGridType.Rectangular, null);
|
||||||
public readonly IReadOnlyDictionary<IReadOnlyPackage, MapClassification> MapLocations;
|
public readonly IReadOnlyDictionary<IReadOnlyPackage, MapClassification> MapLocations;
|
||||||
|
|
||||||
readonly Cache<string, MapPreview> previews;
|
readonly Cache<string, MapPreview> previews;
|
||||||
@@ -41,7 +41,7 @@ namespace OpenRA
|
|||||||
this.modData = modData;
|
this.modData = modData;
|
||||||
|
|
||||||
var gridType = Exts.Lazy(() => modData.Manifest.Get<MapGrid>().Type);
|
var gridType = Exts.Lazy(() => modData.Manifest.Get<MapGrid>().Type);
|
||||||
previews = new Cache<string, MapPreview>(uid => new MapPreview(uid, gridType.Value, this));
|
previews = new Cache<string, MapPreview>(uid => new MapPreview(modData, uid, gridType.Value, this));
|
||||||
sheetBuilder = new SheetBuilder(SheetType.BGRA);
|
sheetBuilder = new SheetBuilder(SheetType.BGRA);
|
||||||
|
|
||||||
// Enumerate map directories
|
// Enumerate map directories
|
||||||
|
|||||||
@@ -53,10 +53,11 @@ namespace OpenRA
|
|||||||
public readonly bool downloading;
|
public readonly bool downloading;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MapPreview : IDisposable
|
public class MapPreview : IDisposable, IReadOnlyFileSystem
|
||||||
{
|
{
|
||||||
static readonly CPos[] NoSpawns = new CPos[] { };
|
static readonly CPos[] NoSpawns = new CPos[] { };
|
||||||
MapCache cache;
|
MapCache cache;
|
||||||
|
ModData modData;
|
||||||
|
|
||||||
public readonly string Uid;
|
public readonly string Uid;
|
||||||
public IReadOnlyPackage Package { get; private set; }
|
public IReadOnlyPackage Package { get; private set; }
|
||||||
@@ -65,6 +66,8 @@ namespace OpenRA
|
|||||||
public string Title { get; private set; }
|
public string Title { get; private set; }
|
||||||
public string Type { get; private set; }
|
public string Type { get; private set; }
|
||||||
public string Author { get; private set; }
|
public string Author { get; private set; }
|
||||||
|
public string TileSet { get; private set; }
|
||||||
|
public MapPlayers Players { get; private set; }
|
||||||
public int PlayerCount { get; private set; }
|
public int PlayerCount { get; private set; }
|
||||||
public CPos[] SpawnPoints { get; private set; }
|
public CPos[] SpawnPoints { get; private set; }
|
||||||
public MapGridType GridType { get; private set; }
|
public MapGridType GridType { get; private set; }
|
||||||
@@ -75,6 +78,10 @@ namespace OpenRA
|
|||||||
public MapVisibility Visibility { get; private set; }
|
public MapVisibility Visibility { get; private set; }
|
||||||
public bool SuitableForInitialMap { get; private set; }
|
public bool SuitableForInitialMap { get; private set; }
|
||||||
|
|
||||||
|
Lazy<Ruleset> rules;
|
||||||
|
public Ruleset Rules { get { return rules != null ? rules.Value : null; } }
|
||||||
|
public bool InvalidCustomRules { get; private set; }
|
||||||
|
|
||||||
Download download;
|
Download download;
|
||||||
public long DownloadBytes { get; private set; }
|
public long DownloadBytes { get; private set; }
|
||||||
public int DownloadPercentage { get; private set; }
|
public int DownloadPercentage { get; private set; }
|
||||||
@@ -101,9 +108,11 @@ namespace OpenRA
|
|||||||
generatingMinimap = false;
|
generatingMinimap = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapPreview(string uid, MapGridType gridType, MapCache cache)
|
public MapPreview(ModData modData, string uid, MapGridType gridType, MapCache cache)
|
||||||
{
|
{
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
|
this.modData = modData;
|
||||||
|
|
||||||
Uid = uid;
|
Uid = uid;
|
||||||
Title = "Unknown Map";
|
Title = "Unknown Map";
|
||||||
Type = "Unknown";
|
Type = "Unknown";
|
||||||
@@ -145,6 +154,8 @@ namespace OpenRA
|
|||||||
Title = temp.Value;
|
Title = temp.Value;
|
||||||
if (yaml.TryGetValue("Type", out temp))
|
if (yaml.TryGetValue("Type", out temp))
|
||||||
Type = temp.Value;
|
Type = temp.Value;
|
||||||
|
if (yaml.TryGetValue("Tileset", out temp))
|
||||||
|
TileSet = temp.Value;
|
||||||
if (yaml.TryGetValue("Author", out temp))
|
if (yaml.TryGetValue("Author", out temp))
|
||||||
Author = temp.Value;
|
Author = temp.Value;
|
||||||
if (yaml.TryGetValue("Bounds", out temp))
|
if (yaml.TryGetValue("Bounds", out temp))
|
||||||
@@ -188,9 +199,9 @@ namespace OpenRA
|
|||||||
MiniYaml playerDefinitions;
|
MiniYaml playerDefinitions;
|
||||||
if (yaml.TryGetValue("Players", out playerDefinitions))
|
if (yaml.TryGetValue("Players", out playerDefinitions))
|
||||||
{
|
{
|
||||||
var players = new MapPlayers(playerDefinitions.Nodes).Players;
|
Players = new MapPlayers(playerDefinitions.Nodes);
|
||||||
PlayerCount = players.Count(x => x.Value.Playable);
|
PlayerCount = Players.Players.Count(x => x.Value.Playable);
|
||||||
SuitableForInitialMap = EvaluateUserFriendliness(players);
|
SuitableForInitialMap = EvaluateUserFriendliness(Players.Players);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
@@ -198,11 +209,41 @@ namespace OpenRA
|
|||||||
Status = MapStatus.Unavailable;
|
Status = MapStatus.Unavailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rules = Exts.Lazy(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ruleDefinitions = LoadRuleSection(yaml, "Rules");
|
||||||
|
var weaponDefinitions = LoadRuleSection(yaml, "Weapons");
|
||||||
|
var voiceDefinitions = LoadRuleSection(yaml, "Voices");
|
||||||
|
var musicDefinitions = LoadRuleSection(yaml, "Music");
|
||||||
|
var notificationDefinitions = LoadRuleSection(yaml, "Notifications");
|
||||||
|
var sequenceDefinitions = LoadRuleSection(yaml, "Sequences");
|
||||||
|
return Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
|
||||||
|
voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
InvalidCustomRules = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ruleset.LoadDefaultsForTileSet(modData, TileSet);
|
||||||
|
});
|
||||||
|
|
||||||
if (p.Contains("map.png"))
|
if (p.Contains("map.png"))
|
||||||
using (var dataStream = p.GetStream("map.png"))
|
using (var dataStream = p.GetStream("map.png"))
|
||||||
Preview = new Bitmap(dataStream);
|
Preview = new Bitmap(dataStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MiniYaml LoadRuleSection(Dictionary<string, MiniYaml> yaml, string section)
|
||||||
|
{
|
||||||
|
MiniYaml node;
|
||||||
|
if (!yaml.TryGetValue(section, out node))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
bool EvaluateUserFriendliness(Dictionary<string, PlayerReference> players)
|
bool EvaluateUserFriendliness(Dictionary<string, PlayerReference> players)
|
||||||
{
|
{
|
||||||
if (Status != MapStatus.Available || !Visibility.HasFlag(MapVisibility.Lobby))
|
if (Status != MapStatus.Available || !Visibility.HasFlag(MapVisibility.Lobby))
|
||||||
@@ -367,5 +408,42 @@ namespace OpenRA
|
|||||||
if (deleteFromPackage != null)
|
if (deleteFromPackage != null)
|
||||||
deleteFromPackage.Delete(Package.Name);
|
deleteFromPackage.Delete(Package.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream IReadOnlyFileSystem.Open(string filename)
|
||||||
|
{
|
||||||
|
// Explicit package paths never refer to a map
|
||||||
|
if (!filename.Contains("|") && Package.Contains(filename))
|
||||||
|
return Package.GetStream(filename);
|
||||||
|
|
||||||
|
return modData.DefaultFileSystem.Open(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IReadOnlyFileSystem.TryGetPackageContaining(string path, out IReadOnlyPackage package, out string filename)
|
||||||
|
{
|
||||||
|
// Packages aren't supported inside maps
|
||||||
|
return modData.DefaultFileSystem.TryGetPackageContaining(path, out package, out filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IReadOnlyFileSystem.TryOpen(string filename, out Stream s)
|
||||||
|
{
|
||||||
|
// Explicit package paths never refer to a map
|
||||||
|
if (!filename.Contains("|"))
|
||||||
|
{
|
||||||
|
s = Package.GetStream(filename);
|
||||||
|
if (s != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modData.DefaultFileSystem.TryOpen(filename, out s);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IReadOnlyFileSystem.Exists(string filename)
|
||||||
|
{
|
||||||
|
// Explicit package paths never refer to a map
|
||||||
|
if (!filename.Contains("|") && Package.Contains(filename))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return modData.DefaultFileSystem.Exists(filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ namespace OpenRA.Server
|
|||||||
public List<string> TempBans = new List<string>();
|
public List<string> TempBans = new List<string>();
|
||||||
|
|
||||||
// Managed by LobbyCommands
|
// Managed by LobbyCommands
|
||||||
public Map Map;
|
public MapPreview Map;
|
||||||
public MapPlayers MapPlayers;
|
|
||||||
|
|
||||||
readonly int randomSeed;
|
readonly int randomSeed;
|
||||||
readonly TcpListener listener;
|
readonly TcpListener listener;
|
||||||
@@ -323,7 +322,7 @@ namespace OpenRA.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (client.Slot != null)
|
if (client.Slot != null)
|
||||||
SyncClientToPlayerReference(client, MapPlayers.Players[client.Slot]);
|
SyncClientToPlayerReference(client, Map.Players.Players[client.Slot]);
|
||||||
else
|
else
|
||||||
client.Color = HSLColor.FromRGB(255, 255, 255);
|
client.Color = HSLColor.FromRGB(255, 255, 255);
|
||||||
|
|
||||||
@@ -392,12 +391,12 @@ namespace OpenRA.Server
|
|||||||
SendOrderTo(newConn, "Message", motd);
|
SendOrderTo(newConn, "Message", motd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Map.RuleDefinitions != null && !LobbyInfo.IsSinglePlayer)
|
if (Map.Rules != ModData.DefaultRules && !LobbyInfo.IsSinglePlayer)
|
||||||
SendOrderTo(newConn, "Message", "This map contains custom rules. Game experience may change.");
|
SendOrderTo(newConn, "Message", "This map contains custom rules. Game experience may change.");
|
||||||
|
|
||||||
if (Settings.DisableSinglePlayer)
|
if (Settings.DisableSinglePlayer)
|
||||||
SendOrderTo(newConn, "Message", "Singleplayer games have been disabled on this server.");
|
SendOrderTo(newConn, "Message", "Singleplayer games have been disabled on this server.");
|
||||||
else if (MapPlayers.Players.Where(p => p.Value.Playable).All(p => !p.Value.AllowBots))
|
else if (Map.Players.Players.Where(p => p.Value.Playable).All(p => !p.Value.AllowBots))
|
||||||
SendOrderTo(newConn, "Message", "Bots have been disabled on this map.");
|
SendOrderTo(newConn, "Message", "Bots have been disabled on this map.");
|
||||||
|
|
||||||
if (handshake.Mod == "{DEV_VERSION}")
|
if (handshake.Mod == "{DEV_VERSION}")
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
client.SpawnPoint = 0;
|
client.SpawnPoint = 0;
|
||||||
|
|
||||||
client.Slot = s;
|
client.Slot = s;
|
||||||
S.SyncClientToPlayerReference(client, server.MapPlayers.Players[s]);
|
S.SyncClientToPlayerReference(client, server.Map.Players.Players[s]);
|
||||||
|
|
||||||
if (!slot.LockColor)
|
if (!slot.LockColor)
|
||||||
client.PreferredColor = client.Color = SanitizePlayerColor(server, client.Color, client.Index, conn);
|
client.PreferredColor = client.Color = SanitizePlayerColor(server, client.Color, client.Index, conn);
|
||||||
@@ -311,7 +311,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
var tileset = server.Map.Rules.TileSet;
|
var tileset = server.Map.Rules.TileSet;
|
||||||
var terrainColors = tileset.TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color);
|
var terrainColors = tileset.TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color);
|
||||||
var playerColors = server.LobbyInfo.Clients.Select(c => c.Color.RGB)
|
var playerColors = server.LobbyInfo.Clients.Select(c => c.Color.RGB)
|
||||||
.Concat(server.MapPlayers.Players.Values.Select(p => p.Color.RGB));
|
.Concat(server.Map.Players.Players.Values.Select(p => p.Color.RGB));
|
||||||
bot.Color = bot.PreferredColor = validator.RandomValidColor(server.Random, terrainColors, playerColors);
|
bot.Color = bot.PreferredColor = validator.RandomValidColor(server.Random, terrainColors, playerColors);
|
||||||
|
|
||||||
server.LobbyInfo.Clients.Add(bot);
|
server.LobbyInfo.Clients.Add(bot);
|
||||||
@@ -323,7 +323,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
bot.Bot = botType;
|
bot.Bot = botType;
|
||||||
}
|
}
|
||||||
|
|
||||||
S.SyncClientToPlayerReference(bot, server.MapPlayers.Players[parts[0]]);
|
S.SyncClientToPlayerReference(bot, server.Map.Players.Players[parts[0]]);
|
||||||
server.SyncLobbyClients();
|
server.SyncLobbyClients();
|
||||||
server.SyncLobbySlots();
|
server.SyncLobbySlots();
|
||||||
return true;
|
return true;
|
||||||
@@ -370,9 +370,9 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
if (c.Slot != null)
|
if (c.Slot != null)
|
||||||
{
|
{
|
||||||
// Remove Bot from slot if slot forbids bots
|
// Remove Bot from slot if slot forbids bots
|
||||||
if (c.Bot != null && !server.MapPlayers.Players[c.Slot].AllowBots)
|
if (c.Bot != null && !server.Map.Players.Players[c.Slot].AllowBots)
|
||||||
server.LobbyInfo.Clients.Remove(c);
|
server.LobbyInfo.Clients.Remove(c);
|
||||||
S.SyncClientToPlayerReference(c, server.MapPlayers.Players[c.Slot]);
|
S.SyncClientToPlayerReference(c, server.Map.Players.Players[c.Slot]);
|
||||||
}
|
}
|
||||||
else if (c.Bot != null)
|
else if (c.Bot != null)
|
||||||
server.LobbyInfo.Clients.Remove(c);
|
server.LobbyInfo.Clients.Remove(c);
|
||||||
@@ -387,12 +387,12 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
|
|
||||||
server.SendMessage("{0} changed the map to {1}.".F(client.Name, server.Map.Title));
|
server.SendMessage("{0} changed the map to {1}.".F(client.Name, server.Map.Title));
|
||||||
|
|
||||||
if (server.Map.RuleDefinitions != null)
|
if (server.Map.Rules.Actors != server.ModData.DefaultRules.Actors)
|
||||||
server.SendMessage("This map contains custom rules. Game experience may change.");
|
server.SendMessage("This map contains custom rules. Game experience may change.");
|
||||||
|
|
||||||
if (server.Settings.DisableSinglePlayer)
|
if (server.Settings.DisableSinglePlayer)
|
||||||
server.SendMessage("Singleplayer games have been disabled on this server.");
|
server.SendMessage("Singleplayer games have been disabled on this server.");
|
||||||
else if (server.MapPlayers.Players.Where(p => p.Value.Playable).All(p => !p.Value.AllowBots))
|
else if (server.Map.Players.Players.Where(p => p.Value.Playable).All(p => !p.Value.AllowBots))
|
||||||
server.SendMessage("Bots have been disabled on this map.");
|
server.SendMessage("Bots have been disabled on this map.");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -875,7 +875,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
|
|
||||||
int spawnPoint;
|
int spawnPoint;
|
||||||
if (!Exts.TryParseIntegerInvariant(parts[1], out spawnPoint)
|
if (!Exts.TryParseIntegerInvariant(parts[1], out spawnPoint)
|
||||||
|| spawnPoint < 0 || spawnPoint > server.Map.SpawnPoints.Value.Length)
|
|| spawnPoint < 0 || spawnPoint > server.Map.SpawnPoints.Length)
|
||||||
{
|
{
|
||||||
Log.Write("server", "Invalid spawn point: {0}", parts[1]);
|
Log.Write("server", "Invalid spawn point: {0}", parts[1]);
|
||||||
return true;
|
return true;
|
||||||
@@ -1013,28 +1013,28 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadMapSettings(Session.Global gs, Map map)
|
public static void LoadMapSettings(Session.Global gs, Ruleset rules)
|
||||||
{
|
{
|
||||||
var devMode = map.Rules.Actors["player"].TraitInfo<DeveloperModeInfo>();
|
var devMode = rules.Actors["player"].TraitInfo<DeveloperModeInfo>();
|
||||||
gs.AllowCheats = devMode.Enabled;
|
gs.AllowCheats = devMode.Enabled;
|
||||||
|
|
||||||
var crateSpawner = map.Rules.Actors["world"].TraitInfoOrDefault<CrateSpawnerInfo>();
|
var crateSpawner = rules.Actors["world"].TraitInfoOrDefault<CrateSpawnerInfo>();
|
||||||
gs.Crates = crateSpawner != null && crateSpawner.Enabled;
|
gs.Crates = crateSpawner != null && crateSpawner.Enabled;
|
||||||
|
|
||||||
var shroud = map.Rules.Actors["player"].TraitInfo<ShroudInfo>();
|
var shroud = rules.Actors["player"].TraitInfo<ShroudInfo>();
|
||||||
gs.Fog = shroud.FogEnabled;
|
gs.Fog = shroud.FogEnabled;
|
||||||
gs.Shroud = !shroud.ExploredMapEnabled;
|
gs.Shroud = !shroud.ExploredMapEnabled;
|
||||||
|
|
||||||
var resources = map.Rules.Actors["player"].TraitInfo<PlayerResourcesInfo>();
|
var resources = rules.Actors["player"].TraitInfo<PlayerResourcesInfo>();
|
||||||
gs.StartingCash = resources.DefaultCash;
|
gs.StartingCash = resources.DefaultCash;
|
||||||
|
|
||||||
var startingUnits = map.Rules.Actors["world"].TraitInfoOrDefault<SpawnMPUnitsInfo>();
|
var startingUnits = rules.Actors["world"].TraitInfoOrDefault<SpawnMPUnitsInfo>();
|
||||||
gs.StartingUnitsClass = startingUnits == null ? "none" : startingUnits.StartingUnitsClass;
|
gs.StartingUnitsClass = startingUnits == null ? "none" : startingUnits.StartingUnitsClass;
|
||||||
|
|
||||||
var mapBuildRadius = map.Rules.Actors["world"].TraitInfoOrDefault<MapBuildRadiusInfo>();
|
var mapBuildRadius = rules.Actors["world"].TraitInfoOrDefault<MapBuildRadiusInfo>();
|
||||||
gs.AllyBuildRadius = mapBuildRadius != null && mapBuildRadius.AllyBuildRadiusEnabled;
|
gs.AllyBuildRadius = mapBuildRadius != null && mapBuildRadius.AllyBuildRadiusEnabled;
|
||||||
|
|
||||||
var mapOptions = map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>();
|
var mapOptions = rules.Actors["world"].TraitInfo<MapOptionsInfo>();
|
||||||
gs.ShortGame = mapOptions.ShortGameEnabled;
|
gs.ShortGame = mapOptions.ShortGameEnabled;
|
||||||
gs.TechLevel = mapOptions.TechLevel;
|
gs.TechLevel = mapOptions.TechLevel;
|
||||||
gs.Difficulty = mapOptions.Difficulty ?? mapOptions.Difficulties.FirstOrDefault();
|
gs.Difficulty = mapOptions.Difficulty ?? mapOptions.Difficulties.FirstOrDefault();
|
||||||
@@ -1042,15 +1042,14 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
|
|
||||||
static void LoadMap(S server)
|
static void LoadMap(S server)
|
||||||
{
|
{
|
||||||
server.Map = new Map(server.ModData, server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map].Package);
|
server.Map = server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map];
|
||||||
|
|
||||||
server.MapPlayers = new MapPlayers(server.Map.PlayerDefinitions);
|
server.LobbyInfo.Slots = server.Map.Players.Players
|
||||||
server.LobbyInfo.Slots = server.MapPlayers.Players
|
|
||||||
.Select(p => MakeSlotFromPlayerReference(p.Value))
|
.Select(p => MakeSlotFromPlayerReference(p.Value))
|
||||||
.Where(s => s != null)
|
.Where(s => s != null)
|
||||||
.ToDictionary(s => s.PlayerReference, s => s);
|
.ToDictionary(s => s.PlayerReference, s => s);
|
||||||
|
|
||||||
LoadMapSettings(server.LobbyInfo.GlobalSettings, server.Map);
|
LoadMapSettings(server.LobbyInfo.GlobalSettings, server.Map.Rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HSLColor SanitizePlayerColor(S server, HSLColor askedColor, int playerIndex, Connection connectionToEcho = null)
|
static HSLColor SanitizePlayerColor(S server, HSLColor askedColor, int playerIndex, Connection connectionToEcho = null)
|
||||||
@@ -1067,7 +1066,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
var tileset = server.Map.Rules.TileSet;
|
var tileset = server.Map.Rules.TileSet;
|
||||||
var terrainColors = tileset.TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color).ToList();
|
var terrainColors = tileset.TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color).ToList();
|
||||||
var playerColors = server.LobbyInfo.Clients.Where(c => c.Index != playerIndex).Select(c => c.Color.RGB)
|
var playerColors = server.LobbyInfo.Clients.Where(c => c.Index != playerIndex).Select(c => c.Color.RGB)
|
||||||
.Concat(server.MapPlayers.Players.Values.Select(p => p.Color.RGB)).ToList();
|
.Concat(server.Map.Players.Players.Values.Select(p => p.Color.RGB)).ToList();
|
||||||
|
|
||||||
return validator.MakeValid(askColor.RGB, server.Random, terrainColors, playerColors, onError);
|
return validator.MakeValid(askColor.RGB, server.Random, terrainColors, playerColors, onError);
|
||||||
}
|
}
|
||||||
@@ -1086,7 +1085,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
if (slot == null)
|
if (slot == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return server.MapPlayers.Players[slot.PlayerReference];
|
return server.Map.Players.Players[slot.PlayerReference];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var defaults = new Session.Global();
|
var defaults = new Session.Global();
|
||||||
LobbyCommands.LoadMapSettings(defaults, server.Map);
|
LobbyCommands.LoadMapSettings(defaults, server.Map.Rules);
|
||||||
|
|
||||||
if (server.LobbyInfo.GlobalSettings.AllowCheats != defaults.AllowCheats)
|
if (server.LobbyInfo.GlobalSettings.AllowCheats != defaults.AllowCheats)
|
||||||
server.SendOrderTo(conn, "Message", "Allow Cheats: {0}".F(server.LobbyInfo.GlobalSettings.AllowCheats));
|
server.SendOrderTo(conn, "Message", "Allow Cheats: {0}".F(server.LobbyInfo.GlobalSettings.AllowCheats));
|
||||||
|
|||||||
@@ -43,11 +43,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
readonly ScrollPanelWidget missionList;
|
readonly ScrollPanelWidget missionList;
|
||||||
readonly ScrollItemWidget headerTemplate;
|
readonly ScrollItemWidget headerTemplate;
|
||||||
readonly ScrollItemWidget template;
|
readonly ScrollItemWidget template;
|
||||||
readonly Cache<MapPreview, Map> mapCache;
|
|
||||||
|
|
||||||
MapPreview selectedMapPreview;
|
|
||||||
Map selectedMap;
|
|
||||||
|
|
||||||
|
MapPreview selectedMap;
|
||||||
PlayingVideo playingVideo;
|
PlayingVideo playingVideo;
|
||||||
|
|
||||||
string difficulty;
|
string difficulty;
|
||||||
@@ -56,7 +53,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
public MissionBrowserLogic(Widget widget, ModData modData, World world, Action onStart, Action onExit)
|
public MissionBrowserLogic(Widget widget, ModData modData, World world, Action onStart, Action onExit)
|
||||||
{
|
{
|
||||||
mapCache = new Cache<MapPreview, Map>(p => new Map(modData, p.Package));
|
|
||||||
this.modData = modData;
|
this.modData = modData;
|
||||||
this.onStart = onStart;
|
this.onStart = onStart;
|
||||||
|
|
||||||
@@ -67,12 +63,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
var title = widget.GetOrNull<LabelWidget>("MISSIONBROWSER_TITLE");
|
var title = widget.GetOrNull<LabelWidget>("MISSIONBROWSER_TITLE");
|
||||||
if (title != null)
|
if (title != null)
|
||||||
title.GetText = () => playingVideo != PlayingVideo.None ? selectedMapPreview.Title : title.Text;
|
title.GetText = () => playingVideo != PlayingVideo.None ? selectedMap.Title : title.Text;
|
||||||
|
|
||||||
widget.Get("MISSION_INFO").IsVisible = () => selectedMapPreview != null;
|
widget.Get("MISSION_INFO").IsVisible = () => selectedMap != null;
|
||||||
|
|
||||||
var previewWidget = widget.Get<MapPreviewWidget>("MISSION_PREVIEW");
|
var previewWidget = widget.Get<MapPreviewWidget>("MISSION_PREVIEW");
|
||||||
previewWidget.Preview = () => selectedMapPreview;
|
previewWidget.Preview = () => selectedMap;
|
||||||
previewWidget.IsVisible = () => playingVideo == PlayingVideo.None;
|
previewWidget.IsVisible = () => playingVideo == PlayingVideo.None;
|
||||||
|
|
||||||
videoPlayer = widget.Get<VqaPlayerWidget>("MISSION_VIDEO");
|
videoPlayer = widget.Get<VqaPlayerWidget>("MISSION_VIDEO");
|
||||||
@@ -132,11 +128,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
if (allPreviews.Any())
|
if (allPreviews.Any())
|
||||||
SelectMap(allPreviews.First());
|
SelectMap(allPreviews.First());
|
||||||
|
|
||||||
// Preload map and preview data to reduce jank
|
// Preload map preview and rules to reduce jank
|
||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
{
|
{
|
||||||
foreach (var p in allPreviews)
|
foreach (var p in allPreviews)
|
||||||
modData.MapCache[mapCache[p].Uid].GetMinimap();
|
{
|
||||||
|
p.GetMinimap();
|
||||||
|
var unused = p.Rules;
|
||||||
|
}
|
||||||
}).Start();
|
}).Start();
|
||||||
|
|
||||||
var startButton = widget.Get<ButtonWidget>("STARTGAME_BUTTON");
|
var startButton = widget.Get<ButtonWidget>("STARTGAME_BUTTON");
|
||||||
@@ -163,7 +162,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
var preview = p;
|
var preview = p;
|
||||||
|
|
||||||
var item = ScrollItemWidget.Setup(template,
|
var item = ScrollItemWidget.Setup(template,
|
||||||
() => selectedMapPreview != null && selectedMapPreview.Uid == preview.Uid,
|
() => selectedMap != null && selectedMap.Uid == preview.Uid,
|
||||||
() => SelectMap(preview),
|
() => SelectMap(preview),
|
||||||
StartMissionClicked);
|
StartMissionClicked);
|
||||||
|
|
||||||
@@ -174,8 +173,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
void SelectMap(MapPreview preview)
|
void SelectMap(MapPreview preview)
|
||||||
{
|
{
|
||||||
selectedMap = mapCache[preview];
|
selectedMap = preview;
|
||||||
selectedMapPreview = preview;
|
|
||||||
|
|
||||||
// Cache the rules on a background thread to avoid jank
|
// Cache the rules on a background thread to avoid jank
|
||||||
var difficultyDisabled = true;
|
var difficultyDisabled = true;
|
||||||
@@ -189,17 +187,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
var infoVideoVisible = false;
|
var infoVideoVisible = false;
|
||||||
var infoVideoDisabled = true;
|
var infoVideoDisabled = true;
|
||||||
|
|
||||||
var map = selectedMap;
|
|
||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
{
|
{
|
||||||
map.PreloadRules();
|
var mapOptions = preview.Rules.Actors["world"].TraitInfo<MapOptionsInfo>();
|
||||||
var mapOptions = map.Rules.Actors["world"].TraitInfo<MapOptionsInfo>();
|
|
||||||
|
|
||||||
difficulty = mapOptions.Difficulty ?? mapOptions.Difficulties.FirstOrDefault();
|
difficulty = mapOptions.Difficulty ?? mapOptions.Difficulties.FirstOrDefault();
|
||||||
difficulties = mapOptions.Difficulties;
|
difficulties = mapOptions.Difficulties;
|
||||||
difficultyDisabled = mapOptions.DifficultyLocked || mapOptions.Difficulties.Length <= 1;
|
difficultyDisabled = mapOptions.DifficultyLocked || mapOptions.Difficulties.Length <= 1;
|
||||||
|
|
||||||
var missionData = map.Rules.Actors["world"].TraitInfoOrDefault<MissionDataInfo>();
|
var missionData = preview.Rules.Actors["world"].TraitInfoOrDefault<MissionDataInfo>();
|
||||||
if (missionData != null)
|
if (missionData != null)
|
||||||
{
|
{
|
||||||
briefingVideo = missionData.BriefingVideo;
|
briefingVideo = missionData.BriefingVideo;
|
||||||
@@ -214,7 +210,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
var height = descriptionFont.Measure(briefing).Y;
|
var height = descriptionFont.Measure(briefing).Y;
|
||||||
Game.RunAfterTick(() =>
|
Game.RunAfterTick(() =>
|
||||||
{
|
{
|
||||||
if (map == selectedMap)
|
if (preview == selectedMap)
|
||||||
{
|
{
|
||||||
description.Text = briefing;
|
description.Text = briefing;
|
||||||
description.Bounds.Height = height;
|
description.Bounds.Height = height;
|
||||||
@@ -348,11 +344,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
PlayVideo(fsPlayer, missionData.StartVideo, PlayingVideo.GameStart, () =>
|
PlayVideo(fsPlayer, missionData.StartVideo, PlayingVideo.GameStart, () =>
|
||||||
{
|
{
|
||||||
StopVideo(fsPlayer);
|
StopVideo(fsPlayer);
|
||||||
Game.CreateAndStartLocalServer(selectedMapPreview.Uid, orders, onStart);
|
Game.CreateAndStartLocalServer(selectedMap.Uid, orders, onStart);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Game.CreateAndStartLocalServer(selectedMapPreview.Uid, orders, onStart);
|
Game.CreateAndStartLocalServer(selectedMap.Uid, orders, onStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DropDownOption
|
class DropDownOption
|
||||||
|
|||||||
Reference in New Issue
Block a user