213 lines
8.7 KiB
C#
213 lines
8.7 KiB
C#
using MenuChanger;
|
|
using MenuChanger.Extensions;
|
|
using MenuChanger.MenuElements;
|
|
using MenuChanger.MenuPanels;
|
|
using Modding;
|
|
using System;
|
|
using UnityEngine;
|
|
|
|
namespace Archipelago.HollowKnight.MC
|
|
{
|
|
internal class ArchipelagoModeMenuConstructor : ModeMenuConstructor
|
|
{
|
|
private MenuPage modeConfigPage;
|
|
|
|
private readonly static Type _settingsType = typeof(ConnectionDetails);
|
|
private readonly static Font _perpetua = CanvasUtil.GetFont("Perpetua");
|
|
|
|
public override void OnEnterMainMenu(MenuPage modeMenu)
|
|
{
|
|
modeConfigPage = new MenuPage("Archipelago Settings", modeMenu);
|
|
ConnectionDetails settings = ArchipelagoMod.Instance.GS.MenuConnectionDetails;
|
|
|
|
EntryField<string> urlField = CreateUrlField(modeConfigPage, settings);
|
|
NumericEntryField<int> portField = CreatePortField(modeConfigPage, settings);
|
|
EntryField<string> nameField = CreateSlotNameField(modeConfigPage, settings);
|
|
EntryField<string> passwordField = CreatePasswordField(modeConfigPage, settings);
|
|
|
|
MenuLabel errorLabel = new(modeConfigPage, "");
|
|
BigButton startButton = new(modeConfigPage, "Start", "May stall after clicking");
|
|
|
|
startButton.AddSetResumeKeyEvent("Archipelago");
|
|
startButton.OnClick += () => StartOrResumeGame(true, errorLabel);
|
|
|
|
modeConfigPage.AfterHide += () => errorLabel.Text.text = "";
|
|
|
|
IMenuElement[] elements =
|
|
[
|
|
urlField,
|
|
portField,
|
|
nameField,
|
|
passwordField,
|
|
startButton,
|
|
errorLabel
|
|
];
|
|
VerticalItemPanel vip = new(modeConfigPage, SpaceParameters.TOP_CENTER_UNDER_TITLE, 100, false, elements);
|
|
modeConfigPage.AddToNavigationControl(vip);
|
|
|
|
AttachResumePage();
|
|
}
|
|
|
|
private void AttachResumePage()
|
|
{
|
|
MenuPage resumePage = new("Archipelago Resume");
|
|
|
|
MenuLabel slotName = new(resumePage, "");
|
|
|
|
EntryField<string> urlField = CreateUrlField(resumePage, null);
|
|
NumericEntryField<int> portField = CreatePortField(resumePage, null);
|
|
EntryField<string> passwordField = CreatePasswordField(resumePage, null);
|
|
|
|
SmallButton resumeButton = new(resumePage, "Resume");
|
|
MenuLabel errorLabel = new(resumePage, "");
|
|
|
|
void RebindSettings()
|
|
{
|
|
ConnectionDetails settings = ArchipelagoMod.Instance.LS.ConnectionDetails;
|
|
if (settings != null)
|
|
{
|
|
slotName.Text.text = $"Slot Name: {settings.SlotName}";
|
|
urlField.Bind(settings, _settingsType.GetProperty(nameof(ConnectionDetails.ServerUrl)));
|
|
portField.Bind(settings, _settingsType.GetProperty(nameof(ConnectionDetails.ServerPort)));
|
|
passwordField.Bind(settings, _settingsType.GetProperty(nameof(ConnectionDetails.ServerPassword)));
|
|
}
|
|
else
|
|
{
|
|
slotName.Text.text = "Incompatible save file";
|
|
errorLabel.Text.text = "To resume, recreate your save or downgrade to an older client version.";
|
|
}
|
|
}
|
|
|
|
resumeButton.OnClick += () => StartOrResumeGame(false, errorLabel);
|
|
|
|
resumePage.BeforeShow += RebindSettings;
|
|
resumePage.AfterHide += () => errorLabel.Text.text = "";
|
|
|
|
IMenuElement[] elements =
|
|
[
|
|
slotName,
|
|
urlField,
|
|
portField,
|
|
passwordField,
|
|
resumeButton,
|
|
errorLabel
|
|
];
|
|
|
|
VerticalItemPanel vip = new(resumePage, SpaceParameters.TOP_CENTER_UNDER_TITLE, 100, true, elements);
|
|
resumePage.AddToNavigationControl(vip);
|
|
|
|
ResumeMenu.AddResumePage("Archipelago", resumePage);
|
|
}
|
|
|
|
private static EntryField<string> CreateUrlField(MenuPage apPage, ConnectionDetails settings)
|
|
{
|
|
EntryField<string> urlField = new(apPage, "Server URL: ");
|
|
urlField.InputField.characterLimit = 500;
|
|
RectTransform urlRect = urlField.InputField.gameObject.transform.Find("Text").GetComponent<RectTransform>();
|
|
urlRect.sizeDelta = new Vector2(1500f, 63.2f);
|
|
urlField.InputField.textComponent.font = _perpetua;
|
|
if (settings != null)
|
|
{
|
|
urlField.Bind(settings, _settingsType.GetProperty(nameof(ConnectionDetails.ServerUrl)));
|
|
}
|
|
return urlField;
|
|
}
|
|
|
|
private static NumericEntryField<int> CreatePortField(MenuPage apPage, ConnectionDetails settings)
|
|
{
|
|
NumericEntryField<int> portField = new(apPage, "Server Port: ");
|
|
portField.SetClamp(0, 65535);
|
|
portField.InputField.textComponent.font = _perpetua;
|
|
if (settings != null)
|
|
{
|
|
portField.Bind(settings, _settingsType.GetProperty(nameof(ConnectionDetails.ServerPort)));
|
|
}
|
|
return portField;
|
|
}
|
|
|
|
private static EntryField<string> CreateSlotNameField(MenuPage apPage, ConnectionDetails settings)
|
|
{
|
|
EntryField<string> nameField = new(apPage, "Slot Name: ");
|
|
nameField.InputField.characterLimit = 500;
|
|
nameField.InputField.textComponent.font = _perpetua;
|
|
RectTransform nameRect = nameField.InputField.gameObject.transform.Find("Text").GetComponent<RectTransform>();
|
|
nameRect.sizeDelta = new Vector2(1500f, 63.2f);
|
|
if (settings != null)
|
|
{
|
|
nameField.Bind(settings, _settingsType.GetProperty(nameof(ConnectionDetails.SlotName)));
|
|
}
|
|
return nameField;
|
|
}
|
|
|
|
private static EntryField<string> CreatePasswordField(MenuPage apPage, ConnectionDetails settings)
|
|
{
|
|
EntryField<string> passwordField = new(apPage, "Password: ");
|
|
passwordField.InputField.characterLimit = 500;
|
|
passwordField.InputField.textComponent.font = _perpetua;
|
|
RectTransform passwordRect = passwordField.InputField.gameObject.transform.Find("Text").GetComponent<RectTransform>();
|
|
passwordRect.sizeDelta = new Vector2(1500f, 63.2f);
|
|
if (settings != null)
|
|
{
|
|
passwordField.Bind(settings, _settingsType.GetProperty(nameof(ConnectionDetails.ServerPassword)));
|
|
}
|
|
return passwordField;
|
|
}
|
|
|
|
private static void StartOrResumeGame(bool newGame, MenuLabel errorLabel)
|
|
{
|
|
ArchipelagoMod.Instance.ArchipelagoEnabled = true;
|
|
|
|
// Cloning some settings onto others depending on what is taking precedence.
|
|
// If it's a save slot we're resuming (newGame == false) then we want the slot settings to overwrite the global ones.
|
|
if (newGame)
|
|
{
|
|
ArchipelagoMod.Instance.LS = new APLocalSettings()
|
|
{
|
|
ConnectionDetails = ArchipelagoMod.Instance.GS.MenuConnectionDetails with { },
|
|
};
|
|
}
|
|
else if (ArchipelagoMod.Instance.LS.ConnectionDetails != null)
|
|
{
|
|
ArchipelagoMod.Instance.GS.MenuConnectionDetails = ArchipelagoMod.Instance.LS.ConnectionDetails with { };
|
|
}
|
|
|
|
try
|
|
{
|
|
ArchipelagoMod.Instance.StartOrResumeGame(newGame);
|
|
MenuChangerMod.HideAllMenuPages();
|
|
if (newGame)
|
|
{
|
|
UIManager.instance.StartNewGame();
|
|
}
|
|
else
|
|
{
|
|
UIManager.instance.ContinueGame();
|
|
GameManager.instance.ContinueGame();
|
|
}
|
|
}
|
|
catch (LoginValidationException ex)
|
|
{
|
|
ArchipelagoMod.Instance.DisconnectArchipelago();
|
|
errorLabel.Text.text = ex.Message;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorLabel.Text.text = "An unknown error occurred when attempting to connect.";
|
|
ArchipelagoMod.Instance.LogError(ex);
|
|
ArchipelagoMod.Instance.DisconnectArchipelago();
|
|
}
|
|
}
|
|
|
|
public override void OnExitMainMenu()
|
|
{
|
|
modeConfigPage = null;
|
|
}
|
|
|
|
public override bool TryGetModeButton(MenuPage modeMenu, out BigButton button)
|
|
{
|
|
button = new BigButton(modeMenu, ArchipelagoMod.Instance.spriteManager.GetSprite("IconColorBig"), "Archipelago");
|
|
button.AddHideAndShowEvent(modeMenu, modeConfigPage);
|
|
return true;
|
|
}
|
|
}
|
|
} |