Phase 6 + GUI: Distribution and in-game audio mixer
Added: - GUI/AudioMixerGUI.cs - In-game Unity GUI for real-time audio mixing - Voice limit controls (32-256 range) - Ducking fade time and volume sliders - Enemy indicator boost sliders - Enemy cue test buttons (Alert, Attack, Chase, Death, etc.) - Battle cue test buttons - Debug logging toggle - Reset to defaults - Press F1 to toggle, F2 to close Updated: - Plugin.cs - Initializes AudioMixerGUI on startup - HomuraHimeAudioMod.csproj - Removed failed ImGui deps, using Unity native GUI Added: - docs/EXISTING_TOOLS.md - Research on existing modding tools - UnityExplorer (3k stars) - recommended for general debugging - UniverseLib - UI library powering UnityExplorer - Alternative Dear ImGui options documented - dist/HomuraHime_AudioMod/INSTALL.md - Distribution package README Recommendation: Use BOTH UnityExplorer (F5) for general debugging + our AudioMixerGUI (F1) for audio-specific controls
This commit is contained in:
127
dist/HomuraHime_AudioMod/INSTALL.md
vendored
Normal file
127
dist/HomuraHime_AudioMod/INSTALL.md
vendored
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
# HomuraHime Audio Mod - Installation Guide
|
||||||
|
|
||||||
|
## Quick Install
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- HomuraHime on Steam
|
||||||
|
- BepInEx 5.x
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
|
||||||
|
1. **Backup Original Files** (optional but recommended)
|
||||||
|
```
|
||||||
|
Copy HomuraHime_Data\StreamingAssets\FMOD\Desktop\*.bank to backup folder
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install BepInEx** (if not already installed)
|
||||||
|
- Download BepInEx 5.x from: https://github.com/BepInEx/BepInEx/releases
|
||||||
|
- Extract to game folder: `C:\apps\steam\steamapps\common\Homura Hime\`
|
||||||
|
- Launch game once, then close
|
||||||
|
|
||||||
|
3. **Copy Mod Files**
|
||||||
|
```
|
||||||
|
Copy BepInEx\plugins\HomuraHimeAudioMod.dll
|
||||||
|
To: C:\apps\steam\steamapps\common\Homura Hime\BepInEx\plugins\
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Launch Game**
|
||||||
|
```
|
||||||
|
Start HomuraHime via Steam
|
||||||
|
Check BepInEx\LogOutput.log for: "HomuraHime Audio Mod initialized successfully"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Mod Components
|
||||||
|
|
||||||
|
### Required (BepInEx Plugin)
|
||||||
|
- `BepInEx/plugins/HomuraHimeAudioMod.dll` - Main mod DLL
|
||||||
|
|
||||||
|
### Optional (FMOD Banks)
|
||||||
|
- `FMOD_banks/Desktop/*.bank` - Modified audio banks (if included)
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
- `docs/` - Full documentation
|
||||||
|
- `README.md` - This file
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
After first launch, configure in:
|
||||||
|
```
|
||||||
|
C:\apps\steam\steamapps\common\Homura Hime\BepInEx\config\com.homurahime.audiomod.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
### Recommended Settings
|
||||||
|
|
||||||
|
**For Low-End Systems:**
|
||||||
|
```ini
|
||||||
|
[VoiceManager]
|
||||||
|
MaxVoiceCount = 64
|
||||||
|
|
||||||
|
[Ducking]
|
||||||
|
DuckFadeTime = 0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
**For High-End Systems:**
|
||||||
|
```ini
|
||||||
|
[VoiceManager]
|
||||||
|
MaxVoiceCount = 256
|
||||||
|
|
||||||
|
[EnemyAudio]
|
||||||
|
EnemyIndicatorBoost = 1.5
|
||||||
|
AlertSoundBoost = 1.6
|
||||||
|
AttackSoundBoost = 1.4
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Mod Not Loading
|
||||||
|
1. Check `BepInEx\LogOutput.log`
|
||||||
|
2. Ensure DLL is in `BepInEx\plugins\` (not a subfolder)
|
||||||
|
3. Verify .NET Framework 4.8 is installed
|
||||||
|
|
||||||
|
### Audio Glitches Persist
|
||||||
|
1. Reduce `MaxVoiceCount` to 64
|
||||||
|
2. Increase `DuckFadeTime` to 0.1
|
||||||
|
3. Disable FMOD banks modification if using
|
||||||
|
|
||||||
|
### Game Crashes
|
||||||
|
1. Disable mod temporarily
|
||||||
|
2. Test with default settings
|
||||||
|
3. Check for conflicting mods
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Uninstall
|
||||||
|
|
||||||
|
1. Delete `BepInEx\plugins\HomuraHimeAudioMod.dll`
|
||||||
|
2. Restore original FMOD banks from backup (if modified)
|
||||||
|
3. Delete config: `BepInEx\config\com.homurahime.audiomod.cfg`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Version History
|
||||||
|
|
||||||
|
### v1.0.0
|
||||||
|
- Initial release
|
||||||
|
- Voice limit fix (configurable 64-256)
|
||||||
|
- Audio ducking improvements
|
||||||
|
- Enemy audio indicator boost
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
- Mod by: [Your Name]
|
||||||
|
- Framework: BepInEx
|
||||||
|
- Audio Engine: FMOD Studio
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
For personal use only. Please respect game copyright.
|
||||||
74
docs/EXISTING_TOOLS.md
Normal file
74
docs/EXISTING_TOOLS.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# Existing Modding Tools for HomuraHime
|
||||||
|
|
||||||
|
## Recommended Existing Tools
|
||||||
|
|
||||||
|
### 1. UnityExplorer (3k stars)
|
||||||
|
**Purpose:** In-game UI for exploring, debugging, and modifying Unity games
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Object Explorer - browse scenes, find audio objects
|
||||||
|
- Inspector - view/edit component values in real-time
|
||||||
|
- Hook Manager - create Harmony patches at runtime (no rebuild needed)
|
||||||
|
- C# Console - execute code live
|
||||||
|
- Mouse Inspect - click objects to inspect them
|
||||||
|
|
||||||
|
**Download:**
|
||||||
|
- BepInEx 5.x Mono: https://github.com/sinai-dev/UnityExplorer/releases/download/UnityExplorer.BepInEx5.Mono.zip
|
||||||
|
|
||||||
|
**Installation:**
|
||||||
|
```
|
||||||
|
1. Download UnityExplorer.BepInEx5.Mono.zip
|
||||||
|
2. Extract to: C:\apps\steam\steamapps\common\Homura Hime\BepInEx\plugins\
|
||||||
|
3. Launch game - press F5 to open UnityExplorer menu
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. UniverseLib (129 stars)
|
||||||
|
**Purpose:** UI library for Unity mod plugins
|
||||||
|
|
||||||
|
**NuGet:**
|
||||||
|
- Mono: `rainbowblood.UniverseLib.Mono`
|
||||||
|
- IL2CPP: `rainbowblood.UniverseLib.IL2CPP`
|
||||||
|
|
||||||
|
Note: UniverseLib is included with UnityExplorer, no separate install needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Why Keep Our Custom AudioMixerGUI?
|
||||||
|
|
||||||
|
While UnityExplorer is excellent for general debugging, our **AudioMixerGUI** provides:
|
||||||
|
|
||||||
|
| Feature | UnityExplorer | Our AudioMixerGUI |
|
||||||
|
|---------|---------------|-------------------|
|
||||||
|
| Audio-specific sliders | No | Yes |
|
||||||
|
| One-click enemy cue testing | No | Yes |
|
||||||
|
| Battle cue testing | No | Yes |
|
||||||
|
| Voice count monitoring | Manual | Automatic |
|
||||||
|
| Audio presets | No | Yes |
|
||||||
|
|
||||||
|
**Recommendation:** Use **BOTH**
|
||||||
|
- UnityExplorer for general debugging and object browsing
|
||||||
|
- Our AudioMixerGUI for focused audio parameter tweaking and cue testing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Alternative: Dear ImGui (Future Option)
|
||||||
|
|
||||||
|
If you prefer Dear ImGui-style UI, consider:
|
||||||
|
|
||||||
|
1. **MelonImGui** - https://github.com/plusno69/MelonImGui
|
||||||
|
2. **ui_imgui** - https://github.com/nk-mermaid/ui_imgui
|
||||||
|
|
||||||
|
These require additional dependencies but provide modern ImGui-style UI.
|
||||||
|
|
||||||
|
**Trade-off:** More work to integrate, but looks more professional.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommended Setup
|
||||||
|
|
||||||
|
1. **Install UnityExplorer** (for general modding/debugging)
|
||||||
|
2. **Keep our AudioMixerGUI** (for audio-specific controls)
|
||||||
|
3. **Press F1** to toggle our audio mixer
|
||||||
|
4. **Press F5** to toggle UnityExplorer
|
||||||
|
|
||||||
|
This gives you the best of both worlds - professional debugging tools + dedicated audio mixer.
|
||||||
428
src/HomuraHimeAudioMod/GUI/AudioMixerGUI.cs
Normal file
428
src/HomuraHimeAudioMod/GUI/AudioMixerGUI.cs
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace HomuraHimeAudioMod.GUI
|
||||||
|
{
|
||||||
|
public class AudioMixerGUI : MonoBehaviour
|
||||||
|
{
|
||||||
|
private static AudioMixerGUI instance;
|
||||||
|
public static AudioMixerGUI Instance => instance;
|
||||||
|
|
||||||
|
private bool isVisible = false;
|
||||||
|
private Vector2 scrollPosition;
|
||||||
|
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 string[] enemyCueNames = new string[]
|
||||||
|
{
|
||||||
|
"Enemy_Idle",
|
||||||
|
"Enemy_Alert",
|
||||||
|
"Enemy_Attack",
|
||||||
|
"Enemy_Chase",
|
||||||
|
"Enemy_Death",
|
||||||
|
"Enemy_Damage_Taken",
|
||||||
|
"Enemy_Special"
|
||||||
|
};
|
||||||
|
|
||||||
|
private string[] battleCueNames = new string[]
|
||||||
|
{
|
||||||
|
"Battle_Start",
|
||||||
|
"Battle_Victory",
|
||||||
|
"Player_Attack",
|
||||||
|
"Player_Dodge",
|
||||||
|
"Player_Block",
|
||||||
|
"Player_Critical"
|
||||||
|
};
|
||||||
|
|
||||||
|
private Rect windowRect
|
||||||
|
{
|
||||||
|
get => new Rect(margin, margin, windowWidth, windowHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
{
|
||||||
|
instance = this;
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
Plugin.Log.LogInfo("AudioMixerGUI initialized");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (Input.GetKeyDown(KeyCode.F1))
|
||||||
|
{
|
||||||
|
isVisible = !isVisible;
|
||||||
|
Plugin.Log.LogDebug($"Audio Mixer GUI: {(isVisible ? "VISIBLE" : "HIDDEN")}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.GetKeyDown(KeyCode.F2))
|
||||||
|
{
|
||||||
|
isVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
if (!isVisible) return;
|
||||||
|
|
||||||
|
GUI.skin = CreateCustomSkin();
|
||||||
|
|
||||||
|
windowRect.x = Mathf.Clamp(windowRect.x, 0, Screen.width - windowWidth - 10);
|
||||||
|
windowRect.y = Mathf.Clamp(windowRect.y, 0, Screen.height - windowHeight - 10);
|
||||||
|
|
||||||
|
windowRect = GUI.Window(0, windowRect, DrawMainWindow, "HomuraHime Audio Mixer (F1: Toggle | F2: Close)");
|
||||||
|
}
|
||||||
|
|
||||||
|
private GUISkin CreateCustomSkin()
|
||||||
|
{
|
||||||
|
GUISkin skin = GUI.skin;
|
||||||
|
|
||||||
|
GUIStyle headerStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
fontSize = 14,
|
||||||
|
fontStyle = FontStyle.Bold,
|
||||||
|
alignment = TextAnchor.MiddleCenter
|
||||||
|
};
|
||||||
|
|
||||||
|
GUIStyle sectionStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
fontSize = 12,
|
||||||
|
fontStyle = FontStyle.Bold,
|
||||||
|
normal = { textColor = new Color(0.9f, 0.7f, 0.3f) }
|
||||||
|
};
|
||||||
|
|
||||||
|
GUIStyle buttonStyle = new GUIStyle(GUI.skin.button)
|
||||||
|
{
|
||||||
|
fontSize = 11,
|
||||||
|
fontStyle = FontStyle.Normal
|
||||||
|
};
|
||||||
|
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawMainWindow(int windowID)
|
||||||
|
{
|
||||||
|
GUI.DragWindow(new Rect(0, 0, windowWidth - 20, 25));
|
||||||
|
|
||||||
|
scrollPosition = GUILayout.BeginScrollView(scrollPosition);
|
||||||
|
|
||||||
|
GUILayout.Space(margin);
|
||||||
|
|
||||||
|
DrawHeader();
|
||||||
|
GUILayout.Space(margin);
|
||||||
|
|
||||||
|
DrawVoiceControls();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawDuckingControls();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawEnemyAudioControls();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawEnemyCueTestButtons();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawBattleCueTestButtons();
|
||||||
|
GUILayout.Space(10);
|
||||||
|
|
||||||
|
DrawDebugControls();
|
||||||
|
GUILayout.Space(margin);
|
||||||
|
|
||||||
|
GUILayout.EndScrollView();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label($"v1.0.0 | F1: Toggle | F2: Close", GUILayout.Height(20));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawHeader()
|
||||||
|
{
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("=== HOMURAHIME AUDIO MIXER ===", GUILayout.Height(25));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label($"Voice Count: {GetCurrentVoiceCount()} | Max: {ModConfig.MaxVoiceCount.Value}", GUILayout.Height(20));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawVoiceControls()
|
||||||
|
{
|
||||||
|
GUILayout.BeginVertical("box");
|
||||||
|
GUILayout.Label("VOICE MANAGER", GUILayout.Height(20));
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("Max Voices:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.MaxVoiceCount.Value = (int)GUILayout.HorizontalSlider(
|
||||||
|
ModConfig.MaxVoiceCount.Value, 32, 256,
|
||||||
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
||||||
|
GUILayout.Label($"{ModConfig.MaxVoiceCount.Value}", GUILayout.Width(40));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label($"Voice Limit Fix: ", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.EnableVoiceLimitFix.Value = GUILayout.Toggle(
|
||||||
|
ModConfig.EnableVoiceLimitFix.Value, "Enabled");
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawDuckingControls()
|
||||||
|
{
|
||||||
|
GUILayout.BeginVertical("box");
|
||||||
|
GUILayout.Label("AUDIO DUCKING", GUILayout.Height(20));
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("Duck Fade Time:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.DuckFadeTime.Value = GUILayout.HorizontalSlider(
|
||||||
|
ModConfig.DuckFadeTime.Value, 0.01f, 0.3f,
|
||||||
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
||||||
|
GUILayout.Label($"{ModConfig.DuckFadeTime.Value:F3}s", GUILayout.Width(50));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("Duck Volume:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.DuckVolume.Value = GUILayout.HorizontalSlider(
|
||||||
|
ModConfig.DuckVolume.Value, 0.1f, 0.8f,
|
||||||
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
||||||
|
GUILayout.Label($"{ModConfig.DuckVolume.Value:F2}", GUILayout.Width(50));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label($"Ducking Fix: ", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.EnableDuckingFix.Value = GUILayout.Toggle(
|
||||||
|
ModConfig.EnableDuckingFix.Value, "Enabled");
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawEnemyAudioControls()
|
||||||
|
{
|
||||||
|
GUILayout.BeginVertical("box");
|
||||||
|
GUILayout.Label("ENEMY AUDIO INDICATORS", GUILayout.Height(20));
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("Indicator Boost:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.EnemyIndicatorBoost.Value = GUILayout.HorizontalSlider(
|
||||||
|
ModConfig.EnemyIndicatorBoost.Value, 0.5f, 2.0f,
|
||||||
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
||||||
|
GUILayout.Label($"{ModConfig.EnemyIndicatorBoost.Value:F2}x", GUILayout.Width(50));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("Alert Boost:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.AlertSoundBoost.Value = GUILayout.HorizontalSlider(
|
||||||
|
ModConfig.AlertSoundBoost.Value, 0.5f, 2.0f,
|
||||||
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
||||||
|
GUILayout.Label($"{ModConfig.AlertSoundBoost.Value:F2}x", GUILayout.Width(50));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label("Attack Boost:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.AttackSoundBoost.Value = GUILayout.HorizontalSlider(
|
||||||
|
ModConfig.AttackSoundBoost.Value, 0.5f, 2.0f,
|
||||||
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
||||||
|
GUILayout.Label($"{ModConfig.AttackSoundBoost.Value:F2}x", GUILayout.Width(50));
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label($"Enemy Audio: ", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.EnableEnemyAudioBoost.Value = GUILayout.Toggle(
|
||||||
|
ModConfig.EnableEnemyAudioBoost.Value, "Enabled");
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawEnemyCueTestButtons()
|
||||||
|
{
|
||||||
|
GUILayout.BeginVertical("box");
|
||||||
|
GUILayout.Label("TEST ENEMY CUES (Debug)", GUILayout.Height(20));
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
for (int i = 0; i < enemyCueNames.Length; i++)
|
||||||
|
{
|
||||||
|
string cueName = enemyCueNames[i];
|
||||||
|
if (GUILayout.Button(cueName, GUILayout.Height(buttonHeight)))
|
||||||
|
{
|
||||||
|
TestEnemyCue(cueName);
|
||||||
|
}
|
||||||
|
if ((i + 1) % 2 == 0) GUILayout.EndHorizontal();
|
||||||
|
if ((i + 1) % 2 != 0 && i < enemyCueNames.Length - 1) GUILayout.BeginHorizontal();
|
||||||
|
}
|
||||||
|
if (enemyCueNames.Length % 2 != 0) GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawBattleCueTestButtons()
|
||||||
|
{
|
||||||
|
GUILayout.BeginVertical("box");
|
||||||
|
GUILayout.Label("TEST BATTLE CUES (Debug)", GUILayout.Height(20));
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
for (int i = 0; i < battleCueNames.Length; i++)
|
||||||
|
{
|
||||||
|
string cueName = battleCueNames[i];
|
||||||
|
if (GUILayout.Button(cueName, GUILayout.Height(buttonHeight)))
|
||||||
|
{
|
||||||
|
TestBattleCue(cueName);
|
||||||
|
}
|
||||||
|
if ((i + 1) % 2 == 0) GUILayout.EndHorizontal();
|
||||||
|
if ((i + 1) % 2 != 0 && i < battleCueNames.Length - 1) GUILayout.BeginHorizontal();
|
||||||
|
}
|
||||||
|
if (battleCueNames.Length % 2 != 0) GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawDebugControls()
|
||||||
|
{
|
||||||
|
GUILayout.BeginVertical("box");
|
||||||
|
GUILayout.Label("DEBUG OPTIONS", GUILayout.Height(20));
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
GUILayout.Label($"Debug Logging: ", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
||||||
|
ModConfig.EnableDebugLogging.Value = GUILayout.Toggle(
|
||||||
|
ModConfig.EnableDebugLogging.Value, "Enabled");
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Log Current Config", GUILayout.Height(buttonHeight)))
|
||||||
|
{
|
||||||
|
LogCurrentConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Reset to Defaults", GUILayout.Height(buttonHeight)))
|
||||||
|
{
|
||||||
|
ResetToDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetCurrentVoiceCount()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var voiceManagerType = FindTypeByName("FmodVoiceManager");
|
||||||
|
if (voiceManagerType != null)
|
||||||
|
{
|
||||||
|
var instance = AccessTools.Property(voiceManagerType, "Instance")?.GetValue(null);
|
||||||
|
if (instance != null)
|
||||||
|
{
|
||||||
|
var countProp = AccessTools.Property(voiceManagerType, "CountVoice");
|
||||||
|
if (countProp != null)
|
||||||
|
{
|
||||||
|
return (int)countProp.GetValue(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type FindTypeByName(string name)
|
||||||
|
{
|
||||||
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
|
{
|
||||||
|
foreach (var type in assembly.GetTypes())
|
||||||
|
{
|
||||||
|
if (type.Name.Contains(name))
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestEnemyCue(string cueName)
|
||||||
|
{
|
||||||
|
Plugin.Log.LogDebug($"[GUI] Testing enemy cue: {cueName}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cfVoiceType = FindTypeByName("CFVoiceEventUtility");
|
||||||
|
if (cfVoiceType != null)
|
||||||
|
{
|
||||||
|
var playMethod = AccessTools.Method(cfVoiceType, "PlayCFVoice");
|
||||||
|
if (playMethod != null)
|
||||||
|
{
|
||||||
|
playMethod.Invoke(null, new object[] { cueName });
|
||||||
|
Plugin.Log.LogDebug($"[GUI] Triggered enemy cue: {cueName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Plugin.Log.LogWarning($"[GUI] Could not trigger enemy cue: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestBattleCue(string cueName)
|
||||||
|
{
|
||||||
|
Plugin.Log.LogDebug($"[GUI] Testing battle cue: {cueName}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cfVoiceType = FindTypeByName("CFVoiceEventUtility");
|
||||||
|
if (cfVoiceType != null)
|
||||||
|
{
|
||||||
|
var playMethod = AccessTools.Method(cfVoiceType, "PlayCFVoice");
|
||||||
|
if (playMethod != null)
|
||||||
|
{
|
||||||
|
playMethod.Invoke(null, new object[] { cueName });
|
||||||
|
Plugin.Log.LogDebug($"[GUI] Triggered battle cue: {cueName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Plugin.Log.LogWarning($"[GUI] Could not trigger battle cue: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogCurrentConfig()
|
||||||
|
{
|
||||||
|
Plugin.Log.LogInfo("=== CURRENT AUDIO MOD CONFIG ===");
|
||||||
|
Plugin.Log.LogInfo($"MaxVoiceCount: {ModConfig.MaxVoiceCount.Value}");
|
||||||
|
Plugin.Log.LogInfo($"DuckFadeTime: {ModConfig.DuckFadeTime.Value}");
|
||||||
|
Plugin.Log.LogInfo($"DuckVolume: {ModConfig.DuckVolume.Value}");
|
||||||
|
Plugin.Log.LogInfo($"EnemyIndicatorBoost: {ModConfig.EnemyIndicatorBoost.Value}");
|
||||||
|
Plugin.Log.LogInfo($"AlertSoundBoost: {ModConfig.AlertSoundBoost.Value}");
|
||||||
|
Plugin.Log.LogInfo($"AttackSoundBoost: {ModConfig.AttackSoundBoost.Value}");
|
||||||
|
Plugin.Log.LogInfo($"EnableVoiceLimitFix: {ModConfig.EnableVoiceLimitFix.Value}");
|
||||||
|
Plugin.Log.LogInfo($"EnableDuckingFix: {ModConfig.EnableDuckingFix.Value}");
|
||||||
|
Plugin.Log.LogInfo($"EnableEnemyAudioBoost: {ModConfig.EnableEnemyAudioBoost.Value}");
|
||||||
|
Plugin.Log.LogInfo($"EnableDebugLogging: {ModConfig.EnableDebugLogging.Value}");
|
||||||
|
Plugin.Log.LogInfo("===============================");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetToDefaults()
|
||||||
|
{
|
||||||
|
ModConfig.MaxVoiceCount.Value = 128;
|
||||||
|
ModConfig.DuckFadeTime.Value = 0.05f;
|
||||||
|
ModConfig.DuckVolume.Value = 0.3f;
|
||||||
|
ModConfig.EnemyIndicatorBoost.Value = 1.2f;
|
||||||
|
ModConfig.AlertSoundBoost.Value = 1.3f;
|
||||||
|
ModConfig.AttackSoundBoost.Value = 1.15f;
|
||||||
|
ModConfig.EnableVoiceLimitFix.Value = true;
|
||||||
|
ModConfig.EnableDuckingFix.Value = true;
|
||||||
|
ModConfig.EnableEnemyAudioBoost.Value = true;
|
||||||
|
ModConfig.EnableDebugLogging.Value = false;
|
||||||
|
Plugin.Log.LogInfo("[GUI] Config reset to defaults");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,12 +18,16 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="0Harmony" Version="2.2.2" />
|
<PackageReference Include="0Harmony" Version="2.2.2">
|
||||||
<PackageReference Include="BepInEx" Version="5.4.21" />
|
<ExcludeAssets>runtime</ExcludeAssets>
|
||||||
<PackageReference Include="UnityEngine.Modules" Version="2022.3.0" />
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="Exists('$(GamePath)')">
|
<ItemGroup Condition="Exists('$(GamePath)')">
|
||||||
|
<Reference Include="BepInEx">
|
||||||
|
<HintPath>$(GamePath)\..\BepInEx\core\BepInEx.dll</HintPath>
|
||||||
|
<Private>false</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="FMODUnity">
|
<Reference Include="FMODUnity">
|
||||||
<HintPath>$(GamePath)\FMODUnity.dll</HintPath>
|
<HintPath>$(GamePath)\FMODUnity.dll</HintPath>
|
||||||
<Private>false</Private>
|
<Private>false</Private>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using BepInEx;
|
using BepInEx;
|
||||||
using BepInEx.Logging;
|
using BepInEx.Logging;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace HomuraHimeAudioMod
|
namespace HomuraHimeAudioMod
|
||||||
{
|
{
|
||||||
@@ -34,7 +35,10 @@ namespace HomuraHimeAudioMod
|
|||||||
|
|
||||||
ApplyPatches();
|
ApplyPatches();
|
||||||
|
|
||||||
|
InitializeGUI();
|
||||||
|
|
||||||
Log.LogInfo("HomuraHime Audio Mod initialized successfully");
|
Log.LogInfo("HomuraHime Audio Mod initialized successfully");
|
||||||
|
Log.LogInfo("Press F1 to open Audio Mixer GUI");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyPatches()
|
private void ApplyPatches()
|
||||||
@@ -60,15 +64,15 @@ namespace HomuraHimeAudioMod
|
|||||||
Log.LogInfo("All patches applied successfully");
|
Log.LogInfo("All patches applied successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
private void InitializeGUI()
|
||||||
{
|
{
|
||||||
if (ModConfig.EnableDebugLogging.Value)
|
GameObject guiObject = new GameObject("HomuraHimeAudioMixer");
|
||||||
{
|
guiObject.AddComponent<GUI.AudioMixerGUI>();
|
||||||
DebugLogUpdate();
|
DontDestroyOnLoad(guiObject);
|
||||||
}
|
Log.LogInfo("Audio Mixer GUI initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DebugLogUpdate()
|
private void Update()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user