forked from akanyan/mu3-mods
feat: implement TestMenuConfig
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
using MonoMod;
|
using MonoMod;
|
||||||
using MU3.Battle;
|
using MU3.Battle;
|
||||||
using MU3.Data;
|
|
||||||
using MU3.Game;
|
using MU3.Game;
|
||||||
using MU3.Util;
|
using MU3.Util;
|
||||||
|
|
||||||
@ -10,15 +9,24 @@ class patch_PlayMusic: PlayMusic {
|
|||||||
private GameEngine _gameEngine;
|
private GameEngine _gameEngine;
|
||||||
private SessionInfo _sessionInfo;
|
private SessionInfo _sessionInfo;
|
||||||
private bool _nuclearSkip = false;
|
private bool _nuclearSkip = false;
|
||||||
|
private bool _quickStart = false;
|
||||||
|
|
||||||
[MonoModIgnore]
|
[MonoModIgnore]
|
||||||
private extern bool isPartyPlay();
|
private extern bool isPartyPlay();
|
||||||
|
|
||||||
|
[MonoModIgnore]
|
||||||
|
private extern void Enter_ShowBonusStart();
|
||||||
|
|
||||||
|
private void Leave_LoadScene() {
|
||||||
|
using IniFile iniFile = new("mu3.ini");
|
||||||
|
_quickStart = iniFile.getValue("Sequence", "QuickStart", false);
|
||||||
|
}
|
||||||
|
|
||||||
private extern void orig_Execute_StartCutscene();
|
private extern void orig_Execute_StartCutscene();
|
||||||
private void Execute_StartCutscene() {
|
private void Execute_StartCutscene() {
|
||||||
orig_Execute_StartCutscene();
|
orig_Execute_StartCutscene();
|
||||||
Singleton<Mod.State>.instance.SkipEntry = false;
|
Singleton<Mod.State>.instance.SkipEntry = false;
|
||||||
if(Singleton<Sys.System>.instance.config.isQuickStart || Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.MenuLeft)) {
|
if(_quickStart || Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.MenuLeft)) {
|
||||||
Singleton<Mod.State>.instance.SkipEntry = true;
|
Singleton<Mod.State>.instance.SkipEntry = true;
|
||||||
_gameEngine.skipStartCutscene();
|
_gameEngine.skipStartCutscene();
|
||||||
if(isPartyPlay()) {
|
if(isPartyPlay()) {
|
||||||
@ -45,8 +53,8 @@ class patch_PlayMusic: PlayMusic {
|
|||||||
setNextState(EState.CalcResult);
|
setNextState(EState.CalcResult);
|
||||||
}
|
}
|
||||||
if(state > EState.CalcResult) {
|
if(state > EState.CalcResult) {
|
||||||
int selectorID = SingletonStateMachine<DataManager, DataManager.EState>.instance.getMemoryChapterData(_sessionInfo.chapterSelection.memoryChapterId)?.getMemoryChapterSelectorID() ?? 4;
|
Enter_ShowBonusStart();
|
||||||
Singleton<GameSound>.instance.gameBGM.playBGM(236, selectorID);
|
SingletonMonoBehaviour<SystemUI>.instance.destroySkipButton(true);
|
||||||
setNextState(EState.End);
|
setNextState(EState.End);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
247
Extras/TestMenuConfig/MU3.Mod/TestModePageModConfig.cs
Normal file
247
Extras/TestMenuConfig/MU3.Mod/TestModePageModConfig.cs
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
using MU3.TestMode;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace MU3.Mod;
|
||||||
|
|
||||||
|
class TestModePageModConfig: TestModePage {
|
||||||
|
class Option {
|
||||||
|
public int selection;
|
||||||
|
public string sectionName;
|
||||||
|
public string fieldName;
|
||||||
|
public ItemDefine itemDefine;
|
||||||
|
public List<KeyValuePair<string, string>> values;
|
||||||
|
|
||||||
|
public Option(string label, string fieldName, Dictionary<string, string> values, int indexDefault, bool selectable, string sectionName = "Extra") {
|
||||||
|
this.values = values.ToList();
|
||||||
|
this.fieldName = fieldName;
|
||||||
|
this.sectionName = sectionName;
|
||||||
|
|
||||||
|
itemDefine = new ItemDefine {
|
||||||
|
lineNumber = 0,
|
||||||
|
label = label,
|
||||||
|
isSelectable = selectable,
|
||||||
|
hasValueField = true,
|
||||||
|
numValueField = 1,
|
||||||
|
nextPagePrefab = null,
|
||||||
|
isFinishOnSelect = false,
|
||||||
|
isDefaultSelection = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
using IniFile iniFile = new("mu3.ini");
|
||||||
|
var previous = iniFile.getValue(sectionName, fieldName, values.ElementAt(indexDefault).Value);
|
||||||
|
var found = this.values.FindIndex(i => i.Value == previous);
|
||||||
|
if(found == -1) {
|
||||||
|
itemDefine.isSelectable = false;
|
||||||
|
} else {
|
||||||
|
selection = found == -1 ? indexDefault : found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Option> _options;
|
||||||
|
private Dictionary<string, string> _onOff;
|
||||||
|
private bool _isDisableGPActive;
|
||||||
|
private MethodInfo _writeToFile;
|
||||||
|
|
||||||
|
protected new void Awake() {
|
||||||
|
_titles = [
|
||||||
|
"MODS"
|
||||||
|
];
|
||||||
|
_itemNum = 1;
|
||||||
|
_bottomMargin = 0.3f;
|
||||||
|
_leftMargin = 0.12f;
|
||||||
|
_rightMargin = 0f;
|
||||||
|
|
||||||
|
_options = [];
|
||||||
|
_onOff = new Dictionary<string, string>() {
|
||||||
|
{ "OFF", "0" },
|
||||||
|
{ "ON", "1" }
|
||||||
|
};
|
||||||
|
_isDisableGPActive = typeof(UICredit).GetMethod("orig_initialize") != null;
|
||||||
|
_writeToFile = typeof(IniFile).GetMethod("writeToFile", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
writeOtherOptions();
|
||||||
|
|
||||||
|
base.Awake();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void createItems() {
|
||||||
|
FieldInfo itemsFi = typeof(TestModePage).GetField("_itemDefines", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
FieldInfo opFi = typeof(TestModePage).GetField("_opType", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
_options.Add(new Option(
|
||||||
|
"BGM",
|
||||||
|
"BGM",
|
||||||
|
new Dictionary<string, string> {
|
||||||
|
{ "ORIGINAL", "1" },
|
||||||
|
{ "SUMMER", "2" },
|
||||||
|
{ "R.E.D.", "3" },
|
||||||
|
{ "bright", "4" },
|
||||||
|
{ "END CHAPTER", "5" },
|
||||||
|
{ "bright MEMORY Act.3", "6" },
|
||||||
|
{ "RANDOM", "0" }
|
||||||
|
},
|
||||||
|
5,
|
||||||
|
typeof(Game.GameBGM).GetMethod("orig_playBGM") != null
|
||||||
|
));
|
||||||
|
|
||||||
|
_options.Add(new Option(
|
||||||
|
"HIDE CREDITS",
|
||||||
|
"HideCredits",
|
||||||
|
_onOff,
|
||||||
|
1,
|
||||||
|
_isDisableGPActive
|
||||||
|
));
|
||||||
|
|
||||||
|
_options.Add(new Option(
|
||||||
|
"HIDE GP",
|
||||||
|
"HideGP",
|
||||||
|
_onOff,
|
||||||
|
1,
|
||||||
|
_isDisableGPActive
|
||||||
|
));
|
||||||
|
|
||||||
|
_options.Add(new Option(
|
||||||
|
"HIDE VERSION",
|
||||||
|
"HideVersion",
|
||||||
|
_onOff,
|
||||||
|
0,
|
||||||
|
_isDisableGPActive
|
||||||
|
));
|
||||||
|
|
||||||
|
_options.Add(new Option(
|
||||||
|
"SKIP WEBCAM INITIALIZATION",
|
||||||
|
"SkipCamera",
|
||||||
|
_onOff,
|
||||||
|
1,
|
||||||
|
typeof(Data.DataStudioManager).GetMethod("orig_IsLoaded") != null,
|
||||||
|
"Sequence"
|
||||||
|
));
|
||||||
|
|
||||||
|
_options.Add(new Option(
|
||||||
|
"SKIP BATTLE INTRO",
|
||||||
|
"QuickStart",
|
||||||
|
_onOff,
|
||||||
|
0,
|
||||||
|
typeof(Sequence.PlayMusic).GetMethod("orig_updateState") != null,
|
||||||
|
"Sequence"
|
||||||
|
));
|
||||||
|
|
||||||
|
_options.Add(new Option(
|
||||||
|
"FRAMERATE",
|
||||||
|
"Framerate",
|
||||||
|
new Dictionary<string, string> {
|
||||||
|
{ "60", "60" },
|
||||||
|
{ "120", "120" },
|
||||||
|
{ "144", "144" },
|
||||||
|
{ "165", "165" },
|
||||||
|
{ "240", "240" },
|
||||||
|
{ "UNLOCKED", "0" },
|
||||||
|
{ "VSYNC", "V" }
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
typeof(Notes.NotesManager).GetMethod("orig_initialize") != null,
|
||||||
|
"Video"
|
||||||
|
));
|
||||||
|
|
||||||
|
var itemDefs = _options.Select((x, idx) => {
|
||||||
|
x.itemDefine.lineNumber = idx;
|
||||||
|
return x.itemDefine;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
itemDefs.Add(new() {
|
||||||
|
lineNumber = 8,
|
||||||
|
label = "終了",
|
||||||
|
isSelectable = true,
|
||||||
|
isFinishOnSelect = true,
|
||||||
|
isDefaultSelection = true
|
||||||
|
});
|
||||||
|
|
||||||
|
itemsFi.SetValue(this, itemDefs.ToArray());
|
||||||
|
opFi.SetValue(this, OpType.Select);
|
||||||
|
|
||||||
|
base.createItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void onPostCreate(GameObject prefab, object arg) {
|
||||||
|
gameObject.SetActive(true);
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void onInitializeItem(Item item, int index) {
|
||||||
|
if(!item.define.hasValueField) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var op = _options[index];
|
||||||
|
|
||||||
|
if(op.fieldName == "Framerate") {
|
||||||
|
using IniFile iniFile = new("mu3.ini");
|
||||||
|
if(iniFile.getValue(op.sectionName, "VSync", false)) {
|
||||||
|
op.selection = op.values.FindIndex(i => i.Value == "V");
|
||||||
|
} else if(!op.itemDefine.isSelectable) {
|
||||||
|
item.setValueString(iniFile.getValue(op.sectionName, op.fieldName, "???"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setValueString(op.values[op.selection].Key);
|
||||||
|
item.setState(op.itemDefine.isSelectable ? Item.State.Selectable : Item.State.UnselectableTemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void onSelectItem(Item item, int index) {
|
||||||
|
if(!item.define.hasValueField || !item.define.isSelectable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var op = _options[index];
|
||||||
|
|
||||||
|
op.selection += 1;
|
||||||
|
op.selection %= op.values.Count();
|
||||||
|
|
||||||
|
item.setValueString(op.values[op.selection].Key);
|
||||||
|
|
||||||
|
using IniFile iniFile = new("mu3.ini");
|
||||||
|
using StreamWriter sw = new("mu3.ini");
|
||||||
|
|
||||||
|
var value = op.values[op.selection].Value;
|
||||||
|
if(op.fieldName == "Framerate") {
|
||||||
|
if(value == "V") {
|
||||||
|
iniFile.setValue(op.sectionName, op.fieldName, 0);
|
||||||
|
iniFile.setValue(op.sectionName, "VSync", 1);
|
||||||
|
} else {
|
||||||
|
iniFile.setValue(op.sectionName, op.fieldName, value);
|
||||||
|
iniFile.setValue(op.sectionName, "VSync", 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iniFile.setValue(op.sectionName, op.fieldName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeToFile.Invoke(iniFile, [sw]);
|
||||||
|
}
|
||||||
|
private void rewriteOption(IniFile ini, string sectionName, string fieldName, string defaultValue) {
|
||||||
|
;
|
||||||
|
ini.setValue(sectionName, fieldName, ini.getValue(sectionName, fieldName, defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeOtherOptions() {
|
||||||
|
using IniFile iniFile = new("mu3.ini");
|
||||||
|
using StreamWriter sw = new("mu3.ini");
|
||||||
|
|
||||||
|
rewriteOption(iniFile, "Sound", "WasapiExclusive", "0");
|
||||||
|
rewriteOption(iniFile, "AM", "IgnoreError", "1");
|
||||||
|
rewriteOption(iniFile, "Device", "CameraType", "1");
|
||||||
|
|
||||||
|
rewriteOption(iniFile, "Extra", "CacheDir", ".");
|
||||||
|
if(_isDisableGPActive) {
|
||||||
|
rewriteOption(iniFile, "Extra", "GP", "999");
|
||||||
|
}
|
||||||
|
if(typeof(User.UserManager).GetMethod("orig_getUserFumen") != null) {
|
||||||
|
rewriteOption(iniFile, "Extra", "BlacklistMin", "10000");
|
||||||
|
rewriteOption(iniFile, "Extra", "BlacklistMin", "19999");
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeToFile.Invoke(iniFile, [sw]);
|
||||||
|
}
|
||||||
|
}
|
40
Extras/TestMenuConfig/MU3.TestMode/patch_TestModePageTop.cs
Normal file
40
Extras/TestMenuConfig/MU3.TestMode/patch_TestModePageTop.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace MU3.TestMode;
|
||||||
|
|
||||||
|
internal class patch_TestModePageTop: TestModePageTop {
|
||||||
|
GameObject _testModePageModConfig;
|
||||||
|
|
||||||
|
protected override void createItems() {
|
||||||
|
_bottomMargin = 0.22f;
|
||||||
|
|
||||||
|
_testModePageModConfig = new("TestModePageModConfig");
|
||||||
|
_testModePageModConfig.SetActive(false);
|
||||||
|
_testModePageModConfig.transform.SetParent(transform.parent);
|
||||||
|
_testModePageModConfig.AddComponent<Mod.TestModePageModConfig>();
|
||||||
|
|
||||||
|
FieldInfo fi = typeof(TestModePage).GetField("_itemDefines", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
var defines = ((ItemDefine[])fi.GetValue(this)).ToList();
|
||||||
|
|
||||||
|
var n = defines.Count;
|
||||||
|
defines.Insert(n - 1, new() {
|
||||||
|
lineNumber = n - 1,
|
||||||
|
label = "MODS",
|
||||||
|
isSelectable = true,
|
||||||
|
hasValueField = false,
|
||||||
|
numValueField = 0,
|
||||||
|
nextPagePrefab = _testModePageModConfig,
|
||||||
|
isFinishOnSelect = false,
|
||||||
|
isDefaultSelection = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// The exit button
|
||||||
|
defines.Last().lineNumber += 1;
|
||||||
|
|
||||||
|
fi.SetValue(this, defines.ToArray());
|
||||||
|
|
||||||
|
base.createItems();
|
||||||
|
}
|
||||||
|
}
|
8
Extras/TestMenuConfig/TestMenuConfig.csproj
Normal file
8
Extras/TestMenuConfig/TestMenuConfig.csproj
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblyName>Assembly-CSharp.TestMenuConfig.mm</AssemblyName>
|
||||||
|
<Description>Test menu config</Description>
|
||||||
|
<OutCategory>extras</OutCategory>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="..\..\Mu3Mods.csproj" />
|
||||||
|
</Project>
|
@ -2,7 +2,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net35</TargetFramework>
|
<TargetFramework>net35</TargetFramework>
|
||||||
<Company>7EVENDAYS⇔HOLIDAYS</Company>
|
<Company>7EVENDAYS⇔HOLIDAYS</Company>
|
||||||
<Version>3.0.0.1</Version>
|
<Version>3.0.0.2</Version>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<Platforms>x64</Platforms>
|
<Platforms>x64</Platforms>
|
||||||
|
@ -48,6 +48,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blacklist", "Extras\Blackli
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestMenuScaling", "Fixes\TestMenuScaling\TestMenuScaling.csproj", "{8053743F-24B5-4A39-838E-964091AC7FF1}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestMenuScaling", "Fixes\TestMenuScaling\TestMenuScaling.csproj", "{8053743F-24B5-4A39-838E-964091AC7FF1}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestMenuConfig", "Extras\TestMenuConfig\TestMenuConfig.csproj", "{7043743F-24B5-4A39-838E-964091AC7FF1}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
@ -146,6 +148,10 @@ Global
|
|||||||
{8053743F-24B5-4A39-838E-964091AC7FF1}.Debug|x64.Build.0 = Debug|x64
|
{8053743F-24B5-4A39-838E-964091AC7FF1}.Debug|x64.Build.0 = Debug|x64
|
||||||
{8053743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.ActiveCfg = Release|x64
|
{8053743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.ActiveCfg = Release|x64
|
||||||
{8053743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.Build.0 = Release|x64
|
{8053743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{7043743F-24B5-4A39-838E-964091AC7FF1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{7043743F-24B5-4A39-838E-964091AC7FF1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{7043743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{7043743F-24B5-4A39-838E-964091AC7FF1}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
Reference in New Issue
Block a user