private MessageResponder GetActiveResponder(KMGameInfo.State state)
    {
        switch (state)
        {
        case KMGameInfo.State.Gameplay:
            DefaultCamera();
            return(bombMessageResponder);

        case KMGameInfo.State.Setup:
            DefaultCamera();
            _coroutinesToStart.Enqueue(VanillaRuleModifier.Refresh());
            _coroutinesToStart.Enqueue(MultipleBombs.Refresh());
            _coroutinesToStart.Enqueue(FactoryRoomAPI.Refresh());
            _coroutinesToStart.Enqueue(CreateSolversForAllBombComponents());

            return(missionMessageResponder);

        case KMGameInfo.State.PostGame:
            DefaultCamera();
            return(postGameMessageResponder);

        case KMGameInfo.State.Transitioning:
            ModuleData.LoadDataFromFile();
            TwitchPlaySettings.LoadDataFromFile();
            return(null);

        default:
            return(null);
        }
    }
Exemplo n.º 2
0
    public string ManualFor(string module, string type = "html", bool useVanillaRuleModifier = false)
    {
        if (useVanillaRuleModifier && VanillaRuleModifier.GetRuleSeed() != 1)
        {
            return($"{Repository}manual/{Escape(module)}.html?VanillaRuleSeed={VanillaRuleModifier.GetRuleSeed()}");
        }

        return(string.Format(Repository + "{0}/{1}.{2}", type.ToUpper(), Escape(module), type));
    }
Exemplo n.º 3
0
    private void OnStateChange(KMGameInfo.State state)
    {
        CurrentState = state;
        if (!transform.gameObject.activeInHierarchy)
        {
            return;
        }

        StartCoroutine(StopEveryCoroutine());

        if (state != KMGameInfo.State.PostGame && _leaderboardDisplay != null)
        {
            DestroyObject(_leaderboardDisplay);
            _leaderboardDisplay = null;
        }

        twitchGame?.gameObject.SetActive(state == KMGameInfo.State.Gameplay);

        OtherModes.RefreshModes(state);

        // Automatically check for updates after a round is finished or when entering the setup state but never more than once per hour.
        bool hourPassed = DateTime.Now.Subtract(Updater.LastCheck).TotalHours >= 1;

        if ((state == KMGameInfo.State.PostGame || state == KMGameInfo.State.Setup) && hourPassed && !Updater.UpdateAvailable)
        {
            _coroutinesToStart.Enqueue(AutomaticUpdateCheck());
        }

        switch (state)
        {
        case KMGameInfo.State.Gameplay:
            DefaultCamera();
            break;

        case KMGameInfo.State.Setup:
            DefaultCamera();
            _coroutinesToStart.Enqueue(VanillaRuleModifier.Refresh());
            _coroutinesToStart.Enqueue(MultipleBombs.Refresh());
            _coroutinesToStart.Enqueue(FactoryRoomAPI.Refresh());
            _coroutinesToStart.Enqueue(FindSupportedModules());
            break;

        case KMGameInfo.State.PostGame:
            DefaultCamera();
            if (_leaderboardDisplay == null)
            {
                _leaderboardDisplay = Instantiate(TwitchLeaderboardPrefab);
            }
            Leaderboard.Instance.SaveDataToFile();
            break;

        case KMGameInfo.State.Transitioning:
            ModuleData.LoadDataFromFile();
            TwitchPlaySettings.LoadDataFromFile();
            break;
        }
    }
Exemplo n.º 4
0
    public ButtonComponentSolver(BombCommander bombCommander, ButtonComponent bombComponent) :
        base(bombCommander, bombComponent)
    {
        ModuleInformation buttonInfo         = ComponentSolverFactory.GetModuleInfo("ButtonComponentSolver", "!{0} tap [tap the button] | !{0} hold [hold the button] | !{0} release 7 [release when the digit shows 7]");
        ModuleInformation buttonInfoModified = ComponentSolverFactory.GetModuleInfo("ButtonComponentModifiedSolver", "Click the button with !{0} tap. Click the button at time with !{0} tap 8:55 8:44 8:33. Hold the button with !{0} hold. Release the button with !{0} release 9:58 9:49 9:30.");

        bombComponent.GetComponent <Selectable>().OnCancel += bombComponent.OnButtonCancel;
        _button = bombComponent.button;
        modInfo = VanillaRuleModifier.IsSeedVanilla() ? buttonInfo : buttonInfoModified;
    }
    public ButtonComponentSolver(TwitchModule module) :
        base(module)
    {
        ModuleInformation buttonInfo         = ComponentSolverFactory.GetModuleInfo("ButtonComponentSolver", "!{0} tap [tap the button] | !{0} hold [hold the button] | !{0} release 7 [release when the digit shows 7]");
        ModuleInformation buttonInfoModified = ComponentSolverFactory.GetModuleInfo("ButtonComponentModifiedSolver", "Click the button with !{0} tap. Click the button at a time with !{0} tap 8:55 8:44 8:33. Hold the button with !{0} hold. Release the button with !{0} release 9:58 9:49 9:30.");

        var buttonModule = (ButtonComponent)module.BombComponent;

        buttonModule.GetComponent <Selectable>().OnCancel += buttonModule.OnButtonCancel;
        _button = buttonModule.button;
        ModInfo = VanillaRuleModifier.IsSeedVanilla() ? buttonInfo : buttonInfoModified;
    }
Exemplo n.º 6
0
    private void OnStateChange(KMGameInfo.State state)
    {
        CurrentState = state;
        if (!transform.gameObject.activeInHierarchy)
        {
            return;
        }

        StartCoroutine(StopEveryCoroutine());

        if (state != KMGameInfo.State.PostGame && _leaderboardDisplay != null)
        {
            DestroyObject(_leaderboardDisplay);
            _leaderboardDisplay = null;
        }

        twitchGame?.gameObject.SetActive(state == KMGameInfo.State.Gameplay);

        OtherModes.RefreshModes(state);

        switch (state)
        {
        case KMGameInfo.State.Gameplay:
            DefaultCamera();
            break;

        case KMGameInfo.State.Setup:
            DefaultCamera();
            _coroutinesToStart.Enqueue(VanillaRuleModifier.Refresh());
            _coroutinesToStart.Enqueue(MultipleBombs.Refresh());
            _coroutinesToStart.Enqueue(FactoryRoomAPI.Refresh());
            _coroutinesToStart.Enqueue(FindSupportedModules());
            break;

        case KMGameInfo.State.PostGame:
            DefaultCamera();
            if (_leaderboardDisplay == null)
            {
                _leaderboardDisplay = Instantiate(TwitchLeaderboardPrefab);
            }
            Leaderboard.Instance.SaveDataToFile();
            break;

        case KMGameInfo.State.Transitioning:
            ModuleData.LoadDataFromFile();
            TwitchPlaySettings.LoadDataFromFile();
            break;
        }
    }
    public ButtonComponentSolver(BombCommander bombCommander, ButtonComponent bombComponent, IRCConnection ircConnection, CoroutineCanceller canceller) :
        base(bombCommander, bombComponent, ircConnection, canceller)
    {
        ModuleInformation buttonInfo       = ComponentSolverFactory.GetModuleInfo("ButtonComponentSolver");
        ModuleInformation squarebuttonInfo = ComponentSolverFactory.GetModuleInfo("ButtonV2");

        bombComponent.GetComponent <Selectable>().OnCancel += bombComponent.OnButtonCancel;
        _button = bombComponent.button;
        modInfo = new ModuleInformation
        {
            builtIntoTwitchPlays       = buttonInfo.builtIntoTwitchPlays,
            CameraPinningAlwaysAllowed = buttonInfo.CameraPinningAlwaysAllowed,
            helpText = VanillaRuleModifier.IsSeedVanilla()
                ? buttonInfo.helpText
                : squarebuttonInfo.helpText,
            manualCode        = buttonInfo.manualCode,
            moduleDisplayName = buttonInfo.moduleDisplayName,
            moduleID          = buttonInfo.moduleID,
            moduleScore       = VanillaRuleModifier.IsSeedVanilla()
                ? buttonInfo.moduleScore
                : squarebuttonInfo.moduleScore
        };
    }
Exemplo n.º 8
0
    private MessageResponder GetActiveResponder(KMGameInfo.State state)
    {
        switch (state)
        {
        case KMGameInfo.State.Gameplay:
            return(bombMessageResponder);

        case KMGameInfo.State.Setup:
            StartCoroutine(VanillaRuleModifier.Refresh());
            StartCoroutine(MultipleBombs.Refresh());
            return(missionMessageResponder);

        case KMGameInfo.State.PostGame:
            return(postGameMessageResponder);

        case KMGameInfo.State.Transitioning:
            ModuleData.LoadDataFromFile();
            TwitchPlaySettings.LoadDataFromFile();
            return(null);

        default:
            return(null);
        }
    }
Exemplo n.º 9
0
    public static void Help(TwitchModule module, [Group(1)] bool pdf)
    {
        string manualType = pdf ? "pdf" : "html";

        string manualText = (Repository.GetManual(module.BombComponent.GetModuleID()) ?? module.BombComponent.GetModuleDisplayName()) + TranslatedModuleHelper.GetManualCodeAddOn(module.Solver.LanguageCode);
        string helpText   = string.IsNullOrEmpty(module.Solver.HelpMessage) ? string.Empty : string.Format(module.Solver.HelpMessage, module.Code, module.HeaderText);

        IRCConnection.SendMessage($"{module.HeaderText} : {helpText} : {UrlHelper.ManualFor(manualText, manualType, VanillaRuleModifier.GetModuleRuleSeed(module.Solver.ModInfo.moduleID) != 1)}");
    }
    protected internal override IEnumerator RespondToCommandInternal(string inputCommand)
    {
        bool isModdedSeed = VanillaRuleModifier.IsSeedModded();

        inputCommand = inputCommand.ToLowerInvariant().Trim();
        if (!_held && inputCommand.EqualsAny("tap", "click"))
        {
            yield return("tap");

            yield return(DoInteractionClick(_button));
        }
        if (!_held && (inputCommand.StartsWith("tap ") ||
                       inputCommand.StartsWith("click ")))
        {
            if (!isModdedSeed)
            {
                yield break;
            }
            yield return("tap2");

            IEnumerator releaseCoroutine = ReleaseCoroutineModded(inputCommand.Substring(inputCommand.IndexOf(' ')));
            while (releaseCoroutine.MoveNext())
            {
                yield return(releaseCoroutine.Current);
            }
        }
        else if (!_held && inputCommand.Equals("hold"))
        {
            yield return("hold");

            _held = true;
            DoInteractionStart(_button);
            yield return(new WaitForSeconds(2.0f));
        }
        else if (_held)
        {
            string[] commandParts = inputCommand.Split(' ');
            if (commandParts.Length != 2 || !commandParts[0].Equals("release"))
            {
                yield break;
            }
            IEnumerator releaseCoroutine;

            if (!isModdedSeed)
            {
                if (!int.TryParse(commandParts[1], out int second))
                {
                    yield break;
                }
                if (second >= 0 && second <= 9)
                {
                    releaseCoroutine = ReleaseCoroutineVanilla(second);
                }
                else
                {
                    yield break;
                }
            }
            else
            {
                releaseCoroutine = ReleaseCoroutineModded(inputCommand.Substring(inputCommand.IndexOf(' ')));
            }

            while (releaseCoroutine.MoveNext())
            {
                yield return(releaseCoroutine.Current);
            }
        }
    }
Exemplo n.º 11
0
    public static void Help(TwitchModule module, [Group(1)] bool pdf)
    {
        string manualType = pdf ? "pdf" : "html";

        string manualText = string.IsNullOrEmpty(module.Solver.ManualCode) ? module.HeaderText : module.Solver.ManualCode;
        string helpText   = string.IsNullOrEmpty(module.Solver.HelpMessage) ? string.Empty : string.Format(module.Solver.HelpMessage, module.Code, module.HeaderText);

        IRCConnection.SendMessage(Regex.IsMatch(manualText, @"^https?://", RegexOptions.IgnoreCase)
                        ? $"{module.HeaderText} : {helpText} : {manualText}"
                        : $"{module.HeaderText} : {helpText} : {UrlHelper.Instance.ManualFor(manualText, manualType, VanillaRuleModifier.GetModuleRuleSeed(module.Solver.ModInfo.moduleID) != 1)}");
    }
Exemplo n.º 12
0
 public static string ManualFor(string module, string type = "html", bool useVanillaRuleModifier = false) => string.Format(TwitchPlaySettings.data.RepositoryUrl + "{0}/{1}.{2}{3}", type.ToUpper(), NameToUrl(module), type, (useVanillaRuleModifier && type.Equals("html")) ? $"#{VanillaRuleModifier.GetRuleSeed()}" : "");
    private void OnStateChange(KMGameInfo.State state)
    {
        CurrentState = state;

        if (!transform.gameObject.activeInHierarchy)
        {
            return;
        }

        StartCoroutine(StopEveryCoroutine());
        CheckSupport.Cleanup();
        Votes.Clear();

        if (state != KMGameInfo.State.PostGame && _leaderboardDisplay != null)
        {
            DestroyObject(_leaderboardDisplay);
            _leaderboardDisplay = null;
        }

        twitchGame?.gameObject.SetActive(state == KMGameInfo.State.Gameplay);

        OtherModes.RefreshModes(state);

        // Automatically check for updates after a round is finished or when entering the setup state but never more than once per hour.
        bool hourPassed = DateTime.Now.Subtract(Updater.LastCheck).TotalHours >= 1;

        if ((state == KMGameInfo.State.PostGame || state == KMGameInfo.State.Setup) && hourPassed && !Updater.UpdateAvailable)
        {
            _coroutinesToStart.Enqueue(AutomaticUpdateCheck());
        }

        switch (state)
        {
        case KMGameInfo.State.Gameplay:
            DefaultCamera();
            break;

        case KMGameInfo.State.Setup:
            DefaultCamera();
            _coroutinesToStart.Enqueue(VanillaRuleModifier.Refresh());
            _coroutinesToStart.Enqueue(MultipleBombs.Refresh());
            _coroutinesToStart.Enqueue(FactoryRoomAPI.Refresh());

            if (!initialLoad)
            {
                initialLoad = true;
                _coroutinesToStart.Enqueue(ComponentSolverFactory.LoadDefaultInformation(true));
                if (!TwitchPlaySettings.data.TwitchPlaysDebugEnabled)
                {
                    _coroutinesToStart.Enqueue(CheckSupport.FindSupportedModules());
                }
            }

            // Clear out the retry reward if we return to the setup room since the retry button doesn't return to setup.
            // A post game run command would set the retry bonus and then return to the setup room to start the mission, so we don't want to clear that.
            if (TwitchPlaySettings.GetRewardBonus() == 0)
            {
                TwitchPlaySettings.ClearRetryReward();
            }
            break;

        case KMGameInfo.State.PostGame:
            DefaultCamera();
            if (_leaderboardDisplay == null)
            {
                _leaderboardDisplay = Instantiate(TwitchLeaderboardPrefab);
            }
            Leaderboard.Instance.SaveDataToFile();
            break;

        case KMGameInfo.State.Transitioning:
            ModuleData.LoadDataFromFile();
            TwitchPlaySettings.LoadDataFromFile();

            var pageManager = SceneManager.Instance?.SetupState?.Room.GetComponent <SetupRoom>().BombBinder.MissionTableOfContentsPageManager;
            if (pageManager != null)
            {
                var tableOfContentsList = pageManager.GetValue <List <Assets.Scripts.BombBinder.MissionTableOfContents> >("tableOfContentsList");
                if (tableOfContentsList[SetupState.LastBombBinderTOCIndex].ToCID == "toc_tp_search")
                {
                    SetupState.LastBombBinderTOCIndex = 0;
                    SetupState.LastBombBinderTOCPage  = 0;
                }
            }

            break;
        }
    }
    private IEnumerator ReleaseCoroutineModded(string second)
    {
        bool longwait = false;

        string[]   list        = second.Split(' ');
        List <int> sortedTimes = new List <int>();

        foreach (string value in list)
        {
            if (!int.TryParse(value, out int time))
            {
                int pos = value.LastIndexOf(':');
                if (pos == -1)
                {
                    continue;
                }
                int hour = 0;
                if (!int.TryParse(value.Substring(0, pos), out int min))
                {
                    int pos2 = value.IndexOf(":");
                    if ((pos2 == -1) || (pos == pos2))
                    {
                        continue;
                    }
                    if (!int.TryParse(value.Substring(0, pos2), out hour))
                    {
                        continue;
                    }
                    if (!int.TryParse(value.Substring(pos2 + 1, pos - pos2 - 1), out min))
                    {
                        continue;
                    }
                }
                if (!int.TryParse(value.Substring(pos + 1), out int sec))
                {
                    continue;
                }
                time = (hour * 3600) + (min * 60) + sec;
            }
            sortedTimes.Add(time);
        }
        sortedTimes.Sort();
        sortedTimes.Reverse();
        if (sortedTimes.Count == 0)
        {
            yield break;
        }

        yield return("release");

        TimerComponent timerComponent = BombCommander.Bomb.GetTimer();

        int timeTarget = sortedTimes[0];

        sortedTimes.RemoveAt(0);

        int waitTime = (int)(timerComponent.TimeRemaining + 0.25f);

        waitTime -= timeTarget;
        if (waitTime >= 30)
        {
            yield return("elevator music");

            if (waitTime >= 120)
            {
                yield return(string.Format("sendtochat !!!WARNING!!! - you might want to do a !cancel right about now, as you will be waiting for {0} minutes and {1} seconds for button release. Seed #{2} applies to this button.", waitTime / 60, waitTime % 60, VanillaRuleModifier.GetRuleSeed()));

                yield return(string.Format("sendtochat Click the button with !{0} tap. Click the button at time with !{0} tap 8:55 8:44 8:33. Hold the button with !{0} hold. Release the button with !{0} release 9:58 9:49 9:30.", Code));

                longwait = true;
            }
        }

        float timeRemaining = float.PositiveInfinity;

        while (timeRemaining > 0.0f)
        {
            if (Canceller.ShouldCancel)
            {
                Canceller.ResetCancel();
                if (timeTarget < 10)
                {
                    yield return(string.Format("sendtochat The button was not {0} due to a request to cancel. Remember that the rule set that applies is seed #{1}", _held ? "released" : "tapped", VanillaRuleModifier.GetRuleSeed()));
                }
                else
                {
                    yield return(string.Format("sendtochat The button was not {0} due to a request to cancel.", _held ? "released" : "tapped"));
                }
                yield break;
            }

            timeRemaining = (int)(timerComponent.TimeRemaining + 0.25f);

            if (timeRemaining < timeTarget)
            {
                if (sortedTimes.Count == 0)
                {
                    yield return(string.Format("sendtochaterror The button was not {0} because all of your specfied times are greater than the time remaining.", _held ? "released" : "tapped"));

                    yield break;
                }
                timeTarget = sortedTimes[0];
                sortedTimes.RemoveAt(0);

                waitTime  = (int)timeRemaining;
                waitTime -= timeTarget;
                if (waitTime >= 30)
                {
                    yield return("elevator music");

                    if (waitTime >= 120 && !longwait)
                    {
                        yield return(string.Format("sendtochat !!!WARNING!!! - you might want to do a !cancel right about now, as you will be waiting for {0} minutes and {1} seconds for button release. Seed #{2} applies to this button.", waitTime / 60, waitTime % 60, VanillaRuleModifier.GetRuleSeed()));

                        yield return(string.Format("sendtochat Click the button with !{0} tap. Click the button at time with !{0} tap 8:55 8:44 8:33. Hold the button with !{0} hold. Release the button with !{0} release 9:58 9:49 9:30.", Code));
                    }
                    longwait = true;
                }

                continue;
            }
            if (Math.Abs(timeRemaining - timeTarget) < 0.1f)
            {
                if (!_held)
                {
                    DoInteractionStart(_button);
                    yield return(new WaitForSeconds(0.1f));
                }
                DoInteractionEnd(_button);
                _held = false;
                yield break;
            }

            yield return(null);
        }
    }