From 3599e228f19d5ad6ae4f33246507083e250ada75 Mon Sep 17 00:00:00 2001 From: Maksym Muraviov$ Date: Sun, 7 Jun 2026 22:30:50 +0200 Subject: [PATCH 1/7] feat: updated to the new ui update --- PolyMod.csproj | 4 +- src/Managers/AutoUpdate.cs | 19 +- src/Managers/Compatibility.cs | 46 +++-- src/Managers/Hub.cs | 360 ++++++++++++++++++---------------- src/Managers/Main.cs | 1 - src/Managers/Visual.cs | 30 +-- 6 files changed, 243 insertions(+), 217 deletions(-) diff --git a/PolyMod.csproj b/PolyMod.csproj index a09c089..54dc82f 100644 --- a/PolyMod.csproj +++ b/PolyMod.csproj @@ -11,8 +11,8 @@ IL2CPP PolyMod - 1.2.13 - 2.16.8.15757 + 1.2.14 + 2.17.0.16256 PolyModdingTeam The Battle of Polytopia's mod loader. IDE0130 diff --git a/src/Managers/AutoUpdate.cs b/src/Managers/AutoUpdate.cs index 1f94fb8..c903510 100644 --- a/src/Managers/AutoUpdate.cs +++ b/src/Managers/AutoUpdate.cs @@ -3,6 +3,7 @@ using System.Text.Json; using HarmonyLib; using UnityEngine; +using static PopupManager; namespace PolyMod.Managers; @@ -15,8 +16,8 @@ internal static class AutoUpdate /// Checks for updates when the start screen is shown. /// [HarmonyPostfix] - [HarmonyPatch(typeof(StartScreen), nameof(StartScreen.Start))] - private static void StartScreen_Start() + [HarmonyPatch(typeof(StartScreen_UI2), nameof(StartScreen_UI2.OnShow))] + private static void StartScreen_UI2_OnShow() { if (!Plugin.config.autoUpdate) return; if (Environment.GetEnvironmentVariable("WINEPREFIX") != null) @@ -154,17 +155,19 @@ exit 0 } // Show a popup to the user asking if they want to update - PopupManager.GetBasicPopup(new( - Localization.Get("polymod.autoupdate"), - Localization.Get("polymod.autoupdate.description"), - new(new PopupBase.PopupButtonData[] { + BasicPopup popup = PopupManager.GetBasicPopup(); + popup.Header = Localization.Get("polymod.autoupdate"); + popup.Description = Localization.Get("polymod.autoupdate.description"); + popup.buttonData = new PopupBase.PopupButtonData[] { new( "polymod.autoupdate.update", PopupBase.PopupButtonData.States.None, (Il2CppSystem.Action)Update ) - })) - ).Show(); + }; + + popup.Show(); + } catch (Exception e) { diff --git a/src/Managers/Compatibility.cs b/src/Managers/Compatibility.cs index 4d42033..28e17d2 100644 --- a/src/Managers/Compatibility.cs +++ b/src/Managers/Compatibility.cs @@ -34,7 +34,7 @@ public static void HashSignatures(StringBuilder checksumString) /// Checks the signature of a saved game to ensure it is compatible with the current mods. /// /// True if the signatures match or if the check is ignored, false otherwise. - private static bool CheckSignatures(Action action, int id, BaseEventData eventData, Il2CppSystem.Guid gameId) + private static bool CheckSignatures(Action action, Il2CppSystem.Guid gameId) { if (sawSignatureWarning) { @@ -67,13 +67,15 @@ private static bool CheckSignatures(Action action, int id, B } if (!doChecksumsMatch) { - PopupManager.GetBasicPopup(new( - Localization.Get("polymod.signature.mismatch"), - Localization.Get("polymod.signature.incompatible"), - new(new PopupBase.PopupButtonData[] { - new("OK") - }) - )).Show(); + BasicPopup popup = PopupManager.GetBasicPopup(); + popup.Header = Localization.Get("polymod.signature.mismatch"); + popup.Description = Localization.Get("polymod.signature.incompatible"); + popup.buttonData = new PopupBase.PopupButtonData[] { + new("OK") + }; + + popup.Show(); + return false; } return true; @@ -83,8 +85,8 @@ private static bool CheckSignatures(Action action, int id, B /// Performs compatibility checks when the start screen is shown. /// [HarmonyPostfix] - [HarmonyPatch(typeof(StartScreen), nameof(StartScreen.Start))] - private static void StartScreen_Start() + [HarmonyPatch(typeof(StartScreen_UI2), nameof(StartScreen_UI2.OnShow))] + private static void StartScreen_UI2_OnShow() { string lastChecksum = checksum; try @@ -113,10 +115,11 @@ private static void StartScreen_Start() VersionManager.SemanticVersion.Cast().CutRevision().ToString() ); PlayerPrefs.Save(); - PopupManager.GetBasicPopup(new( - Localization.Get("polymod.version.mismatch"), - Localization.Get("polymod.version.mismatch.description"), - new(new PopupBase.PopupButtonData[] { + + BasicPopup popup = PopupManager.GetBasicPopup(); + popup.Header = Localization.Get("polymod.version.mismatch"); + popup.Description = Localization.Get("polymod.version.mismatch.description"); + popup.buttonData = new PopupBase.PopupButtonData[] { new("buttons.stay", customColorStates: ColorConstants.redButtonColorStates), new( "buttons.exitgame", @@ -124,8 +127,9 @@ private static void StartScreen_Start() (Il2CppSystem.Action)Application.Quit, closesPopup: false ) - })) - ).Show(); + }; + + popup.Show(); } } @@ -134,19 +138,19 @@ private static void StartScreen_Start() /// [HarmonyPrefix] [HarmonyPatch(typeof(GameInfoPopup), nameof(GameInfoPopup.OnMainButtonClicked))] - private static bool GameInfoPopup_OnMainButtonClicked(GameInfoPopup __instance, int id, BaseEventData eventData) + private static bool GameInfoPopup_OnMainButtonClicked(GameInfoPopup __instance) { - return CheckSignatures(__instance.OnMainButtonClicked, id, eventData, __instance.gameId); + return CheckSignatures(__instance.OnMainButtonClicked, __instance.gameId); } /// /// Checks the signature of a single-player game before resuming it. /// [HarmonyPrefix] - [HarmonyPatch(typeof(StartScreen), nameof(StartScreen.OnResumeButtonClick))] - private static bool StartScreen_OnResumeButtonClick(StartScreen __instance, int id, BaseEventData eventData) + [HarmonyPatch(typeof(StartScreen_UI2), nameof(StartScreen_UI2.OnResumeButtonLongPress))] + private static bool StartScreen_OnResumeButtonClick(StartScreen_UI2 __instance) { - return CheckSignatures(__instance.OnResumeButtonClick, id, eventData, LocalSaveFileUtils.GetSaveFiles(PolytopiaBackendBase.Game.GameType.SinglePlayer)[0]); + return CheckSignatures(__instance.OnResumeButtonLongPress, LocalSaveFileUtils.GetSaveFiles(PolytopiaBackendBase.Game.GameType.SinglePlayer)[0]); } /// diff --git a/src/Managers/Hub.cs b/src/Managers/Hub.cs index 9d06de1..b1cb42f 100644 --- a/src/Managers/Hub.cs +++ b/src/Managers/Hub.cs @@ -24,6 +24,7 @@ internal static class Hub private const string HEADER_PREFIX = ""; private const string HEADER_POSTFIX = ""; private const int POPUP_WIDTH = 1400; + private static GameObject? polyModButton = null; /// /// Whether the configuration popup is currently active. @@ -64,65 +65,76 @@ private static void PopupButtonContainer_SetButtonData(PopupButtonContainer __in } } + [HarmonyPostfix] + [HarmonyPatch(typeof(StartScreen_UI2), nameof(StartScreen_UI2.OnHide))] + private static void StartScreen_UI2_OnHide(StartScreen_UI2 __instance) + { + if(polyModButton != null) + GameObject.Destroy(polyModButton); + } /// /// Patches the start screen to add the PolyMod hub button and version text. /// - [HarmonyPrefix] - [HarmonyPatch(typeof(StartScreen), nameof(StartScreen.Start))] - private static void StartScreen_Start(StartScreen __instance) + [HarmonyPostfix] + [HarmonyPatch(typeof(StartScreen_UI2), nameof(StartScreen_UI2.OnShow))] + private static void StartScreen_UI2_OnShow(StartScreen_UI2 __instance) { - var bottomBar = __instance.settingsButton.transform.parent; - var bottomBarHorizontalLayoutGroup = bottomBar.GetComponent(); - bottomBarHorizontalLayoutGroup.childAlignment = TextAnchor.LowerCenter; - bottomBarHorizontalLayoutGroup.childForceExpandWidth = false; - bottomBarHorizontalLayoutGroup.childForceExpandHeight = false; - bottomBarHorizontalLayoutGroup.padding.left = 120; - bottomBarHorizontalLayoutGroup.padding.right = bottomBarHorizontalLayoutGroup.padding.left; - - GameObject versionTextObject = GameObject.Instantiate(__instance.settingsButton.label.gameObject, bottomBar); - versionTextObject.name = "PolyModVersion"; - versionTextObject.SetActive(true); - - LayoutElement versionTextLayoutElement = versionTextObject.GetComponent() - ?? versionTextObject.AddComponent(); - versionTextLayoutElement.ignoreLayout = true; - - RectTransform versionTextRectTransform = versionTextObject.GetComponent(); - versionTextRectTransform.anchorMin = Vector2.zero; - versionTextRectTransform.anchorMax = Vector2.zero; - versionTextRectTransform.pivot = Vector2.zero; - versionTextRectTransform.anchoredPosition = new Vector2(5f, 5f); - - TextMeshProUGUI versionTextComponent = versionTextObject.GetComponent(); - versionTextComponent.fontSize = 18f; - versionTextComponent.alignment = TextAlignmentOptions.MidlineLeft; - versionTextComponent.enableWordWrapping = true; - - versionTextRectTransform.sizeDelta = new Vector2(110f, 50f); - - versionTextObject.GetComponent().Text = $"PolyMod {Plugin.VERSION}"; - - GameObject originalButton = __instance.newsButton.gameObject; - GameObject button = GameObject.Instantiate(originalButton, originalButton.transform.parent); + UIRoundButton_UI2 originalButton = __instance.newsButton; + UIRoundButton_UI2 button = GameObject.Instantiate(originalButton, originalButton.transform.parent); button.name = "PolyModHubButton"; - - RectTransform originalButtonRectTransform = originalButton.GetComponent(); - button.transform.position = originalButton.transform.position - new Vector3(originalButtonRectTransform.rect.width * 1.5f, 0, 0); - - UIRoundButton buttonComponent = button.GetComponent(); - buttonComponent.bg.sprite = Visual.BuildSprite(Plugin.GetResource("polymod_icon.png").ReadBytes()); - buttonComponent.bg.transform.localScale = buttonComponent.bg.transform.localScale * 1.2f; - buttonComponent.bg.color = Color.white; - - GameObject.Destroy(buttonComponent.icon.gameObject); - GameObject.Destroy(buttonComponent.outline.gameObject); - - Transform descriptionText = button.transform.Find("DescriptionText"); - descriptionText.gameObject.SetActive(true); - descriptionText.GetComponentInChildren().Key = "polymod.hub"; - - buttonComponent.OnClicked += (UIButtonBase.ButtonAction)PolyModHubButtonClicked; - + button.SetPosition(750, 460); + button.bg.sprite = Visual.BuildSprite(Plugin.GetResource("polymod_icon.png").ReadBytes()); + button.bg.transform.localScale = button.transform.localScale * 1.2f; + button.bg.color = Color.white; + button.iconContainer.gameObject.SetActive(false); + button.outline.gameObject.SetActive(false); + button.OnClicked += (UIButtonBase_UI2.ButtonAction)PolyModHubButtonClicked; + polyModButton = button.gameObject; + // Console.Write(0); + // GameObject versionTextObject = GameObject.Instantiate(__instance.settingsButton.textBg.gameObject); + // versionTextObject.name = "PolyModVersion"; + // versionTextObject.SetActive(true); + // Console.Write(2); + // LayoutElement versionTextLayoutElement = versionTextObject.GetComponent() + // ?? versionTextObject.AddComponent(); + // versionTextLayoutElement.ignoreLayout = true; + + // RectTransform versionTextRectTransform = versionTextObject.GetComponent(); + // versionTextRectTransform.anchorMin = Vector2.zero; + // versionTextRectTransform.anchorMax = Vector2.zero; + // versionTextRectTransform.pivot = Vector2.zero; + // versionTextRectTransform.anchoredPosition = new Vector2(5f, 5f); + // Console.Write(3); + // TextMeshProUGUI versionTextComponent = versionTextObject.GetComponent(); + // versionTextComponent.fontSize = 18f; + // versionTextComponent.alignment = TextAlignmentOptions.MidlineLeft; + // versionTextComponent.enableWordWrapping = true; + + // versionTextRectTransform.sizeDelta = new Vector2(110f, 50f); + + // versionTextObject.GetComponent().Text = $"PolyMod {Plugin.VERSION}"; + // Console.Write(4); + // GameObject originalButton = __instance.newsButton.gameObject; + // GameObject button = GameObject.Instantiate(originalButton, originalButton.transform.parent); + // button.name = "PolyModHubButton"; + + // RectTransform originalButtonRectTransform = originalButton.GetComponent(); + // button.transform.position = originalButton.transform.position - new Vector3(originalButtonRectTransform.rect.width * 1.5f, 0, 0); + + // UIRoundButton buttonComponent = button.GetComponent(); + // buttonComponent.bg.sprite = Visual.BuildSprite(Plugin.GetResource("polymod_icon.png").ReadBytes()); + // buttonComponent.bg.transform.localScale = buttonComponent.bg.transform.localScale * 1.2f; + // buttonComponent.bg.color = Color.white; + // Console.Write(5); + // GameObject.Destroy(buttonComponent.icon.gameObject); + // GameObject.Destroy(buttonComponent.outline.gameObject); + + // Transform descriptionText = button.transform.Find("DescriptionText"); + // descriptionText.gameObject.SetActive(true); + // descriptionText.GetComponentInChildren().Key = "polymod.hub"; + + // buttonComponent.OnClicked += (UIButtonBase.ButtonAction)PolyModHubButtonClicked; + // Console.Write(6); static void PolyModHubButtonClicked(int buttonId, BaseEventData eventData) { BasicPopup popup = PopupManager.GetBasicPopup(); @@ -147,124 +159,34 @@ static void PolyModHubButtonClicked(int buttonId, BaseEventData eventData) HEADER_PREFIX, HEADER_POSTFIX }); + + void OpenDiscord() + { + NativeHelpers.OpenURL(Plugin.DISCORD_LINK, false); + } + List popupButtons = new() { new("buttons.back"), new( "polymod.hub.discord", - callback: (UIButtonBase.ButtonAction)((_, _) => - NativeHelpers.OpenURL(Plugin.DISCORD_LINK, false)) + callback: DelegateSupport.ConvertDelegate(OpenDiscord) ), new( "polymod.hub.config", - callback: (UIButtonBase.ButtonAction)((_, _) => - { - ShowConfigPopup(); - }) + callback: DelegateSupport.ConvertDelegate(ShowConfigPopup) ) }; if (Plugin.config.debug) { popupButtons.Add(new( "polymod.hub.dump", - callback: (UIButtonBase.ButtonAction)((_, _) => - { - Directory.CreateDirectory(Plugin.DUMPED_DATA_PATH); - Directory.CreateDirectory(Plugin.LOGIC_DUMP_PATH); - Directory.CreateDirectory(Plugin.LOCALIZATION_DUMP_PATH); - File.WriteAllTextAsync( - Path.Combine(Plugin.LOGIC_DUMP_PATH, "gameLogicData.json"), - PolytopiaDataManager.provider.LoadGameLogicData(VersionManager.GameLogicDataVersion) - ); - File.WriteAllTextAsync( - Path.Combine(Plugin.LOGIC_DUMP_PATH, "avatarData.json"), - PolytopiaDataManager.provider.LoadAvatarData(1337) - ); - var source = LocalizationManager.Sources[0]; - foreach (var language in source.GetLanguages()) - { - int languageIndex = source.GetLanguageIndex(language); - var dict = new Dictionary(); - - foreach (var term in source.mTerms) - { - var translation = term.GetTranslation(languageIndex); - - if (!string.IsNullOrEmpty(translation)) - dict[term.Term] = translation; - } - var options = new JsonSerializerOptions - { - WriteIndented = true, - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping - }; - - string json = JsonSerializer.Serialize(dict, options); - - File.WriteAllText( - Path.Combine(Plugin.LOCALIZATION_DUMP_PATH, $"language_{source.mLanguages[languageIndex].Code}.json"), - json - ); - } - foreach (var category in source.GetCategories()) - File.WriteAllTextAsync( - Path.Combine(Plugin.LOCALIZATION_DUMP_PATH, $"localization_{category}.csv"), - source.Export_CSV(category) - ); - foreach (KeyValuePair entry in Registry.mods) - { - foreach (Mod.File file in entry.Value.files) - { - Match spritesMatch = Regex.Match(Path.GetFileName(file.name), @"^sprites(?:_(.*))?\.json$"); - if (spritesMatch.Success) - File.WriteAllBytes( - Path.Combine( - Plugin.DUMPED_DATA_PATH, - $"{Path.GetFileNameWithoutExtension(file.name)}_{entry.Key}.json" - ), - file.bytes - ); - } - } - foreach (TribeType type in Enum.GetValues(typeof(TribeType))) - { - List previewTiles = new(); - SelectTribePopup popup = PopupManager.GetSelectTribePopup(); - for (int x = -3; x <= 3; x++) - { - for (int y = -7; y <= 7; y++) - { - Vector2Int pos = new Vector2Int(x, y); - if (popup.UIWorldPreview.worldPreviewData.TryGetData(pos, type, out UITileData tileData)) - { - Visual.PreviewTile previewTile = new Visual.PreviewTile - { - x = tileData.Position.x, - y = tileData.Position.y, - terrainType = tileData.terrainType, - resourceType = tileData.resourceType, - unitType = tileData.unitType, - improvementType = tileData.improvementType - }; - previewTiles.Add(previewTile); - } - } - } - File.WriteAllTextAsync( - Path.Combine(Plugin.DUMPED_DATA_PATH, $"preview_{type}.json"), - JsonSerializer.Serialize(previewTiles, new JsonSerializerOptions { WriteIndented = true }) - ); - } - NotificationManager.Notify(Localization.Get("polymod.hub.dumped")); - }), + callback: DelegateSupport.ConvertDelegate(DumpData), closesPopup: false )); popupButtons.Add(new( "polymod.hub.spriteinfo.update", - callback: (UIButtonBase.ButtonAction)((_, _) => - { - UpdateSpriteInfos(); - }), + callback: DelegateSupport.ConvertDelegate(UpdateSpriteInfos), closesPopup: false )); } @@ -274,19 +196,19 @@ static void PolyModHubButtonClicked(int buttonId, BaseEventData eventData) if (Main.dependencyCycle) { - var popup = PopupManager.GetBasicPopup(new( - Localization.Get("polymod.cycle"), - Localization.Get("polymod.cycle.description"), - new(new PopupBase.PopupButtonData[] { - new( - "buttons.exitgame", - PopupBase.PopupButtonData.States.None, - (Il2CppSystem.Action)Application.Quit, - closesPopup: false, - customColorStates: ColorConstants.redButtonColorStates - ) - }) - )); + BasicPopup popup = PopupManager.GetBasicPopup(); + popup.Header = Localization.Get("polymod.cycle"); + popup.Description = Localization.Get("polymod.cycle.description"); + popup.buttonData = new PopupBase.PopupButtonData[] { + new( + "buttons.exitgame", + PopupBase.PopupButtonData.States.None, + (Il2CppSystem.Action)Application.Quit, + closesPopup: false, + customColorStates: ColorConstants.redButtonColorStates + ) + }; + popup.IsUnskippable = true; popup.Show(); } @@ -339,6 +261,100 @@ internal static void UpdateSpriteInfos() NotificationManager.Notify(message); } + /// + /// Dump all data. + /// + internal static void DumpData() + { + Directory.CreateDirectory(Plugin.DUMPED_DATA_PATH); + Directory.CreateDirectory(Plugin.LOGIC_DUMP_PATH); + Directory.CreateDirectory(Plugin.LOCALIZATION_DUMP_PATH); + File.WriteAllTextAsync( + Path.Combine(Plugin.LOGIC_DUMP_PATH, "gameLogicData.json"), + PolytopiaDataManager.provider.LoadGameLogicData(VersionManager.GameLogicDataVersion) + ); + File.WriteAllTextAsync( + Path.Combine(Plugin.LOGIC_DUMP_PATH, "avatarData.json"), + PolytopiaDataManager.provider.LoadAvatarData(1337) + ); + var source = LocalizationManager.Sources[0]; + foreach (var language in source.GetLanguages()) + { + int languageIndex = source.GetLanguageIndex(language); + var dict = new Dictionary(); + + foreach (var term in source.mTerms) + { + var translation = term.GetTranslation(languageIndex); + + if (!string.IsNullOrEmpty(translation)) + dict[term.Term] = translation; + } + var options = new JsonSerializerOptions + { + WriteIndented = true, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }; + + string json = JsonSerializer.Serialize(dict, options); + + File.WriteAllText( + Path.Combine(Plugin.LOCALIZATION_DUMP_PATH, $"language_{source.mLanguages[languageIndex].Code}.json"), + json + ); + } + foreach (var category in source.GetCategories()) + File.WriteAllTextAsync( + Path.Combine(Plugin.LOCALIZATION_DUMP_PATH, $"localization_{category}.csv"), + source.Export_CSV(category) + ); + foreach (KeyValuePair entry in Registry.mods) + { + foreach (Mod.File file in entry.Value.files) + { + Match spritesMatch = Regex.Match(Path.GetFileName(file.name), @"^sprites(?:_(.*))?\.json$"); + if (spritesMatch.Success) + File.WriteAllBytes( + Path.Combine( + Plugin.DUMPED_DATA_PATH, + $"{Path.GetFileNameWithoutExtension(file.name)}_{entry.Key}.json" + ), + file.bytes + ); + } + } + foreach (TribeType type in Enum.GetValues(typeof(TribeType))) + { + List previewTiles = new(); + SelectTribePopup popup = PopupManager.GetSelectTribePopup(); + for (int x = -3; x <= 3; x++) + { + for (int y = -7; y <= 7; y++) + { + Vector2Int pos = new Vector2Int(x, y); + if (popup.UIWorldPreview.worldPreviewData.TryGetData(pos, type, out UITileData tileData)) + { + Visual.PreviewTile previewTile = new Visual.PreviewTile + { + x = tileData.Position.x, + y = tileData.Position.y, + terrainType = tileData.terrainType, + resourceType = tileData.resourceType, + unitType = tileData.unitType, + improvementType = tileData.improvementType + }; + previewTiles.Add(previewTile); + } + } + } + File.WriteAllTextAsync( + Path.Combine(Plugin.DUMPED_DATA_PATH, $"preview_{type}.json"), + JsonSerializer.Serialize(previewTiles, new JsonSerializerOptions { WriteIndented = true }) + ); + } + NotificationManager.Notify(Localization.Get("polymod.hub.dumped")); + } + /// /// Shows the configuration popup. /// @@ -362,12 +378,12 @@ internal static PopupButtonData[] CreateConfigPopupButtonData() { List popupButtons = new() { - new(Localization.Get("buttons.back"), PopupButtonData.States.None, (UIButtonBase.ButtonAction)OnBackButtonClicked, -1, true, null) + new(Localization.Get("buttons.back"), PopupButtonData.States.None, DelegateSupport.ConvertDelegate(OnBackButtonClicked), -1, true, null) }; if (GameManager.Instance.isLevelLoaded) { - popupButtons.Add(new PopupButtonData(Localization.Get("polymod.hub.spriteinfo.update"), PopupButtonData.States.None, (UIButtonBase.ButtonAction)OnUpdateSpritesButtonClicked, -1, true, null)); + popupButtons.Add(new PopupButtonData(Localization.Get("polymod.hub.spriteinfo.update"), PopupButtonData.States.None, DelegateSupport.ConvertDelegate(OnUpdateSpritesButtonClicked), -1, true, null)); } else { @@ -386,9 +402,9 @@ internal static PopupButtonData[] CreateConfigPopupButtonData() new Il2CppSystem.Object[] { Localization.Get("polymod.autoupdate.alpha", new Il2CppSystem.Object[]{}).ToUpperInvariant() } ); - popupButtons.Add(new PopupButtonData(debugButtonName, PopupButtonData.States.None, (UIButtonBase.ButtonAction)OnDebugButtonClicked, -1, true, null)); - popupButtons.Add(new PopupButtonData(autoUpdateButtonName, PopupButtonData.States.None, (UIButtonBase.ButtonAction)OnAutoUpdateButtonClicked, -1, true, null)); - popupButtons.Add(new PopupButtonData(includeAlphasButtonName, Plugin.config.autoUpdate ? PopupButtonData.States.None : PopupButtonData.States.Disabled, (UIButtonBase.ButtonAction)OnIncludeAlphasButtonClicked, -1, true, null)); + popupButtons.Add(new PopupButtonData(debugButtonName, PopupButtonData.States.None, DelegateSupport.ConvertDelegate(OnDebugButtonClicked), -1, true, null)); + popupButtons.Add(new PopupButtonData(autoUpdateButtonName, PopupButtonData.States.None, DelegateSupport.ConvertDelegate(OnAutoUpdateButtonClicked), -1, true, null)); + popupButtons.Add(new PopupButtonData(includeAlphasButtonName, Plugin.config.autoUpdate ? PopupButtonData.States.None : PopupButtonData.States.Disabled, DelegateSupport.ConvertDelegate(OnIncludeAlphasButtonClicked), -1, true, null)); } return popupButtons.ToArray(); diff --git a/src/Managers/Main.cs b/src/Managers/Main.cs index 6a728e9..6bead52 100644 --- a/src/Managers/Main.cs +++ b/src/Managers/Main.cs @@ -88,7 +88,6 @@ private static void GameLogicData_AddGameLogicPlaceholders(GameLogicData __insta /// [HarmonyPrefix] [HarmonyPatch(typeof(PurchaseManager), nameof(PurchaseManager.IsSkinUnlocked))] - [HarmonyPatch(typeof(PurchaseManager), nameof(PurchaseManager.IsSkinUnlockedInternal))] private static bool PurchaseManager_IsSkinUnlockedInternal(ref bool __result, SkinType skinType) { __result = (int)skinType >= Plugin.AUTOIDX_STARTS_FROM && skinType != SkinType.Test; diff --git a/src/Managers/Visual.cs b/src/Managers/Visual.cs index 7f0d5e2..1fa01de 100644 --- a/src/Managers/Visual.cs +++ b/src/Managers/Visual.cs @@ -8,6 +8,7 @@ using PolyMod.Json; using System.Text.Json.Serialization; using PolytopiaBackendBase.Common; +using Il2CppInterop.Runtime; namespace PolyMod.Managers; @@ -128,8 +129,8 @@ private static void TechItem_SetupComplete() /// Resets the firstTimeOpeningPreview flag when the start screen is shown. [HarmonyPrefix] - [HarmonyPatch(typeof(StartScreen), nameof(StartScreen.Start))] - private static void StartScreen_Start() + [HarmonyPatch(typeof(StartScreen_UI2), nameof(StartScreen_UI2.OnShow))] + private static void StartScreen_UI2_OnShow() { firstTimeOpeningPreview = true; } @@ -176,7 +177,7 @@ void GetAtlas(SpriteAtlas spriteAtlas) /// Patches the sprite atlas manager to look up custom sprites. [HarmonyPostfix] [HarmonyPatch(typeof(SpriteAtlasManager), nameof(SpriteAtlasManager.DoSpriteLookup))] - private static void SpriteAtlasManager_DoSpriteLookup(ref SpriteAtlasManager.SpriteLookupResult __result, SpriteAtlasManager __instance, string baseName, TribeType tribe, SkinType skin, bool checkForOutline, int level) + private static void SpriteAtlasManager_DoSpriteLookup(ref SpriteAtlasManager.SpriteLookupResult __result, SpriteAtlasManager __instance, string baseName, TribeType tribe, SkinType skin, int level) { baseName = Util.FormatSpriteName(baseName); @@ -463,7 +464,7 @@ private static void UIWorldPreviewData_TryGetData(ref bool __result, UIWorldPrev [HarmonyPatch(typeof(UIWorldPreview), nameof(UIWorldPreview.SetPreview), new Type[] { })] private static void UIWorldPreview_SetPreview(UIWorldPreview __instance) { - if (Plugin.config.debug && UIManager.Instance.CurrentScreen == UIConstants.Screens.TribeSelector) + if (Plugin.config.debug && UIManager.Instance.CurrentScreen == UIConstants.Screens.TribePicker) { if (firstTimeOpeningPreview) { @@ -646,8 +647,8 @@ private static void PlayerInfoIcon_SetData(PlayerInfoIcon __instance, TribeType /// Updates the width of a basic popup if a custom width is set. [HarmonyPostfix] - [HarmonyPatch(typeof(BasicPopup), nameof(BasicPopup.Update))] - private static void BasicPopup_Update(BasicPopup __instance) + [HarmonyPatch(typeof(PopupBase), nameof(PopupBase.RefreshHeight))] + private static void BasicPopup_RefreshHeight(ref Il2CppSystem.Collections.IEnumerator __result, PopupBase __instance, Il2CppSystem.Action OnComplete) { int id = __instance.GetInstanceID(); if (basicPopupWidths.ContainsKey(id)) @@ -691,25 +692,28 @@ private static void PopupBase_Hide(PopupBase __instance) } [HarmonyPrefix] - [HarmonyPatch(typeof(StartScreen), nameof(StartScreen.OnWeeklyChallengedButtonClick))] - private static bool StartScreen_OnWeeklyChallengedButtonClick(StartScreen __instance) + [HarmonyPatch(typeof(StartScreen_UI2), nameof(StartScreen_UI2.OnWeeklyChallengeClicked))] + private static bool StartScreen_OnWeeklyChallengeClicked(StartScreen_UI2 __instance) { if(seenWarningWCPopup) return true; + BasicPopup popup = PopupManager.GetBasicPopup(); popup.Header = Localization.Get("polymod.hub"); popup.Description = Localization.Get("polymod.wc.warning", new Il2CppSystem.Object[] { Localization.Get("weeklychallenge", new Il2CppSystem.Object[] { }) }); + + void WCProceed() + { + seenWarningWCPopup = true; + __instance.OnWeeklyChallengeClicked(); + } List popupButtons = new() { new("buttons.back"), new( "polymod.wc.proceed", PopupBase.PopupButtonData.States.None, - callback: (UIButtonBase.ButtonAction)((_, _) => - { - seenWarningWCPopup = true; - __instance.OnWeeklyChallengedButtonClick(); - }), + callback: DelegateSupport.ConvertDelegate(WCProceed), customColorStates: ColorConstants.redButtonColorStates ) }; From a56cad639847361f1c79740dd505d7d37df44624 Mon Sep 17 00:00:00 2001 From: Maksym Muraviov$ Date: Mon, 8 Jun 2026 09:36:53 +0200 Subject: [PATCH 2/7] Using new overload for basic popup --- src/Managers/AutoUpdate.cs | 15 +++++------- src/Managers/Compatibility.cs | 44 +++++++++++++++++------------------ src/Managers/Hub.cs | 23 ++++++++++-------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/Managers/AutoUpdate.cs b/src/Managers/AutoUpdate.cs index c903510..6384616 100644 --- a/src/Managers/AutoUpdate.cs +++ b/src/Managers/AutoUpdate.cs @@ -3,7 +3,6 @@ using System.Text.Json; using HarmonyLib; using UnityEngine; -using static PopupManager; namespace PolyMod.Managers; @@ -155,19 +154,17 @@ exit 0 } // Show a popup to the user asking if they want to update - BasicPopup popup = PopupManager.GetBasicPopup(); - popup.Header = Localization.Get("polymod.autoupdate"); - popup.Description = Localization.Get("polymod.autoupdate.description"); - popup.buttonData = new PopupBase.PopupButtonData[] { + PopupManager.GetBasicPopupWithData(new( + Localization.Get("polymod.autoupdate"), + Localization.Get("polymod.autoupdate.description"), + new(new PopupBase.PopupButtonData[] { new( "polymod.autoupdate.update", PopupBase.PopupButtonData.States.None, (Il2CppSystem.Action)Update ) - }; - - popup.Show(); - + })) + ).Show(); } catch (Exception e) { diff --git a/src/Managers/Compatibility.cs b/src/Managers/Compatibility.cs index 28e17d2..6e7c3df 100644 --- a/src/Managers/Compatibility.cs +++ b/src/Managers/Compatibility.cs @@ -67,14 +67,13 @@ private static bool CheckSignatures(Action action, Il2CppSystem.Guid gameId) } if (!doChecksumsMatch) { - BasicPopup popup = PopupManager.GetBasicPopup(); - popup.Header = Localization.Get("polymod.signature.mismatch"); - popup.Description = Localization.Get("polymod.signature.incompatible"); - popup.buttonData = new PopupBase.PopupButtonData[] { - new("OK") - }; - - popup.Show(); + PopupManager.GetBasicPopupWithData(new( + Localization.Get("polymod.signature.mismatch"), + Localization.Get("polymod.signature.incompatible"), + new(new PopupBase.PopupButtonData[] { + new("OK") + }) + )).Show(); return false; } @@ -116,20 +115,21 @@ private static void StartScreen_UI2_OnShow() ); PlayerPrefs.Save(); - BasicPopup popup = PopupManager.GetBasicPopup(); - popup.Header = Localization.Get("polymod.version.mismatch"); - popup.Description = Localization.Get("polymod.version.mismatch.description"); - popup.buttonData = new PopupBase.PopupButtonData[] { - new("buttons.stay", customColorStates: ColorConstants.redButtonColorStates), - new( - "buttons.exitgame", - PopupBase.PopupButtonData.States.None, - (Il2CppSystem.Action)Application.Quit, - closesPopup: false - ) - }; - - popup.Show(); + PopupManager.GetBasicPopupWithData( + new( + Localization.Get("polymod.version.mismatch"), + Localization.Get("polymod.version.mismatch.description"), + new PopupBase.PopupButtonData[] { + new("buttons.stay", customColorStates: ColorConstants.redButtonColorStates), + new( + "buttons.exitgame", + PopupBase.PopupButtonData.States.None, + (Il2CppSystem.Action)Application.Quit, + closesPopup: false + ) + } + ) + ).Show(); } } diff --git a/src/Managers/Hub.cs b/src/Managers/Hub.cs index b1cb42f..2d831c1 100644 --- a/src/Managers/Hub.cs +++ b/src/Managers/Hub.cs @@ -196,18 +196,21 @@ void OpenDiscord() if (Main.dependencyCycle) { - BasicPopup popup = PopupManager.GetBasicPopup(); - popup.Header = Localization.Get("polymod.cycle"); - popup.Description = Localization.Get("polymod.cycle.description"); - popup.buttonData = new PopupBase.PopupButtonData[] { + BasicPopup popup = PopupManager.GetBasicPopupWithData( new( - "buttons.exitgame", - PopupBase.PopupButtonData.States.None, - (Il2CppSystem.Action)Application.Quit, - closesPopup: false, - customColorStates: ColorConstants.redButtonColorStates + Localization.Get("polymod.cycle"), + Localization.Get("polymod.cycle.description"), + new PopupBase.PopupButtonData[] { + new( + "buttons.exitgame", + PopupBase.PopupButtonData.States.None, + (Il2CppSystem.Action)Application.Quit, + closesPopup: false, + customColorStates: ColorConstants.redButtonColorStates + ) + } ) - }; + ); popup.IsUnskippable = true; popup.Show(); From bc4b06d28d4fb4d9685dd10a0e031a4341623483 Mon Sep 17 00:00:00 2001 From: Maksym Muraviov$ Date: Mon, 8 Jun 2026 10:37:13 +0200 Subject: [PATCH 3/7] space --- src/Managers/Compatibility.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Managers/Compatibility.cs b/src/Managers/Compatibility.cs index 6e7c3df..1d55bb7 100644 --- a/src/Managers/Compatibility.cs +++ b/src/Managers/Compatibility.cs @@ -114,7 +114,6 @@ private static void StartScreen_UI2_OnShow() VersionManager.SemanticVersion.Cast().CutRevision().ToString() ); PlayerPrefs.Save(); - PopupManager.GetBasicPopupWithData( new( Localization.Get("polymod.version.mismatch"), From 032c850d94f9cd0c21e4742bc7e4d2b040c4bd4e Mon Sep 17 00:00:00 2001 From: Maksym Muraviov$ Date: Tue, 9 Jun 2026 14:38:14 +0200 Subject: [PATCH 4/7] Partially implemented new custom tribe previews, added debug tile coordinates in tribe preview --- src/Managers/Visual.cs | 89 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/Managers/Visual.cs b/src/Managers/Visual.cs index 1fa01de..1dc6065 100644 --- a/src/Managers/Visual.cs +++ b/src/Managers/Visual.cs @@ -9,6 +9,7 @@ using System.Text.Json.Serialization; using PolytopiaBackendBase.Common; using Il2CppInterop.Runtime; +using TMPro; namespace PolyMod.Managers; @@ -75,6 +76,8 @@ public UnitPrefabInfo(string type, string tribe, string skin) /// A dictionary of skin types of tribes, which can flood tiles, keyed by custom flood tile effect. /// internal static Dictionary customFloodingSkins = new(); + private static bool isTakingSnapshot = false; + private static float? baseOrthographicCameraSize = null; /// The type of a custom prefab. public enum PrefabType @@ -481,6 +484,92 @@ private static void UIWorldPreview_SetPreview(UIWorldPreview __instance) } } + + [HarmonyPostfix] + [HarmonyPatch(typeof(TribePreviewRegistry), nameof(TribePreviewRegistry.GetTribePreviewData))] + private static void TribePreviewRegistry_GetTribePreviewData(ref SaveStateData __result, TribeType tribeType, SkinType skinType) + { + string tribeName = EnumCache.GetName(tribeType).ToLower(); + if (!Registry.tribePreviews.ContainsKey(tribeName)) + return; + + PreviewTile[]? preview = Registry.tribePreviews[tribeName]; + if (preview == null) + return; + + ClientSerializationWrapper result = new ClientSerializationWrapper(null); + int version; + bool num = DiskSerializationHelpers.FromLZ4CompressedByteArray(__result.byteArray, out result, out version); + if (num) + { + GameState currentGameState = result.GetCurrentGameState(); + Console.Write(currentGameState.Map.tiles.Count); + foreach (var previewTile in preview) + { + if(previewTile.x == null || previewTile.y == null) + continue; + + WorldCoordinates coordinates = new((int)previewTile.x, (int)previewTile.y); + TileData tileData = currentGameState.Map.GetTile(coordinates); + tileData.terrain = previewTile.terrainType; + // DO THE STATES AND MAYBE THE EFFECTS + //tileData.resource = previewTile.resourceType; + // tileData.unitType = previewTile.unitType; + // tileData.improvement = previewTile.improvementType; + } + // TODO: override tiles based on gld stuff + } + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(SpriteCamera), nameof(SpriteCamera.TakeSnapshotOfMapState))] + private static bool SpriteCamera_TakeSnapshotOfMapState(ref Texture2D __result, SpriteCamera.SnapshotMapData mapSnapshot, + float w, float h, TribeType tribe, SkinType skin, TribeType climate, int color, bool clearMapAfterwards) + { + if(!Plugin.config.debug) + return true; + + var instance = SpriteCamera.instance; + if(baseOrthographicCameraSize == null) + baseOrthographicCameraSize = instance.spriteCamera.orthographicSize; + + instance.spriteCamera.orthographicSize = (float)baseOrthographicCameraSize * 2; + isTakingSnapshot = true; + + return true; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(SpriteCamera), nameof(SpriteCamera.TakeSnapshotOfMapState))] + private static void SpriteCamera_TakeSnapshotOfMapState_Postfix(ref Texture2D __result, SpriteCamera.SnapshotMapData mapSnapshot, + float w, float h, TribeType tribe, SkinType skin, TribeType climate, int color, bool clearMapAfterwards) + { + if(isTakingSnapshot) + isTakingSnapshot = false; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(Tile), nameof(Tile.RenderDebug))] + public static void Tile_RenderDebug(Tile __instance) + { + if(!isTakingSnapshot) + return; + + GameObject textObj = new GameObject("CoordinateText"); + textObj.transform.SetParent(__instance.transform); + textObj.transform.localPosition = new Vector3(0, 0.0f, 0); + + TextMeshPro textMesh = textObj.AddComponent(); + textMesh.text = __instance.Data.coordinates.ToString(); + textMesh.fontSize = 3; + textMesh.alignment = TextAlignmentOptions.Center; + textMesh.color = Color.white; + + MeshRenderer renderer = textObj.GetComponent(); + renderer.sortingLayerID = MeshCache.TERRAIN_LAYER_ID; + renderer.sortingOrder = __instance.Depth + 10; + } + #endregion #region UI From 97e5ccfc60ff04f97f79b036eb2d47f2a42303c1 Mon Sep 17 00:00:00 2001 From: Maksym Muraviov$ Date: Tue, 9 Jun 2026 21:50:22 +0200 Subject: [PATCH 5/7] finished preview and got stuck on popups shit --- src/Managers/Hub.cs | 20 +++++++------ src/Managers/Visual.cs | 66 +++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/Managers/Hub.cs b/src/Managers/Hub.cs index 2d831c1..980025d 100644 --- a/src/Managers/Hub.cs +++ b/src/Managers/Hub.cs @@ -137,7 +137,8 @@ private static void StartScreen_UI2_OnShow(StartScreen_UI2 __instance) // Console.Write(6); static void PolyModHubButtonClicked(int buttonId, BaseEventData eventData) { - BasicPopup popup = PopupManager.GetBasicPopup(); + WhatsNewPopup popup = PopupManager.GetWhatsNewPopup(); + popup.Header = Localization.Get("polymod.hub"); popup.Description = Localization.Get("polymod.hub.header", new Il2CppSystem.Object[] { HEADER_PREFIX, @@ -191,7 +192,8 @@ void OpenDiscord() )); } popup.buttonData = popupButtons.ToArray(); - popup.ShowSetWidth(POPUP_WIDTH); + popup.Show(); + // popup.ShowSetWidth(POPUP_WIDTH); } if (Main.dependencyCycle) @@ -363,13 +365,13 @@ internal static void DumpData() /// internal static void ShowConfigPopup() { - BasicPopup polymodPopup = PopupManager.GetBasicPopup(); + WhatsNewPopup polymodPopup = PopupManager.GetWhatsNewPopup(); polymodPopup.Header = Localization.Get("polymod.hub.config"); polymodPopup.Description = ""; polymodPopup.buttonData = CreateConfigPopupButtonData(); - polymodPopup.ShowSetWidth(POPUP_WIDTH); + // polymodPopup.ShowSetWidth(POPUP_WIDTH); polymodPopup.Show(); } @@ -411,7 +413,7 @@ internal static PopupButtonData[] CreateConfigPopupButtonData() } return popupButtons.ToArray(); - void OnDebugButtonClicked(int buttonId, BaseEventData eventData) + void OnDebugButtonClicked() { Plugin.config = new(debug: !Plugin.config.debug, autoUpdate: Plugin.config.autoUpdate, updatePrerelease: Plugin.config.updatePrerelease); Plugin.WriteConfig(); @@ -424,7 +426,7 @@ void OnDebugButtonClicked(int buttonId, BaseEventData eventData) isConfigPopupActive = false; } - void OnAutoUpdateButtonClicked(int buttonId, BaseEventData eventData) + void OnAutoUpdateButtonClicked() { Plugin.config = new(debug: Plugin.config.debug, autoUpdate: !Plugin.config.autoUpdate, updatePrerelease: Plugin.config.updatePrerelease); Plugin.WriteConfig(); @@ -437,7 +439,7 @@ void OnAutoUpdateButtonClicked(int buttonId, BaseEventData eventData) isConfigPopupActive = false; } - void OnIncludeAlphasButtonClicked(int buttonId, BaseEventData eventData) + void OnIncludeAlphasButtonClicked() { Plugin.config = new(debug: Plugin.config.debug, autoUpdate: Plugin.config.autoUpdate, updatePrerelease: !Plugin.config.updatePrerelease); Plugin.WriteConfig(); @@ -450,13 +452,13 @@ void OnIncludeAlphasButtonClicked(int buttonId, BaseEventData eventData) isConfigPopupActive = false; } - void OnUpdateSpritesButtonClicked(int buttonId, BaseEventData eventData) + void OnUpdateSpritesButtonClicked() { UpdateSpriteInfos(); isConfigPopupActive = false; } - void OnBackButtonClicked(int buttonId, BaseEventData eventData) + void OnBackButtonClicked() { isConfigPopupActive = false; } diff --git a/src/Managers/Visual.cs b/src/Managers/Visual.cs index 1dc6065..36fd13b 100644 --- a/src/Managers/Visual.cs +++ b/src/Managers/Visual.cs @@ -32,7 +32,7 @@ public class PreviewTile /// The terrain type of the tile. [JsonInclude] [JsonConverter(typeof(EnumCacheJson))] - public Polytopia.Data.TerrainData.Type terrainType = Polytopia.Data.TerrainData.Type.Ocean; + public Polytopia.Data.TerrainData.Type terrainType = Polytopia.Data.TerrainData.Type.None; /// The resource type on the tile. [JsonInclude] [JsonConverter(typeof(EnumCacheJson))] @@ -503,21 +503,45 @@ private static void TribePreviewRegistry_GetTribePreviewData(ref SaveStateData _ if (num) { GameState currentGameState = result.GetCurrentGameState(); - Console.Write(currentGameState.Map.tiles.Count); foreach (var previewTile in preview) { if(previewTile.x == null || previewTile.y == null) continue; WorldCoordinates coordinates = new((int)previewTile.x, (int)previewTile.y); - TileData tileData = currentGameState.Map.GetTile(coordinates); - tileData.terrain = previewTile.terrainType; - // DO THE STATES AND MAYBE THE EFFECTS - //tileData.resource = previewTile.resourceType; - // tileData.unitType = previewTile.unitType; - // tileData.improvement = previewTile.improvementType; + TileData? tileData = currentGameState.Map.GetTile(coordinates); + if(tileData == null) + continue; + + if(previewTile.terrainType != Polytopia.Data.TerrainData.Type.None) + tileData.terrain = previewTile.terrainType; + + if(previewTile.resourceType != Polytopia.Data.ResourceData.Type.None) + tileData.resource = new ResourceState { type = previewTile.resourceType }; + + if(previewTile.unitType != Polytopia.Data.UnitData.Type.None && + currentGameState.TryGetPlayer(currentGameState.CurrentPlayer, out PlayerState playerState) && + currentGameState.GameLogicData.TryGetData(previewTile.unitType, out UnitData unitData)) + { + ActionUtils.TrainUnit(currentGameState, playerState, tileData, unitData); + } + + if(previewTile.improvementType != Polytopia.Data.ImprovementData.Type.None && + currentGameState.GameLogicData.TryGetData(previewTile.improvementType, out var improvementData)) + { + tileData.improvement = new ImprovementState + { + type = previewTile.improvementType, + borderSize = (ushort)improvementData.borderSize, + level = 0, + xp = 0, + production = 1, + founded = (ushort)currentGameState.CurrentTurn, + baseScore = (ushort)improvementData.GetScoreReward(), + founder = currentGameState.CurrentPlayer + }; + } } - // TODO: override tiles based on gld stuff } } @@ -739,9 +763,7 @@ private static void PlayerInfoIcon_SetData(PlayerInfoIcon __instance, TribeType [HarmonyPatch(typeof(PopupBase), nameof(PopupBase.RefreshHeight))] private static void BasicPopup_RefreshHeight(ref Il2CppSystem.Collections.IEnumerator __result, PopupBase __instance, Il2CppSystem.Action OnComplete) { - int id = __instance.GetInstanceID(); - if (basicPopupWidths.ContainsKey(id)) - __instance.rectTransform.SetWidth(basicPopupWidths[id]); + __instance.rectTransform.sizeDelta = new Vector2(2000, __instance.rectTransform.sizeDelta.y); } /// Sets the attacker's tribe before a unit attacks. @@ -812,12 +834,30 @@ void WCProceed() } /// Shows a basic popup with a custom width. - public static void ShowSetWidth(this BasicPopup self, int width) + public static void ShowSetWidth(this BasicPopupLegacy self, int width) { basicPopupWidths.Add(self.GetInstanceID(), width); self.Show(); } + [HarmonyPrefix] + [HarmonyPatch(typeof(BasicPopup), nameof(BasicPopup.SetButtonData))] + public static bool SetButtonData(BasicPopup __instance, PopupBase.PopupButtonData[] buttonDatas, bool updateOmniCursor) + { + if (buttonDatas == null) + { + __instance.SetDefaultOkbutton(); + return false; + } + foreach (var buttonData in buttonDatas) + { + var MainButton = __instance.createButton(buttonData.text, buttonData.callback, UIButtonBase_UI2.ButtonStyle.Suggested); + MainButton.OnClickedSignal.Add(DelegateSupport.ConvertDelegate(__instance.Hide)); + } + __instance.RunLayout(); + return false; + } + #endregion /// Updates a visual part with a custom sprite. From 89f0aba4ce14f92fd1174b823a9de790906182cb Mon Sep 17 00:00:00 2001 From: Maksym Muraviov$ Date: Tue, 9 Jun 2026 22:34:08 +0200 Subject: [PATCH 6/7] added temporary popup fix --- src/Managers/Hub.cs | 6 ++--- src/Managers/Visual.cs | 51 +++++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/Managers/Hub.cs b/src/Managers/Hub.cs index 980025d..84fc071 100644 --- a/src/Managers/Hub.cs +++ b/src/Managers/Hub.cs @@ -192,8 +192,7 @@ void OpenDiscord() )); } popup.buttonData = popupButtons.ToArray(); - popup.Show(); - // popup.ShowSetWidth(POPUP_WIDTH); + popup.ShowSetWidth(POPUP_WIDTH); } if (Main.dependencyCycle) @@ -371,8 +370,7 @@ internal static void ShowConfigPopup() polymodPopup.Description = ""; polymodPopup.buttonData = CreateConfigPopupButtonData(); - // polymodPopup.ShowSetWidth(POPUP_WIDTH); - polymodPopup.Show(); + polymodPopup.ShowSetWidth(POPUP_WIDTH); } /// diff --git a/src/Managers/Visual.cs b/src/Managers/Visual.cs index 36fd13b..97bdbc1 100644 --- a/src/Managers/Visual.cs +++ b/src/Managers/Visual.cs @@ -763,7 +763,22 @@ private static void PlayerInfoIcon_SetData(PlayerInfoIcon __instance, TribeType [HarmonyPatch(typeof(PopupBase), nameof(PopupBase.RefreshHeight))] private static void BasicPopup_RefreshHeight(ref Il2CppSystem.Collections.IEnumerator __result, PopupBase __instance, Il2CppSystem.Action OnComplete) { - __instance.rectTransform.sizeDelta = new Vector2(2000, __instance.rectTransform.sizeDelta.y); + UpdateWidth(__instance); + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(PopupBase), nameof(PopupBase.OnShowComplete))] + private static bool BasicPopup_ShowInternal(PopupBase __instance) + { + UpdateWidth(__instance); + return true; + } + + private static void UpdateWidth(PopupBase __instance) + { + int id = __instance.GetInstanceID(); + if (basicPopupWidths.ContainsKey(id)) + __instance.rectTransform.SetWidth(basicPopupWidths[id]); } /// Sets the attacker's tribe before a unit attacks. @@ -840,23 +855,23 @@ public static void ShowSetWidth(this BasicPopupLegacy self, int width) self.Show(); } - [HarmonyPrefix] - [HarmonyPatch(typeof(BasicPopup), nameof(BasicPopup.SetButtonData))] - public static bool SetButtonData(BasicPopup __instance, PopupBase.PopupButtonData[] buttonDatas, bool updateOmniCursor) - { - if (buttonDatas == null) - { - __instance.SetDefaultOkbutton(); - return false; - } - foreach (var buttonData in buttonDatas) - { - var MainButton = __instance.createButton(buttonData.text, buttonData.callback, UIButtonBase_UI2.ButtonStyle.Suggested); - MainButton.OnClickedSignal.Add(DelegateSupport.ConvertDelegate(__instance.Hide)); - } - __instance.RunLayout(); - return false; - } + // [HarmonyPrefix] + // [HarmonyPatch(typeof(BasicPopup), nameof(BasicPopup.SetButtonData))] + // public static bool SetButtonData(BasicPopup __instance, PopupBase.PopupButtonData[] buttonDatas, bool updateOmniCursor) + // { + // if (buttonDatas == null) + // { + // __instance.SetDefaultOkbutton(); + // return false; + // } + // foreach (var buttonData in buttonDatas) + // { + // var MainButton = __instance.createButton(buttonData.text, buttonData.callback, UIButtonBase_UI2.ButtonStyle.Suggested); + // MainButton.OnClickedSignal.Add(DelegateSupport.ConvertDelegate(__instance.Hide)); + // } + // __instance.RunLayout(); + // return false; + // } #endregion From a7a136e011b5bc4cc7a2f6ee85be0c9dda53482c Mon Sep 17 00:00:00 2001 From: Maksym Muraviov$ Date: Tue, 9 Jun 2026 22:47:25 +0200 Subject: [PATCH 7/7] finished tribe preview --- src/Managers/Visual.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Managers/Visual.cs b/src/Managers/Visual.cs index 97bdbc1..19f3dc4 100644 --- a/src/Managers/Visual.cs +++ b/src/Managers/Visual.cs @@ -542,6 +542,7 @@ private static void TribePreviewRegistry_GetTribePreviewData(ref SaveStateData _ }; } } + __result.byteArray = DiskSerializationHelpers.ToLZ4CompressedByteArray(result, version); } }