Compare commits

...

23 Commits
1.8.1 ... main

Author SHA1 Message Date
ca15fac6a1 fix: don't store SortByInternal in db 2024-08-30 17:20:26 +00:00
ebb78efcde fix: item popup disappearing 2024-08-30 14:54:59 +00:00
2204fb4756 fix: shop confirmation dialog not showing (#7)
Co-authored-by: Jujuforce <jujuforce@gmail.com>
Co-authored-by: akanyan <alicechecker01@proton.me>
Co-authored-by: あかニャン <akanyan@noreply.gitea.tendokyu.moe>
Reviewed-on: #7
Co-authored-by: jujuforce <jujuforce@noreply.gitea.tendokyu.moe>
Co-committed-by: jujuforce <jujuforce@noreply.gitea.tendokyu.moe>
2024-08-30 14:53:27 +00:00
66fdc27787 feat: implement InfiniteStory (#6)
Infinite Story mod
- Allows watching an infinite number of stories per session
- Skips the dialog about it when selecting a story

Co-authored-by: Jujuforce <jujuforce@gmail.com>
Co-authored-by: akanyan <alicechecker01@proton.me>
Reviewed-on: #6
Co-authored-by: jujuforce <jujuforce@noreply.gitea.tendokyu.moe>
Co-committed-by: jujuforce <jujuforce@noreply.gitea.tendokyu.moe>
2024-08-24 16:29:07 +00:00
032b6864da fix: cache mkdir
I originally left it out because I wanted to avoid unnecessary
code duplication. Turns out it wasn't unnecessary.
2024-08-24 14:14:02 +00:00
07ee892b43 feat: implement SelectBGM 2024-07-30 02:22:25 +09:00
920d2386d5 chore: bump to 2.1.0 2024-07-23 01:51:40 +09:00
4ad595f6c3 feat: various enhancements
* AttractVideoPlayer,LoadBoost: allow setting a cache directory
* AttractVideoPlayer: color leds
* BetterGiveUp: prevent multiple restarts in a row
* use GetTriggerOn in general where applicable
2024-07-23 01:45:36 +09:00
8cbc7e8b86 feat: implement AttractVideoPlayer (#2)
Service Button : Pause the attract video
L2/L3 Buttons : Previous/next to cycle through all the attract videos
Saving the selected video for future game launches

Co-authored-by: akanyan <alicechecker01@proton.me>
Reviewed-on: #2
Co-authored-by: jujuforce <jujuforce@noreply.gitea.tendokyu.moe>
Co-committed-by: jujuforce <jujuforce@noreply.gitea.tendokyu.moe>
2024-07-22 14:55:49 +00:00
7f5cd6d0d7 fix(PlatinumTiming): reset 2024-07-22 01:02:19 +09:00
381d888da6 feat(InfiniteGP): make UI changes optional 2024-07-21 22:07:16 +09:00
946402fa82 feat: implement PlatinumTiming
* Also fix icons in InfiniteGP.
2024-07-21 02:24:09 +09:00
b2ecf368fb fix(UnlockFrameRate): revert a bad idea 2024-07-12 08:32:49 +09:00
c349854cb0 fix: various fixes 2024-07-12 08:14:06 +09:00
26fffefbae fix(SkipPreMusic): allow permanent skip 2024-07-08 04:50:37 +09:00
5872a05c7b chore: bump to 2.0.0 2024-07-08 03:37:49 +09:00
c1954d76c1 feat(SkipPreMusic): now triggered by LMenu 2024-07-08 03:33:38 +09:00
579790663e feat(SkipNotice): merge SkipLoginReward back
Except it's now triggered by LMenu.
2024-07-08 03:19:01 +09:00
8a6ad2e523 docs: stop screwing around 2024-07-08 02:53:10 +09:00
079b7b6495 feat: remove ExportChartData 2024-07-08 02:17:59 +09:00
cc7bc8613b feat: add the remaining things
* DisableMaintenance
* UnlockAllMusic
* UnlockGameEvents
* UnlockMemoryChapters
2024-07-08 02:10:46 +09:00
42cf65bdb7 feat: add 4 things
* DisableEncryption
* LoadBoost
* UnlockFrameRate
* UnlockMasterDifficulty

WIP, not fully reviewed/tested yet.
2024-07-08 00:42:55 +09:00
b54b8676c1 feat(NaiveRating): make it togglable 2024-07-07 23:47:46 +09:00
70 changed files with 1321 additions and 216 deletions

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.AttractVideoPlayer.mm</AssemblyName>
<Description>Control attract video</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,57 @@
using System;
using System.Collections.ObjectModel;
using System.IO;
namespace MU3.Operation;
class patch_OperationManager: OperationManager {
private ReadOnlyCollection<MovieData> _movieDataList;
private int _movieIndex;
private string _fileName;
~patch_OperationManager() {
try {
File.WriteAllText(_fileName, MovieIndex.ToString());
} catch(Exception ex) {
System.Console.WriteLine(ex);
}
}
public int MovieIndex {
set {
if(_movieDataList.Count > 0) {
_movieIndex = (value + _movieDataList.Count) % _movieDataList.Count;
} else {
_movieIndex = 0;
}
}
get {
return _movieIndex;
}
}
public new MovieData movieData {
get {
if(_movieDataList.Count > 0) {
return _movieDataList[MovieIndex];
}
return null;
}
}
public extern void orig_initialize();
public new void initialize() {
orig_initialize();
using IniFile iniFile = new("mu3.ini");
var dir = iniFile.getValue("Extra", "CacheDir", ".");
Directory.CreateDirectory(dir);
_fileName = Path.Combine(dir, "data_advert_cache.txt");
try {
_movieIndex = Math.Max(0, int.Parse(File.ReadAllText(_fileName)));
} catch(Exception) {
_movieIndex = 0;
}
}
}

View File

@ -0,0 +1,20 @@
using MU3.Util;
namespace MU3.Sequence;
class patch_Advertise: Advertise {
// Exclude Back/Left/Right
private bool anyKeyDown() {
UIInput instance = Singleton<UIInput>.instance;
if(instance.getTriggerOn(UIInput.Key.Decision)
|| instance.getTriggerOn(UIInput.Key.OptionBackward)
|| instance.getTriggerOn(UIInput.Key.OptionForward)
|| instance.getTriggerOn(UIInput.Key.SkipLeft)
|| instance.getTriggerOn(UIInput.Key.SkipRight)
|| instance.getTriggerOn(UIInput.Key.MenuLeft)
|| instance.getTriggerOn(UIInput.Key.MenuRight)) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,53 @@
using MU3.Operation;
using MU3.Util;
using UnityEngine;
namespace MU3;
class patch_AdvManager: AdvManager {
private GameObject objMovie;
private CriManaMovieMaterial movieController;
private extern bool orig_exec();
public new bool exec() {
if(movieController?.player?.status == CriMana.Player.Status.Playing) {
if(Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.Service)) {
movieController.player.Pause(!movieController.player.IsPaused());
} else if(Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.L2)) {
addMovieOffset(-1);
} else if(Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.L3)) {
addMovieOffset(1);
}
}
return orig_exec();
}
public void addMovieOffset(int offset) {
var om = (patch_OperationManager)Singleton<OperationManager>.instance;
om.MovieIndex += offset;
movieController.Stop();
Utility.destroyGameObject(ref movieController);
Utility.destroyGameObject(ref objMovie);
initMovie();
}
public extern bool orig_initMovie();
public new bool initMovie() {
UIInput instance = Singleton<UIInput>.instance;
instance.setLedColor(UIInput.Key.L2, new Color(0f, 0.7f, 0f));
instance.setLedColor(UIInput.Key.L3, new Color(0f, 0.7f, 0f));
return orig_initMovie();
}
public extern void orig_exitMovie();
public new void exitMovie() {
orig_exitMovie();
UIInput instance = Singleton<UIInput>.instance;
instance.setLedColor(UIInput.Key.L2, Color.black);
instance.setLedColor(UIInput.Key.L3, Color.black);
}
}

View File

@ -13,6 +13,7 @@ class patch_PlayMusic: PlayMusic {
public static bool QuickSkip = false;
private GameEngine _gameEngine;
private SessionInfo _sessionInfo;
private bool _pressedYellow;
private bool _isRolling;
private float _totalRollingFrame;
private DateTime _rollingStartTime;
@ -30,11 +31,13 @@ class patch_PlayMusic: PlayMusic {
return min + (max - min) * Math.Pow(progress, 2.0);
}
private static bool IsHolding() {
return Singleton<UIInput>.instance.getStateOn(UIInput.Key.MenuLeft) ^ Singleton<UIInput>.instance.getStateOn(UIInput.Key.MenuRight);
private bool IsHolding() {
return Singleton<UIInput>.instance.getStateOn(UIInput.Key.MenuLeft)
^ (_pressedYellow && Singleton<UIInput>.instance.getStateOn(UIInput.Key.MenuRight));
}
private void StartRolling() {
_pressedYellow = false;
_isRolling = true;
_totalRollingFrame = ntMgr.getCurrentFrame();
_rollingStartTime = CustomDateTime.Now;
@ -60,6 +63,9 @@ class patch_PlayMusic: PlayMusic {
}
private void Execute_Play() {
if(Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.MenuRight)) {
_pressedYellow = true;
}
if(_isRolling) {
TimeSpan timeSpan = CustomDateTime.Now - _rollingStartTime;
if(timeSpan <= ROLL_DURATION) {

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.DisableEncryption.mm</AssemblyName>
<Description>Disable encryption</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,28 @@
using MonoMod;
namespace MU3;
[MonoModPatch("global::MU3.NetConfig")]
public static class patch_NetConfig {
private static int encryptVersion_;
private static bool useTLS_;
public static int EncryptVersion {
get {
return 0;
}
set {
encryptVersion_ = 0;
}
}
public static bool UseTLS {
get {
return false;
}
set {
useTLS_ = false;
}
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.DisableMaintenance.mm</AssemblyName>
<Description>Disable maintenance</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,27 @@
namespace MU3.Operation;
class patch_ClosingManager: ClosingManager {
public new int getRemainingMinutes() {
return int.MaxValue;
}
public new int getClosedRemainingMinutes() {
return int.MaxValue;
}
public new bool isShowRemainingMinutes() {
return false;
}
public new bool isReceptionClosed() {
return false;
}
public new bool isForceLogout() {
return false;
}
public new CreditUseRestriction getCreditUseRestriction() {
return CreditUseRestriction.None;
}
}

View File

@ -0,0 +1,47 @@
namespace MU3.Operation;
class patch_MaintenanceTimer: MaintenanceTimer {
public new bool isUnderServerMaintenance() {
return false;
}
public new int getServerMaintenanceSec() {
return int.MaxValue;
}
public new int getAutoRebootSec() {
return int.MaxValue;
}
public new bool isAutoRebootNeeded() {
return false;
}
public new int getRemainingMinutes() {
return int.MaxValue;
}
public new int getClosedRemainingMinutes() {
return int.MaxValue;
}
public new bool isShowRemainingMinutes() {
return false;
}
public new bool isClosed() {
return false;
}
public new bool isForceLogout() {
return false;
}
public new ClosingManager.CreditUseRestriction getCreditUseRestriction() {
return ClosingManager.CreditUseRestriction.None;
}
public new bool isCoinAcceptable() {
return true;
}
}

View File

@ -1,7 +0,0 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.ExportChartData.mm</AssemblyName>
<Description>Export chart data to charts.csv</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -1,58 +0,0 @@
using System.IO;
namespace MU3.Data;
class patch_DataManager: DataManager {
private extern void orig_linkFumenAnalysisData();
private const string SEPARATOR = "$";
private string PrintHeader() {
return string.Join(SEPARATOR, new string[] {
"id",
"name",
"difficulty",
"name for sort",
"artist",
"genre",
"internal level",
"charter",
"max platinum score",
"release date",
"release version",
"bpm",
"location"
});
}
private string PrintLine(FumenData fumen, MusicData mus, int level) {
return string.Join(SEPARATOR, new string[] {
mus.id.ToString(),
mus.name,
level.ToString(),
mus.nameForSort,
mus.artistName,
mus.genreName,
fumen.fumenConst.ToString(),
fumen.notesDesignerName ?? "",
fumen.platinumScoreMax.ToString(),
mus.ReleaseVersion.ToUniversalTime().ToString(),
mus.versionTitle,
fumen.bpm.ToString(),
fumen.fumenFile.Substring(fumen.fumenFile.LastIndexOf('A'))
});
}
private void linkFumenAnalysisData() {
orig_linkFumenAnalysisData();
using StreamWriter writer = new("charts.csv");
writer.WriteLine(PrintHeader());
foreach(var mus in allMusicData) {
int i = 0;
foreach(var fumen in mus.fumenData) {
if(fumen.isExist) {
writer.WriteLine(PrintLine(fumen, mus, i));
}
i += 1;
}
}
UnityEngine.Debug.Log("[ExportChartData] Written to charts.csv");
}
}

View File

@ -1,13 +1,12 @@
namespace MU3.User;
class patch_UserManager: UserManager {
public new const int DefaultGP = 666;
public new const int DefaultGP = 999;
private int _gp;
private OnUpdate _onUpdateGP;
private OnReset _onResetGP;
public new void resetGP() {
_gp = 999;
if(_onResetGP != null) {
_onResetGP(_gp);
}
@ -18,10 +17,20 @@ class patch_UserManager: UserManager {
return _gp;
}
private set {
_gp = 999;
if(_onUpdateGP != null) {
_onUpdateGP(_gp);
}
}
}
public new bool checkBattleGP(int needed) {
return true;
}
public extern void orig_initialize();
public new void initialize() {
orig_initialize();
using IniFile iniFile = new("mu3.ini");
_gp = iniFile.getIntValue("Extra", "GP", 999);
}
}

View File

@ -0,0 +1,55 @@
using MU3.CustomUI;
using UnityEngine;
namespace MU3;
class patch_UICredit: UICredit {
private Animator gpAnimator_;
private GameObject creditRoot_;
private MU3UICounter credit_;
private GameObject freePlayRoot_;
private GameObject gpRoot_;
private MU3UICounter gp_;
private MU3UICounter gpPlus_;
private MU3UICounter gpMinus_;
private MU3UIImageChanger netIcon_;
private MU3UIImageChanger groupIcon_;
private void onUpdateGP(int value) { /* nop */ }
public extern void orig_initialize();
public new void initialize() {
orig_initialize();
using IniFile iniFile = new("mu3.ini");
if(iniFile.getValue("Extra", "HideGP", true)) {
DestroyImmediate(gpAnimator_);
gpRoot_.transform.localScale = new Vector3(0, 0, 0);
gp_.transform.localScale = new Vector3(0, 0, 0);
gpPlus_.transform.localScale = new Vector3(0, 0, 0);
gpMinus_.transform.localScale = new Vector3(0, 0, 0);
}
if(iniFile.getValue("Extra", "HideCredits", true)) {
creditRoot_.transform.localScale = new Vector3(0, 0, 0);
credit_.transform.localScale = new Vector3(0, 0, 0);
freePlayRoot_.transform.localScale = new Vector3(0, 0, 0);
netIcon_.transform.localPosition = new Vector3(
-514,
netIcon_.transform.localPosition.y,
netIcon_.transform.localPosition.z
);
netIcon_.image.rectTransform.pivot = new Vector2(0f, 0.5f);
groupIcon_.transform.localPosition = new Vector3(
-476,
groupIcon_.transform.localPosition.y,
groupIcon_.transform.localPosition.z
);
groupIcon_.image.rectTransform.pivot = new Vector2(0f, 0.5f);
}
}
}

View File

@ -1,42 +0,0 @@
using MU3.CustomUI;
using UnityEngine;
namespace MU3;
class patch_UICredit: UICredit {
private Animator gpAnimator_;
private GameObject creditRoot_;
private MU3UICounter credit_;
private GameObject freePlayRoot_;
private GameObject gpRoot_;
private MU3UICounter gp_;
private MU3UICounter gpPlus_;
private MU3UICounter gpMinus_;
private MU3UIImageChanger netIcon_;
private void onUpdateGP(int value) { /* nop */ }
public extern void orig_initialize();
public new void initialize() {
orig_initialize();
DestroyImmediate(gpAnimator_);
creditRoot_.transform.localScale = new Vector3(0, 0, 0);
credit_.transform.localScale = new Vector3(0, 0, 0);
freePlayRoot_.transform.localScale = new Vector3(0, 0, 0);
gpRoot_.transform.localScale = new Vector3(0, 0, 0);
gp_.transform.localScale = new Vector3(0, 0, 0);
gpPlus_.transform.localScale = new Vector3(0, 0, 0);
gpMinus_.transform.localScale = new Vector3(0, 0, 0);
var tf = (RectTransform)netIcon_.transform;
tf.localPosition = new Vector3(35, netIcon_.transform.localPosition.y, netIcon_.transform.localPosition.z);
for(int i = 0; i < 3; ++i) {
tf.anchorMin = new Vector2(0f, 0.5f);
tf.anchorMax = new Vector2(1f, 0.5f);
tf = (RectTransform)tf.parent;
}
netIcon_.image.rectTransform.pivot = new Vector2(0f, 0.5f);
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.InfiniteStory.mm</AssemblyName>
<Description>Allows watching the story endlessly</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,12 @@
using MU3.User;
using MU3.Util;
namespace MU3.Sequence;
class patch_Play: Play {
private extern void orig_Enter_PlayScenario();
private void Enter_PlayScenario() {
orig_Enter_PlayScenario();
Singleton<UserManager>.instance.userLocal.isStoryWatched = false;
}
}

View File

@ -0,0 +1,30 @@
using MonoMod;
using MU3.ViewData;
namespace MU3;
class patch_Scene_32_PrePlayMusic_MusicSelect: Scene_32_PrePlayMusic_MusicSelect {
private MusicSelectViewDataList _selectList;
private UIMusicSelector _selector;
private UIDialogBase _dialogBase;
[MonoModIgnore]
private extern void onFinishPlayScenario(int status, bool flag);
[MonoModIgnore]
private extern void updateSystemUIPanel();
private extern void orig_Execute_Select();
private void Execute_Select() {
// Walk around the warning dialog
if(_dialogBase == null && !_selector.isDecided && !_selector.isCanceled && (_selector.isPressed || _selector.isPressedDisabledElement)) {
MusicSelectViewData musicViewData = _selectList.getMusicViewData(_selector.selectIndex);
if(musicViewData != null && musicViewData.kind == MusicSelectViewData.Kind.Scenario
&& musicViewData.scenarioViewData.ngReason == ScenarioViewData.PlayNGReason.None) {
onFinishPlayScenario(0, false);
updateSystemUIPanel();
return;
}
}
orig_Execute_Select();
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.LoadBoost.mm</AssemblyName>
<Description>Speed up startup</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace MU3.Data;
public class patch_DataManager: DataManager {
private Dictionary<int, FumenAnalysisData> _fumenAnalysisData;
private string _fileName;
private void initCache() {
if(File.Exists(_fileName)) {
System.Console.WriteLine("Loading chart analysis cache...");
_fumenAnalysisData = new Dictionary<int, FumenAnalysisData>();
using FileStream input = File.OpenRead(_fileName);
using BinaryReader binaryReader = new BinaryReader(input);
while(binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) {
int key = binaryReader.ReadInt32();
bool isExist = binaryReader.ReadBoolean();
int bpm = binaryReader.ReadInt32();
int platinumScoreMax = binaryReader.ReadInt32();
string notesDesignerName = binaryReader.ReadString();
_fumenAnalysisData.Add(key, new FumenAnalysisData {
isExist = isExist,
bpm = bpm,
platinumScoreMax = platinumScoreMax,
notesDesignerName = notesDesignerName
});
}
} else {
_fumenAnalysisData = new Dictionary<int, FumenAnalysisData>();
}
}
private void saveCache() {
System.Console.WriteLine($"Saving chart analysis cache...{Enumerable.First(_fumenAnalysisData).Key},{Enumerable.First(_fumenAnalysisData).Value.notesDesignerName}");
if(File.Exists(_fileName)) {
File.Delete(_fileName);
}
using FileStream fileStream = File.OpenWrite(_fileName);
using BinaryWriter binaryWriter = new BinaryWriter(fileStream);
foreach(KeyValuePair<int, FumenAnalysisData> fumenAnalysisDatum in _fumenAnalysisData) {
binaryWriter.Write(fumenAnalysisDatum.Key);
binaryWriter.Write(fumenAnalysisDatum.Value.isExist);
binaryWriter.Write(fumenAnalysisDatum.Value.bpm);
binaryWriter.Write(fumenAnalysisDatum.Value.platinumScoreMax);
binaryWriter.Write(fumenAnalysisDatum.Value.notesDesignerName);
}
fileStream.Flush();
}
private extern void orig_makeFumenAnalysisDataList();
private void makeFumenAnalysisDataList() {
using IniFile iniFile = new("mu3.ini");
_fileName = Path.Combine(iniFile.getValue("Extra", "CacheDir", "."), "data_fumen_analysis_cache.bin");
try {
if(patch_DataStudioManager.needSave || !File.Exists(_fileName)) {
orig_makeFumenAnalysisDataList();
saveCache();
} else {
initCache();
}
} catch(Exception value) {
System.Console.WriteLine(value);
}
}
}

View File

@ -0,0 +1,68 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace MU3.Data;
public class patch_DataStudioManager: DataStudioManager {
public static bool needSave;
private static string _fileName;
private static Dictionary<string, object> _dataCache;
private static extern bool orig_Deserialize<T>(string filePath, out T dsr) where T : new();
private static void initCache() {
using IniFile iniFile = new("mu3.ini");
var dir = iniFile.getValue("Extra", "CacheDir", ".");
Directory.CreateDirectory(dir);
_fileName = Path.Combine(dir, "data_cache.bin");
if(File.Exists(_fileName)) {
System.Console.WriteLine("Loading data cache...");
using FileStream serializationStream = File.OpenRead(_fileName);
_dataCache = (Dictionary<string, object>)new BinaryFormatter().Deserialize(serializationStream);
return;
}
_dataCache = new();
}
private static void saveCache() {
if(_fileName == "") {
return;
}
if(File.Exists(_fileName)) {
File.Delete(_fileName);
}
using FileStream serializationStream = File.OpenWrite(_fileName);
new BinaryFormatter().Serialize(serializationStream, _dataCache);
}
private static bool Deserialize<T>(string filePath, out T dsr) where T : new() {
if(_dataCache == null) {
initCache();
}
if(_dataCache.ContainsKey(filePath)) {
dsr = (T)_dataCache[filePath];
return true;
}
if(orig_Deserialize(filePath, out dsr)) {
needSave = true;
_dataCache.Add(filePath, dsr);
return true;
}
return false;
}
public extern bool orig_IsLoaded();
public new bool IsLoaded() {
if(orig_IsLoaded()) {
if(needSave) {
System.Console.WriteLine("Saving data cache...");
saveCache();
}
return true;
}
return false;
}
}

View File

@ -0,0 +1,16 @@
using MU3.SceneObject;
namespace MU3.Sequence;
public class patch_Initialize: Initialize {
private Scene_12_Initialize _initializeObject;
private void Execute_InitQRReader() {
_initializeObject.setQRCodeReaderStatus("SKIP");
setNextState(EState.CheckDelivery);
}
private void Enter_Warning() {
setNextState(EState.StateEnd);
}
}

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net35</TargetFramework>
<Company>7EVENDAYS⇔HOLIDAYS</Company>
<Version>1.8.1</Version>
<Version>2.3.1</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<Platforms>x64</Platforms>

View File

@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
MinimumVisualStudioVersion = 10.0.40219.1
@ -7,8 +6,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BetterGiveUp", "BetterGiveU
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NaiveRating", "NaiveRating\NaiveRating.csproj", "{1FEA698E-DF5E-46CF-8023-F2B2F57885C5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExportChartData", "ExportChartData\ExportChartData.csproj", "{8BFC37B1-C6C8-492A-B8DC-99BD1F1B9576}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkipNotice", "SkipNotice\SkipNotice.csproj", "{A1F32CB9-56C2-458A-B369-C61BD3A6AFBB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkipPreMusicRitual", "SkipPreMusicRitual\SkipPreMusicRitual.csproj", "{BB9CB905-9989-466C-9A91-D2F323005237}"
@ -17,14 +14,36 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InfiniteGP", "InfiniteGP\In
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockSelectionTime", "LockSelectionTime\LockSelectionTime.csproj", "{66DE85AD-58AD-467C-B1C0-6B98BB27265D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkipLoginReward", "SkipLoginReward\SkipLoginReward.csproj", "{6E078B7E-7965-4CFF-9590-5C27A009BA7A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pause", "Pause\Pause.csproj", "{627B3AA0-25E2-4C3E-A211-66BAB0E997E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnlockAndSetJewelBoostNine", "UnlockAndSetJewelBoostNine\UnlockAndSetJewelBoostNine.csproj", "{70C775D7-8C47-4CFE-B91D-6AAEB17389F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SortByInternalDifficulty", "SortByInternalDifficulty\SortByInternalDifficulty.csproj", "{0BF799DF-8837-4372-9F36-705CDC22374C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoadBoost", "LoadBoost\LoadBoost.csproj", "{56B75395-ED26-479B-B59F-DABB74513335}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DisableEncryption", "DisableEncryption\DisableEncryption.csproj", "{3F05931E-4444-4616-A0AC-047809821B0E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnlockMasterDifficulty", "UnlockMasterDifficulty\UnlockMasterDifficulty.csproj", "{965FCDBC-12EA-4F31-AAF6-9C4C3B9F7022}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnlockFrameRate", "UnlockFrameRate\UnlockFrameRate.csproj", "{0C3E8145-F91B-4F1F-97D1-17E12D49891B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnlockAllMusic", "UnlockAllMusic\UnlockAllMusic.csproj", "{C8948C3E-0434-429E-AFE6-4FB2DF246872}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DisableMaintenance", "DisableMaintenance\DisableMaintenance.csproj", "{6C91EB92-3A30-43B5-8954-E84C610C1D67}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnlockGameEvents", "UnlockGameEvents\UnlockGameEvents.csproj", "{3B9B843D-DCA0-41FE-B642-6BCB187BBD5D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnlockMemoryChapters", "UnlockMemoryChapters\UnlockMemoryChapters.csproj", "{3A217A12-6082-491B-89F6-C1D13AD69A19}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatinumTiming", "PlatinumTiming\PlatinumTiming.csproj", "{099AD6AF-181A-4745-88C4-1D0466BECCB1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AttractVideoPlayer", "AttractVideoPlayer\AttractVideoPlayer.csproj", "{6889330F-2E7E-4778-ADFF-70AF036F1BD5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SelectBGM", "SelectBGM\SelectBGM.csproj", "{07C01DA1-7ABF-4759-A1C2-9DCD04298E85}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InfiniteStory", "InfiniteStory\InfiniteStory.csproj", "{939914E5-8D9A-4696-9957-AA6C6480FE94}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -39,10 +58,6 @@ Global
{1FEA698E-DF5E-46CF-8023-F2B2F57885C5}.Debug|x64.Build.0 = Debug|x64
{1FEA698E-DF5E-46CF-8023-F2B2F57885C5}.Release|x64.ActiveCfg = Release|x64
{1FEA698E-DF5E-46CF-8023-F2B2F57885C5}.Release|x64.Build.0 = Release|x64
{8BFC37B1-C6C8-492A-B8DC-99BD1F1B9576}.Debug|x64.ActiveCfg = Debug|x64
{8BFC37B1-C6C8-492A-B8DC-99BD1F1B9576}.Debug|x64.Build.0 = Debug|x64
{8BFC37B1-C6C8-492A-B8DC-99BD1F1B9576}.Release|x64.ActiveCfg = Release|x64
{8BFC37B1-C6C8-492A-B8DC-99BD1F1B9576}.Release|x64.Build.0 = Release|x64
{A1F32CB9-56C2-458A-B369-C61BD3A6AFBB}.Debug|x64.ActiveCfg = Debug|x64
{A1F32CB9-56C2-458A-B369-C61BD3A6AFBB}.Debug|x64.Build.0 = Debug|x64
{A1F32CB9-56C2-458A-B369-C61BD3A6AFBB}.Release|x64.ActiveCfg = Release|x64
@ -59,10 +74,6 @@ Global
{66DE85AD-58AD-467C-B1C0-6B98BB27265D}.Debug|x64.Build.0 = Debug|x64
{66DE85AD-58AD-467C-B1C0-6B98BB27265D}.Release|x64.ActiveCfg = Release|x64
{66DE85AD-58AD-467C-B1C0-6B98BB27265D}.Release|x64.Build.0 = Release|x64
{6E078B7E-7965-4CFF-9590-5C27A009BA7A}.Debug|x64.ActiveCfg = Debug|x64
{6E078B7E-7965-4CFF-9590-5C27A009BA7A}.Debug|x64.Build.0 = Debug|x64
{6E078B7E-7965-4CFF-9590-5C27A009BA7A}.Release|x64.ActiveCfg = Release|x64
{6E078B7E-7965-4CFF-9590-5C27A009BA7A}.Release|x64.Build.0 = Release|x64
{627B3AA0-25E2-4C3E-A211-66BAB0E997E2}.Debug|x64.ActiveCfg = Debug|x64
{627B3AA0-25E2-4C3E-A211-66BAB0E997E2}.Debug|x64.Build.0 = Debug|x64
{627B3AA0-25E2-4C3E-A211-66BAB0E997E2}.Release|x64.ActiveCfg = Release|x64
@ -75,6 +86,54 @@ Global
{0BF799DF-8837-4372-9F36-705CDC22374C}.Debug|x64.Build.0 = Debug|x64
{0BF799DF-8837-4372-9F36-705CDC22374C}.Release|x64.ActiveCfg = Release|x64
{0BF799DF-8837-4372-9F36-705CDC22374C}.Release|x64.Build.0 = Release|x64
{56B75395-ED26-479B-B59F-DABB74513335}.Debug|x64.ActiveCfg = Debug|x64
{56B75395-ED26-479B-B59F-DABB74513335}.Debug|x64.Build.0 = Debug|x64
{56B75395-ED26-479B-B59F-DABB74513335}.Release|x64.ActiveCfg = Release|x64
{56B75395-ED26-479B-B59F-DABB74513335}.Release|x64.Build.0 = Release|x64
{3F05931E-4444-4616-A0AC-047809821B0E}.Debug|x64.ActiveCfg = Debug|x64
{3F05931E-4444-4616-A0AC-047809821B0E}.Debug|x64.Build.0 = Debug|x64
{3F05931E-4444-4616-A0AC-047809821B0E}.Release|x64.ActiveCfg = Release|x64
{3F05931E-4444-4616-A0AC-047809821B0E}.Release|x64.Build.0 = Release|x64
{965FCDBC-12EA-4F31-AAF6-9C4C3B9F7022}.Debug|x64.ActiveCfg = Debug|x64
{965FCDBC-12EA-4F31-AAF6-9C4C3B9F7022}.Debug|x64.Build.0 = Debug|x64
{965FCDBC-12EA-4F31-AAF6-9C4C3B9F7022}.Release|x64.ActiveCfg = Release|x64
{965FCDBC-12EA-4F31-AAF6-9C4C3B9F7022}.Release|x64.Build.0 = Release|x64
{0C3E8145-F91B-4F1F-97D1-17E12D49891B}.Debug|x64.ActiveCfg = Debug|x64
{0C3E8145-F91B-4F1F-97D1-17E12D49891B}.Debug|x64.Build.0 = Debug|x64
{0C3E8145-F91B-4F1F-97D1-17E12D49891B}.Release|x64.ActiveCfg = Release|x64
{0C3E8145-F91B-4F1F-97D1-17E12D49891B}.Release|x64.Build.0 = Release|x64
{C8948C3E-0434-429E-AFE6-4FB2DF246872}.Debug|x64.ActiveCfg = Debug|x64
{C8948C3E-0434-429E-AFE6-4FB2DF246872}.Debug|x64.Build.0 = Debug|x64
{C8948C3E-0434-429E-AFE6-4FB2DF246872}.Release|x64.ActiveCfg = Release|x64
{C8948C3E-0434-429E-AFE6-4FB2DF246872}.Release|x64.Build.0 = Release|x64
{6C91EB92-3A30-43B5-8954-E84C610C1D67}.Debug|x64.ActiveCfg = Debug|x64
{6C91EB92-3A30-43B5-8954-E84C610C1D67}.Debug|x64.Build.0 = Debug|x64
{6C91EB92-3A30-43B5-8954-E84C610C1D67}.Release|x64.ActiveCfg = Release|x64
{6C91EB92-3A30-43B5-8954-E84C610C1D67}.Release|x64.Build.0 = Release|x64
{3B9B843D-DCA0-41FE-B642-6BCB187BBD5D}.Debug|x64.ActiveCfg = Debug|x64
{3B9B843D-DCA0-41FE-B642-6BCB187BBD5D}.Debug|x64.Build.0 = Debug|x64
{3B9B843D-DCA0-41FE-B642-6BCB187BBD5D}.Release|x64.ActiveCfg = Release|x64
{3B9B843D-DCA0-41FE-B642-6BCB187BBD5D}.Release|x64.Build.0 = Release|x64
{3A217A12-6082-491B-89F6-C1D13AD69A19}.Debug|x64.ActiveCfg = Debug|x64
{3A217A12-6082-491B-89F6-C1D13AD69A19}.Debug|x64.Build.0 = Debug|x64
{3A217A12-6082-491B-89F6-C1D13AD69A19}.Release|x64.ActiveCfg = Release|x64
{3A217A12-6082-491B-89F6-C1D13AD69A19}.Release|x64.Build.0 = Release|x64
{099AD6AF-181A-4745-88C4-1D0466BECCB1}.Debug|x64.ActiveCfg = Debug|x64
{099AD6AF-181A-4745-88C4-1D0466BECCB1}.Debug|x64.Build.0 = Debug|x64
{099AD6AF-181A-4745-88C4-1D0466BECCB1}.Release|x64.ActiveCfg = Release|x64
{099AD6AF-181A-4745-88C4-1D0466BECCB1}.Release|x64.Build.0 = Release|x64
{6889330F-2E7E-4778-ADFF-70AF036F1BD5}.Debug|x64.ActiveCfg = Debug|x64
{6889330F-2E7E-4778-ADFF-70AF036F1BD5}.Debug|x64.Build.0 = Debug|x64
{6889330F-2E7E-4778-ADFF-70AF036F1BD5}.Release|x64.ActiveCfg = Release|x64
{6889330F-2E7E-4778-ADFF-70AF036F1BD5}.Release|x64.Build.0 = Release|x64
{07C01DA1-7ABF-4759-A1C2-9DCD04298E85}.Debug|x64.ActiveCfg = Debug|x64
{07C01DA1-7ABF-4759-A1C2-9DCD04298E85}.Debug|x64.Build.0 = Debug|x64
{07C01DA1-7ABF-4759-A1C2-9DCD04298E85}.Release|x64.ActiveCfg = Release|x64
{07C01DA1-7ABF-4759-A1C2-9DCD04298E85}.Release|x64.Build.0 = Release|x64
{939914E5-8D9A-4696-9957-AA6C6480FE94}.Debug|x64.ActiveCfg = Debug|x64
{939914E5-8D9A-4696-9957-AA6C6480FE94}.Debug|x64.Build.0 = Debug|x64
{939914E5-8D9A-4696-9957-AA6C6480FE94}.Release|x64.ActiveCfg = Release|x64
{939914E5-8D9A-4696-9957-AA6C6480FE94}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -82,4 +141,4 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D9317002-F66D-4CDE-8FF5-FF2A0D8DC021}
EndGlobalSection
EndGlobal
EndGlobal

View File

@ -0,0 +1,18 @@
namespace MU3.CustomUI;
class patch_MU3UICounter: MU3UICounter {
protected extern void orig_calcNumFiguresFloat(double value);
protected new void calcNumFiguresFloat(double value) {
orig_calcNumFiguresFloat(value);
if(isDispSuffix) {
pushFigureFront(10);
}
}
public bool isDispSuffix { get; set; }
protected void pushFigureFront(byte c) {
for(int i = numFigures_; i > 0; --i) {
figures_[i] = figures_[i - 1];
}
figures_[0] = c;
numFigures_ += 1;
}
}

View File

@ -5,6 +5,10 @@ namespace MU3.Data;
class patch_GameData: GameData {
public extern static RatingColorID orig_getRatingColorIDFromRating100(int rating100);
public static new RatingColorID getRatingColorIDFromRating100(int rating100) {
return orig_getRatingColorIDFromRating100(NaiveRating.Get());
if(NaiveRating.IsEnabled()) {
return orig_getRatingColorIDFromRating100(NaiveRating.Get());
} else {
return orig_getRatingColorIDFromRating100(rating100);
}
}
}

View File

@ -0,0 +1,11 @@
using MU3.CustomUI;
namespace MU3.SceneObject;
class patch_ANM_CMN_UserDeta_01: ANM_CMN_UserDeta_01 {
private MU3UICounter rating;
public extern void orig_setUserDetail();
public new void setUserDetail() {
((patch_MU3UICounter)rating).isDispSuffix = NaiveRating.IsEnabled();
orig_setUserDetail();
}
}

View File

@ -1,11 +0,0 @@
using MU3.Game;
namespace MU3.User;
class patch_UserManager: UserManager {
public extern void orig_updateUserRating(SessionInfo sessionInfo, SessionResult result);
public new void updateUserRating(SessionInfo sessionInfo, SessionResult result) {
NaiveRating.PrevRating = NaiveRating.Get();
orig_updateUserRating(sessionInfo, result);
}
}

View File

@ -0,0 +1,36 @@
using MonoMod;
namespace MU3.User;
class patch_UserOption: UserOption {
[MonoModEnumReplace]
public enum patch_eRating {
OFF = 0,
Default = 1,
ON = 1,
Naive = 2,
MAX = 2
}
class patch_DataSet: DataSet {
private patch_eRating rating = patch_eRating.ON;
public extern bool orig_isMax(OptionName id);
public new bool isMax(OptionName id) {
if(id == OptionName.Rating) {
return rating == patch_eRating.MAX;
}
return orig_isMax(id);
}
public new patch_eRating Rating {
get => rating;
set {
if(patch_eRating.MAX < value) {
rating = patch_eRating.MAX;
} else if(value < patch_eRating.OFF) {
rating = patch_eRating.OFF;
} else {
rating = value;
}
}
}
}
}

View File

@ -4,7 +4,12 @@ namespace MU3.User;
[MonoModPatch("global::MU3.User.UserUtil")]
public static class patch_UserUtil {
public extern static float orig_toRatingFloat(int rating);
public static float toRatingFloat(int rating) {
return NaiveRating.Get() * 0.01f + 1E-05f;
if(NaiveRating.IsEnabled()) {
return orig_toRatingFloat(NaiveRating.Get());
} else {
return orig_toRatingFloat(rating);
}
}
}

View File

@ -9,11 +9,15 @@ class patch_ANM_SWH_Profile: ANM_SWH_Profile {
// Fixes login display
public new void setUpLogin() {
UserManager instance = Singleton<UserManager>.instance;
var prev = instance.userPreview;
var temp = prev;
temp.dispRating = 0;
instance.userPreview = temp;
orig_setUpLogin();
instance.userPreview = prev;
var up = instance.userPreview;
if(NaiveRating.IsEnabled()) {
up.dispRating = 0;
instance.userPreview = up;
orig_setUpLogin();
up.dispRating = 2;
instance.userPreview = up;
} else {
orig_setUpLogin();
}
}
}

View File

@ -0,0 +1,23 @@
using MU3.CustomUI;
using MU3.User;
using MU3.Util;
namespace MU3;
class patch_OptionSelecterController: OptionSelecterController {
private chengeParamFuncArray[] cpFuncArray = new chengeParamFuncArray[35];
public extern void orig_init(UserOption.OptionName id);
private extern void orig_chengeParamOther(int currentParam);
public new void init(UserOption.OptionName id) {
orig_init(id);
cpFuncArray[33].max = 2;
}
private void chengeParamOther(int currentParam) {
if(myOptionId == UserOption.OptionName.Rating) {
transform.Find("NUL_SWH_Option_00/NUL_Select/PAT_OnOff").GetComponent<MU3UIImageChanger>().patternNumber = currentParam != 0 ? 0f : 1f;
Singleton<UserManager>.instance.userOption.customSet.Rating = (UserOption.eRating)currentParam;
SingletonMonoBehaviour<SystemUI>.instance.userData.setUserDetail();
} else {
orig_chengeParamOther(currentParam);
}
}
}

View File

@ -0,0 +1,10 @@
namespace MU3;
// It doesn't have to be PrePlayMusic_Confirm, but it prev rating has to be stored at some point
class patch_Scene_32_PrePlayMusic_Confirm: Scene_32_PrePlayMusic_Confirm {
private extern void orig_Enter_Select();
private void Enter_Select() {
NaiveRating.SavePrev();
orig_Enter_Select();
}
}

View File

@ -1,22 +0,0 @@
using MU3.Sequence;
namespace MU3;
class patch_Scene_37_Result_Score: Scene_37_Result_Score {
private PlayInfo playInfo_;
private extern void orig_TechRating_Init();
// Fixes rating+/rating- display
private void TechRating_Init() {
var origRating = playInfo_.sessionResult.rating_;
var origPrevRating = playInfo_.sessionResult.prevRating_;
playInfo_.sessionResult.rating_ = NaiveRating.Get();
playInfo_.sessionResult.prevRating_ = NaiveRating.PrevRating;
orig_TechRating_Init();
playInfo_.sessionResult.rating_ = origRating;
playInfo_.sessionResult.prevRating_ = origPrevRating;
}
}

View File

@ -0,0 +1,47 @@
using MU3.CustomUI;
using MU3.Sequence;
using MU3.User;
using UnityEngine;
namespace MU3;
class patch_UIResultBattlePoint: UIResultBattlePoint {
private Animator animator_;
private MU3UICounter counterScore_;
private MU3UIImageChanger imageHeader_;
private MU3UICounter counterScorePlus_;
private MU3UICounter counterScoreMinus_;
private GameObject hideScore_;
private extern void orig_disable(MU3UICounter counter);
private void disable(MU3UICounter counter) => orig_disable(counter);
public extern void orig_initTechRating(PlayInfo playInfo);
public new void initTechRating(PlayInfo playInfo) {
((patch_MU3UICounter)counterScore_).isDispSuffix = NaiveRating.IsEnabled();
if(!NaiveRating.IsEnabled()) {
orig_initTechRating(playInfo);
return;
}
int prevRating = NaiveRating.PrevRating;
int rating1 = NaiveRating.Get();
if((bool)hideScore_) {
hideScore_.SetActive(false);
}
counterScore_.Counter = (double)UserUtil.toRatingFloat(rating1);
int ratingPatternNo = UserUtil.toRatingPatternNo(rating1);
counterScore_.SpriteIndex = ratingPatternNo;
imageHeader_.patternNumber = (float)ratingPatternNo;
int rating2 = rating1 - prevRating;
if(rating2 == 0) {
disable(counterScorePlus_);
disable(counterScoreMinus_);
animator_.SetInteger(MU3.Sys.Const.AnimatorID_State, 2);
} else if(0 < rating2) {
disable(counterScoreMinus_);
if((bool)counterScorePlus_) {
counterScorePlus_.Counter = rating2 * 0.01f + 1E-05f;
}
animator_.SetInteger(MU3.Sys.Const.AnimatorID_State, 0);
}
animator_.SetTrigger(MU3.Sys.Const.AnimatorID_In);
}
}

View File

@ -5,10 +5,8 @@ using MU3.Util;
using System.Collections.Generic;
using System.Linq;
namespace MU3;
public static class NaiveRating {
public static int PrevRating { get; set; }
public static int PrevRating { get; private set; }
// Adapted from MU3.User.UserRating.calcBest()
private static RatingList calcSane() {
@ -48,4 +46,10 @@ public static class NaiveRating {
}
return res / 45;
}
public static bool IsEnabled() {
return Singleton<UserManager>.instance.userOption.customSet.Rating == (UserOption.eRating)patch_UserOption.patch_eRating.Naive;
}
public static void SavePrev() {
PrevRating = Get();
}
}

View File

@ -22,7 +22,7 @@ class patch_PlayMusic: PlayMusic {
}
public override bool updateState(float deltaTime = -1f) {
pauseTimer += deltaTime;
if(Singleton<UIInput>.instance.getStateOn(UIInput.Key.Service)) {
if(Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.Service) && !Singleton<UIInput>.instance.getStateOn(UIInput.Key.Test)) {
if((!Paused && pauseTimer >= PAUSE_CD) || (Paused && pauseTimer >= UNPAUSE_CD)) {
Paused = !Paused;
pgm.pause(Paused);

View File

@ -0,0 +1,26 @@
using MU3.Notes;
namespace MU3.Battle;
class patch_Counters: Counters {
public int PlatinumFastCount { get; private set; } = 0;
public int PlatinumLateCount { get; private set; } = 0;
public extern void orig_addPlatinumScore(Judge judge, Timing timing);
public new void addPlatinumScore(Judge judge, Timing timing) {
orig_addPlatinumScore(judge, timing);
if(judge == Judge.Perfect) {
if(timing == Timing.Fast) {
PlatinumFastCount += 1;
} else if(timing == Timing.Late) {
PlatinumLateCount += 1;
}
}
}
public extern void orig_reset();
public new void reset() {
orig_reset();
PlatinumFastCount = 0;
PlatinumLateCount = 0;
}
}

View File

@ -0,0 +1,13 @@
using MU3.Game;
namespace MU3.Battle;
class patch_GameEngine: GameEngine {
private patch_Counters _counters;
public extern void orig_calcCurrentBattleResult(SessionResult sessionResult);
public void calcCurrentBattleResult(patch_SessionResult sessionResult) {
orig_calcCurrentBattleResult(sessionResult);
sessionResult.PlatinumFastCount = _counters.PlatinumFastCount;
sessionResult.PlatinumLateCount = _counters.PlatinumLateCount;
}
}

View File

@ -0,0 +1,5 @@
namespace MU3.Game;
class patch_SessionResult: SessionResult {
public int PlatinumFastCount { get; set; }
public int PlatinumLateCount { get; set; }
}

View File

@ -0,0 +1,63 @@
using MU3.CustomUI;
using MU3.Game;
using MU3.Sequence;
using MU3.Util;
using System.Collections;
using UnityEngine;
namespace MU3;
class patch_UIResultTechScore: UIResultTechScore {
private MU3UICounter counterFast_;
private MU3UICounter counterLate_;
private Animator animator_;
private static readonly int State_TechnicalScore_Loop;
private void cloneCounter(MU3UICounter counter, Color color, int value) {
var otherValue = counter.CounterAsInt;
var offset = 12;
while(otherValue > 9) {
otherValue /= 10;
offset += 8;
}
var cpy = Instantiate(counter);
cpy.color = color;
cpy.gameObject.transform.SetParent(counter.transform.parent, false);
var pos = counter.gameObject.transform.localPosition;
cpy.gameObject.transform.localPosition = new Vector3(pos.x - offset, pos.y, pos.z);
cpy.gameObject.SetActive(true);
cpy.CounterAsInt = value;
}
private void drawCounters() {
float posXf = counterFast_.gameObject.transform.localPosition.x + 5.0f;
float posXl = counterLate_.gameObject.transform.localPosition.x + 5.0f;
float posY = counterLate_.gameObject.transform.localPosition.y;
counterFast_.gameObject.transform.localPosition = new Vector3(posXf, posY, 0.0f);
counterLate_.gameObject.transform.localPosition = new Vector3(posXl, posY, 0.0f);
var sessionResult = (patch_SessionResult)Singleton<PlayInfo>.instance.sessionResult;
cloneCounter(
counterFast_,
new Color(0.630f, 0.766f, 0.829f, 1.000f),
sessionResult.PlatinumFastCount
);
cloneCounter(
counterLate_,
new Color(0.809f, 0.396f, 0.365f, 1.000f),
sessionResult.PlatinumLateCount
);
}
private extern IEnumerator orig_showPlatinumScore(PlayInfo playInfo);
private IEnumerator showPlatinumScore(PlayInfo playInfo) {
StartCoroutine(orig_showPlatinumScore(playInfo));
while(!AnimatorState.stateEquals(animator_, State_TechnicalScore_Loop)) {
yield return null;
}
drawCounters();
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.PlatinumTiming.mm</AssemblyName>
<Description>Platinum early/late</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -1,10 +1,10 @@
## µ3 mods
Miscellaneous mods for µ3/SDDT. Suggestions/PRs are welcome.
Miscellaneous mods for Ongeki. Suggestions/PRs are welcome.
Visit [the wiki](https://gitea.tendokyu.moe/akanyan/mu3-mods/wiki) for more information.
### Supported versions
- 1.39
- 1.40
- 1.45
- 1.45
1.39/1.40 should work but they are generally untested.

View File

@ -0,0 +1,14 @@
using MU3.Sound;
namespace MU3.Game;
class patch_GameBGM: GameBGM {
public static bool WithholdPlay = false;
public extern void orig_playBGM(SoundManager.ACBData acbData, int soundId, int selectorID, bool forcePlay = false);
public new void playBGM(SoundManager.ACBData acbData, int soundId, int selectorID, bool forcePlay = false) {
// Prevents theme music from being restarted
if(!WithholdPlay) {
orig_playBGM(acbData, soundId, selectorID, forcePlay);
}
}
}

View File

@ -0,0 +1,38 @@
using MU3.Data;
using MU3.Game;
using MU3.Util;
using System;
namespace MU3.Sequence;
class patch_Play: Play {
private LocalSessionInfo _localSessionInfo;
public static int RecentID = 6;
private extern void orig_Enter_Login();
private void Enter_Login() {
orig_Enter_Login();
using IniFile iniFile = new("mu3.ini");
var index = iniFile.getIntValue("Extra", "BGM", 6);
if(index == 0) {
var rnd = new Random();
index = rnd.Next(1, 7);
}
if(index < 0 || index > 6) {
index = 6;
}
RecentID = index;
Singleton<GameSound>.instance.gameBGM.playBGM(233, index);
}
private extern void orig_Enter_ChapterSelect();
private void Enter_ChapterSelect() {
patch_GameBGM.WithholdPlay = true;
orig_Enter_ChapterSelect();
patch_GameBGM.WithholdPlay = false;
int selectorID = SingletonStateMachine<DataManager, DataManager.EState>.instance.getMemoryChapterData(
_localSessionInfo.chapterSelection.memoryChapterId
)?.getMemoryChapterSelectorID() ?? RecentID;
Singleton<GameSound>.instance.gameBGM.playBGM(233, selectorID);
}
}

View File

@ -0,0 +1,22 @@
using MU3.Game;
using MU3.Sequence;
using MU3.Util;
using MU3.ViewData;
namespace MU3;
class patch_Scene_32_PrePlayMusic_ChapterSelect: Scene_32_PrePlayMusic_ChapterSelect {
private ChapterSelectorItemViewData _selectItemViewData;
private extern void orig_onChangeElement(int index, int indexRaw);
private void onChangeElement(int index, int indexRaw) {
patch_GameBGM.WithholdPlay = true;
orig_onChangeElement(index, indexRaw);
patch_GameBGM.WithholdPlay = false;
int selectorID = (
(_selectItemViewData.memoryChapterViewData == null)
? null
: _selectItemViewData.memoryChapterViewData.memoryChapterData
)?.getMemoryChapterSelectorID() ?? patch_Play.RecentID;
Singleton<GameSound>.instance.gameBGM.playBGM(233, selectorID);
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.SelectBGM.mm</AssemblyName>
<Description>Select main menu BGM</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -1,14 +0,0 @@
using MU3.Util;
namespace MU3;
class patch_Scene_30_NoticeReward: Scene_30_NoticeReward {
private Mode<Scene_30_NoticeReward, State> _mode;
private enum State {
RankingReward = 2,
FadeOut = 8,
}
private void RankingReward_Init() {
_mode.set(State.FadeOut);
}
}

View File

@ -1,7 +0,0 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.SkipLoginReward.mm</AssemblyName>
<Description>Skip event/login rewards</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -4,13 +4,27 @@ namespace MU3;
class patch_Scene_30_NoticeReward: Scene_30_NoticeReward {
private Mode<Scene_30_NoticeReward, State> _mode;
public static bool Skipped { get; private set; }
private enum State {
RankingReward = 2,
FadeOut = 8,
}
private void Start() {
Skipped = false;
_mode = new Mode<Scene_30_NoticeReward, State>(this);
_mode.set(State.RankingReward);
SingletonMonoBehaviour<SystemUI>.instance.Panel.pushState(0, show: true);
}
private void Update() {
if(_mode.get() < (int)State.FadeOut && Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.MenuLeft)) {
Skipped = true;
_mode.set(State.FadeOut);
} else {
_mode.update();
}
}
private void End_Init() {
Skipped = false;
}
}

View File

@ -0,0 +1,18 @@
namespace MU3;
class patch_UIGetRewards: UIGetRewards {
private extern void orig_invokeOnFinish();
private extern void orig_startNextItem();
private void invokeOnFinish() => orig_invokeOnFinish();
private void startNextItem() {
if(!patch_Scene_30_NoticeReward.Skipped) {
orig_startNextItem();
}
}
void Update() {
// The panel state will still be screwed up for some reason but it won't crash
// This could be improved
if(patch_Scene_30_NoticeReward.Skipped) {
invokeOnFinish();
}
}
}

View File

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.SkipNotice.mm</AssemblyName>
<Description>Skip event/safety notice</Description>
<Description>Skip event/safety notices</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -1,7 +0,0 @@
namespace MU3.Battle;
class patch_GameEngine: GameEngine {
public new bool isStartCutsceneFinish() {
return true;
}
}

View File

@ -1,14 +1,20 @@
using MU3.Battle;
using MU3.Util;
namespace MU3.Sequence;
class patch_PlayMusic: PlayMusic {
private GameEngine _gameEngine;
private extern void orig_Execute_StartCutscene();
public static bool ForceSkipped { get; private set; }
private void Execute_StartCutscene() {
orig_Execute_StartCutscene();
_gameEngine.skipStartCutscene();
setNextState(EState.Countdown);
ForceSkipped = false;
if(Singleton<Sys.System>.instance.config.isQuickStart || Singleton<UIInput>.instance.getTriggerOn(UIInput.Key.MenuLeft)) {
ForceSkipped = true;
_gameEngine.skipStartCutscene();
setNextState(EState.Countdown);
}
}
}

View File

@ -1,11 +1,15 @@
using MU3.Util;
using MonoMod;
using MU3.Sequence;
using MU3.Util;
using System;
using UnityEngine;
namespace MU3;
class patch_BattleUI: BattleUI {
private System.Collections.IEnumerator playReadyProc(Action onFinish) {
[MonoModIgnore]
private extern System.Collections.IEnumerator playReadyProc(Action onFinish);
private System.Collections.IEnumerator playReadyProcSkipped(Action onFinish) {
if(!SystemUI.Exists) {
onFinish();
yield break;
@ -17,6 +21,15 @@ class patch_BattleUI: BattleUI {
time -= Time.deltaTime;
}
onFinish();
systemUI.removeCanvas(MU3.Graphics.Const.SortOrder.UI);
systemUI.removeCanvas(Graphics.Const.SortOrder.UI);
}
public new void playReady(Action onFinish) {
if(patch_PlayMusic.ForceSkipped) {
StartCoroutine(playReadyProcSkipped(onFinish));
} else {
StartCoroutine(playReadyProc(onFinish));
}
}
}

View File

@ -0,0 +1,20 @@
using MU3.Client;
using MU3.DB;
namespace MU3.User;
class patch_UserDetail: UserDetail {
public extern void orig_copyTo(UserData userDetail);
public new void copyTo(UserData userDetail) {
orig_copyTo(userDetail);
// Attempting to use a profile with InternalLevel sorting enabled
// causes unpatched clients to crash thanks to enormous incompetence
// of Sxga's interns. So, unfortunately, this value has to be discarded.
// See:
// * MusicSelectViewDataList._sort1 set
// * UserDetail.copyFrom()
if(userDetail.tabSetting == (int)patch_MusicSort1ID.InternalLevel) {
userDetail.tabSetting = (int)patch_MusicSort1ID.Level;
}
}
}

View File

@ -15,6 +15,7 @@ class patch_MusicSelectViewDataList: MusicSelectViewDataList {
private CompareProc _compareProc1;
private CompareProc _compareProc2;
private GetCategoryNameProc _getCategoryNameProc;
private PropertyInfo _reMasterPi = null;
private extern void orig_set__sort1(MusicSort1ID value);
private extern void orig_set__sort2(MusicSort2ID value);
@ -36,19 +37,18 @@ class patch_MusicSelectViewDataList: MusicSelectViewDataList {
}
}
private PropertyInfo reMasterPi = null;
private bool isReMaster(Data.MusicData d) {
// Fall back for pre-Act3
if(reMasterPi == null) {
if(_reMasterPi == null) {
return false;
}
return (bool)reMasterPi.GetValue(d, null);
return (bool)_reMasterPi.GetValue(d, null);
}
public extern void orig_create(GameViewData gameViewData, ChapterSelection chapterSelection, FumenDifficulty difficulty, MusicSort1ID sort1, MusicSort2ID sort2);
public new void create(GameViewData gameViewData, ChapterSelection chapterSelection, FumenDifficulty difficulty, MusicSort1ID sort1, MusicSort2ID sort2) {
reMasterPi = typeof(Data.MusicData).GetProperty("isReMaster");
_reMasterPi = typeof(Data.MusicData).GetProperty("isReMaster");
orig_create(gameViewData, chapterSelection, difficulty, sort1, sort2);
}
@ -100,7 +100,7 @@ class patch_MusicSelectViewDataList: MusicSelectViewDataList {
private extern int orig_getMetaSortKey(MusicSelectViewData d, bool forCategorySort);
private int getMetaSortKey(MusicSelectViewData d, bool forCategorySort) {
if(reMasterPi == null) {
if(_reMasterPi == null) {
return orig_getMetaSortKey(d, forCategorySort);
}
var remas = isReMaster(d.musicViewData.data);

View File

@ -0,0 +1,24 @@
namespace MU3.DataStudio;
class patch_MusicData: MusicData {
public new int CostToUnlock {
get {
return 0;
}
private set { /* nop */ }
}
public new bool PossessingFromTheBeginning {
get {
return true;
}
private set { /* nop */ }
}
public new bool IsLockedAtTheBeginning {
get {
return false;
}
private set { /* nop */ }
}
}

View File

@ -0,0 +1,20 @@
using MU3.User;
using MU3.Util;
namespace MU3;
class patch_Scene_25_Login: Scene_25_Login {
private enum State {
GetUserRatinglog = 24
}
private Mode<Scene_25_Login, State> mode_;
private void GetUserActivityMusic_Init() {
// nop
}
private void GetUserActivityMusic_Proc() {
Singleton<UserManager>.instance.updateUserActivityInLoginEnd();
mode_.set(State.GetUserRatinglog);
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.UnlockAllMusic.mm</AssemblyName>
<Description>Unlock all music</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,26 @@
using MU3.Game;
using MU3.Sys;
using MU3.Util;
namespace MU3.Notes;
class patch_NotesManager: NotesManager {
private float _frame;
private float _frameReal;
private bool _altMode;
public extern void orig_initialize(SessionInfo sessionInfo);
public new void initialize(SessionInfo sessionInfo) {
orig_initialize(sessionInfo);
var cfg = (patch_Config)Singleton<Sys.System>.instance.config;
_altMode = cfg.isVsync || (cfg.framerate != 60);
}
private extern void orig_progressFrameAndFrameReal();
private void progressFrameAndFrameReal() {
if(_altMode) {
_frame = _frameReal;
} else {
orig_progressFrameAndFrameReal();
}
}
}

View File

@ -0,0 +1,38 @@
using UnityEngine;
namespace MU3.Sys;
class patch_Config: Config {
public extern void orig_initialize();
public int framerate { get; private set; }
public bool isVsync { get; private set; }
public new void initialize() {
orig_initialize();
using IniFile iniFile = new("mu3.ini");
framerate = iniFile.getIntValue("Video", "Framerate", 60);
isVsync = iniFile.getValue("Video", "VSync", false);
if(framerate == 0) {
framerate = -1;
}
if(isVsync) {
QualitySettings.vSyncCount = 1;
framerate = -1;
Debug.Log("[UnlockFrameRate] VSync on");
} else {
Application.targetFrameRate = framerate;
QualitySettings.vSyncCount = 0;
if(framerate == 60) {
Debug.Log("[UnlockFrameRate] Framerate locked to 60 (vanilla)");
} else if(framerate == -1) {
Debug.Log("[UnlockFrameRate] Framerate unlocked");
} else {
Debug.Log("[UnlockFrameRate] Framerate locked to " + framerate);
}
}
}
}

View File

@ -0,0 +1,29 @@
using MU3.Util;
namespace MU3.Sys;
class patch_Time: Time {
private static bool _init;
private static float _deltaTime;
private static float _adjustAccumlation;
private static float _realtimeSinceStartup;
private static bool _altMode;
public extern static void orig_update();
public static new void update() {
if(!_init) {
_deltaTime = UnityEngine.Time.deltaTime;
_adjustAccumlation = 0f;
_realtimeSinceStartup = UnityEngine.Time.realtimeSinceStartup;
var cfg = (patch_Config)Singleton<Sys.System>.instance.config;
_altMode = cfg.isVsync || (cfg.framerate != 60);
_init = true;
}
if(_altMode) {
_deltaTime = UnityEngine.Time.deltaTime;
_realtimeSinceStartup = UnityEngine.Time.realtimeSinceStartup;
} else {
orig_update();
}
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.UnlockFramerate.mm</AssemblyName>
<Description>Unlock framerate</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,35 @@
using MU3.Data;
using MU3.Operation;
using MU3.Util;
using System;
using System.Linq;
namespace MU3.Client;
class patch_PacketGetGameEvent: Packet {
public Operation.GameEvent _gameEvent;
public Operation.GameEvent gameEvent => _gameEvent;
public extern State orig_proc();
public override State proc() {
State state = orig_proc();
if(state == State.Done) {
DateTime endDate = DateTime.Parse("2099-01-01 05:00:00.0");
_gameEvent ??= new Operation.GameEvent();
foreach(EventData eventData in SingletonStateMachine<DataManager, DataManager.EState>.instance.allEventData) {
IdPeriod idPeriod = Enumerable.FirstOrDefault(_gameEvent.list, (IdPeriod e) => e.id == eventData.id);
if(idPeriod != null) {
if(idPeriod.period.endDate < CustomDateTime.Now) {
idPeriod.period.endDate = endDate;
}
} else {
idPeriod = new();
idPeriod.id = eventData.id;
idPeriod.period = new Period(DateTime.MinValue.Date, endDate);
_gameEvent.list.Add(idPeriod);
_gameEvent.lastUpdate = CustomDateTime.Now;
}
}
}
return state;
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.UnlockGameEvents.mm</AssemblyName>
<Description>Unlock game events</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,13 @@
using MonoMod;
namespace MU3.ViewData;
[MonoModPatch("global::MU3.ViewData.MusicViewData")]
public class patch_MusicViewData {
public bool isMasterLock {
get {
return false;
}
set { /* nop */ }
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.UnlockMasterDifficulty.mm</AssemblyName>
<Description>Unlock master difficulty</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>

View File

@ -0,0 +1,32 @@
using MU3.Data;
using MU3.User;
using MU3.Util;
using System.Collections.Generic;
using System.Linq;
namespace MU3.Client;
class patch_PacketGetUserMemoryChapter: Packet {
private Dictionary<int, User.UserMemoryChapter> userMemoryChapter_;
public override State proc() {
switch(procImpl()) {
case State.Done: {
GetUserMemoryChapterResponse response_ = (query_ as GetUserMemoryChapter).response_;
foreach(MemoryChapterData memoryChapterData in SingletonStateMachine<DataManager, DataManager.EState>.instance.allMemoryChapterData) {
UserMemoryChapter userMemoryChapter = Enumerable.FirstOrDefault(response_.userMemoryChapterList, (UserMemoryChapter c) => c.chapterId == memoryChapterData.id);
if(userMemoryChapter != null) {
User.UserMemoryChapter userMemoryChapter2 = new User.UserMemoryChapter();
userMemoryChapter2.copyFrom(userMemoryChapter);
userMemoryChapter_[userMemoryChapter2.ChapterId] = userMemoryChapter2;
} else {
User.UserMemoryChapter userMemoryChapter3 = new User.UserMemoryChapter(memoryChapterData.id);
userMemoryChapter_[userMemoryChapter3.ChapterId] = userMemoryChapter3;
}
}
Singleton<UserManager>.instance.UserMemoryChapter = userMemoryChapter_;
break;
}
}
return state_;
}
}

View File

@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<AssemblyName>Assembly-CSharp.UnlockMemoryChapters.mm</AssemblyName>
<Description>Unlock memory chapters</Description>
</PropertyGroup>
<Import Project="..\Mu3Mods.csproj" />
</Project>