From fbf408b886befcbb052f9fd8d4e3c41b0df7f9c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 8 Mar 2014 06:57:56 +0100 Subject: [PATCH] add a spectator player that shares shroud with everyone closes #4607 --- CHANGELOG | 1 + OpenRA.FileFormats/Map/PlayerReference.cs | 1 + OpenRA.Game/Player.cs | 4 ++++ OpenRA.Mods.RA/ConquestVictoryConditions.cs | 6 +++--- OpenRA.Mods.RA/CreateMPPlayers.cs | 16 +++++++++++++++- .../Widgets/Logic/ObserverShroudSelectorLogic.cs | 13 +++++++------ 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ecf80cdea1..1f41cd0f84 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -22,6 +22,7 @@ NEW: Removed the ability of commandos to plant C4 on walls. Order lines are now shown on unit selection. Fixed chat synchronization in replays. + Added a combined shroud view of every player to the replay viewer and spectator mode. Fixed the game sometimes crashing when deploying and activating the guard cursor at the same time. Build time is now set when an item reaches the front of a queue, instead of immediately when queued. The attack cursor now changes if the target is out of range. diff --git a/OpenRA.FileFormats/Map/PlayerReference.cs b/OpenRA.FileFormats/Map/PlayerReference.cs index e9a56d4e09..a64d827a84 100644 --- a/OpenRA.FileFormats/Map/PlayerReference.cs +++ b/OpenRA.FileFormats/Map/PlayerReference.cs @@ -17,6 +17,7 @@ namespace OpenRA.FileFormats public bool OwnsWorld = false; public bool NonCombatant = false; public bool Playable = false; + public bool Spectating = false; public string Bot = null; public string StartingUnitsClass = null; public bool AllowBots = true; diff --git a/OpenRA.Game/Player.cs b/OpenRA.Game/Player.cs index 5d9648dd8a..2b9e36d4ab 100644 --- a/OpenRA.Game/Player.cs +++ b/OpenRA.Game/Player.cs @@ -30,6 +30,8 @@ namespace OpenRA public readonly string InternalName; public readonly CountryInfo Country; public readonly bool NonCombatant = false; + public readonly bool Spectating = false; + public readonly bool Playable = true; public readonly int ClientIndex; public readonly PlayerReference PlayerReference; public bool IsBot; @@ -70,6 +72,8 @@ namespace OpenRA Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; + Playable = pr.Playable; + Spectating = pr.Spectating; botType = pr.Bot; Country = ChooseCountry(world, pr.Race); } diff --git a/OpenRA.Mods.RA/ConquestVictoryConditions.cs b/OpenRA.Mods.RA/ConquestVictoryConditions.cs index fa903fdaa7..6119882048 100644 --- a/OpenRA.Mods.RA/ConquestVictoryConditions.cs +++ b/OpenRA.Mods.RA/ConquestVictoryConditions.cs @@ -36,13 +36,13 @@ namespace OpenRA.Mods.RA if (self.Owner.WinState != WinState.Undefined || self.Owner.NonCombatant) return; var hasAnything = self.World.ActorsWithTrait() - .Any( a => a.Actor.Owner == self.Owner ); + .Any(a => a.Actor.Owner == self.Owner); if (!hasAnything && !self.Owner.NonCombatant) Lose(self); - var others = self.World.Players.Where( p => !p.NonCombatant - && p != self.Owner && p.Stances[self.Owner] != Stance.Ally ); + var others = self.World.Players.Where(p => !p.NonCombatant + && p != self.Owner && p.Stances[self.Owner] != Stance.Ally); if (!others.Any()) return; diff --git a/OpenRA.Mods.RA/CreateMPPlayers.cs b/OpenRA.Mods.RA/CreateMPPlayers.cs index 02efe48fbc..455133e2f9 100644 --- a/OpenRA.Mods.RA/CreateMPPlayers.cs +++ b/OpenRA.Mods.RA/CreateMPPlayers.cs @@ -9,6 +9,7 @@ #endregion using System.Linq; +using OpenRA.FileFormats; using OpenRA.Network; using OpenRA.Traits; @@ -43,6 +44,15 @@ namespace OpenRA.Mods.RA w.SetLocalPlayer(player.InternalName); } + // create a player that is allied with everyone for shared observer shroud + w.AddPlayer(new Player(w, null, null, new PlayerReference + { + Name = "Everyone", + NonCombatant = true, + Spectating = true, + Allies = w.Players.Where(p => !p.NonCombatant && p.Playable).Select(p => p.InternalName).ToArray() + })); + foreach (var p in w.Players) foreach (var q in w.Players) if (!p.Stances.ContainsKey(q)) @@ -51,7 +61,11 @@ namespace OpenRA.Mods.RA static Stance ChooseInitialStance(Player p, Player q) { - if (p == q) return Stance.Ally; + if (p == q) + return Stance.Ally; + + if (q.Spectating && !p.NonCombatant && p.Playable) + return Stance.Ally; // Stances set via PlayerReference if (p.PlayerReference.Allies.Contains(q.InternalName)) diff --git a/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs index b623de83e6..51e19b1aba 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ObserverShroudSelectorLogic.cs @@ -32,17 +32,18 @@ namespace OpenRA.Mods.RA.Widgets.Logic static string LabelForPlayer(Player p) { - return p != null ? "{0}'s view".F(p.PlayerName) : "World view"; + return p != null ? p.PlayerName == "Everyone" ? "Combined view" : "{0}'s view".F(p.PlayerName) : "World view"; } [ObjectCreator.UseCtor] public ObserverShroudSelectorLogic(Widget widget, World world) { - var views = world.Players.Where(p => !p.NonCombatant).Concat(new[] { (Player)null }).Select( - p => new CameraOption(LabelForPlayer(p), - () => world.RenderPlayer == p, - () => world.RenderPlayer = p - )).ToArray(); + var views = world.Players.Where(p => (p.NonCombatant && p.Spectating) + || !p.NonCombatant).Concat(new[] { (Player)null }).Select( + p => new CameraOption(LabelForPlayer(p), + () => world.RenderPlayer == p, + () => world.RenderPlayer = p + )).ToArray(); var shroudSelector = widget.Get("SHROUD_SELECTOR"); shroudSelector.GetText = () => LabelForPlayer(world.RenderPlayer);