Skip to content

Commit

Permalink
Add play map button to map editor
Browse files Browse the repository at this point in the history
  • Loading branch information
PunkPun committed Jul 13, 2022
1 parent 911bc26 commit 47de5ca
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 29 deletions.
9 changes: 7 additions & 2 deletions OpenRA.Game/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static class Game
static bool takeScreenshot = false;
static Benchmark benchmark = null;

public static event Action OnShellmapLoaded = () => { };
public static Action<string> LoadMainMenuMap = _ => { };

public static OrderManager JoinServer(ConnectionTarget endpoint, string password, bool recordReplay = true)
{
Expand Down Expand Up @@ -508,12 +508,17 @@ public static void LoadEditor(string mapUid)
}

public static void LoadShellMap()
{
LoadShallmapLobby(null);
}

public static void LoadShallmapLobby(string map)
{
var shellmap = ChooseShellmap();
using (new PerfTimer("StartGame"))
{
StartGame(shellmap, WorldType.Shellmap);
OnShellmapLoaded();
LoadMainMenuMap(map);
}
}

Expand Down
84 changes: 77 additions & 7 deletions OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class IngameMenuLogic : ChromeLogic
bool leaving;
bool hideMenu;

public static bool LastGameEditor = false;

[ObjectCreator.UseCtor]
public IngameMenuLogic(Widget widget, ModData modData, World world, Action onExit, WorldRenderer worldRenderer,
IngameInfoPanel initialPanel, Dictionary<string, MiniYaml> logicArgs)
Expand All @@ -48,6 +50,7 @@ public class IngameMenuLogic : ChromeLogic

var buttonHandlers = new Dictionary<string, Action>
{
{ "BACK_TO_EDITOR", CreateBackToEditorButton },
{ "ABORT_MISSION", CreateAbortMissionButton },
{ "RESTART", CreateRestartButton },
{ "SURRENDER", CreateSurrenderButton },
Expand All @@ -57,6 +60,7 @@ public class IngameMenuLogic : ChromeLogic
{ "SETTINGS", CreateSettingsButton },
{ "RESUME", CreateResumeButton },
{ "SAVE_MAP", CreateSaveMapButton },
{ "PLAY_MAP", CreatePlayMapButton },
{ "EXIT_EDITOR", CreateExitEditorButton }
};

Expand Down Expand Up @@ -111,7 +115,7 @@ public class IngameMenuLogic : ChromeLogic
}
}

void OnQuit()
void OnQuit(string map)
{
// TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions
if (world.Type == WorldType.Regular)
Expand Down Expand Up @@ -146,7 +150,14 @@ void OnQuit()
Game.Disconnect();
Ui.ResetAll();
Game.LoadShellMap();
map = modData.MapCache.GetUpdatedMap(map);
if (map != null)
{
Game.Settings.Server.Map = map;
Game.Settings.Save();
}
Game.LoadShallmapLobby(map);
});
}

Expand Down Expand Up @@ -196,7 +207,7 @@ void CreateAbortMissionButton()
ConfirmationDialogs.ButtonPrompt(
title: "Leave Mission",
text: "Leave this game and return to the menu?",
onConfirm: OnQuit,
onConfirm: () => { OnQuit(null); },
onCancel: ShowMenu,
confirmText: "Leave",
cancelText: "Stay");
Expand Down Expand Up @@ -369,15 +380,74 @@ void CreateSaveMapButton()
Ui.OpenWindow("SAVE_MAP_PANEL", new WidgetArgs()
{
{ "onSave", (Action<string>)(_ => { hideMenu = false; actionManager.Modified = false; }) },
{ "onExit", () => hideMenu = false },
{ "onSave", (Action<string>)(_ => { actionManager.Modified = false; ShowMenu(); }) },
{ "onExit", () => ShowMenu() },
{ "map", world.Map },
{ "playerDefinitions", playerDefinitions },
{ "actorDefinitions", editorActorLayer.Save() }
});
};
}

void CreatePlayMapButton()
{
if (world.Type != WorldType.Editor)
return;

var actionManager = world.WorldActor.Trait<EditorActionManager>();

var button = AddButton("PLAY_MAP", "Play Map");
button.OnClick = () =>
{
hideMenu = true;
var uid = world.Map.Uid;
if (actionManager.HasUnsavedItems())
{
hideMenu = true;
ConfirmationDialogs.ButtonPrompt(
title: "Exit Map Editor",
text: "Exit and lose all unsaved changes?",
onConfirm: () => { LastGameEditor = true; OnQuit(uid); },
onCancel: ShowMenu);
}
else
{
LastGameEditor = true;
OnQuit(uid);
}
};

button.IsDisabled = () =>
{
var map = modData.MapCache[world.Map.Uid];
if (map.Status == MapStatus.Available && (map.Visibility == MapVisibility.Lobby || map.Visibility == MapVisibility.MissionSelector))
return false;
return true;
};
}

void CreateBackToEditorButton()
{
if (world.Type != WorldType.Regular || !LastGameEditor)
return;

var button = AddButton("BACK_TO_EDITOR", "Back To Editor");

button.OnClick = () =>
{
hideMenu = true;
ConfirmationDialogs.ButtonPrompt(
title: "Leave Mission",
text: "Leave this game and return to the editor?",
onConfirm: () => { Game.LoadEditor(Game.Settings.Server.Map); DiscordService.UpdateStatus(DiscordState.InMapEditor); },
onCancel: ShowMenu,
confirmText: "Back To Editor",
cancelText: "Stay");
};
}

void CreateExitEditorButton()
{
if (world.Type != WorldType.Editor)
Expand All @@ -395,11 +465,11 @@ void CreateExitEditorButton()
ConfirmationDialogs.ButtonPrompt(
title: "Exit Map Editor",
text: "Exit and lose all unsaved changes?",
onConfirm: OnQuit,
onConfirm: () => { OnQuit(null); },
onCancel: ShowMenu);
}
else
OnQuit();
OnQuit(null);
};
}
}
Expand Down
44 changes: 31 additions & 13 deletions OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ protected enum MenuPanel { None, Missions, Skirmish, Multiplayer, MapEditor, Rep
readonly ScrollPanelWidget newsPanel;
readonly Widget newsTemplate;
readonly LabelWidget newsStatus;
readonly ModData modData;

// Update news once per game launch
static bool fetchedNews;
Expand All @@ -52,6 +53,7 @@ void SwitchMenu(MenuType type)
[ObjectCreator.UseCtor]
public MainMenuLogic(Widget widget, World world, ModData modData)
{
this.modData = modData;
rootMenu = widget;
rootMenu.Get<LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;

Expand Down Expand Up @@ -92,7 +94,7 @@ public MainMenuLogic(Widget widget, World world, ModData modData)
singleplayerMenu.IsVisible = () => menuType == MenuType.Singleplayer;

var missionsButton = singleplayerMenu.Get<ButtonWidget>("MISSIONS_BUTTON");
missionsButton.OnClick = OpenMissionBrowserPanel;
missionsButton.OnClick = () => OpenMissionBrowserPanel(modData.MapCache.LastModifiedMap);

var hasCampaign = modData.Manifest.Missions.Length > 0;
var hasMissions = modData.MapCache
Expand All @@ -102,7 +104,7 @@ public MainMenuLogic(Widget widget, World world, ModData modData)

var hasMaps = modData.MapCache.Any(p => p.Visibility.HasFlag(MapVisibility.Lobby));
var skirmishButton = singleplayerMenu.Get<ButtonWidget>("SKIRMISH_BUTTON");
skirmishButton.OnClick = StartSkirmishGame;
skirmishButton.OnClick = () => StartSkirmishGame(modData.MapCache.LastModifiedMap);
skirmishButton.Disabled = !hasMaps;

var loadButton = singleplayerMenu.Get<ButtonWidget>("LOAD_BUTTON");
Expand Down Expand Up @@ -262,7 +264,7 @@ public MainMenuLogic(Widget widget, World world, ModData modData)
else
onIntroductionComplete();

Game.OnShellmapLoaded += OpenMenuBasedOnLastGame;
Game.LoadMainMenuMap = OpenMenuBasedOnLastGame;

DiscordService.UpdateStatus(DiscordState.InMenu);
}
Expand Down Expand Up @@ -431,9 +433,9 @@ void RemoveShellmapUI()
rootMenu.Parent.RemoveChild(rootMenu);
}

void StartSkirmishGame()
void StartSkirmishGame(string map)
{
var map = Game.ModData.MapCache.ChooseInitialMap(Game.Settings.Server.Map, Game.CosmeticRandom);
map = modData.MapCache.ChooseInitialMap(map ?? Game.ModData.MapCache.LastModifiedMap ?? Game.Settings.Server.Map, Game.CosmeticRandom);
Game.Settings.Server.Map = map;
Game.Settings.Save();

Expand All @@ -443,13 +445,14 @@ void StartSkirmishGame()
() => { Game.CloseServer(); SwitchMenu(MenuType.Main); });
}

void OpenMissionBrowserPanel()
void OpenMissionBrowserPanel(string map)
{
SwitchMenu(MenuType.None);
Game.OpenWindow("MISSIONBROWSER_PANEL", new WidgetArgs
{
{ "onExit", () => SwitchMenu(MenuType.Singleplayer) },
{ "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.Missions; } }
{ "onExit", () => { IngameMenuLogic.LastGameEditor = false; IngameMenuLogic.LastGameEditor = false; SwitchMenu(MenuType.Singleplayer); } },
{ "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.Missions; } },
{ "initialMap", map }
});
}

Expand All @@ -458,7 +461,7 @@ void OpenSkirmishLobbyPanel()
SwitchMenu(MenuType.None);
Game.OpenWindow("SERVER_LOBBY", new WidgetArgs
{
{ "onExit", () => { Game.Disconnect(); SwitchMenu(MenuType.Singleplayer); } },
{ "onExit", () => { IngameMenuLogic.LastGameEditor = false; IngameMenuLogic.LastGameEditor = false; Game.Disconnect(); SwitchMenu(MenuType.Singleplayer); } },
{ "onStart", () => { RemoveShellmapUI(); lastGameState = MenuPanel.Skirmish; } },
{ "skirmishMode", true }
});
Expand Down Expand Up @@ -505,24 +508,39 @@ protected override void Dispose(bool disposing)
Game.BeforeGameStart -= RemoveShellmapUI;
}

Game.OnShellmapLoaded -= OpenMenuBasedOnLastGame;
base.Dispose(disposing);
}

void OpenMenuBasedOnLastGame()
void OpenMenuBasedOnLastGame(string map)
{
// Used to select a map from foreign code via Game.LoadShellMap(string map)
if (map != null)
{
var m = Game.ModData.MapCache[map];
if (m.Visibility.HasFlag(MapVisibility.MissionSelector))
{
OpenMissionBrowserPanel(map);
return;
}
else if (m.Visibility.HasFlag(MapVisibility.Lobby))
{
StartSkirmishGame(map);
return;
}
}

switch (lastGameState)
{
case MenuPanel.Missions:
OpenMissionBrowserPanel();
OpenMissionBrowserPanel(map);
break;

case MenuPanel.Replays:
OpenReplayBrowserPanel();
break;

case MenuPanel.Skirmish:
StartSkirmishGame();
StartSkirmishGame(map);
break;

case MenuPanel.Multiplayer:
Expand Down
18 changes: 14 additions & 4 deletions OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ enum PlayingVideo { None, Info, Briefing, GameStart }
string gameSpeed;

[ObjectCreator.UseCtor]
public MissionBrowserLogic(Widget widget, ModData modData, World world, Action onStart, Action onExit)
public MissionBrowserLogic(Widget widget, ModData modData, World world, Action onStart, Action onExit, string initialMap)
{
this.modData = modData;
this.onStart = onStart;
Expand Down Expand Up @@ -136,7 +136,15 @@ public MissionBrowserLogic(Widget widget, ModData modData, World world, Action o
}

if (allPreviews.Count > 0)
SelectMap(allPreviews.First());
{
if (initialMap != null && modData.MapCache[initialMap].Status == MapStatus.Available && modData.MapCache[initialMap].Visibility.HasFlag(MapVisibility.MissionSelector))
{
SelectMap(modData.MapCache[initialMap]);
missionList.ScrollToSelectedItem();
}
else
SelectMap(allPreviews.First());
}

// Preload map preview to reduce jank
new Thread(() =>
Expand Down Expand Up @@ -181,7 +189,7 @@ protected override void Dispose(bool disposing)

void CreateMissionGroup(string title, IEnumerable<MapPreview> previews, Action onExit)
{
var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { });
var header = ScrollItemWidget.Setup(headerTemplate, () => false, () => { });
header.Get<LabelWidget>("LABEL").GetText = () => title;
missionList.AddChild(header);

Expand Down Expand Up @@ -370,14 +378,16 @@ void StartMissionClicked(Action onExit)
StopVideo(videoPlayer);

// If selected mission becomes unavailable, exit MissionBrowser to refresh
if (modData.MapCache[selectedMap.Uid].Status != MapStatus.Available)
var map = modData.MapCache.GetUpdatedMap(selectedMap.Uid);
if (map == null)
{
Game.Disconnect();
Ui.CloseWindow();
onExit();
return;
}

selectedMap = modData.MapCache[map];
var orders = new List<Order>();
if (difficulty != null)
orders.Add(Order.Command($"option difficulty {difficulty}"));
Expand Down
2 changes: 1 addition & 1 deletion mods/cnc/chrome/ingame-menu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Container@INGAME_MENU:
Width: WINDOW_RIGHT
Height: WINDOW_BOTTOM
Logic: IngameMenuLogic
Buttons: EXIT_EDITOR, SAVE_MAP, ABORT_MISSION, SURRENDER, RESTART, LOAD_GAME, SAVE_GAME, MUSIC, SETTINGS, RESUME
Buttons: EXIT_EDITOR, PLAY_MAP, SAVE_MAP, BACK_TO_EDITOR, ABORT_MISSION, SURRENDER, RESTART, LOAD_GAME, SAVE_GAME, MUSIC, SETTINGS, RESUME
ButtonStride: 130, 0
Children:
Image@EVA:
Expand Down
2 changes: 1 addition & 1 deletion mods/common/chrome/ingame-menu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Container@INGAME_MENU:
Width: WINDOW_RIGHT
Height: WINDOW_BOTTOM
Logic: IngameMenuLogic
Buttons: RESUME, LOAD_GAME, SAVE_GAME, SETTINGS, MUSIC, SURRENDER, RESTART, ABORT_MISSION, SAVE_MAP, EXIT_EDITOR
Buttons: RESUME, LOAD_GAME, SAVE_GAME, SETTINGS, MUSIC, SURRENDER, RESTART, ABORT_MISSION, BACK_TO_EDITOR, SAVE_MAP, PLAY_MAP, EXIT_EDITOR
ButtonStride: 0, 40
Children:
Background@BORDER:
Expand Down
2 changes: 1 addition & 1 deletion mods/d2k/chrome/ingame-menu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Container@INGAME_MENU:
Width: WINDOW_RIGHT
Height: WINDOW_BOTTOM
Logic: IngameMenuLogic
Buttons: RESUME, LOAD_GAME, SAVE_GAME, SETTINGS, MUSIC, SURRENDER, RESTART, ABORT_MISSION, SAVE_MAP, EXIT_EDITOR
Buttons: RESUME, LOAD_GAME, SAVE_GAME, SETTINGS, MUSIC, SURRENDER, RESTART, ABORT_MISSION, BACK_TO_EDITOR, SAVE_MAP, PLAY_MAP, EXIT_EDITOR
ButtonStride: 0, 40
Children:
Label@VERSION_LABEL:
Expand Down

0 comments on commit 47de5ca

Please sign in to comment.