From c8f2ee5270d5c8ca195b5b1b1c8a499bf9e1de91 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 20 Apr 2019 11:01:55 +0000 Subject: [PATCH] Save and load skirmish spectator viewport. --- .../Traits/World/GameSaveViewportManager.cs | 29 +++++++++++++++---- .../Ingame/ObserverShroudSelectorLogic.cs | 21 ++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/World/GameSaveViewportManager.cs b/OpenRA.Mods.Common/Traits/World/GameSaveViewportManager.cs index 39705f1e2b..4ba112c44e 100644 --- a/OpenRA.Mods.Common/Traits/World/GameSaveViewportManager.cs +++ b/OpenRA.Mods.Common/Traits/World/GameSaveViewportManager.cs @@ -29,25 +29,44 @@ namespace OpenRA.Mods.Common.Traits List IGameSaveTraitData.IssueTraitData(Actor self) { - if (worldRenderer.World.LocalPlayer == null || self != worldRenderer.World.LocalPlayer.PlayerActor) + // HACK: Store the viewport state for the skirmish observer on the first bot's trait + // TODO: This won't make sense for MP saves + var localPlayer = worldRenderer.World.LocalPlayer; + if ((localPlayer != null && localPlayer.PlayerActor != self) || + self.Owner != self.World.Players.FirstOrDefault(p => p.IsBot)) return null; - return new List() + var nodes = new List() { - new MiniYamlNode("Viewport", FieldSaver.FormatValue(worldRenderer.Viewport.CenterPosition)), - new MiniYamlNode("Selection", "", self.World.Selection.Serialize()) + new MiniYamlNode("Viewport", FieldSaver.FormatValue(worldRenderer.Viewport.CenterPosition)) }; + + var renderPlayer = worldRenderer.World.RenderPlayer; + if (localPlayer == null && renderPlayer != null) + nodes.Add(new MiniYamlNode("RenderPlayer", FieldSaver.FormatValue(renderPlayer.PlayerActor.ActorID))); + + if (localPlayer != null && localPlayer.PlayerActor == self) + nodes.Add(new MiniYamlNode("Selection", "", self.World.Selection.Serialize())); + + return nodes; } void IGameSaveTraitData.ResolveTraitData(Actor self, List data) { var viewportNode = data.FirstOrDefault(n => n.Key == "Viewport"); if (viewportNode != null) - worldRenderer.Viewport.Center(FieldLoader.GetValue("data", viewportNode.Value.Value)); + worldRenderer.Viewport.Center(FieldLoader.GetValue("Viewport", viewportNode.Value.Value)); var selectionNode = data.FirstOrDefault(n => n.Key == "Selection"); if (selectionNode != null) self.World.Selection.Deserialize(self.World, selectionNode.Value.Nodes); + + var renderPlayerNode = data.FirstOrDefault(n => n.Key == "RenderPlayer"); + if (renderPlayerNode != null) + { + var renderPlayerActorID = FieldLoader.GetValue("RenderPlayer", renderPlayerNode.Value.Value); + worldRenderer.World.RenderPlayer = worldRenderer.World.GetActorById(renderPlayerActorID).Owner; + } } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs index 0b461613a7..1758d15fdc 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ObserverShroudSelectorLogic.cs @@ -29,6 +29,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly HotkeyReference combinedViewKey = new HotkeyReference(); readonly HotkeyReference worldViewKey = new HotkeyReference(); + readonly World world; + CameraOption selected; class CameraOption @@ -64,6 +66,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic [ObjectCreator.UseCtor] public ObserverShroudSelectorLogic(Widget widget, ModData modData, World world, Dictionary logicArgs) { + this.world = world; + MiniYaml yaml; if (logicArgs.TryGetValue("CombinedViewKey", out yaml)) combinedViewKey = modData.Hotkeys[yaml.Value]; @@ -182,5 +186,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic return false; } + + public override void Tick() + { + // Fix the selector if something else has changed the render player + if (selected != null && world.RenderPlayer != selected.Player) + { + if (combined.Player == world.RenderPlayer) + combined.OnClick(); + else if (disableShroud.Player == world.RenderPlayer) + disableShroud.OnClick(); + else + foreach (var group in teams) + foreach (var option in group) + if (option.Player == world.RenderPlayer) + option.OnClick(); + } + } } }