initial commit

This commit is contained in:
あかニャン 2024-05-22 06:57:39 +09:00
commit edddcbffd7
9 changed files with 333 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.vs/
*.sln
*.csproj
**/bin/*
**/obj/*
*.dll

View File

@ -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<patch_ButtonParam> {}
}

View File

@ -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;
}
}
}
}

View File

@ -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();
}
}

View File

@ -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<UIInput>.instance.getStateOn(UIInput.Key.MenuLeft) ^ Singleton<UIInput>.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<GameSound>.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<GameSound>.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<UIInput>.instance.getStateOn(UIInput.Key.MenuRight)) {
StartRolling();
} else {
ntMgr.forceDamage(damage: 100);
}
}
} else {
_isHoldingAck = false;
orig_Execute_Play();
}
}
}

View File

@ -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");
}
}

24
LICENSE Normal file
View File

@ -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 <http://unlicense.org/>

View File

@ -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<UserManager>.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<int, UserMusic> item in musicDict) {
MU3.Data.MusicData musicData = SingletonStateMachine<DataManager, DataManager.EState>.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;
}
}

16
README.md Normal file
View File

@ -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.