using System.IO; using System.Linq; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; namespace IngameReveries { // ModBehaviour will be instantiated and attached as a component in a container game object named // Multiple ModBehaviours in your mod will share the same container. public class IngameReveries : ModBehaviour { private GameObject _ingameReveriesUI; private AssetBundle _reveriesBundle; private GameObject _reveriesPrefab; private void Awake() { // Metadata of your mod is stored in this.about Debug.Log("Hello! I'm loaded! " + mod.metadata.id); // If you need to patch with Harmony, you can use this.harmony to access the Harmony instance for your mod. // It will be created with your mod's id automatically, the first time you access the property. harmony.PatchAll(); } private void Start() { InitializeAssets(); SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDestroy() { // Make sure you clean up properly to support Live Reload. Debug.Log("Good bye! " + mod.metadata.id); harmony.UnpatchAll(); SceneManager.sceneLoaded -= OnSceneLoaded; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { // Check if UI already instantiated if (_ingameReveriesUI != null) { return; } string gameSceneDir = "Assets/Dew/Zones/"; string relativeToScene = Path.GetRelativePath(gameSceneDir, scene.path); if (!relativeToScene.StartsWith("..")) { Debug.Log($"[IngameReveries] Switched to scene inside {gameSceneDir}"); GameObject menuViewGO = GameObject.Find("GameLogicPackage/UI/InGame/UI_Common_MenuView"); if (menuViewGO == null) { Debug.Log("Couldn't find menu view"); return; } _ingameReveriesUI = Instantiate(_reveriesPrefab, menuViewGO.transform); _ingameReveriesUI.SetActive(true); _ingameReveriesUI.name = "IngameReveriesUI"; _ingameReveriesUI.transform.SetSiblingIndex(1); var reveries = _ingameReveriesUI.GetComponent(); // Show reveries window var canvasGroup = _ingameReveriesUI.GetComponent(); canvasGroup.alpha = 1f; canvasGroup.interactable = true; canvasGroup.blocksRaycasts = true; // Position reveries window top left var rect = _ingameReveriesUI.GetComponent(); rect.anchorMin = new Vector2(0f, 1f); rect.anchorMax = new Vector2(0f, 1f); rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = new Vector2(+70f, -400f); FixFonts(); } } private void InitializeAssets() { string bundlePath = Path.Combine(mod.path, "assets", "bundle"); if (!File.Exists(bundlePath)) { Debug.LogError($"[IngameReveries] Bundle not found at: {bundlePath}"); return; } _reveriesBundle = AssetBundle.GetAllLoadedAssetBundles() .FirstOrDefault(b => b.name == "logosteal" || b.mainAsset != null); if (_reveriesBundle == null) { // If it isn't loaded yet, load it from disk Debug.Log("[IngameReveries] Loading Bundle"); _reveriesBundle = AssetBundle.LoadFromFile(bundlePath); } else { Debug.Log("[IngameReveries] Bundle already loaded"); } if (_reveriesBundle == null) { Debug.LogError("[IngameReveries] Failed to load AssetBundle!"); return; } // Load the prefab from the bundle string assetName = _reveriesBundle.GetAllAssetNames().First(); _reveriesPrefab = _reveriesBundle.LoadAsset(assetName); if (_reveriesPrefab == null) { Debug.LogError("[IngameReveries] Failed to load prefab!"); // List what's in the bundle for debugging string[] assetNames = _reveriesBundle.GetAllAssetNames(); Debug.Log("[IngameReveries] Assets in bundle:"); foreach (string name in assetNames) { Debug.Log($" - {name}"); } return; } Debug.Log("[IngameReveries] Successfully loaded prefab!"); } private void FixFonts() { // Get all fonts TMP_FontAsset[] loadedFonts = Resources.FindObjectsOfTypeAll(); // Get all text from the reveries window TMP_Text[] textComponents = _ingameReveriesUI.GetComponentsInChildren(true); foreach (TMP_Text textComp in textComponents) { if (textComp.font == null) continue; string originalFontName = textComp.font.name; // Match the font by name, ensuring we don't pick the dead assetbundle version foreach (TMP_FontAsset loadedFont in loadedFonts) { // Pick a matching font that has an active atlas/material if (loadedFont.name == originalFontName && loadedFont.atlasTexture != null) { textComp.font = loadedFont; // Force TMP to update its internal mesh and material reference textComp.ForceMeshUpdate(); textComp.SetAllDirty(); break; } } } } } }