Merge pull request #7875 from penev92/bleed_exposePlayerReferences

Add upgrade rules support for map PlayerReferences
This commit is contained in:
abcdefg30
2015-04-26 22:53:42 +02:00
17 changed files with 181 additions and 117 deletions

View File

@@ -9,7 +9,6 @@
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
@@ -224,12 +223,9 @@ namespace OpenRA
[FieldLoader.Ignore] public Lazy<Dictionary<string, ActorReference>> Actors;
public int PlayerCount { get { return Players.Count(p => p.Value.Playable); } }
public Rectangle Bounds;
// Yaml map data
[FieldLoader.Ignore] public Dictionary<string, PlayerReference> Players = new Dictionary<string, PlayerReference>();
[FieldLoader.Ignore] public Lazy<List<SmudgeReference>> Smudges;
[FieldLoader.Ignore] public List<MiniYamlNode> RuleDefinitions = new List<MiniYamlNode>();
@@ -239,6 +235,7 @@ namespace OpenRA
[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>();
[FieldLoader.Ignore] public List<MiniYamlNode> PlayerDefinitions = new List<MiniYamlNode>();
// Binary map data
[FieldLoader.Ignore] public byte TileFormat = 2;
@@ -348,13 +345,6 @@ namespace OpenRA
Visibility = MapVisibility.MissionSelector;
}
// Load players
foreach (var my in nd["Players"].ToDictionary().Values)
{
var player = new PlayerReference(my);
Players.Add(player.Name, player);
}
Actors = Exts.Lazy(() =>
{
var ret = new Dictionary<string, ActorReference>();
@@ -387,10 +377,11 @@ namespace OpenRA
VoiceDefinitions = MiniYaml.NodesOrEmpty(yaml, "Voices");
NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications");
TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations");
PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
MapTiles = Exts.Lazy(() => LoadMapTiles());
MapResources = Exts.Lazy(() => LoadResourceTiles());
MapHeight = Exts.Lazy(() => LoadMapHeight());
MapTiles = Exts.Lazy(LoadMapTiles);
MapResources = Exts.Lazy(LoadResourceTiles);
MapHeight = Exts.Lazy(LoadMapHeight);
TileShape = Game.ModData.Manifest.TileShape;
SubCellOffsets = Game.ModData.Manifest.SubCellOffsets;
@@ -496,8 +487,7 @@ namespace OpenRA
root.Add(new MiniYamlNode("Options", FieldSaver.SaveDifferences(Options, new MapOptions())));
root.Add(new MiniYamlNode("Players", null,
Players.Select(p => new MiniYamlNode("PlayerReference@{0}".F(p.Key), FieldSaver.SaveDifferences(p.Value, new PlayerReference()))).ToList()));
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()));
@@ -768,45 +758,6 @@ namespace OpenRA
}
}
public void MakeDefaultPlayers()
{
var firstRace = Rules.Actors["world"].Traits
.WithInterface<CountryInfo>().First(c => c.Selectable).Race;
if (!Players.ContainsKey("Neutral"))
Players.Add("Neutral", new PlayerReference
{
Name = "Neutral",
Race = firstRace,
OwnsWorld = true,
NonCombatant = true
});
var numSpawns = GetSpawnPoints().Length;
for (var index = 0; index < numSpawns; index++)
{
if (Players.ContainsKey("Multi{0}".F(index)))
continue;
var p = new PlayerReference
{
Name = "Multi{0}".F(index),
Race = "Random",
Playable = true,
Enemies = new[] { "Creeps" }
};
Players.Add(p.Name, p);
}
Players.Add("Creeps", new PlayerReference
{
Name = "Creeps",
Race = firstRace,
NonCombatant = true,
Enemies = Players.Where(p => p.Value.Playable).Select(p => p.Key).ToArray()
});
}
public void FixOpenAreas(Ruleset rules)
{
var r = new Random();

View File

@@ -0,0 +1,75 @@
#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
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA
{
public class MapPlayers
{
public readonly Dictionary<string, PlayerReference> Players;
public MapPlayers() : this(new List<MiniYamlNode>()) { }
public MapPlayers(IEnumerable<MiniYamlNode> playerDefinitions)
{
Players = playerDefinitions.Select(pr => new PlayerReference(new MiniYaml(pr.Key, pr.Value.Nodes)))
.ToDictionary(player => player.Name);
}
public MapPlayers(Ruleset rules, int playerCount)
{
var firstRace = rules.Actors["world"].Traits
.WithInterface<CountryInfo>().First(c => c.Selectable).Race;
Players = new Dictionary<string, PlayerReference>
{
{
"Neutral", new PlayerReference
{
Name = "Neutral",
Race = firstRace,
OwnsWorld = true,
NonCombatant = true
}
},
{
"Creeps", new PlayerReference
{
Name = "Creeps",
Race = firstRace,
NonCombatant = true,
Enemies = Exts.MakeArray(playerCount, i => "Multi{0}".F(i))
}
}
};
for (var index = 0; index < playerCount; index++)
{
var p = new PlayerReference
{
Name = "Multi{0}".F(index),
Race = "Random",
Playable = true,
Enemies = new[] { "Creeps" }
};
Players.Add(p.Name, p);
}
}
public List<MiniYamlNode> ToMiniYaml()
{
return Players.Select(p => new MiniYamlNode("PlayerReference@{0}".F(p.Key),
FieldSaver.SaveDifferences(p.Value, new PlayerReference()))).ToList();
}
}
}

View File

@@ -67,6 +67,7 @@ namespace OpenRA
public Map Map { get; private set; }
public MapStatus Status { get; private set; }
public MapClassification Class { get; private set; }
public bool SuitableForInitialMap { get; private set; }
public MapRuleStatus RuleStatus { get; private set; }
@@ -117,12 +118,36 @@ namespace OpenRA
Type = m.Type;
Type = m.Type;
Author = m.Author;
PlayerCount = m.Players.Count(x => x.Value.Playable);
Bounds = m.Bounds;
SpawnPoints = m.GetSpawnPoints();
CustomPreview = m.CustomPreview;
Status = MapStatus.Available;
Class = classification;
var players = new MapPlayers(m.PlayerDefinitions).Players;
PlayerCount = players.Count(x => x.Value.Playable);
SuitableForInitialMap = EvaluateUserFriendliness(players);
}
bool EvaluateUserFriendliness(Dictionary<string, PlayerReference> players)
{
if (Status != MapStatus.Available || !Map.Visibility.HasFlag(MapVisibility.Lobby))
return false;
// Other map types may have confusing settings or gameplay
if (Type != "Conquest")
return false;
// Maps with bots disabled confuse new players
if (players.Any(x => !x.Value.AllowBots))
return false;
// Large maps expose unfortunate performance problems
if (Bounds.Width > 128 || Bounds.Height > 128)
return false;
return true;
}
public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml)