public void SongStart(SongList.SongData song) { this.initialiseStateManagers(); this.songCalculator = new SongLengthCalculator(); this.songData = song; this.songPlaying = true; }
private void EvaluateDifficulties(SongList.SongData songData) { var expertCues = SongCues.GetCues(songData, KataConfig.Difficulty.Expert); if (expertCues.Length > 0 && expertCues != null) { this.expert = new CalculatedDifficulty(expertCues, songData); } var advancedCues = SongCues.GetCues(songData, KataConfig.Difficulty.Hard); if (advancedCues.Length > 0 && advancedCues != null) { this.advanced = new CalculatedDifficulty(advancedCues, songData); } var standardCues = SongCues.GetCues(songData, KataConfig.Difficulty.Normal); if (standardCues.Length > 0 && standardCues != null) { this.standard = new CalculatedDifficulty(standardCues, songData); } var beginnerCues = SongCues.GetCues(songData, KataConfig.Difficulty.Easy); if (beginnerCues.Length > 0 && beginnerCues != null) { this.beginner = new CalculatedDifficulty(beginnerCues, songData); } }
public static void SelectRandomSong() { if (currentSongsFull.Count == 0) { return; } if (currentSongs.Count == 0) { recentlySelected.Clear(); FillSongList(); } int songCount = currentSongs.Count; System.Random rand = new System.Random(); int idx = rand.Next(0, songCount); string songID = currentSongs[idx]; SongList.SongData data = SongList.I.GetSong(songID); if (data != null) { // remove from the random songs list currentSongs.RemoveAt(idx); if (recentlySelected.Count > historySize) { recentlySelected.RemoveAt(0); } recentlySelected.Add(songID); SongDataHolder.I.songData = data; MenuState.I.GoToLaunchPage(); } }
private static SongList.SongData SearchSong(QueryData data, out bool foundExactMatch) { SongList.SongData song = null; bool foundAny = false; bool foundBetter = false; foundExactMatch = false; for (int i = 0; i < SongList.I.songs.Count; i++) { SongList.SongData currentSong = SongList.I.songs[i]; if ((data.Artist == null || currentSong.artist.ToLowerInvariant().Replace(" ", "").Contains(data.Artist)) && (data.Mapper == null || currentSong.author.ToLowerInvariant().Replace(" ", "").Contains(data.Mapper)) && (currentSong.title.ToLowerInvariant().Contains(data.Title) || currentSong.songID.ToLowerInvariant().Contains(data.Title.Replace(" ", "")))) { if (LookForMatch(data.Title, currentSong.title, ref foundAny, ref foundBetter, ref foundExactMatch)) { song = currentSong; if (foundExactMatch) { break; } } } } return(song); }
public static void SelectRandomSong() { SongSelect select = GameObject.FindObjectOfType <SongSelect>(); if (select == null) { return; } List <SongSelectItem> songs = select.GetSongButtons(); if (songs.Count == 0) { return; } int songCount = songs.Count; System.Random rand = new System.Random(); int idx = rand.Next(0, songCount); SongList.SongData data = songs[idx].mSongData; if (data != null) { SongDataHolder.I.songData = data; MenuState.I.GoToLaunchPage(); } }
public DifficultyCalculator(SongList.SongData songData) { if (songData == null) { return; } this.songID = songData.songID; EvaluateDifficulties(songData); }
public void EvaluateCues(SongCues.Cue[] cues, SongList.SongData songData) { this.length = AudioDriver.TickSpanToMs(songData, cues[0].tick, cues[cues.Length - 1].tick); SplitCues(cues); CalculateSpacing(); CalculateDensity(); CalculateReadability(); difficultyRating = ((spacing + readability) / length) * 500f + (length / 100000f * lengthMultiplier); }
public static int GetFirstTick() { if (cachedFirstTick == 0) { SongList.SongData songData = SongDataHolder.I.songData; KataConfig.Difficulty diff = KataConfig.I.GetDifficulty(); cachedFirstTick = SongCues.GetCues(songData, diff)[0].tick; } return(cachedFirstTick); }
public static IEnumerator ChangeNamesDS(DifficultySelect __instance) { yield return(new WaitForSeconds(0.05f)); SongList.SongData song = SongDataHolder.I.songData; ChangeSpecificDifficulty(ref song, __instance.expert.label, difficultyNameToTag["Expert"]); ChangeSpecificDifficulty(ref song, __instance.hard.label, difficultyNameToTag["Advanced"]); ChangeSpecificDifficulty(ref song, __instance.normal.label, difficultyNameToTag["Moderate"]); ChangeSpecificDifficulty(ref song, __instance.easy.label, difficultyNameToTag["Beginner"]); }
public static IEnumerator ChangeNamesLP(LaunchPanel __instance) { yield return(new WaitForSeconds(0.05f)); SongList.SongData song = SongDataHolder.I.songData; ChangeSpecificDifficulty(ref song, __instance.expert.GetComponentInChildren <TextMeshPro>(), difficultyNameToTag["Expert"]); ChangeSpecificDifficulty(ref song, __instance.hard.GetComponentInChildren <TextMeshPro>(), difficultyNameToTag["Advanced"]); ChangeSpecificDifficulty(ref song, __instance.normal.GetComponentInChildren <TextMeshPro>(), difficultyNameToTag["Moderate"]); ChangeSpecificDifficulty(ref song, __instance.easy.GetComponentInChildren <TextMeshPro>(), difficultyNameToTag["Beginner"]); }
private static void Postfix(SongSelectItem __instance) { SongList.SongData currentSong = SongDataHolder.I.songData; AudicaRPC.Presence.state = currentSong.artist; AudicaRPC.Presence.details = currentSong.title; AudicaRPC.Presence.startTimestamp = default(long); AudicaRPC.Presence.largeImageKey = "audica_main"; AudicaRPC.Presence.largeImageText = "Audica"; AudicaRPC.Presence.smallImageKey = "expert"; AudicaRPC.Presence.smallImageText = "Expert difficulty"; DiscordRpc.UpdatePresence(AudicaRPC.Presence); }
public static void UpdateUiInfo(SongList.SongData data) { songInfo.text = Utility.RemoveFormatting($"{data.artist} - {data.title}"); mapperInfo.text = data.author; difficultyLabel.text = kataConfig.mDifficulty.ToString(); var scoreKeeper = ScoreKeeper.I; scoreText.text = scoreKeeper.GetScore().ToString("N0", CultureInfo.CreateSpecificCulture("en-US")); comboText.text = scoreKeeper.mStreak > 1 ? scoreKeeper.mStreak.ToString() + " Streak!" : ""; int aimAssistPercent = (int)(PlayerPreferences.I.AimAssistAmount.mVal * 100f); aimAssistLabel.text = aimAssistPercent != 100 ? $"{aimAssistPercent}% AA" : ""; ModifierText.text = Utility.GetModText(); }
private string GetSongName(string song) { string fileName = song + ".audica"; if (PlaylistManager.internalSongList.Any(s => Path.GetFileName(s.zipPath) == fileName)) { SongList.SongData _song = PlaylistManager.internalSongList.First(s => Path.GetFileName(s.zipPath) == fileName); SetSongDownloaded(song, true); return(_song.title + " - " + _song.author); } else { SetSongDownloaded(song, false); return(song); } }
public static void OnSelect(IntPtr @this) { AudicaRPC.SongSelectItem_OnSelect.InvokeOriginal(@this); MelonModLogger.Log("Song Selected!"); SongList.SongData currentSong = SongDataHolder.I.songData; Presence.state = currentSong.artist; Presence.details = currentSong.title; Presence.startTimestamp = default(long); Presence.largeImageKey = "audica_main"; Presence.largeImageText = "Audica"; Presence.smallImageKey = "expert"; Presence.smallImageText = "Expert difficulty"; DiscordRpc.UpdatePresence(Presence); }
private static void ChangeSpecificDifficulty(ref SongList.SongData song, TextMeshPro label, string difficultyTag) { bool hasCustom = SongDataLoader.AllSongData[song.songID].HasCustomData(); if (hasCustom && SongDataLoader.AllSongData[song.songID].SongHasCustomDataKey(difficultyTag)) { string text = SongDataLoader.AllSongData[song.songID].GetCustomData <string>(difficultyTag); if (text.Length > 0) { label.SetText(text); } } else { label.SetText(difficultyTagToName[difficultyTag]); } }
public static void ProcessQueue() { bool addedAny = false; MelonLogger.Log(requestQueue.Count + " in queue."); if (requestQueue.Count != 0) { foreach (string str in requestQueue) { QueryData data = new QueryData(str); SongList.SongData result = SearchSong(data, out bool foundExactMatch); if ((!hasCompatibleSongBrowser || foundExactMatch) && result != null) { // if we have web search we want to make sure we prioritize exact matches // over partial local ones MelonLogger.Log("Result: " + result.songID); if (!requestList.Contains(result.songID)) { requestList.Add(result.songID); addedAny = true; } } else if (hasCompatibleSongBrowser) { StartWebSearch(data); } else { MelonLogger.Log($"Found no match for \"{str}\""); } } requestQueue.Clear(); } if (addedAny && MenuState.GetState() == MenuState.State.SongPage) { RequestUI.UpdateFilter(); } RequestUI.UpdateButtonText(); }
private static void Postfix(AudioDriver __instance) { if (!Config.Enabled) { return; } SongCues.Cue[] cues = SongCues.I.GetCues(); SongList.SongData song = SongList.I.GetSong(SongDataHolder.I.songData.songID); SongList.SongData.TempoChange[] tempos = song.tempos; for (int i = 0; i < tempos.Length; i++) { float timingWindowMs = 200 * Mathf.Lerp(0.07f, 1.0f, percent); float ticks = timingWindowMs / (60000 / (tempos[i].tempo * 480)); float halfTicks = ticks / 2; for (int j = 0; j < cues.Length; j++) { if (cues[j].behavior != Target.TargetBehavior.Chain && cues[j].behavior != Target.TargetBehavior.Dodge && cues[j].behavior != Target.TargetBehavior.Melee) { void UpdateTarget(SongCues.Cue cue) { cue.slopAfterTicks = halfTicks; cue.slopBeforeTicks = halfTicks; } if (cues[j].tick >= tempos[i].tick) { if (tempos.Length >= tempos.Length + 1 && cues[j].tick < tempos[i + 1].tick) { UpdateTarget(cues[j]); } else if (tempos.Length < tempos.Length + 1) { UpdateTarget(cues[j]); } } } } } }
public static void Search() { searchResult.Clear(); searchInProgress = false; if (query == null) { return; } for (int i = 0; i < SongList.I.songs.Count; i++) { SongList.SongData currentSong = SongList.I.songs[i]; bool isCustom = Utility.IsCustomSong(currentSong.songID); if ((mapType == MapType.CustomsOnly && !isCustom) || (mapType == MapType.OfficialOnly && isCustom)) { continue; } if (currentSong.songID == "tutorial") { continue; // never return the tutorial as result } string cleanQuery = CleanForSearch(query); if (CleanForSearch(currentSong.artist).Contains(cleanQuery) || CleanForSearch(currentSong.title).Contains(cleanQuery) || CleanForSearch(currentSong.songID).Contains(cleanQuery) || currentSong.author != null && CleanForSearch(currentSong.author).Contains(cleanQuery) || CleanForSearch(currentSong.artist).Replace(" ", "").Contains(cleanQuery) || CleanForSearch(currentSong.title).Replace(" ", "").Contains(cleanQuery)) { searchResult.Add(currentSong.songID); } } }
private void Precalc() { this.song = SongDataHolder.I.songData; UnhollowerBaseLib.Il2CppReferenceArray <SongCues.Cue> cues = AudicaGameStateManager.songCues.mCues.cues; SongCues.Cue endCue = cues[cues.Length - 1]; float endTick = endCue.tick + endCue.tickLength; this.songLengthMs = 0; for (int i = 0; i < song.tempos.Length; i++) { float startChunkTick = song.tempos[i].tick; float endChunkTick = endTick; // if it's NOT the last tempo change, grab the tick from the next one instead. if (i != song.tempos.Length - 1) { endChunkTick = song.tempos[i + 1].tick; } // complete chunk length in ticks float chunkTickLength = endChunkTick - startChunkTick; // ms accumulator float chunkMilliseconds = GetTicksMillisconds(chunkTickLength, song.tempos[i].tempo); this.songLengthMs += chunkMilliseconds; // cache ChunkCache chunk = new ChunkCache(); chunk.startTick = startChunkTick; chunk.endTick = endChunkTick; chunk.lengthMs = chunkMilliseconds; this.chunkCache.Add(chunk); } }
public CalculatedDifficulty(SongCues.Cue[] cues, SongList.SongData songData) { EvaluateCues(cues, songData); }
public DifficultyCalculator(SongList.SongData songData) { this.songID = songData.songID; EvaluateDifficulties(songData); }
//The process to update a LeaderboardRow public static void UpdateLeaderboardRow(LeaderboardRow leaderboardRow) { //DoWork function is really intensive so it's called only when absolutely required //This function will calculate the total max possible score for either OST or with extras void DoWork(bool e) { Il2CppSystem.Collections.Generic.List <SongList.SongData> songs = SongList.I.songs; int totalMaxScore = 0; for (int i = 0; i < songs.Count; i++) { SongList.SongData song = songs[i]; if (e) { if (song.dlc | song.unlockable) { totalMaxScore += starThresholds.GetMaxRawScore(song.songID, KataConfig.Difficulty.Expert); } } if (song.dlc == false && song.unlockable == false && song.extrasSong == false) { totalMaxScore += starThresholds.GetMaxRawScore(song.songID, KataConfig.Difficulty.Expert); } } if (e) { extrasMaxTotalScore = totalMaxScore; } else { ostMaxTotalScore = totalMaxScore; } } float score = Convert.ToSingle(leaderboardRow.mData.score.Split('.')[0]); float percentage; if (menuState != MenuState.State.MainPage) { percentage = GetScorePercentage(selectedSong, score, KataConfig.Difficulty.Expert); } else { LeaderboardDisplay leaderboardDisplay = UnityEngine.Object.FindObjectOfType <LeaderboardDisplay>(); bool extras = leaderboardDisplay.extrasButton.IsChecked.Invoke(); DoWork(extras); if (extras) { if (extrasMaxTotalScore == 0) { DoWork(extras); } percentage = (score / extrasMaxTotalScore) * 100; } else { if (ostMaxTotalScore == 0) { DoWork(extras); } percentage = (score / ostMaxTotalScore) * 100; } } //Make pretty-ish strings leaderboardRow.username.text = "<size=" + leaderboardUsernameSize + ">" + leaderboardRow.username.text + "</size>"; string scoreString = "<size=" + leaderboardHighScoreSize + ">" + String.Format("{0:n0}", score).Replace(",", " ") + "</size>"; string percentageString = "<size=" + leaderboardPercentSize + "> (" + String.Format("{0:0.00}", percentage) + "%)</size>"; //Update label if (leaderboardRow.score.text.Contains("<color=yellow>")) { leaderboardRow.score.text = "<color=" + leaderboardUserColor + ">" + scoreString + percentageString + "</color>"; } else { leaderboardRow.score.text = scoreString + percentageString; } if (leaderboardRow.rank.text.Contains("<color=yellow>")) { leaderboardRow.rank.text = leaderboardRow.rank.text.Replace("<color=yellow>", "<color=" + leaderboardUserColor + ">"); } if (leaderboardRow.username.text.Contains("<color=yellow>")) { leaderboardRow.username.text = leaderboardRow.username.text.Replace("<color=yellow>", "<color=" + leaderboardUserColor + ">"); } }
private static void ProcessWebSearchResult(string query, APISongList response) { QueryData data = webSearchQueryData[query]; bool addedLocalMatch = false; if (response.song_count > 0) { Song bestMatch = null; bool foundAny = false; bool foundBetter = false; bool foundExact = false; foreach (Song s in response.songs) { if ((data.Artist == null || s.artist.ToLowerInvariant().Replace(" ", "").Contains(data.Artist)) && (data.Mapper == null || s.author.ToLowerInvariant().Replace(" ", "").Contains(data.Mapper)) && (s.title.ToLowerInvariant().Contains(data.Title) || s.song_id.ToLowerInvariant().Contains(data.Title.Replace(" ", "")))) { if (LookForMatch(data.Title, s.title, ref foundAny, ref foundBetter, ref foundExact)) { bestMatch = s; if (foundExact) { break; } } } } if (bestMatch != null) { // check if we already have that file downloaded QueryData matchData = new QueryData($"{bestMatch.title} -artist {bestMatch.artist} -mapper {bestMatch.author}"); SongList.SongData s = SearchSong(matchData, out bool isExactMatch); if (isExactMatch) { MelonLogger.Log("Result: " + s.songID); if (!requestList.Contains(s.songID)) { requestList.Add(s.songID); addedLocalMatch = true; } } else if (!missingSongs.ContainsKey(bestMatch.song_id)) { missingSongs.Add(bestMatch.song_id, bestMatch); MelonLogger.Log("Result (missing): " + bestMatch.song_id); } } else { MelonLogger.Log($"Found no match for \"{data.FullQuery}\""); } } else { // check if we have a local match (can happen if // this particular map hasn't been uploaded or was taken down) SongList.SongData s = SearchSong(data, out bool _); if (s != null) { MelonLogger.Log("Result: " + s.songID); if (!requestList.Contains(s.songID)) { requestList.Add(s.songID); addedLocalMatch = true; } } else { MelonLogger.Log($"Found no match for \"{data.FullQuery}\""); } } if (addedLocalMatch && MenuState.GetState() == MenuState.State.SongPage) { RequestUI.UpdateFilter(); } webSearchQueryData.Remove(query); if (GetActiveWebSearchCount() == 0) { RequestUI.UpdateButtonText(); } }