#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; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Scripting; using OpenRA.Mods.Common.Traits; using OpenRA.Traits; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic { public class IngameMenuLogic : ChromeLogic { Widget menu; [ObjectCreator.UseCtor] public IngameMenuLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer, IngameInfoPanel activePanel) { var leaving = false; menu = widget.Get("INGAME_MENU"); var mpe = world.WorldActor.TraitOrDefault(); if (mpe != null) mpe.Fade(mpe.Info.MenuEffect); menu.Get("VERSION_LABEL").Text = Game.ModData.Manifest.Mod.Version; var hideMenu = false; menu.Get("MENU_BUTTONS").IsVisible = () => !hideMenu; var scriptContext = world.WorldActor.TraitOrDefault(); var hasError = scriptContext != null && scriptContext.FatalErrorOccurred; // TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions Action onQuit = () => { if (world.Type == WorldType.Regular) Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", "Leave", world.LocalPlayer == null ? null : world.LocalPlayer.Faction.InternalName); leaving = true; var iop = world.WorldActor.TraitsImplementing().FirstOrDefault(); var exitDelay = iop != null ? iop.ExitDelay : 0; if (mpe != null) { Game.RunAfterDelay(exitDelay, () => { if (Game.IsCurrentWorld(world)) mpe.Fade(MenuPaletteEffect.EffectType.Black); }); exitDelay += 40 * mpe.Info.FadeLength; } Game.RunAfterDelay(exitDelay, () => { if (!Game.IsCurrentWorld(world)) return; Game.Disconnect(); Ui.ResetAll(); Game.LoadShellMap(); }); }; Action closeMenu = () => { Ui.CloseWindow(); if (mpe != null) mpe.Fade(MenuPaletteEffect.EffectType.None); onExit(); }; Action showMenu = () => hideMenu = false; var abortMissionButton = menu.Get("ABORT_MISSION"); abortMissionButton.IsVisible = () => world.Type == WorldType.Regular; abortMissionButton.IsDisabled = () => leaving; if (world.IsGameOver) abortMissionButton.GetText = () => "Leave"; abortMissionButton.OnClick = () => { hideMenu = true; if (world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Won) { Action restartAction = null; var iop = world.WorldActor.TraitsImplementing().FirstOrDefault(); var exitDelay = iop != null ? iop.ExitDelay : 0; if (world.LobbyInfo.IsSinglePlayer) { restartAction = () => { Ui.CloseWindow(); if (mpe != null) { if (Game.IsCurrentWorld(world)) mpe.Fade(MenuPaletteEffect.EffectType.Black); exitDelay += 40 * mpe.Info.FadeLength; } Game.RunAfterDelay(exitDelay, Game.RestartGame); }; } ConfirmationDialogs.PromptConfirmAction( title: "Leave Mission", text: "Leave this game and return to the menu?", onConfirm: onQuit, onCancel: showMenu, confirmText: "Leave", cancelText: "Stay", otherText: "Restart", onOther: restartAction); } else onQuit(); }; var exitEditorButton = menu.Get("EXIT_EDITOR"); exitEditorButton.IsVisible = () => world.Type == WorldType.Editor; exitEditorButton.OnClick = () => { hideMenu = true; ConfirmationDialogs.PromptConfirmAction( title: "Exit Map Editor", text: "Exit and lose all unsaved changes?", onConfirm: onQuit, onCancel: showMenu); }; Action onSurrender = () => { world.IssueOrder(new Order("Surrender", world.LocalPlayer.PlayerActor, false)); closeMenu(); }; var surrenderButton = menu.Get("SURRENDER"); surrenderButton.IsVisible = () => world.Type == WorldType.Regular; surrenderButton.IsDisabled = () => world.LocalPlayer == null || world.LocalPlayer.WinState != WinState.Undefined || world.Map.Visibility.HasFlag(MapVisibility.MissionSelector) || hasError; surrenderButton.OnClick = () => { hideMenu = true; ConfirmationDialogs.PromptConfirmAction( title: "Surrender", text: "Are you sure you want to surrender?", onConfirm: onSurrender, onCancel: showMenu, confirmText: "Surrender", cancelText: "Stay"); }; var saveMapButton = menu.Get("SAVE_MAP"); saveMapButton.IsVisible = () => world.Type == WorldType.Editor; saveMapButton.OnClick = () => { hideMenu = true; var editorActorLayer = world.WorldActor.Trait(); Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs() { { "onSave", (Action)(_ => hideMenu = false) }, { "onExit", () => hideMenu = false }, { "map", world.Map }, { "playerDefinitions", editorActorLayer.Players.ToMiniYaml() }, { "actorDefinitions", editorActorLayer.Save() } }); }; var musicButton = menu.Get("MUSIC"); musicButton.IsDisabled = () => leaving; musicButton.OnClick = () => { hideMenu = true; Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs() { { "onExit", () => hideMenu = false }, { "world", world } }); }; var settingsButton = widget.Get("SETTINGS"); settingsButton.IsDisabled = () => leaving; settingsButton.OnClick = () => { hideMenu = true; Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs() { { "world", world }, { "worldRenderer", worldRenderer }, { "onExit", () => hideMenu = false }, }); }; var resumeButton = menu.Get("RESUME"); resumeButton.IsDisabled = () => leaving; if (world.IsGameOver) resumeButton.GetText = () => "Return to map"; resumeButton.OnClick = closeMenu; var panelRoot = widget.GetOrNull("PANEL_ROOT"); if (panelRoot != null && world.Type != WorldType.Editor) { var gameInfoPanel = Game.LoadWidget(world, "GAME_INFO_PANEL", panelRoot, new WidgetArgs() { { "activePanel", activePanel } }); gameInfoPanel.IsVisible = () => !hideMenu; } } } }