From c7d4824ee0c677846e1ce087be68ae37d23ea794 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Thu, 23 Mar 2023 11:30:26 -0500 Subject: [PATCH] Gauntlet creation automated; run display functional --- cogs/admins.py | 136 +++++++++++++++++++++++++++++++++------------ cogs/gameplay.py | 28 ++++++++-- cogs/players.py | 34 ++++++++++++ gauntlets.py | 142 ++++++++++++++++++++++++++++++++++------------- 4 files changed, 261 insertions(+), 79 deletions(-) diff --git a/cogs/admins.py b/cogs/admins.py index 7f2ca0b..f19a76c 100644 --- a/cogs/admins.py +++ b/cogs/admins.py @@ -34,42 +34,108 @@ class Admins(commands.Cog): async def cog_command_error(self, ctx, error): await ctx.send(f'{error}') - # @tasks.loop(minutes=10) - # async def weekly_loop(self): - # now = datetime.datetime.now() - # if now.hour == 6 and now.weekday() == 0 and not self.weekly_reset_done: - # weekly_packs = await self.increment_week() - # self.weekly_reset_done = True - # - # sba = self.bot.get_guild(613880856032968834) - # news_ticker = discord.utils.get(sba.text_channels, name='pd-news-ticker') - # await news_ticker.send('The new week is here! Run `.comeonmanineedthis` for your weekly pack!\n\n' - # 'Cal will hand out packs for the final standings when he wakes his lazy ass up. ') - # - # cal_private = discord.utils.get(sba.text_channels, name='hello-manticorum67') - # await cal_private.send(f'Weekly packs:\n\n{weekly_packs}') - # - # if now.weekday() != 0 and self.weekly_reset_done: - # self.weekly_reset_done = False - # - # db.close() + async def dev_startup(self): + # Check for Paper Sluggers event + e_query = db_get('events', params=[('name', 'Paper Sluggers')]) + if e_query is None: + this_event = db_post( + 'events', + payload={ + "name": "Paper Sluggers", + "short_desc": f'Draft a team to win you ten games as we celebrate the introduction of the ' + f'Mario Super Sluggers cardset to Paper Dynasty!', + "long_desc": "", + "url": f'https://cdn.discordapp.com/attachments/603421569972305921/1087862987215347805/' + f'PD-Mario-Full.png', + "active": True + } + ) + else: + this_event = e_query['events'][0] - # @staticmethod - # async def increment_week(): - # current = Current.get() - # current.week += 1 - # current.save() - # - # weekly_string = '' - # all_teams = Team.select() - # for x in all_teams: - # weekly_string += f'{x.sname}: {x.weeklypacks} packs\n' - # x.weeklyclaim = False - # x.dailyclaim = False - # x.weeklypacks = 0 - # x.save() - # - # return weekly_string + # Check for Game Rewards + gr_query = db_get('gamerewards', params=[('name', 'MVP Pack')]) + if gr_query['count'] == 0: + mv_pack = db_post( + 'gamerewards', + payload={ + 'name': 'MVP', + 'pack_type_id': 5 + } + ) + else: + mv_pack = gr_query['gamerewards'][0] + + gr_query = db_get('gamerewards', params=[('name', 'All-Star Pack')]) + if gr_query['count'] == 0: + as_pack = db_post( + 'gamerewards', + payload={ + 'name': 'All-Star Pack', + 'pack_type_id': 6 + } + ) + else: + as_pack = gr_query['gamerewards'][0] + + gr_query = db_get('gamerewards', params=[('name', 'Mario Pack')]) + if gr_query['count'] == 0: + m_pack = db_post( + 'gamerewards', + payload={ + 'name': 'Mario Pack', + 'pack_type_id': 7 + } + ) + else: + m_pack = gr_query['gamerewards'][0] + + # Check for Gauntlet rewards + gr_query = db_get('gauntletrewards', params=[('gauntlet_id', this_event['id'])]) + if gr_query['count'] == 0: + db_post( + 'gauntletrewards', + payload={ + 'rewards': [ + { + 'name': '3 Wins', + 'gauntlet_id': this_event['id'], + 'reward_id': m_pack['id'], + 'win_num': 3 + }, + { + 'name': '6 Wins', + 'gauntlet_id': this_event['id'], + 'reward_id': as_pack['id'], + 'win_num': 6 + }, + { + 'name': '8 Wins', + 'gauntlet_id': this_event['id'], + 'reward_id': m_pack['id'], + 'win_num': 8 + }, + { + 'name': '10 Wins', + 'gauntlet_id': this_event['id'], + 'reward_id': mv_pack['id'], + 'win_num': 10 + }, + { + 'name': '10-0', + 'gauntlet_id': this_event['id'], + 'reward_id': m_pack['id'], + 'win_num': 10, + 'loss_max': 0 + } + ] + } + ) + + @commands.command(name='dev_startup', help='Run startup function') + async def dev_startup_command(self, ctx): + await self.dev_startup() + await ctx.send(random_conf_gif()) group_give = app_commands.Group(name='give', description='Mod: Distribute packs or tokens') diff --git a/cogs/gameplay.py b/cogs/gameplay.py index f0b5574..716476c 100644 --- a/cogs/gameplay.py +++ b/cogs/gameplay.py @@ -1325,7 +1325,7 @@ class Gameplay(commands.Cog): @group_new_game.command(name='gauntlet', description='Start a new Gauntlet game against an AI') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) - async def new_game_gauntlet_command(self, interaction: discord.Interaction, event_name: Literal['Test Gauntlet']): + async def new_game_gauntlet_command(self, interaction: discord.Interaction, event_name: Literal['Paper Sluggers']): await interaction.response.defer() conflict = get_one_game(channel_id=interaction.channel.id, active=True) @@ -1369,7 +1369,7 @@ class Gameplay(commands.Cog): 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"]}')]) - await gauntlets.wipe_team(draft_team, interaction) + await gauntlets.wipe_team(draft_team, interaction, delete_runs=True) 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 ' @@ -1400,9 +1400,26 @@ class Gameplay(commands.Cog): ) if r_query['count'] == 0: - raise KeyError(f'I found your Gauntlet team, but no run data') - else: - this_run = r_query['runs'][0] + try: + await gauntlets.run_draft(interaction, main_team, this_event, draft_team=team) + except Exception as e: + logging.error(f'Failed to run {event_name} draft for the {team["sname"]}: {e}') + await gauntlets.wipe_team(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 + + await interaction.channel.send( + f'Good luck, champ in the making! To start playing, follow these steps:\n\n' + f'1) Update your Gauntlet lineups here: {team["gsheet"]}`\n' + f'2) Go play your first game with `/new-game gauntlet {this_event["name"]}`' + ) + return + + 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) @@ -1906,6 +1923,7 @@ class Gameplay(commands.Cog): db_post(f'teams/{winning_team["id"]}/money/{win_reward["money"]}') db_post(f'teams/{losing_team["id"]}/money/{loss_reward["money"]}') + # Gauntlet results and reward if gauntlet_team is not None: await gauntlets.post_result( int(this_game.game_type.split('-')[3]), diff --git a/cogs/players.py b/cogs/players.py index bb8206c..e372026 100644 --- a/cogs/players.py +++ b/cogs/players.py @@ -14,6 +14,8 @@ from discord.ext import commands, tasks from difflib import get_close_matches from discord.ext.commands import Greedy + +import gauntlets from db_calls import db_get, db_post, db_patch from helpers import 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, \ @@ -727,6 +729,38 @@ class Players(commands.Cog): await ctx.send(random_conf_gif()) + @app_commands.command(name='gauntlet-run', description='View status of current Gauntlet run') + @app_commands.checks.has_any_role(PD_PLAYERS_ROLE_NAME) + async def gauntlet_run_command(self, interaction: discord.Interaction, team_abbrev: str = None): + if team_abbrev: + if 'Gauntlet-' not in team_abbrev: + team_abbrev = f'Gauntlet-{team_abbrev}' + t_query = db_get('teams', params=[('abbrev', team_abbrev)]) + else: + ot_query = db_get('teams', params=[('gm_id', interaction.user.id)]) + team_abbrev = ot_query['teams'][0]['abbrev'] + t_query = db_get('teams', params=[('abbrev', f'Gauntlet-{team_abbrev}')]) + + if t_query['count'] == 0: + await interaction.response.send_message( + f'Hmm...I see any gauntlet teams for {team_abbrev}.', + ephemeral=True + ) + return + + team = t_query['teams'][0] + + await interaction.response.defer() + r_query = db_get('gauntletruns', params=[('team_id', team['id']), ('is_active', True)]) + if r_query['count'] > 0: + this_run = r_query['runs'][0] + await interaction.edit_original_response( + content=None, + embed=gauntlets.get_embed(this_run) + ) + else: + await interaction.edit_original_response(content=f'I do not see any Gauntlet runs for the {team["lname"]}.') + # @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): diff --git a/gauntlets.py b/gauntlets.py index f2653cd..6021736 100644 --- a/gauntlets.py +++ b/gauntlets.py @@ -12,7 +12,7 @@ from helpers import RARITY, get_cal_user, get_or_create_role, send_to_channel, g from db_calls import db_get, db_post, db_delete, db_patch -async def wipe_team(this_team, interaction: discord.Interaction, delete_team: bool = False): +async def wipe_team(this_team, interaction: discord.Interaction, delete_team: bool = False, delete_runs: bool = False): await interaction.edit_original_response(content=f'Looking for cards...') # Delete cards c_query = db_get('cards', params=[('team_id', this_team['id'])]) @@ -33,10 +33,11 @@ async def wipe_team(this_team, interaction: discord.Interaction, delete_team: bo db_delete('teams', object_id=this_team['id']) await interaction.edit_original_response(content=f'Team is deleted; now finding the run...') - r_query = db_get('gauntletruns', params=[('team_id', this_team['id']), ('is_active', True)]) - await interaction.edit_original_response(content=f'Found {r_query["count"]} runs; deleting now...') - for x in r_query['runs']: - db_delete('gauntletruns', object_id=x['id']) + if delete_runs: + r_query = db_get('gauntletruns', params=[('team_id', this_team['id']), ('is_active', True)]) + await interaction.edit_original_response(content=f'Found {r_query["count"]} runs; deleting now...') + for x in r_query['runs']: + db_delete('gauntletruns', object_id=x['id']) def get_game_code(this_team, this_event, this_run): @@ -130,7 +131,7 @@ def get_starting_pitcher(this_team, this_game, this_event, this_run): } -async def run_draft(interaction: discord.Interaction, main_team, this_event): +async def run_draft(interaction: discord.Interaction, main_team, this_event, draft_team=None): if this_event['id'] == 1: embed_title = f'{main_team["lname"]} - {this_event["name"]} Draft' embed_description = f'{this_event["name"]}' @@ -140,22 +141,23 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event): 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'] - } - ) + if draft_team is None: + # 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 = [] @@ -181,7 +183,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event): round_num = 1 counter = 1 - def get_embeds(): + def get_embeds(include_links=True): top_embed = helpers.get_team_embed(f'{embed_title} - Round {round_num}') top_embed.description = f'Rarity Counts' bot_embed = helpers.get_team_embed(f'{embed_title} - Round {round_num}') @@ -207,9 +209,13 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event): } for y in all_players: - all_str[y['rarity']['name']] += f'[{y["description"]}]({y["image"]})\n' + if include_links: + name_string = f'[{y["description"]}]({y["image"]})' + else: + name_string = f'{y["description"]}' + all_str[y['rarity']['name']] += f'{name_string}\n' for z in helpers.get_all_pos(y): - all_str[z] += f'[{y["description"]}]({y["image"]})\n' + all_str[z] += f'{name_string}\n' top_embed.add_field(name=f'MVPs ({counts["MVP"]}/1)', value=all_str['MVP'], inline=False) top_embed.add_field(name=f'All-Stars ({counts["All-Star"]}/3)', value=all_str['All-Star'], inline=False) @@ -305,14 +311,19 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event): if round_num > 20 and counts[x] < 2: params.append(('pos_inc', x)) - if counts['RP'] > 8: + if counts['RP'] > 7: params.append(('pos_exc', 'RP')) - if counts['SP'] > 6: + if counts['SP'] > 5: 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')) + if round_num > 20: + if counts['SP'] < 5: + params.append(('pos_inc', 'SP')) + if counts['RP'] < 5: + params.append(('pos_inc', 'RP')) # Call /players/random to get eight cards p_query = None @@ -349,7 +360,7 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event): # Update roster embed await interaction.edit_original_response( content=None, - embeds=get_embeds() + embeds=get_embeds(include_links=False) ) round_num += 1 else: @@ -373,46 +384,99 @@ async def run_draft(interaction: discord.Interaction, main_team, this_event): db_post( 'gauntletruns', payload={ - 'team_id': main_team['id'], + 'team_id': draft_team['id'], 'gauntlet_id': this_event['id'] } ) +def get_embed(this_run): + embed = helpers.image_embed( + image_url=this_run['gauntlet']['url'], + title=f'{this_run["gauntlet"]["name"]}', + desc=f'{this_run["team"]["lname"]}' + ) + if this_run['team']['logo']: + embed.set_thumbnail(url=this_run['team']['logo']) + else: + embed.set_thumbnail(url=helpers.IMAGES['logo']) + + embed.add_field(name='Event Info', value=this_run['gauntlet']['short_desc'], inline=False) + embed.add_field(name='Record', value=f'{this_run["wins"]}-{this_run["losses"]}', inline=False) + + # TODO: make sure 10-0 is last (maybe sort by strings?); add an x for 10-0 reward if there is a loss + r_query = db_get('gauntletrewards', params=[('gauntlet_id', this_run['gauntlet']['id'])]) + reward_string = '' + for x in r_query['rewards']: + reward_string += f'{x["win_num"]}{"-0" if x["loss_max"] == 0 else " Wins"}: ' + reward_string += '☑ ' if this_run['wins'] >= x['win_num'] else '⬜ ' + if x['reward']['money']: + reward_string += f' {x["reward"]["money"]}₼\n' + elif x['reward']['player']: + reward_string += f' {x["reward"]["player"]["description"]}\n' + elif x['reward']['pack_type']: + reward_string += f' {x["reward"]["pack_type"]["name"]} Pack\n' + if len(reward_string) > 0: + embed.add_field(name='Rewards', value=reward_string, inline=False) + + return embed + + async def post_result(run_id: int, is_win: bool, this_team, bot, ctx): this_run = db_get('gauntletruns', object_id=run_id) this_event = db_get('events', object_id=this_run['gauntlet']['id']) if is_win: - db_patch( + this_run = db_patch( 'gauntletruns', object_id=this_run['id'], params=[('wins', this_run['wins'] + 1), ('ended', this_run['wins'] + 1 == 10)] ) + r_query = db_get( + 'gauntletrewards', + params=[('gauntlet_id', this_event['id']), ('wins', this_run['wins']), ('loss_max', this_run['losses'])] + ) + reward_string = '' + for x in r_query['rewards']: + if x['reward']['money']: + db_post(f'teams/{this_team["id"]}/money/{x["reward"]["money"]}') + reward_string += f'- {x["reward"]["money"]}₼\n' + elif x['reward']['player']: + # TODO: add give player code + pass + elif x['reward']['pack_type']: + helpers.give_packs(this_team, 1, x['reward']['pack_type']) + reward_string += f'- 1x {x["reward"]["pack_type"]["name"]} Pack' - if this_run['wins'] + 1 == 10: + if this_run['wins'] == 10: choas_role = await get_or_create_role(ctx, "CHOAS ALERT", mentionable=True) await send_to_channel( bot, 'pd-network-news', content=f'{choas_role.mention}\n\nThe **{this_team["lname"]}** have completed the ' - f'**{this_event["name"]} Gauntlet** with a record of {this_run["wins"] + 1}-' + f'**{this_event["name"]} Gauntlet** with a record of {this_run["wins"]}-' f'{this_run["losses"]}!' ) else: - await ctx.send(f'Big win there! Your {this_event["name"]} record is now ' - f'**{this_run["wins"] + 1}-{this_run["losses"]}**. Go share the highlights in ' - f'{get_channel(ctx, "pd-news-ticker").mention}!') + await ctx.send( + content=f'Big win there! Your {this_event["name"]} record is now **{this_run["wins"]}-' + f'{this_run["losses"]}**. Go share the highlights in ' + f'{get_channel(ctx, "pd-news-ticker").mention}!', + embed=get_embed(this_run) + ) else: - db_patch( + this_run = db_patch( 'gauntletruns', object_id=this_run['id'], params=[('losses', this_run['losses'] + 1), ('ended', this_run['losses'] + 1 == 2)] ) l_message = f'Tough loss. That brings your {this_event["name"]} record to ' \ - f'**{this_run["wins"]}-{this_run["losses"] + 1}**. ' - if this_run['losses'] + 1 == 2: + f'**{this_run["wins"]}-{this_run["losses"]}**. ' + if this_run['losses'] == 2: l_message += 'That\'s the end of this run - better luck next time!' - await ctx.send(l_message) + await ctx.send( + content=l_message, + embed=get_embed(this_run) + )