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)); }
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); } }
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; } }
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; }
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; } }
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; }
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); } }