1
0
forked from akanyan/mu3-mods

add offgeki

This commit is contained in:
2025-04-01 22:58:19 -06:00
parent 8c58151b81
commit 2ebd5fd29f
12 changed files with 644 additions and 0 deletions

BIN
Assets/icon-Offgeki.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -0,0 +1,22 @@
using MU3.Util;
namespace MU3.Battle;
class patch_EnemyFactory : EnemyFactory
{
extern public Enemy orig_create(EnemyParam param, CharacterPrefab prefab);
public new Enemy create(EnemyParam param, CharacterPrefab prefab)
{
Enemy enemy = orig_create(param, prefab);
Mod.State state = Singleton<Mod.State>.instance;
if (
(state.RemoveEnemy && enemy.name.Contains("Zako")) ||
(state.RemoveBoss && enemy.name.Contains("Boss"))
)
{
enemy?.gameObject.SetActive(false);
}
return enemy;
}
}

View File

@ -0,0 +1,16 @@
using MU3.Util;
namespace MU3.Battle;
class patch_EnemyManager : EnemyManager
{
extern void orig_playEnemyDamageUI(DamageParam dp);
public new void playEnemyDamageUI(DamageParam dp)
{
Mod.State state = Singleton<Mod.State>.instance;
if (!state.RemoveEnemy && !state.RemoveBullets)
{
orig_playEnemyDamageUI(dp);
}
}
}

View File

@ -0,0 +1,36 @@
using MU3.Util;
namespace MU3.Battle;
class patch_GameEngine
{
private Player _player;
private Ally[] _allies;
extern public void orig_createPlayer(StartCutscenePosition startCutscenePos, int charaId);
public void createPlayer(StartCutscenePosition startCutscenePos, int charaId)
{
orig_createPlayer(startCutscenePos, charaId);
if (Singleton<Mod.State>.instance.RemovePlayerGeki && _player)
{
_player.gameObject.SetActive(false);
}
}
extern public void orig_createAlly(int id, StartCutscenePosition startCutscenePos, int charaId, int allyNum);
public void createAlly(int id, StartCutscenePosition startCutscenePos, int charaId, int allyNum)
{
orig_createAlly(id, startCutscenePos, charaId, allyNum);
if (Singleton<Mod.State>.instance.RemoveAllyGekis)
{
foreach (var a in _allies)
{
if (a) {
a.gameObject.SetActive(false);
}
}
}
}
}

View File

@ -0,0 +1,111 @@
using MU3.Util;
namespace MU3.Mod;
class State: Singleton<State> {
public bool RemoveBackground { get; set; } = false;
public bool RemoveBackgroundFrame { get; set; } = false;
public bool RemoveHeader { get; set; } = false;
public bool RemoveFooter { get; set; } = false;
public bool RemovePlayerHealthUI { get; set; } = false;
public bool RemovePlayerBattleScoreUI { get; set; } = false;
public bool RemovePlayerScoreUI { get; set; } = false;
public bool RemoveEnemyUI { get; set; } = false;
public bool RemovePlayerCardUI { get; set; } = false;
public bool RemovePlayerGeki { get; set; } = false;
public bool RemoveAllyGekis { get; set; } = false;
public bool RemoveCharacterLine { get; set; } = false;
public bool RemoveEnemy { get; set; } = false;
public bool RemoveBoss { get; set; } = false;
public bool RemoveBullets { get; set; } = false;
public bool ReducedNoteFX { get; set; } = false;
public bool RemoveNoteFX { get; set; } = false;
public float BackgroundR { get; set; } = 0f;
public float BackgroundG { get; set; } = 0f;
public float BackgroundB { get; set; } = 0f;
private bool getValue(IniFile ini, string key)
{
UnityEngine.Debug.Log("Get value for key: " + key);
var value = ini.getValue("Offgeki", key, false);
UnityEngine.Debug.Log("Value: " + value);
return value;
}
private float getColorValue(IniFile ini, string key)
{
UnityEngine.Debug.Log("Get color value for key: " + key);
var value = ini.getValue("Offgeki", key, 0f);
// Ceiling to 255
if (value > 255)
{
value = 255;
}
// Divide by 255
value = value / 255.0f;
UnityEngine.Debug.Log("Value: " + value);
return value;
}
public void Init()
{
UnityEngine.Debug.Log("[Nogeki] Initializing State");
using IniFile ini = new("mu3.ini");
RemoveBackground = getValue(ini, "RemoveBackground");
RemoveBackgroundFrame = getValue(ini, "RemoveBackgroundFrame");
RemoveHeader = getValue(ini, "RemoveHeader");
RemoveFooter = getValue(ini, "RemoveFooter");
RemovePlayerHealthUI = getValue(ini, "RemovePlayerHealthUI");
RemovePlayerBattleScoreUI = getValue(ini, "RemovePlayerBattleScoreUI");
RemovePlayerScoreUI = getValue(ini, "RemovePlayerScoreUI");
RemovePlayerCardUI = getValue(ini, "RemovePlayerCardUI");
RemoveEnemyUI = getValue(ini, "RemoveEnemyUI");
RemovePlayerGeki = getValue(ini, "RemovePlayerGeki");
RemoveAllyGekis = getValue(ini, "RemoveAllyGekis");
RemoveCharacterLine = getValue(ini, "RemoveCharacterLine");
RemoveEnemy = getValue(ini, "RemoveEnemy");
RemoveBoss = getValue(ini, "RemoveBoss");
RemoveBullets = getValue(ini, "RemoveBullets");
ReducedNoteFX = getValue(ini, "ReducedNoteFX");
RemoveNoteFX = getValue(ini, "RemoveNoteFX");
BackgroundR = getColorValue(ini, "BackgroundR");
BackgroundG = getColorValue(ini, "BackgroundG");
BackgroundB = getColorValue(ini, "BackgroundB");
UnityEngine.Debug.Log("[Nogeki] State initialized");
}
override public string ToString()
{
return "State: \n"
+ "\tRemove Background: " + RemoveBackground + "\n"
+ "\tRemove Background Frame: " + RemoveBackgroundFrame + "\n"
+ "\tRemove Header: " + RemoveHeader + "\n"
+ "\tRemove Footer: " + RemoveFooter + "\n"
+ "\tRemove Player Health UI: " + RemovePlayerHealthUI + "\n"
+ "\tRemove Player Battle Score UI: " + RemovePlayerBattleScoreUI + "\n"
+ "\tRemove Player Score UI: " + RemovePlayerScoreUI + "\n"
+ "\tRemove Player Card UI: " + RemovePlayerCardUI + "\n"
+ "\tRemove Enemy UI: " + RemoveEnemyUI + "\n"
+ "\tRemove Player Geki: " + RemovePlayerGeki + "\n"
+ "\tRemove Ally Gekis: " + RemoveAllyGekis + "\n"
+ "\tRemove Enemy: " + RemoveEnemy + "\n"
+ "\tRemove Boss: " + RemoveBoss + "\n"
+ "\tRemove Bullets: " + RemoveBullets + "\n"
+ "\tRemove Bright Note FX: " + ReducedNoteFX + "\n"
+ "\tRemove All Note FX: " + RemoveNoteFX + "\n"
+ "\tRemove Character Line: " + RemoveCharacterLine + "\n"
+ "\tBackground R: " + BackgroundR + "\n"
+ "\tBackground G: " + BackgroundG + "\n"
+ "\tBackground B: " + BackgroundB + "\n";
}
}

View File

@ -0,0 +1,230 @@
using UnityEngine;
using MU3.Util;
using MU3.Game;
using UnityEngine.SceneManagement;
using System.Linq;
using System.Collections.Generic;
namespace MU3.Sequence;
class patch_PlayMusic : PlayMusic
{
private SessionInfo _sessionInfo;
//private State _state = State;
private bool _nogeki_removed = false;
private bool _nogeki_enabled = false;
private GameObject _offgeki_bg;
private void disableEffect(GameObject effect)
{
var childCount = effect.transform.childCount;
effect.transform.DetachChildren();
effect.transform.localScale = new Vector3(0, 0, 0);
effect.SetActive(false);
}
private extern void orig_Execute_SetupScene();
private void Execute_SetupScene()
{
Mod.State state = Singleton<Mod.State>.instance;
state.Init();
orig_Execute_SetupScene();
if (state.RemoveBackground && _offgeki_bg == null)
{
// Create a black quad that fills the screen
GameObject bgQuad = GameObject.CreatePrimitive(PrimitiveType.Quad);
bgQuad.name = "OffgekiBackground";
// Scale it to cover the view
bgQuad.transform.localScale = new Vector3(10000, 10000, 1);
// Position it far behind other elements
bgQuad.transform.position = new Vector3(0, 0, 500);
// Assign the material
bgQuad.GetComponent<Renderer>().material = new(Shader.Find("Unlit/Color"))
{
color = new Color(state.BackgroundR, state.BackgroundG, state.BackgroundB)
};
_offgeki_bg = bgQuad;
}
// Remove canvases
SystemUI systemUI = SingletonMonoBehaviour<SystemUI>.instance;
List<string> disableCanvases = [];
if (state.RemoveBackground)
{
disableCanvases.Add("Canvas_P_Background");
disableCanvases.Add("Canvas_P_FadeOut");
}
if (state.RemoveHeader)
{
disableCanvases.Add("Canvas_P_UserData");
disableCanvases.Add("Canvas_P_Signage");
}
if (state.RemoveFooter)
{
disableCanvases = [
..disableCanvases,
"Canvas_P_SystemButton",
"Canvas_P_ButtonGuide",
"Canvas_P_Credit"
];
}
foreach (var item in systemUI.GetComponentsInChildren<Canvas>())
{
if (!item.enabled) continue;
if (disableCanvases.Contains(item.name))
{
item.enabled = false;
}
}
string name = $"st_{_sessionInfo.stageId:0000}";
Scene sceneByName = SceneManager.GetSceneByName(name);
GameObject[] rootObjects = sceneByName.GetRootGameObjects();
foreach (var obj in rootObjects)
{
if (obj.name == "BattleStage(Clone)" && state.RemoveBackgroundFrame)
{
obj.SetActive(false);
continue;
}
if (obj.name == "NotesPrimitiveManager(Clone)")
{
PrimitiveMesh[] childs = obj.GetComponentsInChildren<PrimitiveMesh>();
for (int i = 0; i < childs.Length; i++)
{
if (i == 2)
{
PrimitiveMesh child = childs[i];
child.gameObject.SetActive(false);
}
}
}
}
List<string> disableCharacterLines = state.RemoveCharacterLine ? [
"fd_charaline",
"fd_charaline(Clone)",
"fd_charapole",
"fd_charapole (1)",
"fd_charazone",
"fd_checkpole",
"fd_checkpole (1)",
"fd_zonetry",
] : [];
List<string> disableBullets = state.RemoveBullets ? [
"FX_Bullet_03_Hit(Clone)",
"FX_Bullet_03_Break(Clone)",
"FX_Bullet_03_CBreak(Clone)",
"FX_Bullet_02_Hit(Clone)",
"FX_Bullet_02_Break(Clone)",
"FX_Bullet_02_CBreak(Clone)",
"FX_Bullet_Hit(Clone)",
"FX_Bullet_Break(Clone)",
"FX_Bullet_CBreak(Clone)",
] : [];
List<string> disableHitFX = state.RemoveNoteFX ? [
"EffectCache_attachBell",
"EffectCache_flickHit",
"EffectCache_flickBreak",
"EffectCache_flickCBreak",
"EffectCache_flickPBreak",
"EffectCache_crFlickHit",
"EffectCache_crFlickBreak",
"EffectCache_crFlickCBreak",
"EffectCache_crFlickPBreak",
"EffectCache_normalHit",
"EffectCache_normalBreak",
"EffectCache_normalCBreak",
"EffectCache_normalPBreak",
"EffectCache_holdEndHit",
"EffectCache_holdEndBreak",
"EffectCache_holdEndCBreak",
"EffectCache_holdEndPBreak",
"EffectCache_holdKeep",
"FX_Tap_PBreak(Clone)",
"FX_Tap_CBreak(Clone)",
"FX_Tap_Break(Clone)",
"FX_Tap_Hit(Clone)",
"FX_Release_PBreak(Clone)",
] : [];
List<string> reducedNoteFX = state.ReducedNoteFX ? [
"EffectCache_holdEndCBreak",
"EffectCache_holdEndPBreak",
"EffectCache_holdKeep",
"EffectCache_crFlickPBreak",
"EffectCache_flickPBreak",
] : [];
List<string> disableBulletFX = state.RemoveBullets ? [
"hitZako",
"criticalZako",
"explosionZako",
"EffectCache_explosionZako",
"EffectCache_hitZako",
"EffectCache_criticalZako",
"hitBoss",
"criticalBoss",
"explosionBoss",
"EffectCache_explosionBoss",
"EffectCache_hitBoss",
"EffectCache_criticalBoss",
] : [];
List<string> disableNames = [
..disableCharacterLines,
..disableBullets,
..disableHitFX,
..reducedNoteFX,
..disableBulletFX,
];
Transform[] arrTransforms = Resources.FindObjectsOfTypeAll<Transform>().Where((s) => (s.hideFlags == HideFlags.None)).ToArray();
for (int i = 0; i < arrTransforms.Length; i++)
{
//UnityEngine.Debug.Log($"[Nogeki] Transform: {arrTransforms[i].name}");
if (disableNames.Contains(arrTransforms[i].name))
{
disableEffect(arrTransforms[i].gameObject);
}
}
}
private extern void orig_Enter_DispCombo();
private void Enter_DispCombo()
{
SystemUI systemUI = SingletonMonoBehaviour<SystemUI>.instance;
foreach (var item in systemUI.GetComponentsInChildren<Canvas>())
{
if (item.enabled) continue;
item.enabled = true;
}
orig_Enter_DispCombo();
}
}

View File

@ -0,0 +1,24 @@
using MU3.CustomUI;
using MU3.Util;
using UnityEngine;
namespace MU3;
class patch_ANM_PLY_score : ANM_PLY_score
{
private GameObject _baseBattleScore;
private MU3UICounter[] _scoreCountersMU3;
extern private void orig_Awake();
private void Awake()
{
orig_Awake();
if (Singleton<Mod.State>.instance.RemovePlayerBattleScoreUI)
{
_baseBattleScore.SetActive(value: false);
_scoreCountersMU3[0].gameObject.SetActive(value: false);
}
}
}

View File

@ -0,0 +1,53 @@
using MU3.Util;
using UnityEngine;
using System.Collections.Generic;
namespace MU3;
public class patch_BattleUI : BattleUI
{
private extern void orig_Awake();
public extern void orig_dispFinish();
private void Awake()
{
orig_Awake();
Mod.State state = Singleton<Mod.State>.instance;
state.Init();
List<string> disabled = [];
if (state.RemoveBackground)
{
disabled.Add("CVS_SurfBoard3D");
}
if (state.RemoveEnemyUI)
{
disabled.Add("CVS_PLY_EnemyDamage");
disabled.Add("CVS_PLY_Enemyinfo_00");
}
if (state.RemovePlayerCardUI)
{
disabled.Add("CVS_PLY_Cardinfo_00");
}
foreach (var item in GetComponentsInChildren<Canvas>())
{
if (item.enabled && disabled.Contains(item.name)){
item.enabled = false;
}
}
}
public void dispFinish()
{
foreach (var item in GetComponentsInChildren<Canvas>())
{
item.enabled = true;
}
orig_dispFinish();
}
}

View File

@ -0,0 +1,17 @@
using MU3.Util;
namespace MU3;
class patch_UIPlayerInfo : UIPlayerInfo
{
private ANM_PLY_life _playerLife;
extern private void orig_create();
private new void create()
{
orig_create();
if(Singleton<Mod.State>.instance.RemovePlayerHealthUI)
{
_playerLife.gameObject.SetActive(false);
}
}
}

View File

@ -0,0 +1,9 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.Offgeki.mm</AssemblyName>
<Description>Modular removal of UI elements</Description>
<Version>1.0.0</Version>
<OutCategory>extras</OutCategory>
</PropertyGroup>
<Import Project="..\..\Mu3Mods.csproj" />
</Project>

120
Extras/Offgeki/README.md Normal file
View File

@ -0,0 +1,120 @@
# Offgeki
Modular removal of UI elements.
Currently only supports removing elements during music play.
Potentially will support removing elements during other parts of the game.
## Features
- Remove various UI elements during music play
- Background
- Player UI Elements
- Health
- Battle Score
- Technical Score
- Enemy UI Elements
- Health
- Bullets
- Gekis (enemies, boss, player, allies)
- NoteFX
## Installation
1. Install BepInEx
2. Drop the `Assembly-CSharp.Offgeki.mm.dll` file into the `BepInEx/monomod` folder
3. Launch the game
## Configuration
Populate these values in `mu3.ini` to configure the mod.
```
[Offgeki]
RemoveBackground = 1
RemoveBackgroundFrame = 1
RemoveSignage = 1
RemovePlayerHealthUI = 1
RemovePlayerBattleScoreUI = 1
RemovePlayerScoreUI = 0
RemovePlayerCardUI = 1
RemoveEnemyUI = 1
RemovePlayerGeki = 1
RemoveAllyGekis = 0
RemoveCharacterLine = 1
RemoveEnemy = 1
RemoveBoss = 0
RemoveBullets = 1
ReducedNoteFX = 1
RemoveNoteFX = 0
BackgroundR = 25
BackgroundG = 25
BackgroundB = 25
```
## Details
### RemoveBackground
Removes the background. A blue frame is still present, but the background is removed.
### RemoveBackgroundFrame
Removes the blue framing in the background
### RemoveSignage
Removes the header and footer sections
### RemovePlayerHealthUI
Removes the player's health
### RemovePlayerBattleScoreUI
Removes the player's battle score
### RemovePlayerScoreUI
Removes the player's technical score
### RemovePlayerCardUI
Removes the player/ally card UI
### RemoveEnemyUI
Removes the enemy's health
### RemovePlayerGeki
Removes the player's geki
### RemoveAllyGekis
Removes the ally's gekis
(Currently does not allow no player and allies)
### RemoveCharacterLine
Removes the lines and area rendering underneath player characters.
Retains the note judgement line.
### RemoveEnemy
Removes the enemies (Zekos)
### RemoveBoss
Removes the boss
### RemoveBullets
Removes the bullets
### ReducedNoteFX
Reduces the note FX a bit by disabling a few FX but not all
### RemoveNoteFX
Removes all note FX
### BackgroundR
Background color red value
### BackgroundG
Background color green value
### BackgroundB
Background color blue value
## Known Issues
- Unable to show only allies and not primary character. Probably due to the allies being anchored to the primary character.
- Some stages have background overlay that color the background a bit differently.
- Signage doesn't return after play. Will need to revise when the canvas's are reactivated.
- Need to fix player damage effect

View File

@ -52,6 +52,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestMenuConfig", "Extras\Te
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExclusiveAudio", "Fixes\ExclusiveAudio\ExclusiveAudio.csproj", "{0043743F-24B5-4A39-838E-964091AC7FF1}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExclusiveAudio", "Fixes\ExclusiveAudio\ExclusiveAudio.csproj", "{0043743F-24B5-4A39-838E-964091AC7FF1}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Offgeki", "Extras\Offgeki\Offgeki.csproj", "{A052743F-24B5-4A39-838E-964091AC7FF1}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
@ -158,6 +160,10 @@ Global
{0043743F-24B5-4A39-838E-964091AC7FF1}.Debug|x64.Build.0 = Debug|x64 {0043743F-24B5-4A39-838E-964091AC7FF1}.Debug|x64.Build.0 = Debug|x64
{0043743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.ActiveCfg = Release|x64 {0043743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.ActiveCfg = Release|x64
{0043743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.Build.0 = Release|x64 {0043743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.Build.0 = Release|x64
{A052743F-24B5-4A39-838E-964091AC7FF1}.Debug|x64.ActiveCfg = Debug|x64
{A052743F-24B5-4A39-838E-964091AC7FF1}.Debug|x64.Build.0 = Debug|x64
{A052743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.ActiveCfg = Release|x64
{A052743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE