commit edddcbffd7f6314542cb85d5a436b2bfb4c157f1 Author: akanyan Date: Wed May 22 06:57:39 2024 +0900 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..413ca7a --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.vs/ +*.sln +*.csproj +**/bin/* +**/obj/* +*.dll \ No newline at end of file diff --git a/BetterGiveUp/MU3.Game/patch_GameLED.cs b/BetterGiveUp/MU3.Game/patch_GameLED.cs new file mode 100644 index 0000000..36c8dbe --- /dev/null +++ b/BetterGiveUp/MU3.Game/patch_GameLED.cs @@ -0,0 +1,23 @@ +#pragma warning disable CS0626 +#pragma warning disable CS0649 +#pragma warning disable IDE0051 +#pragma warning disable IDE1006 + +using System.Collections.Generic; + +namespace MU3.Game; + +public class patch_GameLED : GameLED { + private patch_ButtonList _buttonList = new(); + + public extern void orig_initialize(); + + public new void initialize() { + _buttonList.Clear(); + orig_initialize(); + } + + private class patch_ButtonParam {} + + private class patch_ButtonList : List {} +} \ No newline at end of file diff --git a/BetterGiveUp/MU3.Notes/patch_FieldObject.cs b/BetterGiveUp/MU3.Notes/patch_FieldObject.cs new file mode 100644 index 0000000..128446f --- /dev/null +++ b/BetterGiveUp/MU3.Notes/patch_FieldObject.cs @@ -0,0 +1,23 @@ +#pragma warning disable CS0626 +#pragma warning disable CS0649 +#pragma warning disable IDE0051 +#pragma warning disable IDE1006 + +using UnityEngine; + +namespace MU3.Notes; +public class patch_FieldObject : FieldObject { + public class patch_BarNotes { + public class patch_Bar : BarNotes.Bar { + public extern void orig_update(NotesManager mgr, float width = 1f); + + public new void update(NotesManager mgr, float width = 1f) { + orig_update(mgr, width); + if(frameAppear <= (double)mgr.getCurrentFrame() || itemBar == null) { + return; + } + itemBar.go.transform.localScale = Vector3.zero; + } + } + } +} diff --git a/BetterGiveUp/MU3.Notes/patch_NotesManager.cs b/BetterGiveUp/MU3.Notes/patch_NotesManager.cs new file mode 100644 index 0000000..ffbfe2a --- /dev/null +++ b/BetterGiveUp/MU3.Notes/patch_NotesManager.cs @@ -0,0 +1,23 @@ +#pragma warning disable CS0626 +#pragma warning disable CS0649 +#pragma warning disable IDE0051 +#pragma warning disable IDE1006 + +using UnityEngine; + +namespace MU3.Notes; + +public class patch_NotesManager : NotesManager { + public extern void orig_reset(); + + public extern Vector3 orig_getEnemyPos(); + + public Vector3 enemyOffset { get; set; } + + public new Vector3 getEnemyPos() => orig_getEnemyPos() + enemyOffset; + + public new void reset() { + enemyOffset = Vector3.zero; + orig_reset(); + } +} \ No newline at end of file diff --git a/BetterGiveUp/MU3.Sequence/patch_PlayMusic.cs b/BetterGiveUp/MU3.Sequence/patch_PlayMusic.cs new file mode 100644 index 0000000..0a807e1 --- /dev/null +++ b/BetterGiveUp/MU3.Sequence/patch_PlayMusic.cs @@ -0,0 +1,99 @@ +#pragma warning disable CS0626 +#pragma warning disable CS0649 +#pragma warning disable IDE0051 +#pragma warning disable IDE1006 + +using MU3.Battle; +using MU3.Game; +using MU3.Notes; +using MU3.Util; +using System; +using UnityEngine; + +namespace MU3.Sequence; + +public class patch_PlayMusic : PlayMusic { + private static readonly TimeSpan HOLD_DURATION = TimeSpan.FromSeconds(1.0f); + private static readonly TimeSpan ROLL_DURATION = TimeSpan.FromSeconds(0.5f); + private GameEngine _gameEngine; + private SessionInfo _sessionInfo; + private bool _isRolling; + private float _totalRollingFrame; + private DateTime _rollingStartTime; + private bool _isHoldingAck; + private DateTime _holdingStartTime; + private float enemyPosX; + + private patch_NotesManager ntMgr => (patch_NotesManager) _gameEngine?.notesManager; + + private extern void orig_Execute_Play(); + + public static double FadeOut(double progress, double min, double max) { + return min + (max - min) * (1.0 - Math.Pow(1.0 - progress, 2.0)); + } + + public static double FadeIn(double progress, double min, double max) { + return min + (max - min) * Math.Pow(progress, 2.0); + } + + private static bool IsHolding() { + return Singleton.instance.getStateOn(UIInput.Key.MenuLeft) ^ Singleton.instance.getStateOn(UIInput.Key.MenuRight); + } + + private void StartRolling() { + _isRolling = true; + _totalRollingFrame = ntMgr.getCurrentFrame(); + _rollingStartTime = CustomDateTime.Now; + enemyPosX = ntMgr.getEnemyPos().x; + ntMgr.forceRecover(recover: 100); + Singleton.instance.gameBGM.stop(); + } + + private void EndRolling() { + _isRolling = false; + ntMgr.stopPlay(); + ntMgr.reset(); + ntMgr.reloadScore(_gameEngine.IsStageDazzling); + _gameEngine.counters.reset(); + _gameEngine.battleReward.initialize(_sessionInfo); + _gameEngine.enemyManager.destroy(); + _gameEngine.enemyManager.initialize(); + _gameEngine.reset(); + Singleton.instance.gameBGM.playMusic(_sessionInfo.musicData, 0); + ntMgr.startPlay(0.0f); + ntMgr.led.setGameColor(true); + } + + private void Execute_Play() { + if(_isRolling) { + TimeSpan timeSpan = CustomDateTime.Now - _rollingStartTime; + if (timeSpan <= ROLL_DURATION) { + double num1 = FadeOut(timeSpan.TotalMilliseconds / ROLL_DURATION.TotalMilliseconds, 0.0, 1.0); + double num2 = FadeIn(timeSpan.TotalMilliseconds / ROLL_DURATION.TotalMilliseconds, 0.0, 1.0); + ntMgr.setFrameForce(_totalRollingFrame * (float)(1.0 - num1)); + ntMgr.enemyOffset = new Vector3( + ntMgr.enemyOffset.x + (enemyPosX - ntMgr.getEnemyPos().x), 20f * (float) num2, 0.0f + ); + } else { + EndRolling(); + } + } else if(IsHolding() && !_sessionInfo.isTutorial) { + if(!_isHoldingAck) { + _holdingStartTime = CustomDateTime.Now; + _isHoldingAck = true; + } + + TimeSpan ts = CustomDateTime.Now - _holdingStartTime; + if(ts > HOLD_DURATION) { + if(Singleton.instance.getStateOn(UIInput.Key.MenuRight)) { + StartRolling(); + } else { + ntMgr.forceDamage(damage: 100); + } + } + } else { + _isHoldingAck = false; + orig_Execute_Play(); + } + } +} \ No newline at end of file diff --git a/ExportChartData/MU3.Data/patch_DataManager.cs b/ExportChartData/MU3.Data/patch_DataManager.cs new file mode 100644 index 0000000..fed6b6b --- /dev/null +++ b/ExportChartData/MU3.Data/patch_DataManager.cs @@ -0,0 +1,63 @@ +#pragma warning disable CS0626 +#pragma warning disable CS0649 +#pragma warning disable IDE0051 +#pragma warning disable IDE1006 + +using System.IO; + +namespace MU3.Data; + +public 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"); + } +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..00d2e13 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/NaiveRating/MU3.User/patch_UserRating.cs b/NaiveRating/MU3.User/patch_UserRating.cs new file mode 100644 index 0000000..e5cdfe9 --- /dev/null +++ b/NaiveRating/MU3.User/patch_UserRating.cs @@ -0,0 +1,56 @@ +#pragma warning disable CS0626 +#pragma warning disable CS0649 +#pragma warning disable IDE0051 +#pragma warning disable IDE1006 + +using MU3.Data; +using MU3.DataStudio; +using MU3.Util; +using System.Collections.Generic; +using System.Linq; + +namespace MU3.User; + +public class patch_UserRating: UserRating { + private int _rating100; + private UserManager usMgr => Singleton.instance; + + // Adaptation of calcBest() without bullshit + // The original lists stay intact because the game expects them to be filled + private RatingList calcSane() { + RatingList ratingList = new(); + + var musicDict = usMgr.userMusic; + + foreach (KeyValuePair item in musicDict) { + MU3.Data.MusicData musicData = SingletonStateMachine.instance.getMusicData(item.Key); + if (musicData == null || item.Key == 1 || musicData.isBonusTrack) { + continue; + } + for (int i = 0; i < 5; i++) { + FumenDifficulty fumenDifficulty = (FumenDifficulty)i; + UserFumen userFumen = usMgr.getUserFumen(item.Key, fumenDifficulty, create: false); + if (userFumen == null) { + continue; + } + Rating rating = new Rating(musicData.id, fumenDifficulty, userFumen.TechScoreMax); + if (rating.level100 == 0) { + continue; + } + ratingList.Add(rating); + } + } + + ratingList.Sort(); + + return ratingList; + } + + private void calcRate() { + _rating100 = 0; + foreach (Rating best in calcSane().Take(45)) { + _rating100 += best.rate100; + } + _rating100 /= 45; + } +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..457c030 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +## µ3 mods + +Miscellaneous mods for µ3/SDDT for my personal use. + +### BetterGiveUp + +Hold down the evil red menu button for 1 second to give up, or the friendlier yellow button to restart. Based on GiveUp, but Better (impossible to misclick). + +### ExportChartData + +Export some useful chart data into a dollar-separated file (charts.csv) when the game launches. + +### NaiveRating + +Replace the in-game rating algorithm (OldBest30+NewBest15+Recent10) with Best45. +This change is client-side and immediate, but **the server will acknowledge it**. I host my own server and don't care, but you have been warned. \ No newline at end of file