diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index f6f03ced2a..4cacd3392d 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -38,9 +38,14 @@ namespace OpenRA public readonly MersenneTwister SharedRandom; - public readonly List Players = new List(); + public Player[] Players = new Player[0]; + + public void SetPlayers(IEnumerable players, Player localPlayer) + { + Players = players.ToArray(); + SetLocalPlayer(localPlayer); + } - public void AddPlayer(Player p) { Players.Add(p); } public Player LocalPlayer { get; private set; } public event Action GameOver = () => { }; @@ -82,12 +87,18 @@ namespace OpenRA get { return LobbyInfo.GlobalSettings.AllowCheats || LobbyInfo.IsSinglePlayer; } } - public void SetLocalPlayer(string pr) + void SetLocalPlayer(Player localPlayer) { + if (localPlayer == null) + return; + + if (!Players.Contains(localPlayer)) + throw new ArgumentException("The local player must be one of the players in the world.", "localPlayer"); + if (IsReplay) return; - LocalPlayer = Players.FirstOrDefault(p => p.InternalName == pr); + LocalPlayer = localPlayer; RenderPlayer = LocalPlayer; } diff --git a/OpenRA.Mods.Common/Traits/World/CreateMPPlayers.cs b/OpenRA.Mods.Common/Traits/World/CreateMPPlayers.cs index 1f24e02b94..53d950cddd 100644 --- a/OpenRA.Mods.Common/Traits/World/CreateMPPlayers.cs +++ b/OpenRA.Mods.Common/Traits/World/CreateMPPlayers.cs @@ -8,6 +8,7 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Network; using OpenRA.Traits; @@ -22,16 +23,19 @@ namespace OpenRA.Mods.Common.Traits public void CreatePlayers(World w) { var players = new MapPlayers(w.Map.PlayerDefinitions).Players; + var worldPlayers = new List(); // Create the unplayable map players -- neutral, shellmap, scripted, etc. foreach (var kv in players.Where(p => !p.Value.Playable)) { var player = new Player(w, null, kv.Value); - w.AddPlayer(player); + worldPlayers.Add(player); if (kv.Value.OwnsWorld) w.WorldActor.Owner = player; } + Player localPlayer = null; + // Create the regular playable players. foreach (var kv in w.LobbyInfo.Slots) { @@ -40,22 +44,24 @@ namespace OpenRA.Mods.Common.Traits continue; var player = new Player(w, client, players[kv.Value.PlayerReference]); - w.AddPlayer(player); + worldPlayers.Add(player); if (client.Index == Game.LocalClientId) - w.SetLocalPlayer(player.InternalName); + localPlayer = player; } // Create a player that is allied with everyone for shared observer shroud. - w.AddPlayer(new Player(w, null, new PlayerReference + worldPlayers.Add(new Player(w, null, new PlayerReference { Name = "Everyone", NonCombatant = true, Spectating = true, Faction = "Random", - Allies = w.Players.Where(p => !p.NonCombatant && p.Playable).Select(p => p.InternalName).ToArray() + Allies = worldPlayers.Where(p => !p.NonCombatant && p.Playable).Select(p => p.InternalName).ToArray() })); + w.SetPlayers(worldPlayers, localPlayer); + foreach (var p in w.Players) foreach (var q in w.Players) if (!p.Stances.ContainsKey(q)) diff --git a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs index ff64e6a07f..940ebbb612 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs @@ -164,10 +164,7 @@ namespace OpenRA.Mods.Common.Traits var index = int.Parse(name.Substring(5)); if (index >= newCount) - { Players.Players.Remove(name); - worldRenderer.World.Players.RemoveAll(pp => pp.InternalName == name); - } } for (var index = 0; index < newCount; index++)