using MonoMod; using MU3.Battle; using MU3.Game; using MU3.Notes; using MU3.Util; using System; using UnityEngine; namespace MU3.Sequence; class patch_PlayMusic: PlayMusic { private static readonly TimeSpan HOLD_DURATION = TimeSpan.FromSeconds(1.0f); private static readonly TimeSpan ROLL_DURATION = TimeSpan.FromSeconds(0.5f); public static bool QuickSkip = false; private GameEngine _gameEngine; private SessionInfo _sessionInfo; private bool _pressedYellow; 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; [MonoModIgnore] private extern bool isPartyPlay(); 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 bool IsHolding() { return Singleton.instance.getStateOn(UIInput.Key.MenuLeft) ^ (_pressedYellow && Singleton.instance.getStateOn(UIInput.Key.MenuRight)); } private void StartRolling() { _pressedYellow = false; _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.setPause(false); 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 extern void orig_Execute_Play(); private void Execute_Play() { if(isPartyPlay()) { return; } if(Singleton.instance.getTriggerOn(UIInput.Key.MenuRight)) { _pressedYellow = true; } 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 { QuickSkip = true; setNextState(EState.End); destroy(); ntMgr.stopPlay(); _gameEngine.destroyAllies(); _gameEngine.finishGame(); _gameEngine.playFinish(); } } } else { _isHoldingAck = false; orig_Execute_Play(); } } private extern void orig_Execute_DispCombo(); private void Execute_DispCombo() { orig_Execute_DispCombo(); if(Singleton.instance.getTriggerOn(UIInput.Key.MenuRight) && ntMgr.retireResult != RetireResult.None) { setNextState(EState.Init); } } }