From 07c0a63d8f28ff2e117bffec29bf25a37cb032af Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Fri, 17 Mar 2023 16:27:56 -0500 Subject: [PATCH] Gauntlet pass 1 Three functional rounds of gauntlet draft --- Dockerfile | 1 - ai_manager.py | 36 +----- cogs/admins.py | 19 ++++ cogs/gameplay.py | 203 ++++++++++++++++++++++++++------- db_calls.py | 2 +- gameplay_helpers.py | 8 ++ gauntlets.py | 271 ++++++++++++++++++++++++++++++++++++++++++++ helpers.py | 102 +++++++++++++++++ 8 files changed, 569 insertions(+), 73 deletions(-) create mode 100644 gauntlets.py diff --git a/Dockerfile b/Dockerfile index d946150..29bb9d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,6 @@ FROM python:3.8-slim WORKDIR /usr/src/app -RUN apt-get update && apt-get install -y git COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt diff --git a/ai_manager.py b/ai_manager.py index 947050b..5ce1cd4 100644 --- a/ai_manager.py +++ b/ai_manager.py @@ -101,6 +101,7 @@ def get_or_create_card(player: dict, team: dict) -> int: ) if card_id is None: logging.error(f'Could not create card for {player["p_name"]} on the {team["lname"]}') + raise DatabaseError(f'Could not create card for {player["p_name"]} on the {team["lname"]}') return card_id @@ -295,23 +296,7 @@ def build_lineup(team_object: dict, game_id: int, league_name: str, vs_hand: str i = 1 for x in [grp_1, grp_2, grp_3]: for y in x: - # get player card; create one if none found - z = 0 - card_id = None - while z < 2 and card_id is None: - z += 1 - c_query = db_get('cards', params=[('team_id', team_object['id']), ('player_id', y[1]['player_id'])]) - if c_query['count'] > 0: - card_id = c_query['cards'][0]['id'] - else: - db_post( - 'cards', - payload={'cards': [ - {'player_id': y[1]['player_id'], 'team_id': team_object['id'], 'pack_id': 1} - ]} - ) - if card_id is None: - logging.error(f'Could not create card for {y[1]["p_name"]} on the {team_object["lname"]}') + card_id = get_or_create_card(y[1], team_object) lineups.append({ 'game_id': game_id, @@ -386,22 +371,7 @@ def get_starting_pitcher(team_object: dict, game_id: int, is_home: bool, league_ starter = pitchers['players'][0] # get player card; create one if none found - z = 0 - card_id = None - while z < 2 and card_id is None: - z += 1 - c_query = db_get('cards', params=[('team_id', team_object['id']), ('player_id', starter['player_id'])]) - if c_query['count'] > 0: - card_id = c_query['cards'][0]['id'] - else: - db_post( - 'cards', - payload={'cards': [ - {'player_id': starter['player_id'], 'team_id': team_object['id'], 'pack_id': 1} - ]} - ) - if card_id is None: - logging.error(f'Could not create card for {starter["p_name"]} on the {team_object["lname"]}') + card_id = get_or_create_card(starter, team_object) return { 'game_id': game_id, diff --git a/cogs/admins.py b/cogs/admins.py index 6c3c5bb..f59490a 100644 --- a/cogs/admins.py +++ b/cogs/admins.py @@ -259,6 +259,25 @@ class Admins(commands.Cog): e_string = "\n- ".join(errors) await ctx.send(f'I encountered the following errors:\n\n{e_string}') + # @app_commands.command(name='tc', description='Mod: Test choice function') + # async def test_choices_command(self, interaction: discord.Interaction): + # await interaction.response.send_message(f'Let\'s test this function!') + # pl = db_get('players/random', params=[ + # ('min_rarity', 5), ('max_rarity', 5), ('limit', 4) + # ]) + # if pl['count']: + # players = pl['players'] + # else: + # raise ConnectionError(f'Could not create MVP pack') + # + # def p_callback(player): + # db_get('players', object_id=player['player_id']) + # + # choice = await get_choice_from_cards( + # interaction, players, callback=p_callback, temp_message='Hello!', conf_message='All done - great choice!' + # ) + # await interaction.edit_original_response(content=f'The choice was: {choice}') + # @commands.command(name='refresh') # @commands.is_owner() # async def import_players(self, ctx): diff --git a/cogs/gameplay.py b/cogs/gameplay.py index e1f3954..e737a66 100644 --- a/cogs/gameplay.py +++ b/cogs/gameplay.py @@ -6,6 +6,7 @@ import os import ai_manager import discord +import gauntlets from discord import app_commands from discord.app_commands import Choice from discord.ext import commands, tasks @@ -359,8 +360,13 @@ class Gameplay(commands.Cog): this_ai = get_manager(game) logging.debug(f'Pitching team is an AI') gm_name = f'{game_state["pitcher"]["team"]["gmname"]}' - n_pitcher = await next_pitcher(game_state['curr_play'], game_state["pitcher"]["team"], self.bot) - logging.debug(f'n_pitcher: {n_pitcher}') + used_pitchers = await get_team_lineups( + game_id=game_state['curr_play'].game.id, + team_id=game_state["pitcher"]["team"]['id'], + inc_inactive=True, + pitchers_only=True, + as_string=False + ) last_inning_ender = get_last_inning_end_play( game.id, @@ -377,23 +383,24 @@ class Gameplay(commands.Cog): elif game_state['curr_play'].is_new_inning and game.short_game and game_state['curr_play'].inning_num != 1: logging.debug(f'{game_state["pitcher"]["team"]["sname"]} going the to pen.') - if 'card_id' in n_pitcher: - replace_pitcher(game_state['pitcher']['team'], game_state['curr_play'], n_pitcher['card_id']) - embed.set_thumbnail(url=n_pitcher['player']['image']) + if len(used_pitchers) < 8: + make_sub(ai_manager.get_relief_pitcher( + game_state['curr_play'], game_state['pitcher']['team'], used_pitchers, game.game_type + )) + new_pitcher = await get_player(game, get_pitcher(game, game_state['curr_play'])) + embed.set_thumbnail(url=new_pitcher['image']) embed.add_field( name=f'SUBSTITUTION', value=f'The {game_state["pitcher"]["team"]["sname"]} have brought in ' - f'{n_pitcher["player"]["p_name"]} to pitch.' + f'{new_pitcher["p_name"]} to pitch.' ) else: ai_note += f'- continue with auto-fatigued {game_state["pitcher"]["p_name"]}\n' else: - if 'card_id' in n_pitcher: - logging.debug(f'{game_state["pitcher"]["team"]["sname"]} are warming up {n_pitcher}.') + if len(used_pitchers) < 8: ai_note += f'- go to the pen if the pitcher fatigues (`/log ai-pitcher-sub`)\n' else: - logging.warning(f'{game_state["pitcher"]["team"]["sname"]} are out of pitchers.') ai_note += f' - continue with {game_state["pitcher"]["p_name"]}\n' logging.debug(f'past the first conditional in AI stuff') @@ -873,32 +880,32 @@ class Gameplay(commands.Cog): if comp_play: complete_play(this_play.id) - @commands.command(name='tl') - @commands.is_owner() - async def test_lineup_command(self, ctx, team_abbrev: str): - t_query = db_get('teams', params=[('abbrev', team_abbrev)]) - if t_query['count'] > 0: - team = t_query['teams'][0] - await ctx.send(f'Pulling a lineup for the {team["lname"]}...') - lineups = ai_manager.build_lineup(team, 69420, 'l', 'minor-league') - l_output = '' - for line in lineups: - l_output += f'{line["batting_order"]} - {line["player_name"]} - {line["position"]}\n' - await ctx.send(f'Lineups:\n\n{l_output}') - else: - await ctx.send(f'No team found with abbrev {team_abbrev}') - - @commands.command(name='tr') - @commands.is_owner() - async def test_reliever_command(self, ctx, game_id: int): - this_game = get_one_game(game_id=game_id) - ai_id = this_game.away_team_id if this_game.ai_team == 'away' else this_game.home_team_id - ai_team = db_get('teams', object_id=ai_id) - used_pitchers = await get_team_lineups( - game_id=game_id, team_id=ai_team['id'], inc_inactive=True, pitchers_only=True, as_string=False - ) - reliever = ai_manager.get_relief_pitcher(get_current_play(game_id), ai_team, used_pitchers) - await ctx.send(f'Reliever selected:\n\n{reliever}') + # @commands.command(name='tl') + # @commands.is_owner() + # async def test_lineup_command(self, ctx, team_abbrev: str): + # t_query = db_get('teams', params=[('abbrev', team_abbrev)]) + # if t_query['count'] > 0: + # team = t_query['teams'][0] + # await ctx.send(f'Pulling a lineup for the {team["lname"]}...') + # lineups = ai_manager.build_lineup(team, 69420, 'l', 'minor-league') + # l_output = '' + # for line in lineups: + # l_output += f'{line["batting_order"]} - {line["player_name"]} - {line["position"]}\n' + # await ctx.send(f'Lineups:\n\n{l_output}') + # else: + # await ctx.send(f'No team found with abbrev {team_abbrev}') + # + # @commands.command(name='tr') + # @commands.is_owner() + # async def test_reliever_command(self, ctx, game_id: int): + # this_game = get_one_game(game_id=game_id) + # ai_id = this_game.away_team_id if this_game.ai_team == 'away' else this_game.home_team_id + # ai_team = db_get('teams', object_id=ai_id) + # used_pitchers = await get_team_lineups( + # game_id=game_id, team_id=ai_team['id'], inc_inactive=True, pitchers_only=True, as_string=False + # ) + # reliever = ai_manager.get_relief_pitcher(get_current_play(game_id), ai_team, used_pitchers) + # await ctx.send(f'Reliever selected:\n\n{reliever}') group_new_game = app_commands.Group(name='new-game', description='Start a new baseball game') @@ -1337,12 +1344,38 @@ class Gameplay(commands.Cog): except Exception as e: logging.error(f'Could not check channel category: {e}') - team = get_team_by_owner(interaction.user.id) - if not team: + current = db_get('current') + week_num = current['week'] + + e_query = db_get('events', params=[("name", event_name), ("active", True)]) + if e_query['count'] == 0: + await interaction.edit_original_response( + content=f'It looks like the {event_name} has ended! Cal should really remove it from this list.' + ) + return + this_event = e_query['events'][0] + + main_team = get_team_by_owner(interaction.user.id) + team = get_team_by_abbrev(f'Gauntlet-{main_team["abbrev"]}') + if not main_team: await interaction.edit_original_response( content=f'I don\'t see a team for you, yet. You can sign up with the `/newteam` command!' ) return + if not team: + try: + await gauntlets.run_draft(interaction, main_team, this_event) + except Exception as e: + logging.error(f'Failed to run {event_name} draft for the {main_team["sname"]}: {e}') + draft_team = db_get('teams', params=[('abbrev', f'Gauntlet-{main_team["abbrev"]}')]) + for x in draft_team['teams']: + db_delete('teams', object_id=x['id']) + 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 conflict = count_team_games(team['id']) if conflict['count']: @@ -1353,8 +1386,102 @@ class Gameplay(commands.Cog): return # Get or create Gauntlet run - # If a new run, perform draft + r_query = db_get( + 'gauntletruns', + params=[('team_id', team['id']), ('gauntled_id', this_event['id']), ('is_active', True)] + ) + + # If a new run, run draft and return; make sure player has time for a game after draft by running /new-game + if r_query['count'] == 0: + raise KeyError(f'I found your Gauntlet team, but no run data') + else: + this_run = r_query['runs'][0] + # If not new or after draft, create new AI game + is_home = gauntlets.is_home_team(team, this_event, this_run) + opponent = gauntlets.get_opponent(team, this_event, this_run) + if opponent is None: + await interaction.edit_original_response( + content=f'Yike. I\'m not sure who your next opponent is. {get_cal_user(interaction)} help plz!' + ) + return + + game_code = gauntlets.get_game_code(team, this_event, this_run) + this_game = post_game({ + 'away_team_id': opponent['id'] if is_home else team['id'], + 'home_team_id': team['id'] if is_home else opponent['id'], + 'week_num': week_num, + 'channel_id': interaction.channel.id, + 'active': True, + 'is_pd': True, + 'ranked': False, + 'season': current['season'], + 'short_game': False, + 'game_type': game_code + }) + logging.info( + f'Game {this_game.id} between {team["abbrev"]} and {opponent["abbrev"]} is posted!' + ) + t_role = await team_role(interaction, main_team) + + # Get AI Lineup + try: + await interaction.edit_original_response( + content=f'I am getting a lineup card from the {opponent["sname"]}...' + ) + + logging.info(f'new-game - calling lineup for {opponent["abbrev"]}') + all_lineups = gauntlets.build_lineup(opponent, this_game, this_event) + logging.info(f'new-game-gauntlet - got lineup for {opponent["abbrev"]}') + + except Exception as e: + patch_game(this_game.id, active=False) + logging.error(f'could not start a gauntlet game with {opponent["sname"]}: {e}') + await interaction.edit_original_response( + content=f'Looks like the {opponent["sname"]} lineup card didn\'t come through clearly. I\'ll sort ' + f'this out with {opponent["gmname"]} and {get_cal_user(interaction).mention}. I\'ll end ' + f'this game - why don\'t you play against somebody else for now?' + ) + return + + # Get AI Starting Pitcher + try: + await interaction.edit_original_response( + content=f'Now to decide on a Starting Pitcher...' + ) + if opponent['id'] == this_game.away_team_id: + patch_game(this_game.id, away_roster_num=69, ai_team='away') + else: + patch_game(this_game.id, home_roster_num=69, ai_team='home') + + starter = gauntlets.get_starting_pitcher(opponent, this_game, this_event) + all_lineups.append(starter) + + this_card = db_get(f'cards', object_id=starter['card_id']) + await interaction.channel.send( + content=f'The {opponent["sname"]} are starting **{this_card["player"]["description"]}**:\n\n' + f'{this_card["player"]["image"]}' + ) + + except Exception as e: + patch_game(this_game.id, active=False) + logging.error(f'could not start an AI game with {opponent["sname"]}: {e}') + await interaction.edit_original_response( + content=f'Looks like the {opponent["sname"]} rotation didn\'t come through clearly. I\'ll sort ' + f'this out with {opponent["gmname"]} and {get_cal_user(interaction).mention}. I\'ll end ' + f'this game - why don\'t you play against somebody else for now?' + ) + return + + logging.debug(f'Setting lineup for {opponent["sname"]} in PD Gauntlet game {game_code}') + post_lineups(all_lineups) + + await interaction.channel.send( + content=f'Game {gauntlets.games_played(this_run) + 1} of the run is set!\n\n' + f'Go ahead and set lineups with the `/readlineup` command!', + embed=await self.get_game_state_embed(this_game, full_length=False) + ) + return @commands.command(name='force-endgame', help='Mod: Force a game to end without stats') @commands.is_owner() diff --git a/db_calls.py b/db_calls.py index a7cf961..fc3c34c 100644 --- a/db_calls.py +++ b/db_calls.py @@ -115,7 +115,7 @@ def db_post(endpoint: str, api_ver: int = 1, payload: dict = None, timeout: int raise ValueError(f'DB: {resp.text}') -def db_delete(endpoint: str, object_id: int, api_ver: int = 3): +def db_delete(endpoint: str, object_id: int, api_ver: int = 1): req_url = get_req_url(endpoint, api_ver=api_ver, object_id=object_id) log_string = f'delete:\n{endpoint} {object_id}' logging.info(log_string) if master_debug else logging.debug(log_string) diff --git a/gameplay_helpers.py b/gameplay_helpers.py index 787eb2c..ddbfa55 100644 --- a/gameplay_helpers.py +++ b/gameplay_helpers.py @@ -1,6 +1,7 @@ import logging import random +import db_calls_gameplay from db_calls_gameplay import StratGame, StratPlay, StratLineup, StratManagerAi, patch_play, advance_runners, \ complete_play, get_team_lineups, get_or_create_bullpen, get_player, get_sheets, make_sub from db_calls import db_get @@ -155,3 +156,10 @@ def replace_pitcher(ai_team, this_play, pitcher_card_id): } make_sub(new_lineup) + +def get_pitcher(this_game: StratGame, this_play: StratPlay): + p_team_id = this_game.away_team_id + if this_play.inning_half == 'top': + p_team_id = this_game.home_team_id + return db_calls_gameplay.get_one_lineup(this_game.id, team_id=p_team_id, position='P', active=True) + diff --git a/gauntlets.py b/gauntlets.py new file mode 100644 index 0000000..b30ff59 --- /dev/null +++ b/gauntlets.py @@ -0,0 +1,271 @@ +import copy +import datetime +import logging + +import discord +import requests +from peewee import DatabaseError + +import ai_manager +import helpers +from helpers import RARITY +from db_calls import db_get, db_post + + +def get_game_code(this_team, this_event, this_run): + return f'gauntlet-{this_event["id"]}-run-{this_run["id"]}-game-{games_played(this_run) + 1}' + + +def games_played(this_run): + return this_run['wins'] + this_run['losses'] + + +def is_home_team(this_team, this_event, this_run): + if this_event['id'] == 1: + return True + return False + + +def get_opponent(this_team, this_event, this_run): + if this_event['id'] == 1: + gp = games_played(this_run) + if gp == 1: + return db_get('teams', object_id=3, none_okay=False) + else: + return db_get('teams', object_id=19, none_okay=False) + else: + return None + + +def build_lineup(this_team, this_game, this_event): + if this_event['id'] == 1: + return ai_manager.build_lineup(this_team, this_game.id, f'gauntlet-{this_event["id"]}') + else: + raise KeyError(f'Lineups not found for Gauntlet {this_event["id"]}') + + +def get_starting_pitcher(this_team, this_game, this_event): + if this_event['id'] == 1: + set_params = ai_manager.MINOR_CARDSET_PARAMS + params = [ + ('mlbclub', this_team['lname']), ('pos_include', 'SP'), ('pos_exclude', 'RP'), + ('inc_dex', False), ('sort_by', 'cost-desc'), ('limit', 5) + ] + params.extend(set_params) + else: + raise KeyError(f'Pitcher not found for Gauntlet {this_event["id"]}') + + # Pull pitchers + try: + pitchers = db_get( + endpoint='players', + params=params, + timeout=10 + ) + except ConnectionError as e: + logging.error(f'Could not get pitchers for {this_team["lname"]}: {e}') + raise ConnectionError(f'Error pulling starting pitchers for the {this_team["lname"]}. Cal help plz.') + + if pitchers['count'] == 0: + raise DatabaseError(f'Could not find any SP for {this_team["abbrev"]}. Seems like a Cal issue.') + card_id = ai_manager.get_or_create_card(pitchers['players'][0], this_team) + + return { + 'game_id': this_game.id, + 'team_id': this_team['id'], + 'player_id': pitchers['players'][0]['player_id'], + 'card_id': card_id, + 'position': 'P', + 'batting_order': 10, + 'after_play': 0 + } + + +async def run_draft(interaction: discord.Interaction, main_team, this_event): + if this_event['id'] == 1: + draft_embed = helpers.get_team_embed(f'{this_event["name"]}') + draft_embed.description = f'{main_team["lname"]} - Team Draft - Round 1' + base_params = ai_manager.MAJOR_CARDSET_PARAMS + base_params.append(('limit', 8)) + else: + logging.error(f'run_draft - Event ID {this_event["id"]} not recognized') + raise KeyError(f'Draft data not found for Gauntlet {this_event["id"]}') + + # Post draft team linked to main team + draft_team = db_post( + 'teams', + payload={ + 'abbrev': f'Gauntlet-{main_team["abbrev"]}', + 'sname': main_team['sname'], + 'lname': main_team['lname'], + 'gmid': main_team['gmid'], + 'gmname': main_team['gmname'], + 'gsheet': 'NONE', + 'logo': main_team['logo'] if main_team['logo'] else None, + 'color': main_team['color'] if main_team['color'] else None, + 'season': main_team['season'], + 'has_guide': main_team['has_guide'] + } + ) + + all_players = [] + p_names = [] + counts = { + 'SP': 0, + 'RP': 0, + 'CP': 0, + 'C': 0, + '1B': 0, + '2B': 0, + '3B': 0, + 'SS': 0, + 'LF': 0, + 'CF': 0, + 'RF': 0, + 'DH': 0, + 'MVP': 0, + 'All-Star': 0, + 'Starter': 0, + 'Reserve': 0, + 'Replacement': 0, + } + round_num = 1 + counter = 1 + + if this_event['id'] == 1: + while round_num <= 3 and counter < 50: + counter += 1 + + await interaction.edit_original_response( + content=f'**Round {round_num}**\n\n__Draft Picks__\n{p_names}' + ) + # Set params based on current round + params = copy.deepcopy(base_params) + if round_num == 1: + params.extend([ + ('min_rarity', RARITY['MVP']), ('max_rarity', RARITY['MVP']), ('pos_exc', 'RP') + ]) + elif round_num == 2: + params.extend([ + ('min_rarity', RARITY['All-Star']), ('max_rarity', RARITY['All-Star']) + ]) + elif round_num <= 5: + params.extend([ + ('min_rarity', RARITY['Starter']), ('max_rarity', RARITY['Starter']) + ]) + elif round_num <= 10: + params.extend([ + ('min_rarity', RARITY['Reserve']), ('max_rarity', RARITY['Reserve']) + ]) + elif round_num == 11: + params.extend([ + ('min_rarity', RARITY['All-Star']), ('max_rarity', RARITY['All-Star']) + ]) + elif round_num == 12: + params.extend([ + ('min_rarity', RARITY['Starter']), ('max_rarity', RARITY['Starter']) + ]) + elif round_num <= 15: + params.extend([ + ('min_rarity', RARITY['Replacement']), ('max_rarity', RARITY['Replacement']) + ]) + elif round_num <= 18: + params.extend([ + ('min_rarity', RARITY['Starter']), ('max_rarity', RARITY['Starter']) + ]) + elif round_num == 19: + params.extend([ + ('min_rarity', RARITY['All-Star']), ('max_rarity', RARITY['All-Star']) + ]) + elif round_num <= 21: + params.extend([ + ('min_rarity', RARITY['Starter']), ('max_rarity', RARITY['Starter']) + ]) + elif round_num <= 24: + params.extend([ + ('min_rarity', RARITY['Reserve']), ('max_rarity', RARITY['Reserve']) + ]) + elif round_num <= 26: + params.extend([ + ('min_rarity', RARITY['Replacement']), ('max_rarity', RARITY['Replacement']) + ]) + + # Any positional adjustments can be added as params here + for x in ['C', '1B', '2B', '3B', 'SS', 'LF', 'CF', 'RF']: + if counts[x] > 2: + logging.info(f'run_draft pos_check - {x} count up to {counts[x]}') + if 0 in [counts['C'], counts['1B'], counts['2B'], counts['3B'], counts['SS'], counts['LF'], + counts['CF'], counts['RF']]: + logging.info(f'0 exists in other positions; excluding {x}') + params.append(('pos_exc', x)) + + if counts['RP'] > 8: + params.append(('pos_exc', 'RP')) + if counts['SP'] > 6: + params.append(('pos_exc', 'SP')) + if counts['RP'] > counts['SP'] + 3: + params.append(('pos_exc', 'RP')) + if counts['SP'] > counts['RP'] + 3: + params.append(('pos_exc', 'RP')) + + # Call /players/random to get eight cards + p_query = None + try: + p_query = db_get('players/random', params=params) + except requests.ReadTimeout as e: + logging.error(f'run_draft - timeout error pulling player with params {params}') + + if p_query is not None: + test_player_list = '' + for x in p_query['players']: + test_player_list += f'{x["rarity"]["name"]} - {x["description"]} - {helpers.get_all_pos(x)}\n' + await interaction.channel.send(f'The Round {round_num} players drawn are:\n\n{test_player_list}') + + # Collect 4 cards with no repeat player names + this_batch = [] + for x in p_query['players']: + if x['p_name'] not in p_names: + this_batch.append(x) + if len(this_batch) == 4: + break + + # Present choices and capture selection + p_choice = await helpers.get_choice_from_cards(interaction, this_batch) + + # Add player to list and update counts + p_names.append(p_choice['p_name']) + all_players.append(p_choice) + for x in helpers.get_all_pos(p_choice): + if x in counts: + counts[x] += 1 + + # Update roster embed + round_num += 1 + else: + logging.error(f'run_draft - No draft logic for Event ID {this_event["id"]}') + raise KeyError(f'Draft data not found for Gauntlet {this_event["id"]}') + + raise EnvironmentError(f'End test run') + + # Create team google sheet + this_pack = db_post( + 'packs/one', + payload={ + 'team_id': draft_team['id'], + 'pack_type_id': 2, + 'open_time': datetime.datetime.timestamp(datetime.datetime.now()) * 1000 + } + ) + db_post( + 'cards', + payload={'cards': [ + {'player_id': x['player_id'], 'team_id': draft_team['id'], 'pack_id': this_pack['id']} for x in all_players + ]} + ) + db_post( + 'gauntletruns', + payload={ + 'team_id': draft_team['id'], + 'gauntlet_id': this_event['id'] + } + ) diff --git a/helpers.py b/helpers.py index f947aab..dd84519 100644 --- a/helpers.py +++ b/helpers.py @@ -214,6 +214,14 @@ OUTFIELD_X_CHART = { 'no': 'Flyball C' } } +RARITY = { + 'HoF': 8, + 'MVP': 5, + 'All-Star': 3, + 'Starter': 2, + 'Reserve': 1, + 'Replacement': 0 +} class Question: @@ -2563,6 +2571,100 @@ async def open_st_pr_packs(all_packs: list, team: dict, context): await display_cards(all_cards, team, pack_channel, author, pack_cover=pack_cover) +async def get_choice_from_cards( + interaction: discord.Interaction, all_players: list = None, cover_title: str = None, + cover_desc: str = None, cover_image_url: str = None, callback=None, temp_message: str = None, + conf_message: str = None): + # Display them with pagination, prev/next/select + card_embeds = [ + await get_card_embeds( + {'player': x, 'team': {'lname': 'Paper Dynasty', 'season': PD_SEASON, 'logo': IMAGES['logo']}} + ) for x in all_players + ] + logging.info(f'card embeds: {card_embeds}') + + if cover_title is not None and cover_image_url is not None: + page_num = 0 + + view = Pagination([interaction.user], timeout=30) + view.left_button.disabled = True + view.left_button.label = f'Prev: -/{len(card_embeds)}' + view.cancel_button.label = f'Take This Card' + view.cancel_button.style = discord.ButtonStyle.success + view.cancel_button.disabled = True + view.right_button.label = f'Next: 1/{len(card_embeds)}' + + msg = await interaction.channel.send( + content=None, + embed=image_embed( + image_url=cover_image_url, + title=cover_title, + desc=cover_desc + ), + view=view + ) + else: + page_num = 1 + + view = Pagination([interaction.user], timeout=30) + view.left_button.label = f'Prev: -/{len(card_embeds)}' + view.left_button.disabled = True + view.cancel_button.label = f'Take This Card' + view.cancel_button.style = discord.ButtonStyle.success + view.right_button.label = f'Next: {page_num + 1}/{len(card_embeds)}' + + msg = await interaction.channel.send(content=None, embeds=card_embeds[page_num - 1], view=view) + + if temp_message is not None: + temp_msg = await interaction.channel.send(content=temp_message) + else: + temp_msg = None + + while True: + await view.wait() + + if view.value: + if view.value == 'cancel': + await msg.edit(view=None) + + if callback is not None: + callback(all_players[page_num - 1]) + + if conf_message is not None: + if temp_msg is not None: + await temp_msg.edit(content=conf_message) + else: + await interaction.channel.send(content=conf_message) + break + if view.value == 'left': + page_num -= 1 if page_num > 1 else len(card_embeds) + if view.value == 'right': + page_num += 1 if page_num < len(card_embeds) else 1 + else: + if page_num == len(card_embeds): + page_num = 1 + else: + page_num += 1 + + view.value = None + + view = Pagination([interaction.user], timeout=30) + view.left_button.label = f'Prev: {page_num - 1}/{len(card_embeds)}' + view.cancel_button.label = f'Take This Card' + view.cancel_button.style = discord.ButtonStyle.success + view.right_button.label = f'Next: {page_num + 1}/{len(card_embeds)}' + if page_num == 1: + view.left_button.label = f'Prev: -/{len(card_embeds)}' + view.left_button.disabled = True + elif page_num == len(card_embeds): + view.right_button.label = f'Next: -/{len(card_embeds)}' + view.right_button.disabled = True + + await msg.edit(content=None, embeds=card_embeds[page_num - 1], view=view) + + return all_players[page_num - 1] + + async def open_choice_pack(this_pack, team: dict, context): pack_channel = get_channel(context, 'pack-openings') pack_cover = get_pack_cover(this_pack)