Beispiel #1
0
 public TwitchPlaysProperties()
 {
     AddProperty("TimeMode", new Property(() => OtherModes.TimeModeOn, x => OtherModes.TimeModeOn = (bool)x));
     AddProperty("ZenMode", new Property(() => OtherModes.ZenModeOn, x => OtherModes.ZenModeOn    = (bool)x));
     AddProperty("TimeModeTimeLimit", new Property(() => TwitchPlaySettings.data.TimeModeStartingTime, SetTimeModeTimeLimit));
     AddProperty("ircConnectionSendMessage", new Property(null, x => IRCConnection.Instance.SendMessage((string)x)));
     AddProperty("Reward", new Property(() => TwitchPlaySettings.GetRewardBonus(), x => TwitchPlaySettings.SetRewardBonus((int)x)));
     AddProperty("CauseFakeStrike", new Property(null, CauseFakeStrike));
 }
Beispiel #2
0
    public static void Status(TwitchBomb bomb, string user, bool isWhisper)
    {
        int currentReward = TwitchPlaySettings.GetRewardBonus();

        if (OtherModes.TimeModeOn)
        {
            IRCConnection.SendMessage(string.Format(TwitchPlaySettings.data.BombStatusTimeMode, bomb.GetFullFormattedTime, bomb.GetFullStartingTime,
                                                    OtherModes.GetAdjustedMultiplier(), bomb.BombSolvedModules, bomb.BombSolvableModules, currentReward), user, !isWhisper);
        }
        else if (OtherModes.VSModeOn)
        {
            IRCConnection.SendMessage(string.Format(TwitchPlaySettings.data.BombStatusVsMode, bomb.GetFullFormattedTime,
                                                    bomb.GetFullStartingTime, OtherModes.goodHealth, OtherModes.evilHealth, currentReward), user, !isWhisper);
        }
        else
        {
            IRCConnection.SendMessage(string.Format(TwitchPlaySettings.data.BombStatus, bomb.GetFullFormattedTime, bomb.GetFullStartingTime,
                                                    bomb.StrikeCount, bomb.StrikeLimit, bomb.BombSolvedModules, bomb.BombSolvableModules, currentReward), user, !isWhisper);
        }
    }
Beispiel #3
0
 public void UpdateConfidence()
 {
     if (OtherModes.TimeModeOn)
     {
         float timedMultiplier = OtherModes.GetAdjustedMultiplier();
         ConfidencePrefab.color = Color.yellow;
         string conf = "x" + $"{timedMultiplier:0.0}";
         string pts  = "+" + $"{TwitchPlaySettings.GetRewardBonus():0}";
         ConfidencePrefab.text = pts;
         StrikesPrefab.color   = Color.yellow;
         StrikesPrefab.text    = conf;
     }
     else if (OtherModes.ZenModeOn)
     {
         ConfidencePrefab.color = Color.yellow;
         string pts = "+" + $"{TwitchPlaySettings.GetRewardBonus():0}";
         ConfidencePrefab.text = pts;
         StrikesPrefab.color   = Color.red;
         if (_currentBomb != null)
         {
             StrikesPrefab.text = _currentBomb.StrikeCount.ToString();
         }
     }
     else if (OtherModes.VSModeOn)
     {
         int bossHealth = OtherModes.GetEvilHealth();
         int teamHealth = OtherModes.GetGoodHealth();
         StrikesPrefab.color    = Color.cyan;
         ConfidencePrefab.color = Color.red;
         StrikesPrefab.text     = $"{teamHealth} HP";
         ConfidencePrefab.text  = $"{bossHealth} HP";
     }
     else
     {
         ConfidencePrefab.color = Color.yellow;
         string pts = $"+{TwitchPlaySettings.GetRewardBonus():0}";
         ConfidencePrefab.text = pts;
     }
 }
Beispiel #4
0
    public static void NewBomb(string user, bool isWhisper)
    {
        if (!OtherModes.ZenModeOn)
        {
            IRCConnection.SendMessage($"Sorry {user}, the newbomb command is only allowed in Zen mode.", user, !isWhisper);
            return;
        }
        if (isWhisper)
        {
            IRCConnection.SendMessage($"Sorry {user}, the newbomb command is not allowed in whispers.", user, !isWhisper);
            return;
        }

        Leaderboard.Instance.GetRank(user, out var entry);
        if (entry.SolveScore < TwitchPlaySettings.data.MinScoreForNewbomb && !UserAccess.HasAccess(user, AccessLevel.Defuser, true))
        {
            IRCConnection.SendMessage($"Sorry {user}, you don’t have enough points to use the newbomb command.");
        }
        else
        {
            TwitchPlaySettings.AddRewardBonus(-TwitchPlaySettings.GetRewardBonus());

            foreach (var bomb in TwitchGame.Instance.Bombs.Where(x => GameRoom.Instance.IsCurrentBomb(x.BombID)))
            {
                bomb.Bomb.GetTimer().StopTimer();
            }

            foreach (var module in TwitchGame.Instance.Modules.Where(x => GameRoom.Instance.IsCurrentBomb(x.BombID)))
            {
                if (!module.Solved)
                {
                    module.SolveSilently();
                }
            }
        }
    }
    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;
        }
    }
    public IEnumerator OnMessageReceived(string userNickName, string userColor, string text)
    {
        string internalCommand;
        Match  match = Regex.Match(text, string.Format("^{0} (.+)", _code), RegexOptions.IgnoreCase);

        if (!match.Success)
        {
            match = Regex.Match(text, string.Format("^{0}(?> (.+))?", _edgeworkCode), RegexOptions.IgnoreCase);
            if (match.Success)
            {
                internalCommand = match.Groups[1].Value;
                if (!string.IsNullOrEmpty(internalCommand))
                {
                    if (!IsAuthorizedDefuser(userNickName))
                    {
                        return(null);
                    }
                    edgeworkText.text = internalCommand;
                }
                IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.BombEdgework, edgeworkText.text);
            }
            return(null);
        }

        internalCommand = match.Groups[1].Value;

        TwitchMessage message = Instantiate <TwitchMessage>(messagePrefab, messageScrollContents.transform, false);

        message.SetMessage(string.IsNullOrEmpty(userColor)
                        ? string.Format("<b>{0}</b>: {1}", userNickName, internalCommand)
                        : string.Format("<b><color={2}>{0}</color></b>: {1}", userNickName, internalCommand, userColor));

        string internalCommandLower = internalCommand.ToLowerInvariant();

        string[] split = internalCommandLower.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);

        //Respond instantly to these commands without dropping "The Bomb", should the command be for "The Other Bomb" and vice versa.
        ICommandResponseNotifier notifier = message;

        if (internalCommandLower.EqualsAny("timestamp", "date"))
        {
            //Some modules depend on the date/time the bomb, and therefore that Module instance has spawned, in the bomb defusers timezone.

            notifier.ProcessResponse(CommandResponse.Start);
            IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.BombTimeStamp, bombCommander.BombTimeStamp);
            notifier.ProcessResponse(CommandResponse.EndNotComplete);
        }
        else if (internalCommandLower.Equals("help"))
        {
            notifier.ProcessResponse(CommandResponse.Start);

            IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.BombHelp);

            notifier.ProcessResponse(CommandResponse.EndNotComplete);
        }
        else if (internalCommandLower.EqualsAny("time", "timer", "clock"))
        {
            notifier.ProcessResponse(CommandResponse.Start);
            IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.BombTimeRemaining, bombCommander.GetFullFormattedTime, bombCommander.GetFullStartingTime);
            notifier.ProcessResponse(CommandResponse.EndNotComplete);
        }
        else if (internalCommandLower.EqualsAny("explode", "detonate", "endzenmode"))
        {
            if (UserAccess.HasAccess(userNickName, AccessLevel.Mod, true) || (OtherModes.ZenModeOn && internalCommandLower.Equals("endzenmode")))
            {
                return(DelayBombExplosionCoroutine(notifier));
            }

            return(null);
        }
        else if (internalCommandLower.Equals("status") || internalCommandLower.Equals("info"))
        {
            int currentReward = TwitchPlaySettings.GetRewardBonus();
            if (OtherModes.TimeModeOn)
            {
                IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.BombStatusTimeMode, bombCommander.GetFullFormattedTime, bombCommander.GetFullStartingTime,
                                                   OtherModes.GetAdjustedMultiplier(), bombCommander.bombSolvedModules, bombCommander.bombSolvableModules, currentReward);
            }
            else if (OtherModes.VSModeOn)
            {
                IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.BombStatusVsMode, bombCommander.GetFullFormattedTime,
                                                   bombCommander.GetFullStartingTime, OtherModes.teamHealth, OtherModes.bossHealth, currentReward);
            }
            else
            {
                IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.BombStatus, bombCommander.GetFullFormattedTime, bombCommander.GetFullStartingTime,
                                                   bombCommander.StrikeCount, bombCommander.StrikeLimit, bombCommander.bombSolvedModules, bombCommander.bombSolvableModules, currentReward);
            }
        }
        else if (split[0].EqualsAny("add", "increase", "change", "subtract", "decrease", "remove", "set"))
        {
            if (UserAccess.HasAccess(userNickName, AccessLevel.Admin, true))
            {
                bool negitive = split[0].EqualsAny("subtract", "decrease", "remove");
                bool direct   = split[0].EqualsAny("set");
                switch (split[1])
                {
                case "time":
                case "t":
                    float time = 0;
                    Dictionary <string, float> timeLengths = new Dictionary <string, float>()
                    {
                        { "ms", 0.001f },
                        { "s", 1 },
                        { "m", 60 },
                        { "h", 3600 },
                        { "d", 86400 },
                        { "w", 604800 },
                        { "y", 31536000 },
                    };

                    foreach (string part in split.Skip(2))
                    {
                        bool valid = false;
                        foreach (string unit in timeLengths.Keys)
                        {
                            if (!part.EndsWith(unit) || !float.TryParse(part.Substring(0, part.Length - unit.Length), out float length))
                            {
                                continue;
                            }
                            time += length * timeLengths[unit];
                            valid = true;
                            break;
                        }

                        if (!valid)
                        {
                            return(null);
                        }
                    }

                    time = (float)Math.Round((decimal)time, 2, MidpointRounding.AwayFromZero);
                    if (!direct && Math.Abs(time) == 0)
                    {
                        break;
                    }
                    if (negitive)
                    {
                        time = -time;
                    }

                    if (direct)
                    {
                        bombCommander.timerComponent.TimeRemaining = time;
                    }
                    else
                    {
                        bombCommander.timerComponent.TimeRemaining = bombCommander.CurrentTimer + time;
                    }

                    if (direct)
                    {
                        IRCConnection.Instance.SendMessage("Set the bomb's timer to {0}.", Math.Abs(time < 0 ? 0 : time).FormatTime());
                    }
                    else
                    {
                        IRCConnection.Instance.SendMessage("{0} {1} {2} the timer.", time > 0 ? "Added" : "Subtracted", Math.Abs(time).FormatTime(), time > 0 ? "to" : "from");
                    }
                    break;

                case "strikes":
                case "strike":
                case "s":
                    if (int.TryParse(split[2], out int strikes) && (strikes != 0 || direct))
                    {
                        if (negitive)
                        {
                            strikes = -strikes;
                        }

                        if (direct && strikes < 0)
                        {
                            strikes = 0;
                        }
                        else if (!direct && (bombCommander.StrikeCount + strikes) < 0)
                        {
                            strikes = -bombCommander.StrikeCount;                                       //Minimum of zero strikes. (Simon says is unsolvable with negative strikes.)
                        }

                        if (direct)
                        {
                            bombCommander.StrikeCount = strikes;
                        }
                        else
                        {
                            bombCommander.StrikeCount += strikes;
                        }

                        if (direct)
                        {
                            IRCConnection.Instance.SendMessage("Set the bomb's strike count to {0} {1}.", Math.Abs(strikes), Math.Abs(strikes) != 1 ? "strikes" : "strike");
                        }
                        else
                        {
                            IRCConnection.Instance.SendMessage("{0} {1} {2} {3} the bomb.", strikes > 0 ? "Added" : "Subtracted", Math.Abs(strikes), Math.Abs(strikes) != 1 ? "strikes" : "strike", strikes > 0 ? "to" : "from");
                        }
                        BombMessageResponder.moduleCameras.UpdateStrikes();
                    }
                    break;

                case "strikelimit":
                case "sl":
                case "maxstrikes":
                case "ms":
                    if (int.TryParse(split[2], out int maxStrikes) && (maxStrikes != 0 || direct))
                    {
                        if (negitive)
                        {
                            maxStrikes = -maxStrikes;
                        }

                        if (direct && maxStrikes < 0)
                        {
                            maxStrikes = 0;
                        }
                        else if (!direct && (bombCommander.StrikeLimit + maxStrikes) < 0)
                        {
                            maxStrikes = -bombCommander.StrikeLimit;
                        }

                        if (direct)
                        {
                            bombCommander.StrikeLimit = maxStrikes;
                        }
                        else
                        {
                            bombCommander.StrikeLimit += maxStrikes;
                        }

                        if (direct)
                        {
                            IRCConnection.Instance.SendMessage("Set the bomb's strike limit to {0} {1}.", Math.Abs(maxStrikes), Math.Abs(maxStrikes) != 1 ? "strikes" : "strike");
                        }
                        else
                        {
                            IRCConnection.Instance.SendMessage("{0} {1} {2} {3} the strike limit.", maxStrikes > 0 ? "Added" : "Subtracted", Math.Abs(maxStrikes), Math.Abs(maxStrikes) > 1 ? "strikes" : "strike", maxStrikes > 0 ? "to" : "from");
                        }
                        BombMessageResponder.moduleCameras.UpdateStrikes();
                        BombMessageResponder.moduleCameras.UpdateStrikeLimit();
                    }
                    break;
                }
            }

            return(null);
        }
        else if (!IsAuthorizedDefuser(userNickName))
        {
            return(null);
        }
        else
        {
            return(RespondToCommandCoroutine(userNickName, internalCommand, message));
        }

        return(null);
    }
    private void AwardStrikes(string userNickName, int strikeCount)
    {
        BombCommander BombCommander = BombMessageResponder.Instance.BombCommanders[0];
        int           strikePenalty = -5;

        strikePenalty = TwitchPlaySettings.data.EnableRewardMultipleStrikes ? (strikeCount * strikePenalty) : (Math.Min(strikePenalty, strikeCount * strikePenalty));

        IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.AwardHoldableStrike,
                                           HoldableCommander.ID,
                                           strikeCount == 1 ? "a" : strikeCount.ToString(),
                                           strikeCount == 1 ? "" : "s",
                                           strikePenalty,
                                           userNickName,
                                           string.IsNullOrEmpty(StrikeMessage) ? "" : " caused by " + StrikeMessage);
        if (strikeCount <= 0)
        {
            return;
        }

        string RecordMessageTone = $"Holdable ID: {HoldableCommander.ID} | Player: {userNickName} | Strike";

        TwitchPlaySettings.AppendToSolveStrikeLog(RecordMessageTone, TwitchPlaySettings.data.EnableRewardMultipleStrikes ? strikeCount : 1);

        int originalReward = TwitchPlaySettings.GetRewardBonus();
        int currentReward  = Convert.ToInt32(originalReward * TwitchPlaySettings.data.AwardDropMultiplierOnStrike);

        TwitchPlaySettings.AddRewardBonus(currentReward - originalReward);
        if (currentReward != originalReward)
        {
            IRCConnection.Instance.SendMessage($"Reward {(currentReward > 0 ? "reduced" : "increased")} to {currentReward} points.");
        }
        if (OtherModes.TimeModeOn)
        {
            bool   multiDropped = OtherModes.DropMultiplier();
            float  multiplier   = OtherModes.GetMultiplier();
            string tempMessage;
            if (multiDropped)
            {
                tempMessage = "Multiplier reduced to " + Math.Round(multiplier, 1) + " and time";
            }
            else
            {
                tempMessage = $"Multiplier set at {TwitchPlaySettings.data.TimeModeMinMultiplier}, cannot be further reduced.  Time";
            }
            if (BombCommander.CurrentTimer < (TwitchPlaySettings.data.TimeModeMinimumTimeLost / TwitchPlaySettings.data.TimeModeTimerStrikePenalty))
            {
                BombCommander.timerComponent.TimeRemaining = BombCommander.CurrentTimer - TwitchPlaySettings.data.TimeModeMinimumTimeLost;
                tempMessage = tempMessage + $" reduced by {TwitchPlaySettings.data.TimeModeMinimumTimeLost} seconds.";
            }
            else
            {
                float  timeReducer = BombCommander.CurrentTimer * TwitchPlaySettings.data.TimeModeTimerStrikePenalty;
                double easyText    = Math.Round(timeReducer, 1);
                BombCommander.timerComponent.TimeRemaining = BombCommander.CurrentTimer - timeReducer;
                tempMessage = tempMessage + $" reduced by {Math.Round(TwitchPlaySettings.data.TimeModeTimerStrikePenalty * 100, 1)}%. ({easyText} seconds)";
            }
            IRCConnection.Instance.SendMessage(tempMessage);
            BombCommander.StrikeCount = 0;
            BombMessageResponder.moduleCameras?.UpdateStrikes();
        }

        Leaderboard.Instance?.AddScore(userNickName, strikePenalty);
        Leaderboard.Instance?.AddStrike(userNickName, strikeCount);
        StrikeMessage = string.Empty;
    }
Beispiel #8
0
 public void UpdateConfidence()
 {
     if (OtherModes.timedModeOn)
     {
         float timedMultiplier = OtherModes.getMultiplier();
         confidencePrefab.color = Color.yellow;
         string conf = "x" + String.Format("{0:0.0}", timedMultiplier);
         string pts  = "+" + String.Format("{0:0}", TwitchPlaySettings.GetRewardBonus());
         confidencePrefab.text   = pts;
         strikesPrefab.color     = Color.yellow;
         strikeLimitPrefab.color = Color.yellow;
         strikesPrefab.text      = conf;
         strikeLimitPrefab.text  = "";
     }
     //     if (OtherModes.vsModeOn)
     //     {
     //         int bossHealth = OtherModes.getBossHealth();
     //         int teamHealth = OtherModes.getTeamHealth();
     //
     //     }
     else
     {
         confidencePrefab.color = Color.yellow;
         string pts = "+" + String.Format("{0:0}", TwitchPlaySettings.GetRewardBonus());
         confidencePrefab.text = pts;
         //    int previousSuccess = (int)(currentSuccess * 100);
         //    currentSuccess = PlayerSuccessRating;
         //
         //    if (previousSuccess != (int)(currentSuccess * 100))
         //    {
         //        float minHue = 0.0f; // red (0deg)
         //        float maxHue = (float)1 / 3; // green (120deg)
         //        float minBeforeValueDown = 0.25f;
         //        float maxBeforeSaturationDown = 0.75f;
         //        float minValue = 0.25f;
         //        float minSaturation = 0.0f;
         //        float lowSuccessDesaturationSpeed = 3.0f;
         //
         //        float hueSuccessRange = maxBeforeSaturationDown - minBeforeValueDown;
         //        float hueRange = maxHue - minHue;
         //        float valueRange = 1.0f - minValue;
         //        float saturationRange = 1.0f - minSaturation;
         //
         //        float hue, pointOnScale;
         //        float saturation = 1.0f;
         //        float value = 1.0f;
         //
         //        if (currentSuccess < minBeforeValueDown)
         //        {
         //            // At very low ratings, move from red to dark grey
         //            hue = minHue;
         //            pointOnScale = (currentSuccess - (minBeforeValueDown / lowSuccessDesaturationSpeed)) * lowSuccessDesaturationSpeed;
         //            pointOnScale = Math.Max(pointOnScale, 0.0f) / minBeforeValueDown;
         //            saturation = minSaturation + (saturationRange * pointOnScale);
         //            pointOnScale = currentSuccess / maxBeforeSaturationDown;
         //            value = minValue + (valueRange * pointOnScale);
         //        }
         //        else if (currentSuccess > maxBeforeSaturationDown)
         //        {
         //            // At very high ratings, move from green to white
         //            hue = maxHue;
         //            pointOnScale = ((1.0f - currentSuccess) / (1.0f - maxBeforeSaturationDown));
         //            saturation = minSaturation + (saturationRange * pointOnScale);
         //        }
         //        else
         //        {
         //            // At moderate ratings, move between red and green
         //            pointOnScale = ((currentSuccess - minBeforeValueDown) / hueSuccessRange);
         //            hue = minHue + (hueRange * pointOnScale);
         //        }
         //
         //        confidencePrefab.color = Color.HSVToRGB(hue, saturation, value);
         //    }
         //
         //
         //    string conf = string.Format("{0:00}%", currentSuccess * 100);
         //    confidencePrefab.text = conf;
     }
 }
Beispiel #9
0
    private void AwardStrikes(string userNickName, ICommandResponseNotifier responseNotifier, int strikeCount)
    {
        string headerText    = BombComponent.GetModuleDisplayName();
        int    strikePenalty = modInfo.strikePenalty * (TwitchPlaySettings.data.EnableRewardMultipleStrikes ? strikeCount : 1);

        IRCConnection.SendMessage(TwitchPlaySettings.data.AwardStrike, Code, strikeCount == 1 ? "a" : strikeCount.ToString(), strikeCount == 1 ? "" : "s", 0, userNickName, string.IsNullOrEmpty(StrikeMessage) ? "" : " caused by " + StrikeMessage, headerText, strikePenalty);
        if (strikeCount <= 0)
        {
            return;
        }

        string RecordMessageTone = $"Module ID: {Code} | Player: {userNickName} | Module Name: {headerText} | Strike";

        TwitchPlaySettings.AppendToSolveStrikeLog(RecordMessageTone, TwitchPlaySettings.data.EnableRewardMultipleStrikes ? strikeCount : 1);

        int currentReward = TwitchPlaySettings.GetRewardBonus();

        currentReward = Convert.ToInt32(currentReward * .80);
        TwitchPlaySettings.SetRewardBonus(currentReward);
        IRCConnection.SendMessage("Reward reduced to " + currentReward + " points.");
        if (OtherModes.timedModeOn)
        {
            bool   multiDropped = OtherModes.dropMultiplier();
            float  multiplier   = OtherModes.getMultiplier();
            string tempMessage;
            if (multiDropped)
            {
                tempMessage = "Multiplier reduced to " + Math.Round(multiplier, 1) + " and time";
            }
            else
            {
                tempMessage = "Mutliplier set at 1, cannot be further reduced.  Time";
            }
            if (BombCommander.CurrentTimer < 60)
            {
                BombCommander.timerComponent.TimeRemaining = BombCommander.CurrentTimer - 15;
                tempMessage = tempMessage + " reduced by 15 seconds.";
            }
            else
            {
                float  timeReducer = BombCommander.CurrentTimer * .25f;
                double easyText    = Math.Round(timeReducer, 1);
                BombCommander.timerComponent.TimeRemaining = BombCommander.CurrentTimer - timeReducer;
                tempMessage = tempMessage + " reduced by 25%. (" + easyText + " seconds)";
            }
            IRCConnection.SendMessage(tempMessage);
        }
        if (responseNotifier != null)
        {
            responseNotifier.ProcessResponse(CommandResponse.EndErrorSubtractScore, strikePenalty);
            responseNotifier.ProcessResponse(CommandResponse.EndError, strikeCount);
        }
        else
        {
            ComponentHandle.leaderboard.AddScore(userNickName, strikePenalty);
            ComponentHandle.leaderboard.AddStrike(userNickName, strikeCount);
        }
        if (OtherModes.timedModeOn)
        {
            BombCommander.StrikeCount = 0;
            BombMessageResponder.moduleCameras.UpdateStrikes();
        }
        StrikeMessage = string.Empty;
    }
    private void AwardStrikes(string userNickName, int strikeCount)
    {
        string headerText    = UnsupportedModule ? modInfo.moduleDisplayName : BombComponent.GetModuleDisplayName();
        int    strikePenalty = modInfo.strikePenalty * (TwitchPlaySettings.data.EnableRewardMultipleStrikes ? strikeCount : 1);

        if (OtherModes.ZenModeOn)
        {
            strikePenalty = (int)(strikePenalty * 0.20f);
        }
        IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.AwardStrike, Code, strikeCount == 1 ? "a" : strikeCount.ToString(), strikeCount == 1 ? "" : "s", 0, userNickName, string.IsNullOrEmpty(StrikeMessage) ? "" : " caused by " + StrikeMessage, headerText, strikePenalty);
        if (strikeCount <= 0)
        {
            return;
        }

        string RecordMessageTone = $"Module ID: {Code} | Player: {userNickName} | Module Name: {headerText} | Strike";

        TwitchPlaySettings.AppendToSolveStrikeLog(RecordMessageTone, TwitchPlaySettings.data.EnableRewardMultipleStrikes ? strikeCount : 1);

        int originalReward = TwitchPlaySettings.GetRewardBonus();
        int currentReward  = Convert.ToInt32(originalReward * TwitchPlaySettings.data.AwardDropMultiplierOnStrike);

        TwitchPlaySettings.SetRewardBonus(currentReward);
        if (currentReward != originalReward)
        {
            IRCConnection.Instance.SendMessage($"Reward {(currentReward > 0 ? "reduced" : "increased")} to {currentReward} points.");
        }
        if (OtherModes.TimeModeOn)
        {
            float  originalMultiplier = OtherModes.GetAdjustedMultiplier();
            bool   multiDropped       = OtherModes.DropMultiplier();
            float  multiplier         = OtherModes.GetAdjustedMultiplier();
            string tempMessage;
            if (multiDropped)
            {
                if (Mathf.Abs(originalMultiplier - multiplier) >= 0.1)
                {
                    tempMessage = "Multiplier reduced to " + Math.Round(multiplier, 1) + " and time";
                }
                else
                {
                    tempMessage = "Time";
                }
            }
            else
            {
                tempMessage = $"Multiplier set at {TwitchPlaySettings.data.TimeModeMinMultiplier}, cannot be further reduced.  Time";
            }
            if (BombCommander.CurrentTimer < (TwitchPlaySettings.data.TimeModeMinimumTimeLost / TwitchPlaySettings.data.TimeModeTimerStrikePenalty))
            {
                BombCommander.timerComponent.TimeRemaining = BombCommander.CurrentTimer - TwitchPlaySettings.data.TimeModeMinimumTimeLost;
                tempMessage = tempMessage + $" reduced by {TwitchPlaySettings.data.TimeModeMinimumTimeLost} seconds.";
            }
            else
            {
                float  timeReducer = BombCommander.CurrentTimer * TwitchPlaySettings.data.TimeModeTimerStrikePenalty;
                double easyText    = Math.Round(timeReducer, 1);
                BombCommander.timerComponent.TimeRemaining = BombCommander.CurrentTimer - timeReducer;
                tempMessage = tempMessage + $" reduced by {Math.Round(TwitchPlaySettings.data.TimeModeTimerStrikePenalty * 100, 1)}%. ({easyText} seconds)";
            }
            IRCConnection.Instance.SendMessage(tempMessage);
            BombCommander.StrikeCount = 0;
            BombMessageResponder.moduleCameras.UpdateStrikes();
        }
        if (OtherModes.ZenModeOn)
        {
            BombCommander.StrikeLimit += strikeCount;
        }

        Leaderboard.Instance.AddScore(userNickName, strikePenalty);
        Leaderboard.Instance.AddStrike(userNickName, strikeCount);
        StrikeMessage = string.Empty;
    }
Beispiel #11
0
    public override IEnumerator ReportBombStatus()
    {
        if (_gameroom.GetType() == _factoryStaticModeType)
        {
            IEnumerator baseIEnumerator = base.ReportBombStatus();
            while (baseIEnumerator.MoveNext())
            {
                yield return(baseIEnumerator.Current);
            }
            yield break;
        }
        InitializeOnLightsOn = false;


        TwitchBombHandle bombHandle = BombMessageResponder.Instance.BombHandles[0];

        bombHandle.nameText.text = _infiniteMode ? "Infinite bombs incoming" : $"{BombCount} bombs incoming";

        yield return(new WaitUntil(() => GetBomb != null || bombHandle.bombCommander.Bomb.HasDetonated));

        if (bombHandle.bombCommander.Bomb.HasDetonated && !_zenMode)
        {
            yield break;
        }

        float currentBombTimer = bombHandle.bombCommander.timerComponent.TimeRemaining + 5;
        int   currentBombID    = 1;

        while (GetBomb != null)
        {
            int reward = TwitchPlaySettings.GetRewardBonus();
            UnityEngine.Object currentBomb = GetBomb;

            TimerComponent timerComponent = bombHandle.bombCommander.timerComponent;
            yield return(new WaitUntil(() => timerComponent.IsActive));

            if (Math.Abs(currentBombTimer - bombHandle.bombCommander.timerComponent.TimeRemaining) > 1f)
            {
                yield return(null);

                InitializeGameModes(true);
            }

            bombHandle.nameText.text = $"Bomb {currentBombID}  of {(_infiniteMode ? "∞" : BombCount.ToString())}";
            IRCConnection.Instance.SendMessage("Bomb {0} of {1} is now live.", currentBombID++, _infiniteMode ? "∞" : BombCount.ToString());
            if (OtherModes.ZenModeOn && IRCConnection.Instance.State == IRCConnectionState.Connected && TwitchPlaySettings.data.EnableFactoryZenModeCameraWall)
            {
                BombMessageResponder.Instance.OnMessageReceived("Bomb Factory", "!enablecamerawall");
                BombMessageResponder.Instance.OnMessageReceived("Bomb Factory", "!modules");
                BombMessageResponder.Instance.OnMessageReceived("Bomb Factory", "!modules");
            }
            else
            {
                BombMessageResponder.Instance.OnMessageReceived("Bomb Factory", "!disablecamerawall");
            }

            if (TwitchPlaySettings.data.EnableAutomaticEdgework)
            {
                bombHandle.bombCommander.FillEdgework();
            }
            else
            {
                bombHandle.edgeworkText.text = TwitchPlaySettings.data.BlankBombEdgework;
            }
            if (OtherModes.ZenModeOn)
            {
                bombHandle.bombCommander.StrikeLimit += bombHandle.bombCommander.StrikeCount;
            }

            IEnumerator bombHold = bombHandle.OnMessageReceived("Bomb Factory", "red", "bomb hold");
            while (bombHold.MoveNext())
            {
                yield return(bombHold.Current);
            }

            Bomb bomb1 = (Bomb)_internalBombProperty.GetValue(currentBomb, null);
            yield return(new WaitUntil(() =>
            {
                bool result = bomb1.HasDetonated || bomb1.IsSolved() || !BombMessageResponder.BombActive;
                if (!result || OtherModes.TimeModeOn)
                {
                    currentBombTimer = bomb1.GetTimer().TimeRemaining;
                }
                return result;
            }));

            if (!BombMessageResponder.BombActive)
            {
                yield break;
            }

            IRCConnection.Instance.SendMessage(BombMessageResponder.Instance.GetBombResult(false));
            TwitchPlaySettings.SetRewardBonus(reward);

            foreach (TwitchComponentHandle handle in BombMessageResponder.Instance.ComponentHandles)
            {
                //If the camera is still attached to the bomb component when the bomb gets destroyed, then THAT camera is destroyed as wel.
                BombMessageResponder.moduleCameras.DetachFromModule(handle.bombComponent);
            }

            if (TwitchPlaySettings.data.EnableFactoryAutomaticNextBomb)
            {
                bombHold = bombHandle.OnMessageReceived("Bomb Factory", "red", "bomb drop");
                while (bombHold.MoveNext())
                {
                    yield return(bombHold.Current);
                }
            }

            while (currentBomb == GetBomb)
            {
                yield return(new WaitForSeconds(0.10f));

                if (currentBomb != GetBomb || !TwitchPlaySettings.data.EnableFactoryAutomaticNextBomb)
                {
                    continue;
                }

                bombHold = bombHandle.OnMessageReceived("Bomb Factory", "red", "bomb hold");
                while (bombHold.MoveNext())
                {
                    yield return(bombHold.Current);
                }
                yield return(new WaitForSeconds(0.10f));

                bombHold = bombHandle.OnMessageReceived("Bomb Factory", "red", "bomb drop");
                while (bombHold.MoveNext())
                {
                    yield return(bombHold.Current);
                }
            }

            bombHandle.StartCoroutine(DestroyBomb(currentBomb));

            if (GetBomb == null)
            {
                continue;
            }
            Bomb bomb = (Bomb)_internalBombProperty.GetValue(GetBomb, null);
            InitializeBomb(bomb);
        }
    }