コード例 #1
0
ファイル: Main.cs プロジェクト: Contiinuum/AutoLightshow
        private static void PreparePsychedelia(SongCues.Cue cue)
        {
            if (Config.enablePsychedelia)
            {
                if (cue.behavior == Target.TargetBehavior.Melee || cue.behavior == Target.TargetBehavior.ChainStart || cue.behavior == Target.TargetBehavior.Hold)
                {
                    List <float> ticks = new List <float>();
                    if (cue.behavior == Target.TargetBehavior.ChainStart)
                    {
                        LookForEndOfChain(cue, ticks);
                    }
                    else
                    {
                        LookForLastBehavior(cue, new Target.TargetBehavior[] { Target.TargetBehavior.Melee }, ticks);
                    }

                    if (cue.behavior == Target.TargetBehavior.Hold && cue.tickLength >= 1920f)
                    {
                        //MelonCoroutines.Stop(psyToken);
                        //psyToken = MelonCoroutines.Start(DoPsychedelia(AudioDriver.I.mCachedTick + cue.tickLength - 960f));
                        psyEvents.Add(new PsyEvent(cue.tick, cue.tick + cue.tickLength - 960f));
                    }
                    else if (ticks[0] - cue.tick >= 1920f && cue.behavior == Target.TargetBehavior.Melee)
                    {
                        //MelonCoroutines.Stop(psyToken);
                        //psyToken = MelonCoroutines.Start(DoPsychedelia(ticks[0] - 960f));
                        psyEvents.Add(new PsyEvent(cue.tick, ticks[0] - 960f));
                    }
                }
            }
        }
コード例 #2
0
ファイル: Main.cs プロジェクト: Contiinuum/AutoLightshow
        private static float CalculateIntensity(float startTick, float endTick, List <SongCues.Cue> cues)
        {
            float intensity = 0f;
            bool  indexSet  = false;

            for (int i = startIndex; i < cues.Count; i++)
            {
                SongCues.Cue cue = SongCues.I.mCues.cues[i];
                if (cue.tick >= endTick)
                {
                    break;
                }
                if (cue.tick >= startTick && cue.tick < endTick)
                {
                    intensity += GetTargetAmount((Hitsound)cue.velocity, cue.behavior);
                    if (!indexSet)
                    {
                        indexSet   = true;
                        startIndex = i;
                    }
                }
            }

            intensity /= AudioDriver.TickSpanToMs(SongDataHolder.I.songData, startTick, endTick);

            intensity *= 1000f;
            return(intensity);
        }
コード例 #3
0
        private static void RemoveChainCues(Target.TargetHandType handType)
        {
            int length = songCues.Count - 1;
            int index  = 0;

            for (int i = 0; i < length; i++)
            {
                SongCues.Cue cue = songCues[index];
                if (cue.handType == handType)
                {
                    if (cue.behavior == Target.TargetBehavior.Chain)
                    {
                        songCues.RemoveAt(index);
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    index++;
                }
            }
        }
コード例 #4
0
 private static void Postfix(Telegraph __instance, SongCues.Cue cue, float animationSpeed)
 {
     if (Config.HiddenClouds == true || ForceEnable == true || Config.CleanStacks)
     {
         if (cue.behavior == Target.TargetBehavior.Melee || cue.behavior == Target.TargetBehavior.Dodge)
         {
             return;
         }
         if (Config.CleanStacks)
         {
             if (cue.nextCue is null || cue.behavior == Target.TargetBehavior.ChainStart || cue.behavior == Target.TargetBehavior.Chain)
             {
                 return;
             }
             if (cue.nextCue.pitch == cue.pitch && (cue.nextCue.tick - cue.tick < 480))
             {
                 __instance.cloud.enabled = false;
                 hideNextCloud            = true;
                 return;
             }
             if (hideNextCloud)
             {
                 hideNextCloud            = false;
                 __instance.cloud.enabled = false;
             }
         }
         else
         {
             __instance.cloud.enabled = false;
         }
     }
 }
コード例 #5
0
ファイル: Main.cs プロジェクト: Contiinuum/AutoLightshow
        private static void LookForLastBehavior(SongCues.Cue cue, Target.TargetBehavior[] behaviors, List <float> ticks)
        {
            if (cue.nextCue is null)
            {
                ticks.Add(cue.tick);
                return;
            }

            for (int i = 0; i < behaviors.Length; i++)
            {
                if (cue.nextCue.behavior == behaviors[i])
                {
                    if (cue.behavior == Target.TargetBehavior.Hold && cue.nextCue.behavior == Target.TargetBehavior.Hold && cue.tick == cue.nextCue.tick)
                    {
                        continue;
                    }
                    if (cue.behavior == Target.TargetBehavior.Melee && cue.nextCue.behavior == Target.TargetBehavior.Melee && cue.tick == cue.nextCue.tick)
                    {
                        continue;
                    }
                    LookForLastBehavior(cue.nextCue, behaviors, ticks);
                    return;
                }
            }

            ticks.Add(cue.nextCue.tick);
        }
コード例 #6
0
 private void RecursiveAdd(SongCues.Cue cue, List <SongCues.Cue> chain)
 {
     chain.Add(cue);
     if (cue.chainNext != null)
     {
         RecursiveAdd(cue.chainNext, chain);
     }
 }
コード例 #7
0
    Vector2 GetTrueCoordinates(SongCues.Cue cue)
    {
        float x = cue.pitch % 12;
        float y = (int)(cue.pitch / 12);

        x += cue.gridOffset.x;
        y += cue.gridOffset.y;
        return(new Vector2(x, y));
    }
コード例 #8
0
 private void RecursiveGetChain(SongCues.Cue cue, List <SongCues.Cue> chain, List <int> pitches)
 {
     chain.Add(cue);
     pitches.Add(cue.pitch);
     if (cue.chainNext != null)
     {
         RecursiveGetChain(cue.chainNext, chain, pitches);
     }
 }
コード例 #9
0
        private void pollSongState()
        {
            if (this.songPlaying)
            {
                string songClass = "custom";
                if (this.songData.IsCoreSong())
                {
                    songClass = "ost";
                }
                if (this.songData.dlc)
                {
                    songClass = "dlc";
                }
                if (this.songData.extrasSong)
                {
                    songClass = "extras";
                }

                // We don't want to calculate the ticks to the end of the song, it keeps playing!
                // Instead get the last target (plus its length) as the end ticks
                UnhollowerBaseLib.Il2CppReferenceArray <SongCues.Cue> cues = AudicaGameStateManager.songCues.mCues.cues;
                SongCues.Cue endCue       = cues[cues.Length - 1];
                float        songEndTicks = endCue.tick + endCue.tickLength;

                float currentTick = AudicaGameStateManager.scoreKeeper.mLastTick;

                float totalTimeMs     = this.songCalculator.SongLengthMilliseconds;
                float currentTimeMs   = this.songCalculator.GetSongPositionMilliseconds(currentTick);
                float remainingTimeMs = totalTimeMs - currentTimeMs;

                this.songState.songId           = this.songData.songID;
                this.songState.songName         = this.songData.title;
                this.songState.songArtist       = this.songData.artist;
                this.songState.songAuthor       = this.songData.author;
                this.songState.difficulty       = KataConfig.GetDifficultyName(AudicaGameStateManager.config.GetDifficulty());
                this.songState.classification   = songClass;
                this.songState.songLength       = TimeSpan.FromMilliseconds(Convert.ToInt64(totalTimeMs)).ToString();
                this.songState.timeElapsed      = TimeSpan.FromMilliseconds(Convert.ToInt64(currentTimeMs)).ToString();
                this.songState.timeRemaining    = TimeSpan.FromMilliseconds(Convert.ToInt64(remainingTimeMs)).ToString();
                this.songState.progress         = currentTimeMs / totalTimeMs;
                this.songState.currentTick      = currentTick;
                this.songState.ticksTotal       = songEndTicks;
                this.songState.songSpeed        = KataConfig.GetCueDartSpeedMultiplier(); // TODO: not a clue what this value actually is but it's not the speed multiplier!
                this.songState.health           = AudicaGameStateManager.scoreKeeper.GetHealth();
                this.songState.score            = AudicaGameStateManager.scoreKeeper.mScore;
                this.songState.scoreMultiplier  = AudicaGameStateManager.scoreKeeper.GetRawMultiplier();
                this.songState.streak           = AudicaGameStateManager.scoreKeeper.GetStreak();
                this.songState.highScore        = AudicaGameStateManager.scoreKeeper.GetHighScore();
                this.songState.isNoFailMode     = AudicaGameStateManager.prefs.NoFail.mVal;
                this.songState.isPracticeMode   = AudicaGameStateManager.config.practiceMode;
                this.songState.isFullComboSoFar = AudicaGameStateManager.scoreKeeper.GetIsFullComboSoFar();
                this.songState.modifiers        = AudicaGameStateManager.modifiers.GetCurrentModifiers()
                                                  .Select((GameplayModifiers.Modifier mod) => GameplayModifiers.GetModifierString(mod))
                                                  .ToList <string>();
            }
        }
コード例 #10
0
        public AudicaTargetFailState TargetMissAim()
        {
            AudicaTargetFailState targetMiss = new AudicaTargetFailState();

            SongCues.Cue cue = AudicaTargetStateManager.targetTracker.mLastEitherHandTarget.target.GetCue();

            targetMiss.targetIndex = cue.index;
            targetMiss.type        = this.cueToTargetType(cue);
            targetMiss.hand        = this.cueToHand(cue);
            targetMiss.reason      = "aim";
            return(targetMiss);
        }
コード例 #11
0
        private void SpawnMine(float tickStart)
        {
            if (tickStart > SongCues.I.GetLastCueStartTick())
            {
                return;
            }
            float   x      = UnityEngine.Random.Range(minOffset.x, maxOffset.x);
            float   y      = UnityEngine.Random.Range(minOffset.y, maxOffset.y);
            Vector2 offset = new Vector2(x, y);

            SongCues.Cue cue = new SongCues.Cue((int)tickStart, 120, 100, 3, Target.TargetHandType.None, Target.TargetBehavior.Dodge, offset);
            spawner.SpawnCue(cue);
        }
コード例 #12
0
        public AudicaTargetFailState TargetMissEarlyLate(float tick)
        {
            AudicaTargetFailState targetMiss = new AudicaTargetFailState();

            SongCues.Cue cue = AudicaTargetStateManager.targetTracker.mLastEitherHandTarget.target.GetCue();

            targetMiss.targetIndex = cue.index;
            targetMiss.type        = this.cueToTargetType(cue);
            targetMiss.hand        = this.cueToHand(cue);
            targetMiss.reason      = tick < cue.tick ? "early" : "late";

            return(targetMiss);
        }
コード例 #13
0
 private static void Postfix(Telegraph __instance, SongCues.Cue cue, float animationSpeed)
 {
     if (!hideTeles)
     {
         return;
     }
     if (cue.behavior == Target.TargetBehavior.Melee || cue.behavior == Target.TargetBehavior.Dodge)
     {
         return;
     }
     __instance.circleMesh.enabled = false;
     __instance.cloud.enabled      = false;
 }
コード例 #14
0
            private static void Postfix(ScoreKeeper __instance, ref SongCues.Cue cue)
            {
                if (KataConfig.I.practiceMode)
                {
                    return;
                }

                if (GrindMode.waitForRestart)
                {
                    return;
                }
                if (GrindMode.grindMode && Config.highscoreMode && !GrindMode.highscoreIsSetup)
                {
                    GrindMode.SetHighscore(ScoreKeeper.I.GetHighScore());
                }

                if (cue is null)
                {
                    return;
                }

                if (!GrindMode.grindMode || KataConfig.I.NoFail())
                {
                    return;
                }

                if (Config.highscoreMode)
                {
                    //if (!GrindMode.skipSetScoreMiss)
                    GrindMode.SetCurrentScore(__instance.mScore, __instance.mStreak, __instance.mMultiplier, cue, true);

                    //GrindMode.skipSetScoreMiss = !GrindMode.skipSetScoreMiss;
                    return;
                }

                if (!Config.includeChainSustainBreak)
                {
                    if (cue.behavior == Target.TargetBehavior.Chain)
                    {
                        //MelonModLogger.Log("Chain break! Ignoring.");
                        return;
                    }
                    else if (cue.behavior == Target.TargetBehavior.Hold && cue.target.mSustainFailed)
                    {
                        //MelonModLogger.Log("Sustain break! Ignoring.");
                        return;
                    }
                }
                GrindMode.ReportMiss(cue);
            }
コード例 #15
0
        public AudicaTargetHitState TargetHit(GameplayStats gameplayStats, SongCues.Cue cue, Vector2 targetHitPos)
        {
            AudicaTargetHitState targetHit = new AudicaTargetHitState();

            targetHit.targetIndex       = cue.index;
            targetHit.type              = this.cueToTargetType(cue);
            targetHit.hand              = this.cueToHand(cue);
            targetHit.timingScore       = gameplayStats.GetLastTimingScore();
            targetHit.aimScore          = gameplayStats.GetLastAimScore();
            targetHit.score             = targetHit.timingScore + targetHit.aimScore; // TODO: may need to multiply by combo? Need to test
            targetHit.tick              = cue.tick;
            targetHit.targetHitPosition = targetHitPos;

            return(targetHit);
        }
コード例 #16
0
        private string cueToHand(SongCues.Cue cue)
        {
            string hand = "";

            switch (cue.handType)
            {
            case Target.TargetHandType.Left: hand = "left"; break;

            case Target.TargetHandType.Right: hand = "right"; break;

            case Target.TargetHandType.Either: hand = "either"; break;

            case Target.TargetHandType.None: hand = "none"; break;
            }
            return(hand);
        }
コード例 #17
0
ファイル: Main.cs プロジェクト: Contiinuum/AutoLightshow
        private static void LookForEndOfChain(SongCues.Cue cue, List <float> ticks)
        {
            if (cue.nextCue is null)
            {
                ticks.Add(cue.tick);
                return;
            }

            if (cue.nextCue.behavior == Target.TargetBehavior.Chain)
            {
                LookForEndOfChain(cue.nextCue, ticks);
                return;
            }

            ticks.Add(cue.nextCue.tick);
        }
コード例 #18
0
            private static void Postfix(ScoreKeeper __instance, ref SongCues.Cue cue)
            {
                if (KataConfig.I.practiceMode)
                {
                    return;
                }


                if (!GrindMode.grindMode || KataConfig.I.NoFail())
                {
                    return;
                }

                if (Config.highscoreMode)
                {
                    if (!GrindMode.highscoreIsSetup)
                    {
                        GrindMode.SetHighscore(ScoreKeeper.I.GetHighScore());
                    }

                    // if (!GrindMode.skipSetScoreSuccess)
                    GrindMode.SetCurrentScore(__instance.mScore, __instance.mStreak, __instance.mMultiplier, cue);

                    //GrindMode.skipSetScoreSuccess = !GrindMode.skipSetScoreSuccess;
                    return;
                }

                if (GrindMode.chainLH)
                {
                    if (cue.handType == Target.TargetHandType.Left)
                    {
                        GrindMode.chainLH = false;
                    }
                }
                else if (GrindMode.chainRH)
                {
                    if (cue.handType == Target.TargetHandType.Right)
                    {
                        GrindMode.chainRH = false;
                    }
                }
            }
コード例 #19
0
        public static void ReportMiss(SongCues.Cue cue)
        {
            if (Config.highscoreMode)
            {
                return;
            }
            //return here, else every single chain node would count as an individual miss
            if (lastTarget.behavior == Target.TargetBehavior.Chain && cue.behavior == Target.TargetBehavior.Chain && lastTarget.handType == cue.handType)
            {
                return;
            }

            if (cue.behavior == Target.TargetBehavior.Chain || cue.behavior == Target.TargetBehavior.ChainStart)
            {
                if (cue.handType == Target.TargetHandType.Left)
                {
                    chainLH = true;
                }
                else
                {
                    chainRH = true;
                }
            }
            else if (chainLH)
            {
                chainLH = false;
            }
            else if (chainRH)
            {
                chainRH = false;
            }
            lastTarget = cue;
            reportedCues.Add(cue);

            missCount++;
            CheckFail();
        }
コード例 #20
0
        private string cueToTargetType(SongCues.Cue cue)
        {
            string type = "";

            switch (cue.behavior)
            {
            case Target.TargetBehavior.Melee: type = "melee"; break;

            case Target.TargetBehavior.Standard: type = "standard"; break;

            case Target.TargetBehavior.Hold: type = "sustain"; break;

            case Target.TargetBehavior.Vertical: type = "vertical"; break;

            case Target.TargetBehavior.Horizontal: type = "horizontal"; break;

            case Target.TargetBehavior.ChainStart: type = "chain-start"; break;

            case Target.TargetBehavior.Chain: type = "chain"; break;

            case Target.TargetBehavior.Dodge: type = "bomb"; break;
            }
            return(type);
        }
コード例 #21
0
        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);
            }
        }
コード例 #22
0
 public static void Postfix(ref GameplayStats __instance, ref SongCues.Cue cue, ref Vector2 targetHitPos)
 {
     MelonLoader.MelonModLogger.Log("Target Hit! " + targetHitPos.ToString());
     AudicaTargetHitState targetHit = AudicaHTTPStatus.AudicaTargetState.TargetHit(__instance, cue, targetHitPos);
     // TODO: feed output into JSON parser then to HTTP server as websocket event
 }
コード例 #23
0
        public static void SetCurrentScore(int score, int streak, int multiplier, SongCues.Cue cue, bool miss = false)
        {
            if (waitForRestart)
            {
                return;
            }
            if (cue.behavior == Target.TargetBehavior.Chain)
            {
                lastTarget = cue;
                if (cue.nextCue.behavior == Target.TargetBehavior.Chain)
                {
                    return;
                }
                else
                {
                    if (chainLH && cue.handType == Target.TargetHandType.Left)
                    {
                        chainLH = false;
                    }
                    else if (chainRH && cue.handType == Target.TargetHandType.Right)
                    {
                        chainRH = false;
                    }
                    RemoveChainCues(cue.handType);
                }
            }

            if (cue.behavior == Target.TargetBehavior.ChainStart)
            {
                if (cue.handType == Target.TargetHandType.Left)
                {
                    chainLH = true;
                }
                else
                {
                    chainRH = true;
                }
            }


            lastTarget = cue;

            int length = songCues.Count - 1;

            if (chainLH)
            {
                int index = 0;
                for (int i = 0; i < length; i++)
                {
                    SongCues.Cue c = songCues[i];
                    if (c.behavior == Target.TargetBehavior.Chain && c.handType == Target.TargetHandType.Left)
                    {
                        index++;
                    }
                    else
                    {
                        songCues.RemoveAt(index);
                        break;
                    }
                }
            }
            else if (chainRH)
            {
                int index = 0;
                for (int i = 0; i < length; i++)
                {
                    SongCues.Cue c = songCues[i];
                    if (c.behavior == Target.TargetBehavior.Chain && c.handType == Target.TargetHandType.Right)
                    {
                        index++;
                    }
                    else
                    {
                        songCues.RemoveAt(index);
                        break;
                    }
                }
            }
            else
            {
                if (cue.behavior != Target.TargetBehavior.Chain)
                {
                    songCues.RemoveAt(0);
                }
            }


            currentScore      = score;
            currentMultiplier = multiplier;
            currentStreak     = streak;

            CalculateMaxPossibleScore();
        }
コード例 #24
0
 private static void Prefix(Target __instance, TargetSpawner.SpawnInfo info, SongCues.Cue cue)
 {
     if (!updateChainColor)
     {
         return;
     }
     if (cue.behavior != Target.TargetBehavior.Chain)
     {
         return;
     }
     if (cue.handType == Target.TargetHandType.Left)
     {
         __instance.chainLine.startColor = PlayerPreferences.I.GunColorLeft.Get() / 2;
         __instance.chainLine.endColor   = PlayerPreferences.I.GunColorLeft.Get() / 2;
     }
     else
     {
         __instance.chainLine.startColor = PlayerPreferences.I.GunColorRight.Get() / 2;
         __instance.chainLine.endColor   = PlayerPreferences.I.GunColorRight.Get() / 2;
     }
 }