diff --git a/README.md b/README.md index 44744e5..18d3add 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ these folks are helping me a *ton* via patreon, and i cannot possibly thank them - Ryan Littleton - Evie Diver - iliana etaoin +- yooori ## Attribution diff --git a/games.py b/games.py index 69d1d16..0773eb8 100644 --- a/games.py +++ b/games.py @@ -32,10 +32,12 @@ def all_weathers(): weathers_dic = { #"Supernova" : weather("Supernova", "🌟"), #"Midnight": weather("Midnight", "🕶"), - "Slight Tailwind": weather("Slight Tailwind", "🏌️‍♀️"), + #"Slight Tailwind": weather("Slight Tailwind", "🏌️‍♀️"), "Heavy Snow": weather("Heavy Snow", "❄"), "Twilight" : weather("Twilight", "👻"), - "Thinned Veil" : weather("Thinned Veil", "🌌") + "Thinned Veil" : weather("Thinned Veil", "🌌"), + "Heat Wave" : weather("Heat Wave", "🌄"), + "Drizzle" : weather("Drizzle", "🌧") } return weathers_dic @@ -114,6 +116,11 @@ class team(object): else: return (None, None, None) + def find_player_spec(self, name, roster): + for s_index in range(0,len(roster)): + if roster[s_index].name == name: + return (roster[s_index], s_index) + def average_stars(self): total_stars = 0 for _player in self.lineup: @@ -151,6 +158,21 @@ class team(object): return True else: return False + + def slide_player_spec(self, this_player_name, new_spot, roster): + index = None + for s_index in range(0,len(roster)): + if roster[s_index].name == this_player_name: + index = s_index + this_player = roster[s_index] + if index is None: + return False + elif new_spot <= len(roster): + roster.pop(index) + roster.insert(new_spot-1, this_player) + return True + else: + return False def add_lineup(self, new_player): if len(self.lineup) < 20: @@ -169,7 +191,7 @@ class team(object): def set_pitcher(self, rotation_slot = None, use_lineup = False): temp_rotation = self.rotation.copy() if use_lineup: - for batter in self.rotation: + for batter in self.lineup: temp_rotation.append(batter) if rotation_slot is None: self.pitcher = random.choice(temp_rotation) @@ -616,6 +638,25 @@ class game(object): offense_team.lineup_position += 1 #put next batter up if self.outs >= 3: self.flip_inning() + if self.weather.name == "Heat Wave": + if self.top_of_inning: + self.weather.home_pitcher = self.get_pitcher() + if self.inning >= self.weather.counter_home: + self.weather.counter_home = self.weather.counter_home - (self.weather.counter_home % 5) + 5 + random.randint(1,4) #rounds down to last 5, adds up to next 5. then adds a random number 2<=x<=5 to determine next pitcher + tries = 0 + while self.get_pitcher() == self.weather.home_pitcher and tries < 3: + self.teams["home"].set_pitcher(use_lineup = True) + tries += 1 + + + else: + self.weather.away_pitcher = self.get_pitcher() + if self.inning >= self.weather.counter_away: + self.weather.counter_away = self.weather.counter_away - (self.weather.counter_away % 5) + 5 + random.randint(1,4) + tries = 0 + while self.get_pitcher() == self.weather.away_pitcher and tries < 3: + self.teams["away"].set_pitcher(use_lineup = True) + tries += 1 return (result, scores_to_add) #returns ab information and scores @@ -635,6 +676,12 @@ class game(object): self.over = True self.top_of_inning = not self.top_of_inning + if self.weather.name == "Drizzle": + if self.top_of_inning: + self.bases[2] = self.teams["away"].lineup[(self.teams["away"].lineup_position-1) % len(self.teams["away"].lineup)] + else: + self.bases[2] = self.teams["home"].lineup[(self.teams["home"].lineup_position-1) % len(self.teams["home"].lineup)] + def pitcher_insert(self, this_team): rounds = math.ceil(this_team.lineup_position / len(this_team.lineup)) position = random.randint(0, len(this_team.lineup)-1) diff --git a/league_storage.py b/league_storage.py index 183003e..2b36a6f 100644 --- a/league_storage.py +++ b/league_storage.py @@ -3,6 +3,7 @@ import sqlite3 as sql data_dir = "data" league_dir = "leagues" +statements_file = os.path.join(data_dir, "sql_statements.xvi") def create_connection(league_name): #create connection, create db if doesn't exist @@ -21,6 +22,45 @@ def create_connection(league_name): print("oops, db connection no work") return conn +def statements(): + if not os.path.exists(os.path.dirname(statements_file)): + os.makedirs(os.path.dirname(statements_file)) + if not os.path.exists(statements_file): + #generate default statements: bat_base and pitch_base to be appended with a relevant ORDER BY statement + config_dic = { + "bat_base" : """SELECT name, team_name, + plate_appearances - (walks_taken + sacrifices) as ABs, + ROUND(hits*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as BA, + ROUND(total_bases*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as SLG, + ROUND((walks_taken + hits)*1.0/plate_appearances*1.0,3) as OBP, + ROUND((walks_taken + hits)*1.0/plate_appearances*1.0,3) + ROUND(total_bases*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as OPS +FROM stats WHERE plate_appearances > 8""", + "avg" : ["ORDER BY BA DESC;", "bat_base"], + "slg" : ["ORDER BY SLG DESC;", "bat_base"], + "obp" : ["ORDER BY OBP DESC;", "bat_base"], + "ops" : ["ORDER BY OPS DESC;", "bat_base"], + "pitch_base" : """SELECT name, team_name, + ROUND(((outs_pitched*1.0)/3.0),1) as IP, + ROUND(runs_allowed*27.0/(outs_pitched*1.0),3) as ERA, + ROUND((walks_allowed+hits_allowed)*3.0/(outs_pitched*1.0),3) as WHIP, + ROUND(walks_allowed*27.0/(outs_pitched*1.0),3) as BBper9, + ROUND(strikeouts_given*27.0/(outs_pitched*1.0),3) as Kper9, + ROUND(strikeouts_given*1.0/walks_allowed*1.0,3) as KperBB +FROM stats WHERE outs_pitched > 20 +""", + "era" : ["ORDER BY ERA ASC;", "pitch_base"], + "whip" : ["ORDER BY WHIP ASC;", "pitch_base"], + "kper9" : ["ORDER BY Kper9 DESC;", "pitch_base"], + "bbper9" : ["ORDER BY BBper9 ASC;", "pitch_base"], + "kperbb" : ["ORDER BY KperBB DESC;", "pitch_base"] + } + with open(statements_file, "w") as config_file: + json.dump(config_dic, config_file, indent=4) + return config_dic + else: + with open(statements_file) as config_file: + return json.load(config_file) + def create_season_connection(league_name, season_num): #create connection, create db if doesn't exist conn = None @@ -129,6 +169,19 @@ def add_stats(league_name, player_game_stats_list): conn.commit() conn.close() +def get_stats(league_name, stat, is_batter=True): + conn = create_connection(league_name) + stats = None + if conn is not None: + conn.row_factory = sql.Row + c=conn.cursor() + + if stat in statements().keys(): + c.execute(statements()[statements()[stat][1]]+"\n"+statements()[stat][0]) + stats = c.fetchall() + conn.close() + return stats + def update_standings(league_name, update_dic): if league_exists(league_name): conn = create_connection(league_name) @@ -168,6 +221,13 @@ def season_save(league): if "." in item.name: os.rename(os.path.join(data_dir, league_dir, league.name, item.name), os.path.join(new_dir, item.name)) +def season_restart(league): + if league_exists(league.name): + with os.scandir(os.path.join(data_dir, league_dir, league.name)) as folder: + for item in folder: + if "." in item.name: + os.remove(os.path.join(data_dir, league_dir, league.name, item.name)) + def get_past_standings(league_name, season_num): if league_exists(league_name): with os.scandir(os.path.join(data_dir, league_dir, league_name)) as folder: diff --git a/leagues.py b/leagues.py index c08be59..7970c0d 100644 --- a/leagues.py +++ b/leagues.py @@ -102,6 +102,14 @@ class league_structure(object): teams += teams_list return teams + def team_names_in_league(self): + teams = [] + for division in self.league.values(): + for teams_list in division.values(): + for team in teams_list: + teams.append(team.name) + return teams + def teams_in_subleague(self, subleague_name): teams = [] if subleague_name in self.league.keys(): @@ -201,7 +209,7 @@ class league_structure(object): if extra_teams != []: if len(extra_teams) % 2 == 0: for index in range(0, int(len(extra_teams)/2)): - matchups.append([extra_teams[index], extra_teams[index+1]]) + matchups.append([extra_teams[index].name, extra_teams[index+1].name]) for subleague in league.keys(): @@ -323,6 +331,30 @@ class league_structure(object): this_embed.set_footer(text=f"Standings as of day {self.day-1} / {self.season_length()}") return this_embed + def standings_embed_div(self, division, div_name): + this_embed = Embed(color=Color.purple(), title=f"{self.name} Season {self.season}") + standings = {} + for team_name, wins, losses, run_diff in league_db.get_standings(self.name): + standings[team_name] = {"wins" : wins, "losses" : losses, "run_diff" : run_diff} + teams = self.division_standings(division, standings) + + for index in range(0, len(teams)): + if index == self.constraints["division_leaders"] - 1: + teams[index][4] = "-" + else: + games_behind = ((teams[self.constraints["division_leaders"] - 1][1] - teams[index][1]) + (teams[index][2] - teams[self.constraints["division_leaders"] - 1][2]))/2 + teams[index][4] = games_behind + teams_string = "" + for this_team in teams: + if this_team[2] != 0 or this_team[1] != 0: + teams_string += f"**{this_team[0].name}\n**{this_team[1]} - {this_team[2]} WR: {round(this_team[1]/(this_team[1]+this_team[2]), 3)} GB: {this_team[4]}\n\n" + else: + teams_string += f"**{this_team[0].name}\n**{this_team[1]} - {this_team[2]} WR: - GB: {this_team[4]}\n\n" + + this_embed.add_field(name=f"{div_name} Division:", value=teams_string, inline = False) + this_embed.set_footer(text=f"Standings as of day {self.day-1} / {self.season_length()}") + return this_embed + def wildcard_embed(self): this_embed = Embed(color=Color.purple(), title=f"{self.name} Wildcard Race") standings = {} @@ -383,6 +415,22 @@ class league_structure(object): return tournaments + def stat_embed(self, stat_name): + this_embed = Embed(color=Color.purple(), title=f"{self.name} Season {self.season} {stat_name} Leaders") + stats = league_db.get_stats(self.name, stat_name.lower()) + if stats is None: + return None + else: + stat_names = list(stats[0].keys())[2:] + for index in range(0, min(10,len(stats))): + this_row = list(stats[index]) + player_name = this_row.pop(0) + content_string = f"**{this_row.pop(0)}**\n" + for stat_index in range(0, len(this_row)): + content_string += f"**{stat_names[stat_index]}**: {str(this_row[stat_index])}; " + this_embed.add_field(name=player_name, value=content_string, inline=False) + return this_embed + class tournament(object): def __init__(self, name, team_dic, series_length = 5, finals_series_length = 7, max_innings = 9, id = None, secs_between_games = 300, secs_between_rounds = 600): diff --git a/main_controller.py b/main_controller.py index 0ecfbef..176c28f 100644 --- a/main_controller.py +++ b/main_controller.py @@ -172,11 +172,24 @@ def update_loop(): state["batter"] = "-" elif this_game.top_of_inning: state["update_text"] = f"Top of {this_game.inning}. {this_game.teams['away'].name} batting!" + if this_game.weather.name == "Drizzle": + state["update_emoji"] = "🌧" + state["update_text"] += f' Due to inclement weather, {this_game.teams["away"].lineup[(this_game.teams["away"].lineup_position-1) % len(this_game.teams["away"].lineup)].name} is placed on second base.' + elif this_game.weather.name == "Heat Wave" and hasattr(this_game.weather, "home_pitcher") and this_game.weather.home_pitcher.name != state["pitcher"]: + state["update_emoji"] = "🌄" + state["update_text"] += f' {this_game.weather.home_pitcher} is exhausted from the heat. {state["pitcher"]} is forced to pitch!' + else: if this_game.inning >= this_game.max_innings: if this_game.teams["home"].score > this_game.teams["away"].score: this_game.victory_lap = True state["update_text"] = f"Bottom of {this_game.inning}. {this_game.teams['home'].name} batting!" + if this_game.weather.name == "Drizzle": + state["update_emoji"] = "🌧" + state["update_text"] += f' Due to inclement weather, {this_game.teams["home"].lineup[(this_game.teams["home"].lineup_position-1) % len(this_game.teams["home"].lineup)].name} is placed on second base.' + elif this_game.weather.name == "Heat Wave" and hasattr(this_game.weather, "away_pitcher") and this_game.weather.away_pitcher.name != state["pitcher"]: + state["update_emoji"] = "🌄" + state["update_text"] += f' {this_game.weather.away_pitcher} is exhausted from the heat. {state["pitcher"]} is forced to pitch!' elif state["update_pause"] != 1 and test_string != "Game not started.": if "steals" in this_game.last_update[0].keys(): @@ -225,6 +238,8 @@ def update_loop(): elif "error" in this_game.last_update[0].keys(): state["update_emoji"] = "👻" state["update_text"] = f"{this_game.last_update[0]['batter']}'s hit goes ethereal, and {this_game.last_update[0]['defender']} can't catch it! {this_game.last_update[0]['batter']} reaches base safely." + if this_game.last_update[1] > 0: + updatestring += f"{this_game.last_update[1]} runs scored!" state["bases"] = this_game.named_bases() diff --git a/the_prestige.py b/the_prestige.py index c91853c..b5fdad4 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -1,7 +1,7 @@ import discord, json, math, os, roman, games, asyncio, random, main_controller, threading, time, urllib, leagues, datetime import database as db import onomancer as ono -from league_storage import league_exists, season_save +from league_storage import league_exists, season_save, season_restart from the_draft import Draft, DRAFT_ROUNDS from flask import Flask from uuid import uuid4 @@ -370,13 +370,26 @@ class MovePlayerCommand(Command): if owner_id != msg.author.id and msg.author.id not in config()["owners"]: await msg.channel.send("You're not authorized to mess with this team. Sorry, boss.") return - elif not team.slide_player(player_name, new_pos): - await msg.channel.send("You either gave us a number that was bigger than your current roster, or we couldn't find the player on the team. Try again.") - return else: - await msg.channel.send(embed=build_team_embed(team)) - games.update_team(team) - await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.") + if team.find_player(player_name)[2] is None or len(team.find_player(player_name)[2]) <= new_pos: + await msg.channel.send("You either gave us a number that was bigger than your current roster, or we couldn't find the player on the team. Try again.") + return + + if "batter" in command.split("\n")[0].lower(): + roster = team.lineup + elif "pitcher" in command.split("\n")[0].lower(): + roster = team.rotation + else: + roster = None + + if (roster is not None and team.slide_player_spec(player_name, new_pos, roster)) or (roster is None and team.slide_player(player_name, new_pos)): + await msg.channel.send(embed=build_team_embed(team)) + games.update_team(team) + await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.") + else: + await msg.channel.send("You either gave us a number that was bigger than your current roster, or we couldn't find the player on the team. Try again.") + return + except IndexError: await msg.channel.send("Four lines, remember? Command, then team, then name, and finally, new spot on the lineup or rotation.") @@ -769,38 +782,6 @@ class StartDraftCommand(Command): raise SlowDraftError('Too slow') return draft_message -class DebugLeagueStart(Command): - name = "startdebugleague" - - async def execute(self, msg, command): - if not league_exists("test2"): - league = leagues.league_structure("test2") - league.setup({ - "nL" : { - "nL west" : [get_team_fuzzy_search("lockpicks"), get_team_fuzzy_search("liches")], - "nL east" : [get_team_fuzzy_search("bethesda soft"), get_team_fuzzy_search("traverse city")] - }, - "aL" : { - "aL west" : [get_team_fuzzy_search("deep space"), get_team_fuzzy_search("phoenix")], - "aL east" : [get_team_fuzzy_search("cheyenne mountain"), get_team_fuzzy_search("tarot dragons")] - } - }, division_games=6, inter_division_games=3, inter_league_games=3, games_per_hour = 12) - league.generate_schedule() - leagues.save_league(league) - -class DebugLeagueDisplay(Command): - name = "displaydebugleague" - - async def execute(self, msg, command): - if league_exists("Midseries"): - league = leagues.load_league_file("Midseries") - league.champion = "Butts" - leagues.save_league(league) - season_save(league) - league.season_reset() - - await msg.channel.send(embed=league.past_standings(1)) - class StartLeagueCommand(Command): name = "startleague" @@ -842,6 +823,9 @@ Plays a league with a given name, provided that league has been saved on the web except ValueError: await msg.channel.send("Chief, we need a games per hour number between 1 and 12. We think that's reasonable.") return + except IndexError: + await msg.channel.send("We need a games per hour number in the second line.") + return if league_exists(league_name): league = leagues.load_league_file(league_name) @@ -896,6 +880,60 @@ class LeagueDisplayCommand(Command): else: await msg.channel.send("Can't find that league, boss.") +class LeagueLeadersCommand(Command): + name = "leagueleaders" + template = "m;leagueleaders [league name]\n[stat name/abbreviation]" + description = "Displays a league's leaders in the given stats. A list of the allowed stats can be found on the github readme." + + async def execute(self, msg, command): + if league_exists(command.split("\n")[0].strip()): + league = leagues.load_league_file(command.split("\n")[0].strip()) + stat_name = command.split("\n")[1].strip() + try: + stat_embed = league.stat_embed(stat_name) + except IndexError: + await msg.channel.send("Nobody's played enough games to get meaningful stats in that category yet, chief. Try again after the next game or two.") + return + + if stat_embed is None: + await msg.channel.send("We don't know what that stat is, chief.") + return + try: + await msg.channel.send(embed=stat_embed) + return + except: + await msg.channel.send("Nobody's played enough games to get meaningful stats in that category yet, chief. Try again after the next game or two.") + return + + await msg.channel.send("Can't find that league, boss.") + +class LeagueDivisionDisplayCommand(Command): + name = "divisionstandings" + template = "m;divisionstandings [league name]\n[team name]" + description = "Displays the current standings for the given division in the given league." + + async def execute(self, msg, command): + if league_exists(command.split("\n")[0].strip()): + league = leagues.load_league_file(command.split("\n")[0].strip()) + division_name = command.split("\n")[1].strip() + division = None + for subleague in iter(league.league.keys()): + for div in iter(league.league[subleague].keys()): + if div == division_name: + division = league.league[subleague][div] + if division is None: + await msg.channel.send("Chief, that division doesn't exist in that league.") + return + + try: + await msg.channel.send(embed=league.standings_embed_div(division, division_name)) + except ValueError: + await msg.channel.send("Give us a proper number, boss.") + #except TypeError: + #await msg.channel.send("That season hasn't been played yet, chief.") + else: + await msg.channel.send("Can't find that league, boss.") + class LeagueWildcardCommand(Command): name = "leaguewildcard" template = "m;leaguewildcard [league name]" @@ -976,18 +1014,60 @@ class LeagueScheduleCommand(Command): description = "Sends an embed with the given league's schedule for the next 4 series." async def execute(self, msg, command): - league_name = command.strip() + league_name = command.split("\n")[0].strip() if league_exists(league_name): league = leagues.load_league_file(league_name) current_series = league.day_to_series_num(league.day) if str(current_series+1) in league.schedule.keys(): - sched_embed = discord.Embed(title=f"{league.name}'s Schedule:") + sched_embed = discord.Embed(title=f"{league.name}'s Schedule:", color=discord.Color.magenta()) days = [0,1,2,3] for day in days: if str(current_series+day) in league.schedule.keys(): schedule_text = "" + teams = league.team_names_in_league() for game in league.schedule[str(current_series+day)]: schedule_text += f"**{game[0]}** @ **{game[1]}**\n" + teams.pop(teams.index(game[0])) + teams.pop(teams.index(game[1])) + if len(teams) > 0: + schedule_text += "Resting:\n" + for team in teams: + schedule_text += f"**{team}**\n" + sched_embed.add_field(name=f"Days {((current_series+day-1)*league.series_length) + 1} - {(current_series+day)*(league.series_length)}", value=schedule_text, inline = False) + await msg.channel.send(embed=sched_embed) + else: + await msg.channel.send("That league's already finished with this season, boss.") + else: + await msg.channel.send("We can't find that league. Typo?") + +class LeagueTeamScheduleCommand(Command): + name = "teamschedule" + template = "m;teamschedule [league name]\n[team name]" + description = "Sends an embed with the given team's schedule in the given league for the next 7 series." + + async def execute(self, msg, command): + league_name = command.split("\n")[0].strip() + team_name = command.split("\n")[1].strip() + team = get_team_fuzzy_search(team_name) + if league_exists(league_name): + league = leagues.load_league_file(league_name) + current_series = league.day_to_series_num(league.day) + + if team.name not in league.team_names_in_league(): + await msg.channel.send("Can't find that team in that league, chief.") + return + + if str(current_series+1) in league.schedule.keys(): + sched_embed = discord.Embed(title=f"{team.name}'s Schedule for the {league.name}:", color=discord.Color.purple()) + days = [0,1,2,3,4,5,6] + for day in days: + if str(current_series+day) in league.schedule.keys(): + schedule_text = "" + for game in league.schedule[str(current_series+day)]: + if team.name in game: + schedule_text += f"**{game[0]}** @ **{game[1]}**" + if schedule_text == "": + schedule_text += "Resting" sched_embed.add_field(name=f"Days {((current_series+day-1)*league.series_length) + 1} - {(current_series+day)*(league.series_length)}", value=schedule_text, inline = False) await msg.channel.send(embed=sched_embed) else: @@ -995,6 +1075,48 @@ class LeagueScheduleCommand(Command): else: await msg.channel.send("We can't find that league. Typo?") +class LeagueRegenerateScheduleCommand(Command): + name = "leagueseasonreset" + template = "m;leagueseasonreset [league name]" + description = "Completely scraps the given league's current season, resetting everything to day 1 of the current season. Requires ownership." + + async def execute(self, msg, command): + league_name = command.split("\n")[0].strip() + if league_exists(league_name): + league = leagues.load_league_file(league_name) + if (league.owner is not None and msg.author.id in league.owner) or (league.owner is not None and msg.author.id in config()["owners"]): + await msg.channel.send("You got it, boss. Give us two seconds and a bucket of white-out.") + season_restart(league) + league.season -= 1 + league.season_reset() + await asyncio.sleep(1) + await msg.channel.send("Done and dusted. Go ahead and start the league again whenever you want.") + return + else: + await msg.channel.send("That league isn't yours, boss.") + return + else: + await msg.channel.send("We can't find that league. Typo?") + +class LeagueForceStopCommand(Command): + name = "leagueforcestop" + template = "m;leagueforcestop [league name]" + description = "Halts a league and removes it from the list of currently running leagues. To be used in the case of crashed loops." + + def isauthorized(self, user): + return user.id in config()["owners"] + + async def execute(self, msg, command): + league_name = command.split("\n")[0].strip() + for index in range(0,len(active_leagues)): + if active_leagues[index].name == league_name: + active_leagues.pop(index) + await msg.channel.send("League halted, boss. We hope you did that on purpose.") + return + await msg.channel.send("That league either doesn't exist or isn't in the active list. So, huzzah?") + + + commands = [ IntroduceCommand(), @@ -1023,15 +1145,18 @@ commands = [ StartLeagueCommand(), LeaguePauseCommand(), LeagueDisplayCommand(), + LeagueLeadersCommand(), + LeagueDivisionDisplayCommand(), LeagueWildcardCommand(), LeagueScheduleCommand(), + LeagueTeamScheduleCommand(), + LeagueRegenerateScheduleCommand(), + LeagueForceStopCommand(), CreditCommand(), RomanCommand(), HelpCommand(), StartDraftCommand(), - DraftPlayerCommand(), - DebugLeagueStart(), - DebugLeagueDisplay() + DraftPlayerCommand() ] client = discord.Client() @@ -1294,6 +1419,9 @@ def prepare_game(newgame, league = None, weather_name = None): if newgame.weather.name == "Heavy Snow": newgame.weather.counter_away = random.randint(0,len(newgame.teams['away'].lineup)-1) newgame.weather.counter_home = random.randint(0,len(newgame.teams['home'].lineup)-1) + elif newgame.weather.name == "Heat Wave": + newgame.weather.counter_away = random.randint(2,4) + newgame.weather.counter_home = random.randint(2,4) return newgame, state_init async def start_tournament_round(channel, tourney, seeding = None): @@ -1547,6 +1675,7 @@ def build_team_embed(team): rotation_string += f"{player.name} {player.star_string('pitching_stars')}\n" embed.add_field(name="Rotation:", value=rotation_string, inline = False) embed.add_field(name="Lineup:", value=lineup_string, inline = False) + embed.add_field(name="█a██:", value=str(abs(hash(team.name)) % (10 ** 4))) embed.set_footer(text=team.slogan) return embed