import asyncio import math import os import random import requests import discord import pygsheets import logging import datetime from discord import app_commands, Member from discord.ext import commands, tasks from difflib import get_close_matches from typing import Optional, Literal from discord.ext.commands import Greedy from sqlmodel import Session import gauntlets import helpers # import in_game.data_cache # import in_game.simulations # import in_game # # from in_game import data_cache, simulations # from in_game.data_cache import get_pd_pitchingcard, get_pd_battingcard, get_pd_player from in_game.gameplay_queries import get_team_or_none from in_game.simulations import get_pos_embeds, get_result from in_game.gameplay_models import Lineup, Play, Session, engine from api_calls import db_get, db_post, db_patch, get_team_by_abbrev from helpers import ACTIVE_EVENT_LITERAL, PD_PLAYERS_ROLE_NAME, IMAGES, PD_SEASON, random_conf_gif, fuzzy_player_search, ALL_MLB_TEAMS, \ fuzzy_search, get_channel, display_cards, get_card_embeds, get_team_embed, cardset_search, get_blank_team_card, \ get_team_by_owner, get_rosters, get_roster_sheet, legal_channel, app_legal_channel, random_conf_word, embed_pagination, get_cal_user, \ team_summary_embed, SelectView, SelectPaperdexCardset, SelectPaperdexTeam, get_context_user from utilities.buttons import ask_with_buttons from utilities.autocomplete import cardset_autocomplete, player_autocomplete logger = logging.getLogger('discord_app') def get_ai_records(short_games, long_games): all_results = { 'ARI': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'ATL': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'BAL': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'BOS': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'CHC': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'CHW': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'CIN': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'CLE': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'COL': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'DET': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'HOU': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'KCR': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'LAA': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'LAD': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'MIA': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'MIL': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'MIN': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'NYM': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'NYY': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'OAK': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'PHI': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'PIT': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'SDP': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'SEA': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'SFG': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'STL': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'TBR': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'TEX': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'TOR': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, 'WSN': { 'short': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'minor': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'major': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}, 'hof': {'w': 0, 'l': 0, 'rd': 0, 'points': 0}}, } logger.debug(f'running short games...') for line in short_games: home_win = True if line['home_score'] > line['away_score'] else False if line['away_team']['is_ai']: all_results[line['away_team']['abbrev']]['short']['w'] += 1 if home_win else 0 all_results[line['away_team']['abbrev']]['short']['l'] += 1 if not home_win else 0 all_results[line['away_team']['abbrev']]['short']['points'] += 2 if home_win else 1 all_results[line['away_team']['abbrev']]['short']['rd'] += line['home_score'] - line['away_score'] elif line['home_team']['is_ai']: all_results[line['home_team']['abbrev']]['short']['w'] += 1 if not home_win else 0 all_results[line['home_team']['abbrev']]['short']['l'] += 1 if home_win else 0 all_results[line['home_team']['abbrev']]['short']['points'] += 2 if not home_win else 1 all_results[line['home_team']['abbrev']]['short']['rd'] += line['away_score'] - line['home_score'] logger.debug(f'done short games') logger.debug(f'running league games...') league = {None: 'minor', 'minor-league': 'minor', 'major-league': 'major', 'hall-of-fame': 'hof'} for line in long_games: home_win = True if line['home_score'] > line['away_score'] else False if line['away_team']['is_ai']: all_results[line['away_team']['abbrev']][league[line['game_type']]]['w'] += 1 if home_win else 0 all_results[line['away_team']['abbrev']][league[line['game_type']]]['l'] += 1 if not home_win else 0 all_results[line['away_team']['abbrev']][league[line['game_type']]]['points'] += 2 if home_win else 1 all_results[line['away_team']['abbrev']][league[line['game_type']]]['rd'] += \ line['home_score'] - line['away_score'] elif line['home_team']['is_ai']: all_results[line['home_team']['abbrev']][league[line['game_type']]]['w'] += 1 if not home_win else 0 all_results[line['home_team']['abbrev']][league[line['game_type']]]['l'] += 1 if home_win else 0 all_results[line['home_team']['abbrev']][league[line['game_type']]]['points'] += 2 if not home_win else 1 all_results[line['home_team']['abbrev']][league[line['game_type']]]['rd'] += \ line['away_score'] - line['home_score'] logger.debug(f'done league games') return all_results def get_record_embed_legacy(embed: discord.Embed, results: dict, league: str): ale_points = results["BAL"][league]["points"] + results["BOS"][league]["points"] + \ results["NYY"][league]["points"] + results["TBR"][league]["points"] + results["TOR"][league]["points"] alc_points = results["CLE"][league]["points"] + results["CHW"][league]["points"] + \ results["DET"][league]["points"] + results["KCR"][league]["points"] + results["MIN"][league]["points"] alw_points = results["HOU"][league]["points"] + results["LAA"][league]["points"] + \ results["OAK"][league]["points"] + results["SEA"][league]["points"] + results["TEX"][league]["points"] nle_points = results["ATL"][league]["points"] + results["MIA"][league]["points"] + \ results["NYM"][league]["points"] + results["PHI"][league]["points"] + results["WSN"][league]["points"] nlc_points = results["CHC"][league]["points"] + results["CIN"][league]["points"] + \ results["MIL"][league]["points"] + results["PIT"][league]["points"] + results["STL"][league]["points"] nlw_points = results["ARI"][league]["points"] + results["COL"][league]["points"] + \ results["LAD"][league]["points"] + results["SDP"][league]["points"] + results["SFG"][league]["points"] embed.add_field( name=f'AL East ({ale_points} pts)', value=f'BAL: {results["BAL"][league]["w"]} - {results["BAL"][league]["l"]} ({results["BAL"][league]["rd"]} RD)\n' f'BOS: {results["BOS"][league]["w"]} - {results["BOS"][league]["l"]} ({results["BOS"][league]["rd"]} RD)\n' f'NYY: {results["NYY"][league]["w"]} - {results["NYY"][league]["l"]} ({results["NYY"][league]["rd"]} RD)\n' f'TBR: {results["TBR"][league]["w"]} - {results["TBR"][league]["l"]} ({results["TBR"][league]["rd"]} RD)\n' f'TOR: {results["TOR"][league]["w"]} - {results["TOR"][league]["l"]} ({results["TOR"][league]["rd"]} RD)\n' ) embed.add_field( name=f'AL Central ({alc_points} pts)', value=f'CLE: {results["CLE"][league]["w"]} - {results["CLE"][league]["l"]} ({results["CLE"][league]["rd"]} RD)\n' f'CHW: {results["CHW"][league]["w"]} - {results["CHW"][league]["l"]} ({results["CHW"][league]["rd"]} RD)\n' f'DET: {results["DET"][league]["w"]} - {results["DET"][league]["l"]} ({results["DET"][league]["rd"]} RD)\n' f'KCR: {results["KCR"][league]["w"]} - {results["KCR"][league]["l"]} ({results["KCR"][league]["rd"]} RD)\n' f'MIN: {results["MIN"][league]["w"]} - {results["MIN"][league]["l"]} ({results["MIN"][league]["rd"]} RD)\n' ) embed.add_field( name=f'AL West ({alw_points} pts)', value=f'HOU: {results["HOU"][league]["w"]} - {results["HOU"][league]["l"]} ({results["HOU"][league]["rd"]} RD)\n' f'LAA: {results["LAA"][league]["w"]} - {results["LAA"][league]["l"]} ({results["LAA"][league]["rd"]} RD)\n' f'OAK: {results["OAK"][league]["w"]} - {results["OAK"][league]["l"]} ({results["OAK"][league]["rd"]} RD)\n' f'SEA: {results["SEA"][league]["w"]} - {results["SEA"][league]["l"]} ({results["SEA"][league]["rd"]} RD)\n' f'TEX: {results["TEX"][league]["w"]} - {results["TEX"][league]["l"]} ({results["TEX"][league]["rd"]} RD)\n' ) embed.add_field( name=f'NL East ({nle_points} pts)', value=f'ATL: {results["ATL"][league]["w"]} - {results["ATL"][league]["l"]} ({results["ATL"][league]["rd"]} RD)\n' f'MIA: {results["MIA"][league]["w"]} - {results["MIA"][league]["l"]} ({results["MIA"][league]["rd"]} RD)\n' f'NYM: {results["NYM"][league]["w"]} - {results["NYM"][league]["l"]} ({results["NYM"][league]["rd"]} RD)\n' f'PHI: {results["PHI"][league]["w"]} - {results["PHI"][league]["l"]} ({results["PHI"][league]["rd"]} RD)\n' f'WSN: {results["WSN"][league]["w"]} - {results["WSN"][league]["l"]} ({results["WSN"][league]["rd"]} RD)\n' ) embed.add_field( name=f'NL Central ({nlc_points} pts)', value=f'CHC: {results["CHC"][league]["w"]} - {results["CHC"][league]["l"]} ({results["CHC"][league]["rd"]} RD)\n' f'CHW: {results["CIN"][league]["w"]} - {results["CIN"][league]["l"]} ({results["CIN"][league]["rd"]} RD)\n' f'MIL: {results["MIL"][league]["w"]} - {results["MIL"][league]["l"]} ({results["MIL"][league]["rd"]} RD)\n' f'PIT: {results["PIT"][league]["w"]} - {results["PIT"][league]["l"]} ({results["PIT"][league]["rd"]} RD)\n' f'STL: {results["STL"][league]["w"]} - {results["STL"][league]["l"]} ({results["STL"][league]["rd"]} RD)\n' ) embed.add_field( name=f'NL West ({nlw_points} pts)', value=f'ARI: {results["ARI"][league]["w"]} - {results["ARI"][league]["l"]} ({results["ARI"][league]["rd"]} RD)\n' f'COL: {results["COL"][league]["w"]} - {results["COL"][league]["l"]} ({results["COL"][league]["rd"]} RD)\n' f'LAD: {results["LAD"][league]["w"]} - {results["LAD"][league]["l"]} ({results["LAD"][league]["rd"]} RD)\n' f'SDP: {results["SDP"][league]["w"]} - {results["SDP"][league]["l"]} ({results["SDP"][league]["rd"]} RD)\n' f'SFG: {results["SFG"][league]["w"]} - {results["SFG"][league]["l"]} ({results["SFG"][league]["rd"]} RD)\n' ) return embed def get_record_embed(team: dict, results: dict, league: str): embed = get_team_embed(league, team) embed.add_field( name=f'AL East', value=f'BAL: {results["BAL"][0]} - {results["BAL"][1]} ({results["BAL"][2]} RD)\n' f'BOS: {results["BOS"][0]} - {results["BOS"][1]} ({results["BOS"][2]} RD)\n' f'NYY: {results["NYY"][0]} - {results["NYY"][1]} ({results["NYY"][2]} RD)\n' f'TBR: {results["TBR"][0]} - {results["TBR"][1]} ({results["TBR"][2]} RD)\n' f'TOR: {results["TOR"][0]} - {results["TOR"][1]} ({results["TOR"][2]} RD)\n' ) embed.add_field( name=f'AL Central', value=f'CLE: {results["CLE"][0]} - {results["CLE"][1]} ({results["CLE"][2]} RD)\n' f'CHW: {results["CHW"][0]} - {results["CHW"][1]} ({results["CHW"][2]} RD)\n' f'DET: {results["DET"][0]} - {results["DET"][1]} ({results["DET"][2]} RD)\n' f'KCR: {results["KCR"][0]} - {results["KCR"][1]} ({results["KCR"][2]} RD)\n' f'MIN: {results["MIN"][0]} - {results["MIN"][1]} ({results["MIN"][2]} RD)\n' ) embed.add_field( name=f'AL West', value=f'HOU: {results["HOU"][0]} - {results["HOU"][1]} ({results["HOU"][2]} RD)\n' f'LAA: {results["LAA"][0]} - {results["LAA"][1]} ({results["LAA"][2]} RD)\n' f'OAK: {results["OAK"][0]} - {results["OAK"][1]} ({results["OAK"][2]} RD)\n' f'SEA: {results["SEA"][0]} - {results["SEA"][1]} ({results["SEA"][2]} RD)\n' f'TEX: {results["TEX"][0]} - {results["TEX"][1]} ({results["TEX"][2]} RD)\n' ) embed.add_field( name=f'NL East', value=f'ATL: {results["ATL"][0]} - {results["ATL"][1]} ({results["ATL"][2]} RD)\n' f'MIA: {results["MIA"][0]} - {results["MIA"][1]} ({results["MIA"][2]} RD)\n' f'NYM: {results["NYM"][0]} - {results["NYM"][1]} ({results["NYM"][2]} RD)\n' f'PHI: {results["PHI"][0]} - {results["PHI"][1]} ({results["PHI"][2]} RD)\n' f'WSN: {results["WSN"][0]} - {results["WSN"][1]} ({results["WSN"][2]} RD)\n' ) embed.add_field( name=f'NL Central', value=f'CHC: {results["CHC"][0]} - {results["CHC"][1]} ({results["CHC"][2]} RD)\n' f'CIN: {results["CIN"][0]} - {results["CIN"][1]} ({results["CIN"][2]} RD)\n' f'MIL: {results["MIL"][0]} - {results["MIL"][1]} ({results["MIL"][2]} RD)\n' f'PIT: {results["PIT"][0]} - {results["PIT"][1]} ({results["PIT"][2]} RD)\n' f'STL: {results["STL"][0]} - {results["STL"][1]} ({results["STL"][2]} RD)\n' ) embed.add_field( name=f'NL West', value=f'ARI: {results["ARI"][0]} - {results["ARI"][1]} ({results["ARI"][2]} RD)\n' f'COL: {results["COL"][0]} - {results["COL"][1]} ({results["COL"][2]} RD)\n' f'LAD: {results["LAD"][0]} - {results["LAD"][1]} ({results["LAD"][2]} RD)\n' f'SDP: {results["SDP"][0]} - {results["SDP"][1]} ({results["SDP"][2]} RD)\n' f'SFG: {results["SFG"][0]} - {results["SFG"][1]} ({results["SFG"][2]} RD)\n' ) return embed class Players(commands.Cog): def __init__(self, bot): self.bot = bot # self.sheets = pygsheets.authorize(service_file='storage/paper-dynasty-service-creds.json', retries=1) self.player_list = [] self.cardset_list = [] self.freeze = False self.build_player_list.start() self.weekly_loop.start() @tasks.loop(hours=1) async def weekly_loop(self): current = await db_get('current') now = datetime.datetime.now() logger.debug(f'Datetime: {now} / weekday: {now.weekday()}') # Begin Freeze # if now.weekday() == 0 and now.hour == 5: # Spring/Summer if now.weekday() == 0 and now.hour == 0: # Fall/Winter current['week'] += 1 await db_patch('current', object_id=current['id'], params=[('week', current['week'])]) # End Freeze # elif now.weekday() == 5 and now.hour == 5 and current['freeze']: # Spring/Summer # elif now.weekday() == 5 and now.hour == 0 and current['freeze']: # Fall/Winter # await db_patch('current', object_id=current['id'], params=[('freeze', False)]) @weekly_loop.before_loop async def before_weekly_check(self): await self.bot.wait_until_ready() async def cog_command_error(self, ctx, error): await ctx.send(f'{error}') @tasks.loop(hours=18) async def build_player_list(self): all_players = await db_get('players', params=[('flat', True), ('inc_dex', False)], timeout=25) all_cardsets = await db_get('cardsets', params=[('flat', True)]) [self.player_list.append(x['p_name'].lower()) for x in all_players['players'] if x['p_name'].lower() not in self.player_list] logger.info(f'There are now {len(self.player_list)} player names in the fuzzy search list.') self.cardset_list = [x['name'].lower() for x in all_cardsets['cardsets']] logger.info(f'There are now {len(self.cardset_list)} cardsets in the fuzzy search list.') @build_player_list.before_loop async def before_player_list(self): await self.bot.wait_until_ready() # def get_standings_embeds(self, current, which: str, title: str): # all_embeds = [ # discord.Embed(title=title), discord.Embed(title=title), discord.Embed(title=title), # discord.Embed(title=title), discord.Embed(title=title), discord.Embed(title=title) # ] # # if which == 'week': # weekly_games = Result.select_season(current.season).where( # (Result.week == current.week) & (Result.game_type == "baseball") # ) # logger.info(f'weekly_games: {weekly_games}') # # if weekly_games.count() == 0: # return None # # active_teams = [] # for game in weekly_games: # if game.awayteam.abbrev not in active_teams: # active_teams.append(game.awayteam.abbrev) # if game.hometeam.abbrev not in active_teams: # active_teams.append(game.hometeam.abbrev) # # records = [] # for abbrev in active_teams: # team = Team.get_season(abbrev) # record = team.get_record(current.week, game_type='baseball') # points = record['w'] * 2.0 + record['l'] # this_record = [ # record, # points, # record['w'] / (record['w'] + record['l']), # team # ] # records.append(this_record) # # else: # records = [] # for this_team in Team.select_season(): # record = this_team.get_record() # points = record['w'] * 2.0 + record['l'] # if record['w'] + record['l'] > 0: # records.append([ # record, # points, # record['w'] / (record['w'] + record['l']), # this_team # ]) # # records.sort(key=lambda x: x[1] + x[2], reverse=True) # # standings_message = '' # count = 1 # embed_count = 0 # for team in records: # standings_message += f'**{count}**: {team[3].sname} - {team[1]:.0f} Pts ({team[0]["w"]}-{team[0]["l"]})\n' # if count % 24 == 0 or count >= len(records): # logger.info(f'standings_message: {standings_message}') # all_embeds[embed_count].add_field(name='Standings', value=standings_message) # all_embeds[embed_count].set_thumbnail(url=self.logo) # # standings_message = '' # embed_count += 1 # count += 1 # # return_embeds = [] # for x in range(embed_count): # return_embeds.append(all_embeds[x]) # # db.close() # return return_embeds @commands.command(name='build_list', help='Mod: Synchronize fuzzy player list') async def build_player_command(self, ctx): self.build_player_list.stop() self.build_player_list.start() await ctx.send(f'Just kicked off the build...') await asyncio.sleep(10) await ctx.send(f'There are now {len(self.player_list)} player names in the fuzzy search list.') @commands.command(name='player', help='For specific cardset, run /player', aliases=['show', 'card']) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def player_card_command(self, ctx, *, player_name: str): this_player = fuzzy_search(player_name, self.player_list) if not this_player: await ctx.send(f'No clue who that is.') return all_players = await db_get('players', params=[('name', this_player)]) all_cards = [ {'player': x, 'team': {'lname': 'Paper Dynasty', 'logo': IMAGES['logo'], 'season': PD_SEASON}} for x in all_players['players'] ] all_cards.sort(key=lambda x: x['player']['rarity']['value'], reverse=True) all_embeds = [] for x in all_cards: all_embeds.extend(await get_card_embeds(x)) await ctx.send(content=None, embeds=all_embeds) @app_commands.command(name='player', description='Display one or more of the player\'s cards') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) @app_commands.autocomplete(player_name=player_autocomplete, cardset=cardset_autocomplete) async def player_slash_command( self, interaction: discord.Interaction, player_name: str, cardset: str = 'All'): ephemeral = False if interaction.channel.name in ['paper-dynasty-chat', 'pd-news-ticker']: ephemeral = True await interaction.response.defer(ephemeral=ephemeral) this_player = fuzzy_search(player_name, self.player_list) if not this_player: await interaction.response.send_message(f'No clue who that is.') return if cardset and cardset != 'All': this_cardset = await cardset_search(cardset, self.cardset_list) if this_cardset: all_params = [('name', this_player), ('cardset_id', this_cardset['id'])] else: await interaction.edit_original_response(content=f'I couldn\'t find {cardset} cardset.') return else: all_params = [('name', this_player)] all_players = await db_get('players', params=all_params) if all_players['count'] == 0: await interaction.edit_original_response(content='No players found') return all_cards = [get_blank_team_card(x) for x in all_players['players']] all_cards.sort(key=lambda x: x['player']['rarity']['value'], reverse=True) all_embeds = [] for x in all_cards: all_embeds.extend(await get_card_embeds(x, include_stats=True)) logger.debug(f'embeds: {all_embeds}') if len(all_embeds) > 1: await interaction.edit_original_response(content=f'# {all_players["players"][0]["p_name"]}') await embed_pagination( all_embeds, interaction.channel, interaction.user, timeout=20, start_page=0 ) else: await interaction.edit_original_response(content=None, embed=all_embeds[0]) @app_commands.command(name='update-player', description='Update a player\'s card to a specific MLB team') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def update_player_team(self, interaction: discord.Interaction, player_id: int): owner_team = await get_team_by_owner(interaction.user.id) if not owner_team: await interaction.response.send_message( 'Thank you for offering to help - if you sign up for a team with /newteam I can let you post updates.', ephemeral=True ) return if interaction.channel.name in ['paper-dynasty-chat', 'pd-news-ticker']: await interaction.response.send_message( f'Slide on down to #pd-bot-hole to run updates - thanks!', ephemeral=True ) await interaction.response.defer() this_player = await db_get('players', object_id=player_id) if not this_player: await interaction.response.send_message(f'No clue who that is.') return embed = await get_card_embeds(get_blank_team_card(this_player)) await interaction.edit_original_response(content=None, embed=embed[0]) view = helpers.Confirm(responders=[interaction.user]) question = await interaction.channel.send( content='Is this the player you want to update?', view=view ) await view.wait() if not view.value: await question.edit(content='Okay, we\'ll leave it be.', view=None) return else: await question.delete() view = SelectView([ helpers.SelectUpdatePlayerTeam('AL', this_player, owner_team, self.bot), helpers.SelectUpdatePlayerTeam('NL', this_player, owner_team, self.bot) ]) await interaction.channel.send(content=None, view=view) @app_commands.command(name='record', description='Display team record against AI teams') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def record_slash_command( self, interaction: discord.Interaction, league: Literal['All', 'Minor League', 'Major League', 'Flashback', 'Hall of Fame'], team_abbrev: Optional[str] = None): ephemeral = False if interaction.channel.name in ['paper-dynasty-chat', 'pd-news-ticker']: ephemeral = True if team_abbrev: t_query = await db_get('teams', params=[('abbrev', team_abbrev)]) else: t_query = await db_get('teams', params=[('gm_id', interaction.user.id)]) if t_query['count'] == 0: await interaction.response.send_message( f'Hmm...I can\'t find the team you looking for.', ephemeral=ephemeral ) return team = t_query['teams'][0] current = await db_get('current') await interaction.response.send_message( f'I\'m tallying the {team["lname"]} results now...', ephemeral=ephemeral ) st_query = await db_get(f'teams/{team["id"]}/season-record', object_id=current["season"]) minor_embed = get_record_embed(team, st_query['minor-league'], 'Minor League') major_embed = get_record_embed(team, st_query['major-league'], 'Major League') flashback_embed = get_record_embed(team, st_query['flashback'], 'Flashback') hof_embed = get_record_embed(team, st_query['hall-of-fame'], 'Hall of Fame') if league == 'All': start_page = 0 elif league == 'Minor League': start_page = 0 elif league == 'Major League': start_page = 1 elif league == 'Flashback': start_page = 2 else: start_page = 3 await interaction.edit_original_response(content=f'Here are the {team["lname"]} campaign records') await embed_pagination( [minor_embed, major_embed, flashback_embed, hof_embed], interaction.channel, interaction.user, timeout=20, start_page=start_page ) @app_commands.command(name='team', description='Show team overview and rosters') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) @app_legal_channel() async def team_command(self, interaction: discord.Interaction, team_abbrev: Optional[str] = None): await interaction.response.defer() if team_abbrev: t_query = await db_get('teams', params=[('abbrev', team_abbrev)]) else: t_query = await db_get('teams', params=[('gm_id', interaction.user.id)]) if t_query['count'] == 0: await interaction.edit_original_response( content=f'Hmm...I can\'t find the team you looking for.' ) return team = t_query['teams'][0] embed = await team_summary_embed(team, interaction) await interaction.edit_original_response(content=None, embed=embed) group_lookup = app_commands.Group(name='lookup', description='Search for cards or players by ID') @group_lookup.command(name='card-id', description='Look up individual card by ID') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def card_lookup_command(self, interaction: discord.Interaction, card_id: int): await interaction.response.defer() c_query = await db_get('cards', object_id=card_id) if c_query: c_string = f'Card ID {card_id} is a {helpers.player_desc(c_query["player"])}' if c_query['team'] is not None: c_string += f' owned by the {c_query["team"]["sname"]}' if c_query["pack"] is not None: c_string += f' pulled from a {c_query["pack"]["pack_type"]["name"]} pack.' else: c_query['team'] = c_query["pack"]["team"] c_string += f' used by the {c_query["pack"]["team"]["sname"]} in a gauntlet' await interaction.edit_original_response( content=c_string, embeds=await get_card_embeds(c_query) ) return await interaction.edit_original_response(content=f'There is no card with ID {card_id}') @group_lookup.command(name='player-id', description='Look up an individual player by ID') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def player_lookup_command(self, interaction: discord.Interaction, player_id: int): await interaction.response.defer() p_query = await db_get('players', object_id=player_id) if p_query: p_card = get_blank_team_card(p_query) await interaction.edit_original_response( content=None, embeds=await get_card_embeds(p_card) ) return await interaction.edit_original_response(content=f'There is no player with ID {player_id}.') @commands.hybrid_command(name='branding-pd', help='Update your team branding') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def branding_command( self, ctx, team_logo_url: str = None, color: str = None, short_name: str = None, full_name: str = None): owner_team = await get_team_by_owner(get_context_user(ctx).id) if not owner_team: await ctx.send(f'Hmm...I don\'t see a team for you, yet. You can create one with `/newteam`!') return params = [] if team_logo_url is not None: params.append(('logo', team_logo_url)) if color is not None: params.append(('color', color)) if short_name is not None: params.append(('sname', short_name)) if full_name is not None: params.append(('lname', full_name)) if not params: await ctx.send(f'You keep thinking on it - I can\'t make updates if you don\'t provide them.') return team = await db_patch('teams', object_id=owner_team['id'], params=params) embed = await team_summary_embed(team, ctx) await ctx.send(content=None, embed=embed) @commands.hybrid_command(name='fuck', help='You know') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def fuck_command(self, ctx, gm: Member): t_query = await db_get('teams', params=[('gm_id', gm.id)]) if t_query['count'] == 0: await ctx.send(f'Who?') return await ctx.send(f'{t_query["teams"][0]["sname"]} are a bunch of cuties!') @commands.hybrid_command(name='random', help='Check out a random card') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def random_card_command(self, ctx: commands.Context): p_query = await db_get('players/random', params=[('limit', 1)]) this_player = p_query['players'][0] this_embed = await get_card_embeds( {'player': this_player, 'team': {'lname': 'Paper Dynasty', 'logo': IMAGES['logo'], 'season': PD_SEASON}} ) await ctx.send(content=None, embeds=this_embed) group_paperdex = app_commands.Group(name='paperdex', description='Check your collection counts') @group_paperdex.command(name='cardset', description='Check your collection of a specific cardset') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def paperdex_cardset_slash(self, interaction: discord.Interaction): team = await get_team_by_owner(interaction.user.id) if not team: await interaction.response.send_message(f'Do you even have a team? I don\'t know you.', ephemeral=True) return view = SelectView([SelectPaperdexCardset()], timeout=15) await interaction.response.send_message( content='You have 15 seconds to select a cardset.', view=view, ephemeral=True ) await view.wait() await interaction.delete_original_response() @group_paperdex.command(name='team', description='Check your collection of a specific MLB franchise') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def paperdex_cardset_slash(self, interaction: discord.Interaction): team = await get_team_by_owner(interaction.user.id) if not team: await interaction.response.send_message(f'Do you even have a team? I don\'t know you.', ephemeral=True) return view = SelectView([SelectPaperdexTeam('AL'), SelectPaperdexTeam('NL')], timeout=30) await interaction.response.send_message( content='You have 30 seconds to select a team.', view=view, ephemeral=True ) await view.wait() await interaction.delete_original_response() @commands.hybrid_command(name='ai-teams', help='Get list of AI teams and abbreviations') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def ai_teams_command(self, ctx: commands.Context): embed = get_team_embed(f'Paper Dynasty AI Teams') embed.description = 'Teams Available for Solo Play' embed.add_field( name='AL East', value=f'BAL - Baltimore Orioles\nBOS - Boston Red Sox\nNYY - New York Yankees\nTBR - Tampa Bay Rays\nTOR - ' f'Toronto Blue Jays' ) embed.add_field( name='AL Central', value=f'CLE - Cleveland Guardians\nCHW - Chicago White Sox\nDET - Detroit Tigers\nKCR - Kansas City ' f'Royals\nMIN - Minnesota Twins' ) embed.add_field( name='NL West', value=f'HOU - Houston Astros\nLAA - Los Angeles Angels\nOAK - Oakland Athletics\nSEA - Seattle Mariners' f'\nTEX - Texas Rangers' ) embed.add_field( name='NL East', value=f'ATL - Atlanta Braves\nMIA - Miami Marlins\nNYM - New York Mets\nPHI - Philadelphia Phillies\n' f'WSN - Washington Nationals' ) embed.add_field( name='NL Central', value=f'CHC - Chicago Cubs\nCIN - Cincinnati Reds\nMIL - Milwaukee Brewers\nPIT - Pittsburgh Pirates\n' f'STL - St Louis Cardinals' ) embed.add_field( name='NL West', value=f'ARI - Arizona Diamondbacks\nCOL - Colorado Rockies\nLAD - Los Angeles Dodgers\nSDP - San Diego ' f'Padres\nSFG - San Francisco Giants' ) await ctx.send(content=None, embed=embed) @commands.hybrid_command(name='standings', help='Check weekly or season-long standings') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def standings_command(self, ctx: commands.Context, which: Literal['week', 'season']): current = await db_get('current') params = [('season', current['season']), ('ranked', True)] if which == 'week': params.append(('week', current['week'])) r_query = await db_get('results', params=params) if not r_query['count']: await ctx.send(f'There are no Ranked games on record this {"week" if which == "week" else "season"}.') return all_records = {} for line in r_query['results']: home_win = True if line['home_score'] > line['away_score'] else False if line['away_team']['id'] not in all_records: all_records[line['away_team']['id']] = { 'wins': 1 if not home_win else 0, 'losses': 1 if home_win else 0, 'points': 2 if not home_win else 1 } else: all_records[line['away_team']['id']]['wins'] += 1 if not home_win else 0 all_records[line['away_team']['id']]['losses'] += 1 if home_win else 0 all_records[line['away_team']['id']]['points'] += 2 if not home_win else 1 if line['home_team']['id'] not in all_records: all_records[line['home_team']['id']] = { 'wins': 1 if home_win else 0, 'losses': 1 if not home_win else 0, 'points': 2 if home_win else 1 } else: all_records[line['home_team']['id']]['wins'] += 1 if home_win else 0 all_records[line['home_team']['id']]['losses'] += 1 if not home_win else 0 all_records[line['home_team']['id']]['points'] += 2 if home_win else 0 # logger.info(f'all_records:\n\n{all_records}') sorted_records = sorted(all_records.items(), key=lambda k_v: k_v[1]['points'], reverse=True) # logger.info(f'sorted_records: {sorted_records}') # await ctx.send(f'sorted: {sorted_records}') embed = get_team_embed( title=f'{"Season" if which == "season" else "Week"} ' f'{current["season"] if which == "season" else current["week"]} Standings' ) chunk_string = '' for index, record in enumerate(sorted_records): # logger.info(f'index: {index} / record: {record}') team = await db_get('teams', object_id=record[0]) if team: chunk_string += f'{record[1]["points"]} pt{"s" if record[1]["points"] != 1 else ""} ' \ f'({record[1]["wins"]}-{record[1]["losses"]}) - {team["sname"]} [{team["ranking"]}]\n' else: logger.error(f'Could not find team {record[0]} when running standings.') if (index + 1) == len(sorted_records): embed.add_field( name=f'Group {math.ceil((index + 1) / 20)} / ' f'{math.ceil(len(sorted_records) / 20)}', value=chunk_string ) elif (index + 1) % 20 == 0: embed.add_field( name=f'Group {math.ceil((index + 1) / 20)} / ' f'{math.floor(len(sorted_records) / 20)}', value=chunk_string ) await ctx.send(content=None, embed=embed) @commands.hybrid_command(name='pullroster', help='Pull saved rosters from your team Sheet', aliases=['roster', 'rosters', 'pullrosters']) @app_commands.describe( specific_roster_num='Enter 1, 2, or 3 to only pull one roster; leave blank to pull all 3', ) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) async def pull_roster_command(self, ctx: commands.Context, specific_roster_num: Optional[int] = None): team = await get_team_by_owner(get_context_user(ctx).id) if not team: await ctx.send(f'Do you even have a team? I don\'t know you.') return # Pull data from Sheets async with ctx.typing(): roster_data = get_rosters(team, self.bot) logger.debug(f'roster_data: {roster_data}') # Post roster team/card ids and throw error if db says no for index, roster in enumerate(roster_data): logger.debug(f'index: {index} / roster: {roster}') if (not specific_roster_num or specific_roster_num == index + 1) and roster: this_roster = await db_post( 'rosters', payload={ 'team_id': team['id'], 'name': roster['name'], 'roster_num': roster['roster_num'], 'card_ids': roster['cards'] } ) await ctx.send(random_conf_gif()) group_gauntlet = app_commands.Group(name='gauntlets', description='Check your progress or start a new Gauntlet') @group_gauntlet.command(name='status', description='View status of current Gauntlet run') @app_commands.describe( team_abbrev='To check the status of a team\'s active run, enter their abbreviation' ) @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_run_command( self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL, # type: ignore team_abbrev: str = None): await interaction.response.defer() e_query = await db_get('events', params=[("name", event_name), ("active", True)]) if e_query['count'] == 0: await interaction.edit_original_response(content=f'Hmm...looks like that event is inactive.') return else: this_event = e_query['events'][0] this_run, this_team = None, None if team_abbrev: if 'Gauntlet-' not in team_abbrev: team_abbrev = f'Gauntlet-{team_abbrev}' t_query = await db_get('teams', params=[('abbrev', team_abbrev)]) if t_query['count'] != 0: this_team = t_query['teams'][0] r_query = await db_get('gauntletruns', params=[ ('team_id', this_team['id']), ('is_active', True), ('gauntlet_id', this_event['id']) ]) if r_query['count'] != 0: this_run = r_query['runs'][0] else: await interaction.channel.send( content=f'I do not see an active run for the {this_team["lname"]}.' ) else: await interaction.channel.send( content=f'I do not see an active run for {team_abbrev.upper()}.' ) await interaction.edit_original_response( content=None, embed=await gauntlets.get_embed(this_run, this_event, this_team) ) @group_gauntlet.command(name='start', description='Start a new Gauntlet run') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_start_command( self, interaction: discord.Interaction): if 'hello' not in interaction.channel.name: await interaction.response.send_message( content='The draft will probably take you about 15 minutes. Why don\'t you head to your private ' 'channel to run the draft?', ephemeral=True ) return logger.info(f'Starting a gauntlet run for user {interaction.user.name}') await interaction.response.defer() with Session(engine) as session: main_team = await get_team_or_none(session, gm_id=interaction.user.id, main_team=True) draft_team = await get_team_or_none(session, gm_id=interaction.user.id, gauntlet_team=True) e_query = await db_get('events', params=[("active", True)]) if e_query['count'] == 0: await interaction.edit_original_response(content='Hmm...I don\'t see any active events.') return elif e_query['count'] == 1: this_event = e_query['events'][0] else: event_choice = await ask_with_buttons( interaction, button_options=[x['name'] for x in e_query['events']], question='Which event would you like to take on?', # edit_original_interaction=True, timeout=3, delete_question=False ) this_event = [event for event in e_query['events'] if event['name'] == event_choice][0] # await interaction.channel.send( # content=f'You chose the {event_choice} event!' # ) logger.info(f'this_event: {this_event}') first_flag = draft_team is None if draft_team is not None: r_query = await db_get( 'gauntletruns', params=[('team_id', draft_team.id), ('gauntlet_id', this_event['id']), ('is_active', True)] ) if r_query['count'] != 0: await interaction.edit_original_response( content=f'Looks like you already have a {r_query["runs"][0]["gauntlet"]["name"]} run active! ' f'You can check it out with the `/gauntlets status` command.' ) return try: draft_embed = await gauntlets.run_draft(interaction, main_team, this_event, draft_team) except ZeroDivisionError as e: return except Exception as e: logger.error(f'Failed to run {this_event["name"]} draft for the {main_team.sname}: {e}') await gauntlets.wipe_team(draft_team, interaction) await interaction.channel.send( content=f'Shoot - it looks like we ran into an issue running the draft. I had to clear it all out ' f'for now. I let {get_cal_user(interaction).mention} know what happened so he better ' f'fix it quick.' ) return if first_flag: await interaction.channel.send( f'Good luck, champ in the making! To start playing, follow these steps:\n\n' f'1) Make a copy of the Team Sheet Template found in `/help-pd links`\n' f'2) Run `/newsheet` to link it to your Gauntlet team\n' f'3) Go play your first game with `/new-game gauntlet {this_event["name"]}`' ) else: await interaction.channel.send( f'Good luck, champ in the making! In your team sheet, sync your cards with **Paper Dynasty** -> ' f'**Data Imports** -> **My Cards** then you can set your lineup here and you\'ll be ready to go!\n\n' f'{get_roster_sheet(draft_team)}' ) await helpers.send_to_channel( bot=self.bot, channel_name='pd-news-ticker', content=f'The {main_team.lname} have entered the {this_event["name"]} Gauntlet!', embed=draft_embed ) @group_gauntlet.command(name='reset', description='Wipe your current team so you can re-draft') @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) async def gauntlet_reset_command( self, interaction: discord.Interaction, event_name: ACTIVE_EVENT_LITERAL): # type: ignore await interaction.response.defer() main_team = await get_team_by_owner(interaction.user.id) draft_team = await get_team_by_abbrev(f'Gauntlet-{main_team["abbrev"]}') if draft_team is None: await interaction.edit_original_response( content='Hmm, I can\'t find a gauntlet team for you. Have you signed up already?') return e_query = await db_get('events', params=[("name", event_name), ("active", True)]) if e_query['count'] == 0: await interaction.edit_original_response(content='Hmm...looks like that event is inactive.') return else: this_event = e_query['events'][0] r_query = await db_get('gauntletruns', params=[ ('team_id', draft_team['id']), ('is_active', True), ('gauntlet_id', this_event['id']) ]) if r_query['count'] != 0: this_run = r_query['runs'][0] else: await interaction.edit_original_response( content=f'I do not see an active run for the {draft_team["lname"]}.' ) return view = helpers.Confirm(responders=[interaction.user], timeout=60) conf_string = f'Are you sure you want to wipe your active run?' await interaction.edit_original_response( content=conf_string, view=view ) await view.wait() if view.value: await gauntlets.end_run(this_run, this_event, draft_team, force_end=True) await interaction.edit_original_response( content=f'Your {event_name} run has been reset. Run `/gauntlets start {event_name}` to redraft!', view=None ) else: await interaction.edit_original_response( content=f'~~{conf_string}~~\n\nNo worries, I will leave it active.', view=None ) # @commands.command(name='standings', aliases=['leaders', 'points', 'weekly'], help='Weekly standings') # async def standings_command(self, ctx, *week_or_season): # if not await legal_channel(ctx): # await ctx.send('Slide on down to my #pd-bot-hole ;)') # return # # current = Current.get() # which = None # # if not week_or_season: # which = 'week' # title = f'Week {current.week} Standings' # elif 'season' in week_or_season: # which = 'season' # title = f'Season {current.season} Standings' # else: # which = 'week' # title = f'Week {current.week} Standings' # # all_embeds = self.get_standings_embeds(current, which, title) # for embed in all_embeds: # await ctx.send(content=None, embed=embed) @commands.command(name='in', help='Get Paper Dynasty Players role') async def give_role(self, ctx, *args): await ctx.author.add_roles(discord.utils.get(ctx.guild.roles, name='Paper Dynasty Players')) await ctx.send('I got u, boo. ;)\n\nNow that you\'ve got the PD role, you can run all of the Paper Dynasty ' 'bot commands. For help, check out `/help-pd`') @commands.command(name='out', help='Remove Paper Dynasty Players role') @commands.has_any_role('Paper Dynasty Players') async def take_role(self, ctx, *args): await ctx.author.remove_roles(discord.utils.get(ctx.guild.roles, name='Paper Dynasty Players')) await ctx.send('Oh no! I\'m so sad to see you go! What are we going to do without you?') # @commands.command(name='teams', help='List all teams') # @commands.has_any_role('Paper Dynasty Players') # async def list_teams(self, ctx): # if not await legal_channel(ctx): # await ctx.send('Slide on down to my #pd-bot-hole ;)') # return # # all_teams = Team.select_season() # team_list = [] # # for x in all_teams: # team_list.append(x) # team_list.sort(key=lambda y: y.collection_value, reverse=True) # # # Collect rarity objects # # try: # # rar_mvp = Rarity.get(Rarity.name == 'MVP') # # rar_als = Rarity.get(Rarity.name == 'All-Star') # # rar_sta = Rarity.get(Rarity.name == 'Starter') # # rar_res = Rarity.get(Rarity.name == 'Reserve') # # rar_rpl = Rarity.get(Rarity.name == 'Replacement') # # except Exception as e: # # logger.error(f'**Error**: (players inv getrars) - {e}') # # return # # all_embeds = [ # discord.Embed(title='All Teams', color=0xdeeadd), discord.Embed(title='All Teams', color=0xdeeadd), # discord.Embed(title='All Teams', color=0xdeeadd), discord.Embed(title='All Teams', color=0xdeeadd), # discord.Embed(title='All Teams', color=0xdeeadd), discord.Embed(title='All Teams', color=0xdeeadd) # ] # # # Build embed # count = 0 # async with ctx.typing(): # for x in team_list: # embed_index = math.floor(count / 24) # all_embeds[embed_index] = helpers.get_team_blurb(ctx, all_embeds[embed_index], x) # count += 1 # # for x in range(math.ceil(len(all_teams) / 24)): # await ctx.send(content=None, embed=all_embeds[x]) # # db.close() # # @commands.command(name='compare', aliases=['vs'], help='Compare two teams') # @commands.has_any_role('Paper Dynasty Players') # async def compare_command(self, ctx, team1_abbrev, team2_abbrev): # if not await legal_channel(ctx): # await ctx.send('Slide on down to my #pd-bot-hole ;)') # return # # away_team = Team.get_season(team1_abbrev) # if not away_team: # await ctx.send(f'I couldn\'t find **{team1_abbrev}**. Is that the team\'s abbreviation?') # return # home_team = Team.get_season(team2_abbrev) # if not home_team: # await ctx.send(f'I couldn\'t find **{team2_abbrev}**. Is that the team\'s abbreviation?') # return # # embed = discord.Embed(title=f'{away_team.abbrev} vs {home_team.abbrev}', color=0xdeeadd) # embed = helpers.get_team_blurb(ctx, embed, away_team) # embed = helpers.get_team_blurb(ctx, embed, home_team) # # away_tv = away_team.team_value # home_tv = home_team.team_value # diff = abs(away_tv - home_tv) # # if diff > 12: # embed.add_field(name='Both Teams Eligible for Packs?', value=f'No, diff is {diff}', inline=False) # else: # embed.add_field(name='Both Teams Eligible for Packs?', value='Yes!', inline=False) # # await ctx.send(content=None, embed=embed) # # db.close() # # @commands.command(name='result', help='Log your game results') # @commands.has_any_role('Paper Dynasty Players') # async def result_command(self, ctx, awayabbrev: str, awayscore: int, homeabbrev: str, # homescore: int, scorecard_url, *game_type: str): # if not await legal_channel(ctx): # await ctx.send('Slide on down to my #pd-bot-hole ;)') # return # # # Check access on the scorecard # try: # await ctx.send('Alright, let me go open that Sheet...') # scorecard = self.sheets.open_by_url(scorecard_url).worksheet_by_title('Results') # except Exception as e: # logger.error(f'Unable to access sheet ({scorecard_url}) submitted by {ctx.author.name}') # await ctx.message.add_reaction('❌') # await ctx.send(f'{ctx.message.author.mention}, I can\'t access that sheet.') # return # # # Validate teams listed # try: # awayteam = Team.get_season(awayabbrev) # hometeam = Team.get_season(homeabbrev) # logger.info(f'Final: {awayabbrev} {awayscore} - {homescore} {homeabbrev}') # if awayteam == hometeam: # await ctx.message.add_reaction('❌') # await helpers.send_to_news( # ctx, # f'{self.bot.get_user(ctx.author.id).mention} just tried to log ' # f'a game result played against themselves...', # embed=None) # return # except Exception as e: # error = f'**ERROR:** {type(e).__name__} - {e}' # logger.error(error) # await ctx.message.add_reaction('❌') # await ctx.send(f'Hey, {ctx.author.mention}, I couldn\'t find the teams you mentioned. You put ' # f'**{awayabbrev}** as the away team and **{homeabbrev}** as the home team.') # return # # # Check for duplicate scorecard # dupes = Result.select().where(Result.scorecard == scorecard_url) # if dupes.count() > 0: # await ctx.message.add_reaction('❌') # await ctx.send(f'Bruh. This scorecard was already submitted for credit.') # return # # if not game_type: # this_q = helpers.Question(self.bot, ctx.channel, 'Was this a wiffleball game?', 'yesno', 15) # resp = await this_q.ask([ctx.author]) # # if resp is None: # await helpers.react_and_reply(ctx, '❌', 'You think on it and get back to me.') # return # elif not resp: # game_type = 'baseball' # else: # game_type = 'wiffleball' # elif game_type[0] in ['b', 'base', 'baseball', 'standard', 'regular']: # game_type = 'baseball' # elif game_type[0] in ['w', 'wif', 'wiff', 'wiffleball']: # game_type = 'wiffleball' # else: # this_q = helpers.Question(self.bot, ctx.channel, 'Was this a wiffleball game?', 'yesno', 15) # resp = await this_q.ask([ctx.author]) # # if resp is None: # await helpers.react_and_reply(ctx, '❌', 'You think on it and get back to me.') # return # elif not resp: # game_type = 'baseball' # else: # game_type = 'wiffleball' # # earnings = { # 'away': 'None', # 'home': 'None', # } # # if game_type == 'wiffleball': # away_team_value = 10 # home_team_value = 10 # else: # away_team_value = awayteam.team_value # home_team_value = hometeam.team_value # # # Check author then log result # if ctx.author.id in [awayteam.gmid, awayteam.gmid2, hometeam.gmid, hometeam.gmid2] \ # or ctx.author.id == self.bot.owner_id: # this_result = Result(week=Current.get_by_id(1).week, # awayteam=awayteam, hometeam=hometeam, # awayscore=awayscore, homescore=homescore, # home_team_value=home_team_value, away_team_value=away_team_value, # scorecard=scorecard_url, season=Current.get_by_id(1).season, game_type=game_type) # this_result.save() # await helpers.pause_then_type( # ctx, # f'Just logged {awayteam.abbrev.upper()} {awayscore} - ' # f'{homescore} {hometeam.abbrev.upper()}' # ) # await ctx.message.add_reaction('✅') # # logger.info('Checking for credit') # # Credit pack for win # economy = self.bot.get_cog('Economy') # if awayscore > homescore: # # Set embed logo # if awayteam.logo: # winner_avatar = awayteam.logo # else: # winner_avatar = self.bot.get_user(awayteam.gmid).avatar_url # # # Check values and distribute earnings # if awayteam.team_value - hometeam.team_value <= 12: # earnings['away'] = '1 Premium Pack' # logger.info(f'{awayteam.sname} earns 1 Premium pack for the win') # economy.give_pack(awayteam, 1, 'Premium') # else: # logger.info(f'{awayteam.sname} earns nothing for the win - team value {awayteam.team_value} vs ' # f'{hometeam.team_value}') # earnings['away'] = f'None - Team was {awayteam.team_value - hometeam.team_value} points higher' # # if hometeam.team_value - awayteam.team_value <= 12: # earnings['home'] = '1 Standard Pack' # logger.info(f'{hometeam.sname} earns 1 Standard pack for the loss') # economy.give_pack(hometeam, 1) # else: # logger.info(f'{hometeam.sname} earns nothing for the loss - team value {hometeam.team_value} vs ' # f'{awayteam.team_value}') # earnings['home'] = f'None - Team was {hometeam.team_value - awayteam.team_value} points higher' # else: # if hometeam.logo: # winner_avatar = hometeam.logo # else: # winner_avatar = self.bot.get_user(hometeam.gmid).avatar_url # # # Check values and distribute earnings # if hometeam.team_value - awayteam.team_value <= 12: # earnings['home'] = '1 Premium Pack' # logger.info(f'{hometeam.sname} earns 1 Premium pack for the win') # economy.give_pack(hometeam, 1, 'Premium') # else: # logger.info(f'{hometeam.sname} earns nothing for the win - team value {hometeam.team_value} vs ' # f'{awayteam.team_value}') # earnings['home'] = f'None - Team was {hometeam.team_value - awayteam.team_value} points higher' # # if awayteam.team_value - hometeam.team_value <= 12: # earnings['away'] = '1 Standard Pack' # logger.info(f'{awayteam.sname} earns 1 Standard pack for the loss') # economy.give_pack(awayteam, 1) # else: # logger.info(f'{awayteam.sname} earns nothing for the loss - team value {awayteam.team_value} vs ' # f'{hometeam.team_value}') # earnings['away'] = f'None - Team was {awayteam.team_value - hometeam.team_value} points higher' # # # Get team records # away_record = awayteam.get_record() # home_record = hometeam.get_record() # # # away_team_value = helpers.get_collection_value(awayteam) # # home_team_value = helpers.get_collection_value(hometeam) # # delta = away_team_value - home_team_value # # if delta < 0: # # increments = divmod(-delta, helpers.TEAM_DELTA_CONSTANT) # # # logger.info(f'increments: {increments}') # # packs = min(increments[0], 5) # # if packs > 0: # # earnings['away'] += packs # # earnings_away.append(f'- {packs} pack{"s" if packs > 1 else ""} for underdog\n') # # else: # # increments = divmod(delta, helpers.TEAM_DELTA_CONSTANT) # # # logger.info(f'increments: {increments}') # # packs = min(increments[0], 5) # # if packs > 0: # # earnings['home'] += packs # # earnings_home.append(f'- {packs} pack{"s" if packs > 1 else ""} for underdog\n') # # # logger.info(f'earn away: {earnings["away"]} / earn home: {earnings["home"]}') # # away_packs_remaining = Current.get_by_id(1).packlimit - awayteam.weeklypacks # # home_packs_remaining = Current.get_by_id(1).packlimit - hometeam.weeklypacks # # away_final_earnings = earnings["away"] if away_packs_remaining >= earnings["away"] else max(away_packs_remaining, 0) # # home_final_earnings = earnings["home"] if home_packs_remaining >= earnings["home"] else max(home_packs_remaining, 0) # # ogging.info(f'away_final_earnings: {away_final_earnings}') # # ogging.info(f'home_final_earnings: {home_final_earnings}') # # # economy = self.bot.get_cog('Economy') # # if away_final_earnings > 0: # # logger.info(f'away_final_earnings: {away_final_earnings}') # # economy.give_pack(awayteam, away_final_earnings, True) # # else: # # away_final_earnings = 0 # # if home_final_earnings > 0: # # logger.info(f'home_final_earnings: {home_final_earnings}') # # economy.give_pack(hometeam, home_final_earnings, True) # # else: # # home_final_earnings = 0 # # embed = discord.Embed(title=f'{awayteam.sname} {awayscore} - {homescore} {hometeam.sname}', # description=f'Score Report - {game_type.title()}') # embed.add_field(name=awayteam.lname, # value=f'Team Value: {awayteam.team_value}\n\n' # f'Earn: {earnings["away"]}\n' # f'Record: {away_record["w"]}-{away_record["l"]}', # inline=False) # embed.add_field(name=hometeam.lname, # value=f'Team Value: {hometeam.team_value}\n\n' # f'Earn: {earnings["home"]}\n' # f'Record: {home_record["w"]}-{home_record["l"]}', # inline=False) # embed.add_field(name='Scorecard', # value=scorecard_url, # inline=False) # embed.set_thumbnail(url=winner_avatar) # await helpers.send_to_news(ctx, None, embed) # # db.close() # # @result_command.error # async def result_command_error(self, ctx, error): # if isinstance(error, commands.MissingRequiredArgument): # await ctx.send('The syntax is .result ' # '') # else: # await ctx.send(f'Error: {error}') # # db.close() # # @commands.command(name='sheet', aliases=['google'], help='Link to your roster sheet') # @commands.has_any_role('Paper Dynasty Players') # async def get_roster_command(self, ctx): # if not await legal_channel(ctx): # await ctx.send('Slide on down to my #pd-bot-hole ;)') # return # # team = Team.get_by_owner(ctx.author.id) # if not team: # await ctx.send(f'Do you have a team? I don\'t see your name here...') # return # # await ctx.send(f'{ctx.author.mention}\n{team.lname} Roster Sheet: <{helpers.get_roster_sheet_legacy(team)}>') # # db.close() # # @commands.command(name='setthumbnail', help='Set your team\'s thumbnail image') # @commands.has_any_role('Paper Dynasty Players') # async def set_thumbnail_command(self, ctx, url): # if not await legal_channel(ctx): # await ctx.send('Slide on down to my #pd-bot-hole ;)') # return # # team = Team.get_by_owner(ctx.author.id) # if not team: # await ctx.send(f'I cannot find a team that you manage. Are you registered for Paper Dynasty?') # return # # try: # team.logo = url # team.save() # embed = discord.Embed(title=f'{team.lname} Test') # embed.set_thumbnail(url=team.logo if team.logo else self.logo) # await ctx.send(content='Got it! What do you think?', embed=embed) # except Exception as e: # await ctx.send(f'Huh. Do you know what this means?\n\n{e}') # # db.close() # # @commands.command(name='rates', help='Check current pull rates') # @commands.has_any_role('Paper Dynasty Players') # async def all_card_pulls(self, ctx): # await self.bot.change_presence(activity=discord.Game(name='strat | .help')) # total_count = Card.select().count() # mvp_count = (Card # .select() # .join(Player) # .join(Rarity) # .where(Card.player.rarity.value == 10)).count() # als_count = (Card # .select() # .join(Player) # .join(Rarity) # .where(Card.player.rarity.value == 7)).count() # sta_count = (Card # .select() # .join(Player) # .join(Rarity) # .where(Card.player.rarity.value == 5)).count() # res_count = (Card # .select() # .join(Player) # .join(Rarity) # .where(Card.player.rarity.value == 3)).count() # rep_count = (Card # .select() # .join(Player) # .join(Rarity) # .where(Card.player.rarity.value == 0)).count() # # embed = discord.Embed(title='Current Pull Rates', color=0x800080) # embed.add_field(name='Total Pulls', value=f'{total_count}') # embed.add_field(name='MVPs', value=f'{mvp_count} ({(mvp_count / total_count)*100:.2f}%)\n' # f'Target: 0.33%', inline=False) # embed.add_field(name='All-Stars', value=f'{als_count} ({(als_count / total_count)*100:.2f}%)\n' # f'Target: 2.50%', inline=False) # embed.add_field(name='Starters', value=f'{sta_count} ({(sta_count / total_count)*100:.2f}%)\n' # f'Target: 18.83%', inline=False) # embed.add_field(name='Reserves', value=f'{res_count} ({(res_count / total_count)*100:.2f}%)\n' # f'Target: 45.00%', inline=False) # embed.add_field(name='Replacements', value=f'{rep_count} ({(rep_count / total_count)*100:.2f}%)\n' # f'Target: 33.33%', inline=False) # await ctx.send(content=None, embed=embed) # # db.close() # # @commands.command(name='paperdex', aliases=['collection', 'pokedex'], help='See collection counts') # @commands.has_any_role('Paper Dynasty Players') # async def collection_command(self, ctx, *team_or_league): # if not await legal_channel(ctx): # await ctx.send('Slide on down to my #pd-bot-hole ;)') # return # league = False # team = None # # if team_or_league: # if team_or_league[0].lower() in ['l', 'lg', 'league']: # league = True # else: # team = Team.get_season(team_or_league[0]) # # if not team: # team = Team.get_by_owner(ctx.author.id) # if not team: # await ctx.send(f'I cannot find a team that you manage. Are you registered for Paper Dynasty?') # return # # if league: # thumb = 'https://sombaseball.ddns.net/static/images/sba-logo.png' # title = 'League Paperdex' # elif team.logo: # thumb = team.logo # title = f'{team.lname} Paperdex' # else: # thumb = self.bot.get_user(team.gmid).avatar_url # title = f'{team.lname} Paperdex' # # embed = helpers.get_random_embed(title, thumb) # embed.description = '(Seen / Owned / Total)' # # cardsets = Player.select(Player.cardset).distinct().order_by(-Player.cardset) # overall_total = 0 # overall_owned = 0 # overall_seen = 0 # # for x in cardsets: # total_players = Player.select().where((Player.cardset == x.cardset) & (Player.pos1 != 'Park')).count() # total_parks = Player.select().where((Player.cardset == x.cardset) & (Player.pos1 == 'Park')).count() # # if league: # owned_cards = Card.select().join(Player).distinct() # seen_cards = len(get_pokedex(cardset=x.cardset, is_park=False)) # seen_parks = len(get_pokedex(cardset=x.cardset, is_park=True)) # else: # owned_cards = Card.select().join(Player).where(Card.team == team) # seen_cards = len(get_pokedex(team, cardset=x.cardset, is_park=False)) # seen_parks = len(get_pokedex(team, cardset=x.cardset, is_park=True)) # # owned_players = owned_cards.select(Card.player).where( # (Card.player.cardset == x.cardset) & (Card.player.pos1 != 'Park') # ).distinct().count() # # owned_parks = owned_cards.select(Card.player).where( # (Card.player.cardset == x.cardset) & (Card.player.pos1 == 'Park') # ).distinct().count() # # set_string = f'Players: {seen_cards} / {owned_players} / {total_players}\n' \ # f'Parks: {seen_parks} / {owned_parks} / {total_parks}\n' # ratio = f'{((seen_cards + seen_parks) / (total_players + total_parks)) * 100:.0f}' # field_name = f'{x.cardset} Set ({ratio}%)' # # embed.add_field(name=field_name, value=set_string, inline=False) # overall_total += total_players + total_parks # overall_owned += owned_players + owned_parks # overall_seen += seen_cards + seen_parks # # overall_ratio = (overall_seen / overall_total) * 100 # embed.add_field(name=f'Paper Dynasty Universe ({overall_ratio:.0f}%)', # value=f'{overall_seen} / {overall_owned} / {overall_total}\n', # inline=False) # # await ctx.send(content=None, embed=embed) # # @commands.command(name='gms', aliases=['allgms', 'list'], help='List team/gm info') # @commands.has_any_role('Paper Dynasty Players') # async def gms_command(self, ctx): # if not await legal_channel(ctx): # await ctx.send('Slide on down to my #pd-bot-hole ;)') # return # # all_teams = Team.select_season() # team_list = [] # # for x in all_teams: # team_list.append(x) # team_list.sort(key=lambda y: y.abbrev) # # this_color = discord.Color.random() # all_embeds = [ # discord.Embed(title='All Teams', color=this_color), discord.Embed(title='All Teams', color=this_color), # discord.Embed(title='All Teams', color=this_color), discord.Embed(title='All Teams', color=this_color), # discord.Embed(title='All Teams', color=this_color), discord.Embed(title='All Teams', color=this_color) # ] # team_strings = [ # '', '', '', '', '', '' # ] # # count = 0 # for x in team_list: # index = math.floor(count / 18) # team_strings[index] += f'**{x.abbrev}** - **{x.lname}** - {x.gmname}\n' # count += 1 # # for x in range(math.ceil(len(team_list) / 18)): # all_embeds[x].set_thumbnail(url=self.logo) # all_embeds[x].add_field(name='Abbrev - Name - GM', value=team_strings[x], inline=False) # await ctx.send(content=None, embed=all_embeds[x]) @commands.command(name='c', aliases=['chaos', 'choas'], help='c, chaos, or choas') async def chaos_roll(self, ctx): """ Have the pitcher check for chaos with a runner on base. """ d_twenty = random.randint(1, 20) d_twenty_two = random.randint(1, 20) flag = None if d_twenty == 1: flag = 'wild pitch' elif d_twenty == 2: if random.randint(1, 2) == 1: flag = 'balk' else: flag = 'passed ball' if not flag: roll_message = f'Chaos roll for {ctx.author.name}\n```md\nNo Chaos```' else: roll_message = f'Chaos roll for {ctx.author.name}\n```md\nCheck {flag}```\n'\ f'{flag.title()} roll```md\n# {d_twenty_two}\nDetails: [1d20 ({d_twenty_two})]```' await ctx.send(roll_message) @commands.command(name='sba', hidden=True) async def sba_command(self, ctx, *, player_name): async def get_one_player(id_or_name): req_url = f'http://database/api/v1/players/{id_or_name}' resp = requests.get(req_url, timeout=3) if resp.status_code == 200: return resp.json() else: logger.warning(resp.text) raise ValueError(f'DB: {resp.text}') this_player = await get_one_player(player_name) logger.debug(f'this_player: {this_player}') # @app_commands.command(name='matchup', description='Simulate a matchup between a pitcher and batter') # @app_commands.describe( # pitcher_id='The pitcher\'s player_id', # batter_id='The batter\'s player_id' # ) # async def matchup_command(self, interaction: discord.Interaction, pitcher_id: int, batter_id: int): # await interaction.response.defer() # try: # pit_card = await get_pd_pitchingcard(pitcher_id) # except KeyError as e: # await interaction.edit_original_response( # content=f'I could not find a pitcher card for player_id {pitcher_id}' # ) # return # try: # bat_card = await get_pd_battingcard(batter_id) # except KeyError as e: # await interaction.edit_original_response( # content=f'I could not find a batter card for player_id {batter_id}' # ) # return # this_pitcher = await get_pd_player(pitcher_id) # this_batter = await get_pd_player(batter_id) # # view = helpers.ButtonOptions( # # responders=[interaction.user], timeout=60, # # labels=['Reroll', None, None, None, None] # # ) # await interaction.edit_original_response( # content=None, # embeds=get_pos_embeds(this_pitcher, this_batter, pit_card, bat_card), # # view=view # ) # # await view.wait() # # # # if view.value: # # await question.delete() # # if view.value == 'Tagged Up': # # advance_one_runner(this_play.id, from_base=2, num_bases=1) # # elif view.value == 'Out at 3rd': # # num_outs += 1 # # patch_play(this_play.id, on_second_final=False, outs=num_outs) # # else: # # await question.delete() async def setup(bot): await bot.add_cog(Players(bot))