public void Produce(BossFighter fighter) { _bossSettings.Fighters.Add(fighter); }
public async Task Consume() { Boss boss = _bossSettings.Bosses[BossLevel() - 1]; _irc.SendPublicChatMessage(_bossSettings.GameStart .Replace("@bossname@", boss.Name)); Thread.Sleep(5000); // wait in anticipation // Raid the boss bool isBossAlive = true; string lastAttackFighter = ""; int turn; for (turn = 0; turn < boss.TurnLimit; turn++) { foreach (BossFighter fighter in _bossSettings.Fighters) { if (fighter.FighterClass.Health <= 0) continue; Random rnd = new Random(DateTime.Now.Millisecond); int chance = rnd.Next(1, 101); // 1 - 100 // check if boss dodged the attack if (boss.Evasion <= chance && fighter.FighterClass.Attack - boss.Defense > 0) boss.Health -= fighter.FighterClass.Attack - boss.Defense; if (boss.Health <= 0) { lastAttackFighter = fighter.Username; isBossAlive = false; break; } rnd = new Random(DateTime.Now.Millisecond); chance = rnd.Next(1, 101); // 1 - 100 // check if fighter dodged the attack if (fighter.FighterClass.Evasion <= chance && boss.Attack - fighter.FighterClass.Defense > 0) fighter.FighterClass.Health -= boss.Attack - fighter.FighterClass.Defense; } if (!isBossAlive) break; } // Evaluate the fight if (isBossAlive) { string bossAliveMessage = ""; if (turn == boss.TurnLimit) { // ToDo: Add boss alive message to database bossAliveMessage = $"It took too long to kill {boss.Name}. Gas floods the room, killing the entire raid party."; } else if (_bossSettings.Fighters.Count == 1) { bossAliveMessage = _bossSettings.SingleUserFail .Replace("user@", _bossSettings.Fighters.First().Username) .Replace("@bossname@", boss.Name); } else { bossAliveMessage = _bossSettings.Success0; } _irc.SendPublicChatMessage(bossAliveMessage); return; } // Calculate surviving raid party earnings IEnumerable<BossFighter> survivors = _bossSettings.Fighters.Where(f => f.FighterClass.Health > 0); int numSurvivors = survivors.Count(); foreach (BossFighter champion in survivors) { int funds = await _bank.CheckBalance(champion.Username.ToLower(), _broadcasterId); decimal earnings = Math.Ceiling(boss.Loot / (decimal)numSurvivors); // give last attack bonus to specified fighter if (champion.Username == lastAttackFighter) { earnings += boss.LastAttackBonus; } await _bank.UpdateFunds(champion.Username.ToLower(), _broadcasterId, (int)earnings + funds); _resultMessage += $" {champion.Username} ({(int)earnings} {_botConfig.CurrencyType}),"; } // remove extra "," _resultMessage = _resultMessage.Remove(_resultMessage.LastIndexOf(','), 1); decimal survivorsPercentage = numSurvivors / (decimal)_bossSettings.Fighters.Count; // Display success outcome if (numSurvivors == 1 && numSurvivors == _bossSettings.Fighters.Count) { BossFighter onlyWinner = _bossSettings.Fighters.First(); int earnings = boss.Loot; _irc.SendPublicChatMessage(_bossSettings.SingleUserSuccess .Replace("user@", onlyWinner.Username) .Replace("@bossname@", boss.Name) .Replace("@winamount@", earnings.ToString()) .Replace("@pointsname@", _botConfig.CurrencyType) .Replace("@lastattackbonus@", boss.LastAttackBonus.ToString())); } else if (survivorsPercentage == 1.0m) { _irc.SendPublicChatMessage(_bossSettings.Success100.Replace("@bossname@", boss.Name) + " " + _resultMessage); } else if (survivorsPercentage >= 0.34m) { _irc.SendPublicChatMessage(_bossSettings.Success34 + " " + _resultMessage); } else if (survivorsPercentage > 0) { _irc.SendPublicChatMessage(_bossSettings.Success1 + " " + _resultMessage); } // show in case Twitch deletes the message because of exceeding character length Console.WriteLine("\n" + _resultMessage + "\n"); }
/// <summary> /// Engage in the boss fight minigame /// </summary> /// <param name="chatter">User that sent the message</param> public async Task <DateTime> BossFight(TwitchChatter chatter) { try { BossFight bossFight = new BossFight(); int funds = await _bank.CheckBalanceAsync(chatter.Username, _broadcasterInstance.DatabaseId); if (_bossSettingsInstance.IsBossFightOnCooldown()) { TimeSpan cooldown = _bossSettingsInstance.CooldownTimePeriod.Subtract(DateTime.Now); if (cooldown.Minutes >= 1) { _irc.SendPublicChatMessage(_bossSettingsInstance.CooldownEntry .Replace("@timeleft@", cooldown.Minutes.ToString())); } else { _irc.SendPublicChatMessage(_bossSettingsInstance.CooldownEntry .Replace("@timeleft@", cooldown.Seconds.ToString()) .Replace("minutes", "seconds")); } return(DateTime.Now); } if (_bossSettingsInstance.RefreshBossFight) { _irc.SendPublicChatMessage($"The boss fight is currently being refreshed with new settings @{chatter.DisplayName}"); return(DateTime.Now); } if (bossFight.HasFighterAlreadyEntered(chatter.Username)) { _irc.SendPublicChatMessage($"You are already in this fight @{chatter.DisplayName}"); return(DateTime.Now); } if (funds < _bossSettingsInstance.Cost) { _irc.SendPublicChatMessage($"You do need {_bossSettingsInstance.Cost} {_botConfig.CurrencyType} to enter this fight @{chatter.DisplayName}"); return(DateTime.Now); } if (!bossFight.IsEntryPeriodOver()) { ChatterType chatterType = ChatterType.DoesNotExist; // join boss fight if (chatter.Badges.Contains("moderator") || chatter.Badges.Contains("admin") || chatter.Badges.Contains("global_mod") || chatter.Badges.Contains("staff") || chatter.Username == _botConfig.Broadcaster.ToLower()) { chatterType = ChatterType.Moderator; } else if (chatter.Badges.Contains("subscriber") || chatter.Badges.Contains("vip")) { chatterType = ChatterType.Subscriber; } // ToDo: Create new columns in the BossFightClassStats table for VIP stats //else if (chatter.Badges.Contains("vip")) //{ // chatterType = ChatterType.VIP; //} else { chatterType = _twitchChatterListInstance.GetUserChatterType(chatter.Username); if (chatterType == ChatterType.DoesNotExist) { using (HttpResponseMessage message = await _twitchInfo.CheckFollowerStatusAsync(chatter.TwitchId)) { // check if chatter is a follower if (!message.IsSuccessStatusCode) { int currentExp = await _follower.CurrentExpAsync(chatter.Username, _broadcasterInstance.DatabaseId); if (_follower.IsRegularFollower(currentExp, _botConfig.RegularFollowerHours)) { chatterType = ChatterType.RegularFollower; } else { chatterType = ChatterType.Follower; } } else { chatterType = ChatterType.Viewer; } } } } // make boss fight announcement if first fighter and start recruiting members if (_bossSettingsInstance.Fighters.Count == 0) { _bossSettingsInstance.EntryPeriod = DateTime.Now.AddSeconds(_bossSettingsInstance.EntryPeriodSeconds); _irc.SendPublicChatMessage(_bossSettingsInstance.EntryMessage.Replace("user@", chatter.Username)); } FighterClass fighterClass = _bossSettingsInstance.ClassStats.Single(c => c.ChatterType == chatterType); BossFighter fighter = new BossFighter { Username = chatter.Username, FighterClass = fighterClass }; bossFight.Produce(fighter); await _bank.UpdateFundsAsync(chatter.Username, _broadcasterInstance.DatabaseId, funds - _bossSettingsInstance.Cost); // display new boss level if (!string.IsNullOrEmpty(bossFight.NextLevelMessage())) { _irc.SendPublicChatMessage(bossFight.NextLevelMessage()); } } } catch (Exception ex) { await _errHndlrInstance.LogError(ex, "MinigameFeature", "BossFight(TwitchChatter)", false, "!raid"); } return(DateTime.Now); }