diff --git a/.beads/dolt-server.activity b/.beads/dolt-server.activity deleted file mode 100644 index ac205a7..0000000 --- a/.beads/dolt-server.activity +++ /dev/null @@ -1 +0,0 @@ -1774200743 \ No newline at end of file diff --git a/.beads/dolt-server.port b/.beads/dolt-server.port deleted file mode 100644 index f4c3ffd..0000000 --- a/.beads/dolt-server.port +++ /dev/null @@ -1 +0,0 @@ -14107 \ No newline at end of file diff --git a/src/HomuraHimeAudioMod/GUI/AudioMixerGUI.cs b/src/HomuraHimeAudioMod/GUI/AudioMixerGUI.cs index 21f4b2c..35dbf0c 100644 --- a/src/HomuraHimeAudioMod/GUI/AudioMixerGUI.cs +++ b/src/HomuraHimeAudioMod/GUI/AudioMixerGUI.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Text; using UnityEngine; using HarmonyLib; @@ -8,15 +9,21 @@ namespace HomuraHimeAudioMod.GUI public class AudioMixerGUI : MonoBehaviour { private bool isVisible = false; + private bool showConsole = true; private Vector2 scrollPosition; + private Vector2 consoleScrollPosition; private float margin = 10f; private float labelWidth = 140f; private float sliderWidth = 200f; private float buttonHeight = 25f; private float lineHeight = 30f; - private float windowWidth = 380f; - private float windowHeight = 520f; - private Rect windowRect = new Rect(10, 10, 380, 520); + private float windowWidth = 450f; + private float windowHeight = 580f; + private Rect windowRect = new Rect(10, 10, 450, 580); + + private const int MAX_CONSOLE_LINES = 100; + private List consoleLines = new List(); + private string lastEventContext = ""; private string[] enemyCueNames = new string[] { @@ -39,23 +46,105 @@ namespace HomuraHimeAudioMod.GUI "Player_Critical" }; + private Type cachedVoiceManagerType; + private Type cachedCFVoiceType; + private bool typesCached = false; + private int cachedVoiceCount = -1; + private float lastVoiceCountUpdate = 0f; + private const float VOICE_COUNT_UPDATE_INTERVAL = 0.5f; + private void Start() { - Plugin.Log.LogInfo("AudioMixerGUI started"); + AddConsoleLine("AudioMixerGUI started"); + AddConsoleLine("Press F1 to toggle GUI"); + AddConsoleLine("Press F2 to close"); + } + + private void OnDestroy() + { + RestoreCursorState(); } private void Update() { + if (!isVisible) + { + if (Cursor.lockState != CursorLockMode.Locked) + { + return; + } + } + if (UnityEngine.Input.GetKeyDown(KeyCode.F1)) { isVisible = !isVisible; - Plugin.Log.LogDebug($"Audio Mixer GUI: {(isVisible ? "VISIBLE" : "HIDDEN")}"); + UpdateCursorState(); + AddConsoleLine(isVisible ? "GUI Opened" : "GUI Closed"); } - if (UnityEngine.Input.GetKeyDown(KeyCode.F2)) + if (UnityEngine.Input.GetKeyDown(KeyCode.F2) && isVisible) { isVisible = false; + UpdateCursorState(); + AddConsoleLine("GUI Closed"); } + + if (Time.time - lastVoiceCountUpdate >= VOICE_COUNT_UPDATE_INTERVAL) + { + int newCount = GetCurrentVoiceCount(); + if (newCount != cachedVoiceCount) + { + cachedVoiceCount = newCount; + if (cachedVoiceCount >= 0) + { + AddConsoleLine($"Voice Count: {cachedVoiceCount}"); + } + } + lastVoiceCountUpdate = Time.time; + } + } + + private void UpdateCursorState() + { + if (isVisible) + { + Cursor.lockState = CursorLockMode.None; + Cursor.visible = true; + } + else + { + RestoreCursorState(); + } + } + + private void RestoreCursorState() + { + Cursor.lockState = CursorLockMode.Locked; + Cursor.visible = false; + } + + private void AddConsoleLine(string line) + { + if (!showConsole) return; + + string timestamp = Time.time.ToString("F2"); + consoleLines.Add($"[{timestamp}] {line}"); + + while (consoleLines.Count > MAX_CONSOLE_LINES) + { + consoleLines.RemoveAt(0); + } + } + + private void CacheTypes() + { + if (typesCached) return; + + cachedVoiceManagerType = FindTypeByName("FmodVoiceManager"); + cachedCFVoiceType = FindTypeByName("CFVoiceEventUtility"); + + typesCached = true; + AddConsoleLine($"Types cached: VoiceManager={cachedVoiceManagerType?.Name}, CFVoice={cachedCFVoiceType?.Name}"); } private void OnGUI() @@ -65,16 +154,24 @@ namespace HomuraHimeAudioMod.GUI windowRect.x = Mathf.Clamp(windowRect.x, 0, Screen.width - windowWidth - 10); windowRect.y = Mathf.Clamp(windowRect.y, 0, Screen.height - windowHeight - 10); - windowRect = UnityEngine.GUI.Window(0, windowRect, DrawMainWindow, "HomuraHime Audio Mixer (F1: Toggle | F2: Close)"); + windowRect = UnityEngine.GUI.Window(0, windowRect, DrawMainWindow, "HomuraHime Audio Mixer"); } private void DrawMainWindow(int windowID) { UnityEngine.GUI.DragWindow(new Rect(0, 0, windowWidth - 20, 25)); - scrollPosition = GUILayout.BeginScrollView(scrollPosition); + GUILayout.BeginHorizontal(); + showConsole = GUILayout.Toggle(showConsole, "Show Console", GUILayout.Width(100)); + GUILayout.FlexibleSpace(); + if (GUILayout.Button("Clear Log", GUILayout.Width(70))) + { + consoleLines.Clear(); + AddConsoleLine("Log cleared"); + } + GUILayout.EndHorizontal(); - GUILayout.Space(margin); + scrollPosition = GUILayout.BeginScrollView(scrollPosition); DrawHeader(); GUILayout.Space(margin); @@ -99,20 +196,75 @@ namespace HomuraHimeAudioMod.GUI GUILayout.EndScrollView(); + if (showConsole) + { + DrawConsole(); + } + GUILayout.BeginHorizontal(); GUILayout.Label($"v1.0.0 | F1: Toggle | F2: Close", GUILayout.Height(20)); GUILayout.EndHorizontal(); } + private void DrawConsole() + { + GUILayout.Box("CONSOLE LOG", GUILayout.Height(20)); + + consoleScrollPosition = GUILayout.BeginScrollView(consoleScrollPosition, GUILayout.Height(120)); + + GUIStyle logStyle = new GUIStyle(UnityEngine.GUI.skin.label) + { + fontSize = 10, + richText = true + }; + + Color normalColor = logStyle.normal.textColor; + Color warningColor = new Color(1f, 0.7f, 0.3f); + Color errorColor = new Color(1f, 0.4f, 0.4f); + Color infoColor = new Color(0.7f, 0.9f, 1f); + + for (int i = 0; i < consoleLines.Count; i++) + { + string line = consoleLines[i]; + GUIStyle lineStyle = new GUIStyle(logStyle); + + if (line.Contains("[ERROR]") || line.Contains("Error")) + { + lineStyle.normal.textColor = errorColor; + } + else if (line.Contains("[WARN]") || line.Contains("Warning")) + { + lineStyle.normal.textColor = warningColor; + } + else if (line.Contains("[GUI]") || line.Contains("Triggered") || line.Contains("Testing")) + { + lineStyle.normal.textColor = infoColor; + } + else + { + lineStyle.normal.textColor = normalColor; + } + + GUILayout.Label(line, lineStyle); + } + + GUILayout.EndScrollView(); + } + private void DrawHeader() { - GUILayout.BeginHorizontal(); + GUILayout.BeginVertical("box"); GUILayout.Label("=== HOMURAHIME AUDIO MIXER ===", GUILayout.Height(25)); - GUILayout.EndHorizontal(); + + int voiceCount = GetCurrentVoiceCount(); + string voiceStatus = voiceCount >= 0 ? $"{voiceCount}" : "N/A"; + string voiceWarning = voiceCount >= ModConfig.MaxVoiceCount.Value * 0.9f ? " (HIGH!)" : ""; GUILayout.BeginHorizontal(); - GUILayout.Label($"Voice Count: {GetCurrentVoiceCount()} | Max: {ModConfig.MaxVoiceCount.Value}", GUILayout.Height(20)); + GUILayout.Label($"Voice Count: {voiceStatus} / {ModConfig.MaxVoiceCount.Value}{voiceWarning}", GUILayout.Height(20)); GUILayout.EndHorizontal(); + + GUILayout.EndVertical(); } private void DrawVoiceControls() @@ -208,7 +360,7 @@ namespace HomuraHimeAudioMod.GUI private void DrawEnemyCueTestButtons() { GUILayout.BeginVertical("box"); - GUILayout.Label("TEST ENEMY CUES (Debug)", GUILayout.Height(20)); + GUILayout.Label("TEST ENEMY CUES", GUILayout.Height(20)); GUILayout.BeginHorizontal(); for (int i = 0; i < enemyCueNames.Length; i++) @@ -229,7 +381,7 @@ namespace HomuraHimeAudioMod.GUI private void DrawBattleCueTestButtons() { GUILayout.BeginVertical("box"); - GUILayout.Label("TEST BATTLE CUES (Debug)", GUILayout.Height(20)); + GUILayout.Label("TEST BATTLE CUES", GUILayout.Height(20)); GUILayout.BeginHorizontal(); for (int i = 0; i < battleCueNames.Length; i++) @@ -275,13 +427,14 @@ namespace HomuraHimeAudioMod.GUI { try { - var voiceManagerType = FindTypeByName("FmodVoiceManager"); - if (voiceManagerType != null) + if (!typesCached) CacheTypes(); + + if (cachedVoiceManagerType != null) { - var instance = AccessTools.Property(voiceManagerType, "Instance")?.GetValue(null); + var instance = AccessTools.Property(cachedVoiceManagerType, "Instance")?.GetValue(null); if (instance != null) { - var countProp = AccessTools.Property(voiceManagerType, "CountVoice"); + var countProp = AccessTools.Property(cachedVoiceManagerType, "CountVoice"); if (countProp != null) { return (int)countProp.GetValue(instance); @@ -290,6 +443,7 @@ namespace HomuraHimeAudioMod.GUI } } catch { } + return -1; } @@ -297,10 +451,16 @@ namespace HomuraHimeAudioMod.GUI { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { - foreach (var type in assembly.GetTypes()) + try + { + foreach (var type in assembly.GetTypes()) + { + if (type.Name.Contains(name)) + return type; + } + } + catch { - if (type.Name.Contains(name)) - return type; } } return null; @@ -308,50 +468,87 @@ namespace HomuraHimeAudioMod.GUI private void TestEnemyCue(string cueName) { + AddConsoleLine($"[GUI] Testing enemy cue: {cueName}"); Plugin.Log.LogDebug($"[GUI] Testing enemy cue: {cueName}"); + try { - var cfVoiceType = FindTypeByName("CFVoiceEventUtility"); - if (cfVoiceType != null) + if (!typesCached) CacheTypes(); + + if (cachedCFVoiceType != null) { - var playMethod = AccessTools.Method(cfVoiceType, "PlayCFVoice"); + var playMethod = AccessTools.Method(cachedCFVoiceType, "PlayCFVoice"); if (playMethod != null) { playMethod.Invoke(null, new object[] { cueName }); - Plugin.Log.LogDebug($"[GUI] Triggered enemy cue: {cueName}"); + AddConsoleLine($"[GUI] Triggered: {cueName}"); } + else + { + AddConsoleLine($"[GUI] Method not found: PlayCFVoice"); + } + } + else + { + AddConsoleLine($"[GUI] CFVoiceEventUtility not found"); } } catch (Exception ex) { + AddConsoleLine($"[GUI] Error: {ex.Message}"); Plugin.Log.LogWarning($"[GUI] Could not trigger enemy cue: {ex.Message}"); } } private void TestBattleCue(string cueName) { + AddConsoleLine($"[GUI] Testing battle cue: {cueName}"); Plugin.Log.LogDebug($"[GUI] Testing battle cue: {cueName}"); + try { - var cfVoiceType = FindTypeByName("CFVoiceEventUtility"); - if (cfVoiceType != null) + if (!typesCached) CacheTypes(); + + if (cachedCFVoiceType != null) { - var playMethod = AccessTools.Method(cfVoiceType, "PlayCFVoice"); + var playMethod = AccessTools.Method(cachedCFVoiceType, "PlayCFVoice"); if (playMethod != null) { playMethod.Invoke(null, new object[] { cueName }); - Plugin.Log.LogDebug($"[GUI] Triggered battle cue: {cueName}"); + AddConsoleLine($"[GUI] Triggered: {cueName}"); } + else + { + AddConsoleLine($"[GUI] Method not found: PlayCFVoice"); + } + } + else + { + AddConsoleLine($"[GUI] CFVoiceEventUtility not found"); } } catch (Exception ex) { + AddConsoleLine($"[GUI] Error: {ex.Message}"); Plugin.Log.LogWarning($"[GUI] Could not trigger battle cue: {ex.Message}"); } } private void LogCurrentConfig() { + AddConsoleLine("=== CONFIG DUMP ==="); + AddConsoleLine($"MaxVoiceCount: {ModConfig.MaxVoiceCount.Value}"); + AddConsoleLine($"DuckFadeTime: {ModConfig.DuckFadeTime.Value}"); + AddConsoleLine($"DuckVolume: {ModConfig.DuckVolume.Value}"); + AddConsoleLine($"EnemyIndicatorBoost: {ModConfig.EnemyIndicatorBoost.Value}"); + AddConsoleLine($"AlertSoundBoost: {ModConfig.AlertSoundBoost.Value}"); + AddConsoleLine($"AttackSoundBoost: {ModConfig.AttackSoundBoost.Value}"); + AddConsoleLine($"VoiceLimitFix: {ModConfig.EnableVoiceLimitFix.Value}"); + AddConsoleLine($"DuckingFix: {ModConfig.EnableDuckingFix.Value}"); + AddConsoleLine($"EnemyAudioBoost: {ModConfig.EnableEnemyAudioBoost.Value}"); + AddConsoleLine($"DebugLogging: {ModConfig.EnableDebugLogging.Value}"); + AddConsoleLine("==================="); + Plugin.Log.LogInfo("=== CURRENT AUDIO MOD CONFIG ==="); Plugin.Log.LogInfo($"MaxVoiceCount: {ModConfig.MaxVoiceCount.Value}"); Plugin.Log.LogInfo($"DuckFadeTime: {ModConfig.DuckFadeTime.Value}"); @@ -378,6 +575,8 @@ namespace HomuraHimeAudioMod.GUI ModConfig.EnableDuckingFix.Value = true; ModConfig.EnableEnemyAudioBoost.Value = true; ModConfig.EnableDebugLogging.Value = false; + + AddConsoleLine("[GUI] Config reset to defaults"); Plugin.Log.LogInfo("[GUI] Config reset to defaults"); } }