# Economy Packs Module # Contains pack opening, daily rewards, and donation commands from the original economy.py import logging from discord.ext import commands from discord import app_commands, Member import discord import datetime # Import specific utilities needed by this module import random from api_calls import db_get, db_post, db_patch from helpers.constants import PD_PLAYERS_ROLE_NAME, PD_PLAYERS, IMAGES from helpers import ( get_team_by_owner, display_cards, give_packs, legal_channel, get_channel, get_cal_user, refresh_sheet, roll_for_cards, int_timestamp, get_context_user ) from helpers.discord_utils import get_team_embed, send_to_channel, get_emoji from discord_ui import SelectView, SelectOpenPack logger = logging.getLogger('discord_app') class Packs(commands.Cog): """Pack management, daily rewards, and donation system for Paper Dynasty.""" def __init__(self, bot): self.bot = bot @commands.hybrid_group(name='donation', help='Mod: Give packs for PD donations') @commands.has_any_role(PD_PLAYERS_ROLE_NAME) async def donation(self, ctx: commands.Context): if ctx.invoked_subcommand is None: await ctx.send('To buy packs, visit https://ko-fi.com/manticorum/shop and include your discord username!') @donation.command(name='premium', help='Mod: Give premium packs', aliases=['p', 'prem']) async def donation_premium(self, ctx: commands.Context, num_packs: int, gm: Member): if ctx.author.id != self.bot.owner_id: await ctx.send('Wait a second. You\'re not in charge here!') return team = await get_team_by_owner(gm.id) p_query = await db_get('packtypes', params=[('name', 'Premium')]) if p_query['count'] == 0: await ctx.send('Oof. I couldn\'t find a Premium Pack') return total_packs = await give_packs(team, num_packs, pack_type=p_query['packtypes'][0]) await ctx.send(f'The {team["lname"]} now have {total_packs["count"]} total packs!') @donation.command(name='standard', help='Mod: Give standard packs', aliases=['s', 'sta']) async def donation_standard(self, ctx: commands.Context, num_packs: int, gm: Member): if ctx.author.id != self.bot.owner_id: await ctx.send('Wait a second. You\'re not in charge here!') return team = await get_team_by_owner(gm.id) p_query = await db_get('packtypes', params=[('name', 'Standard')]) if p_query['count'] == 0: await ctx.send('Oof. I couldn\'t find a Standard Pack') return total_packs = await give_packs(team, num_packs, pack_type=p_query['packtypes'][0]) await ctx.send(f'The {team["lname"]} now have {total_packs["count"]} total packs!') @commands.hybrid_command(name='lastpack', help='Replay your last pack') @commands.check(legal_channel) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) async def last_pack_command(self, ctx: commands.Context): team = await get_team_by_owner(get_context_user(ctx).id) if not team: await ctx.send(f'I don\'t see a team for you, yet. You can sign up with the `/newteam` command!') return p_query = await db_get( 'packs', params=[('opened', True), ('team_id', team['id']), ('new_to_old', True), ('limit', 1)] ) if not p_query['count']: await ctx.send(f'I do not see any packs for you, bub.') return pack_name = p_query['packs'][0]['pack_type']['name'] if pack_name == 'Standard': pack_cover = IMAGES['pack-sta'] elif pack_name == 'Premium': pack_cover = IMAGES['pack-pre'] else: pack_cover = None c_query = await db_get( 'cards', params=[('pack_id', p_query['packs'][0]['id'])] ) if not c_query['count']: await ctx.send(f'Hmm...I didn\'t see any cards in that pack.') return await display_cards(c_query['cards'], team, ctx.channel, ctx.author, self.bot, pack_cover=pack_cover) @app_commands.command(name='comeonmanineedthis', description='Daily check-in for cards, currency, and packs') @commands.has_any_role(PD_PLAYERS) @commands.check(legal_channel) async def daily_checkin(self, interaction: discord.Interaction): await interaction.response.defer() team = await get_team_by_owner(interaction.user.id) if not 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 current = await db_get('current') now = datetime.datetime.now() midnight = int_timestamp(datetime.datetime(now.year, now.month, now.day, 0, 0, 0)) daily = await db_get('rewards', params=[ ('name', 'Daily Check-in'), ('team_id', team['id']), ('created_after', midnight) ]) logger.debug(f'midnight: {midnight} / now: {int_timestamp(now)}') logger.debug(f'daily_return: {daily}') if daily: await interaction.edit_original_response( content=f'Looks like you already checked in today - come back at midnight Central!' ) return await db_post('rewards', payload={ 'name': 'Daily Check-in', 'team_id': team['id'], 'season': current['season'], 'week': current['week'], 'created': int_timestamp(now) }) current = await db_get('current') check_ins = await db_get('rewards', params=[ ('name', 'Daily Check-in'), ('team_id', team['id']), ('season', current['season']) ]) check_count = check_ins['count'] % 5 # 2nd, 4th, and 5th check-ins if check_count == 0 or check_count % 2 == 0: # Every fifth check-in if check_count == 0: greeting = await interaction.edit_original_response( content=f'Hey, you just earned a Standard pack of cards!' ) pack_channel = get_channel(interaction, 'pack-openings') p_query = await db_get('packtypes', params=[('name', 'Standard')]) if not p_query: await interaction.edit_original_response( content=f'I was not able to pull this pack for you. ' f'Maybe ping {get_cal_user(interaction).mention}?' ) return # Every second and fourth check-in else: greeting = await interaction.edit_original_response( content=f'Hey, you just earned a player card!' ) pack_channel = interaction.channel p_query = await db_get('packtypes', params=[('name', 'Check-In Player')]) if not p_query: await interaction.edit_original_response( content=f'I was not able to pull this card for you. ' f'Maybe ping {get_cal_user(interaction).mention}?' ) return await give_packs(team, 1, p_query['packtypes'][0]) p_query = await db_get( 'packs', params=[('opened', False), ('team_id', team['id']), ('new_to_old', True), ('limit', 1)] ) if not p_query['count']: await interaction.edit_original_response( content=f'I do not see any packs in here. {await get_emoji(interaction, "ConfusedPsyduck")}') return pack_ids = await roll_for_cards(p_query['packs'], extra_val=check_ins['count']) if not pack_ids: await greeting.edit( content=f'I was not able to create these cards {await get_emoji(interaction, "slight_frown")}' ) return all_cards = [] for p_id in pack_ids: new_cards = await db_get('cards', params=[('pack_id', p_id)]) all_cards.extend(new_cards['cards']) if not all_cards: await interaction.edit_original_response( content=f'I was not able to pull these cards {await get_emoji(interaction, "slight_frown")}' ) return await display_cards(all_cards, team, pack_channel, interaction.user, self.bot) await refresh_sheet(team, self.bot) return # 1st, 3rd check-ins else: d_1000 = random.randint(1, 1000) m_reward = 0 if d_1000 < 500: m_reward = 10 elif d_1000 < 900: m_reward = 15 elif d_1000 < 990: m_reward = 20 else: m_reward = 25 team = await db_post(f'teams/{team["id"]}/money/{m_reward}') await interaction.edit_original_response( content=f'You just earned {m_reward}₼! That brings your wallet to {team["wallet"]}₼!') @app_commands.command(name='open-packs', description='Open packs from your inventory') @app_commands.checks.has_any_role(PD_PLAYERS) async def open_packs_slash(self, interaction: discord.Interaction): if interaction.channel.name in ['paper-dynasty-chat', 'pd-news-ticker', 'pd-network-news']: await interaction.response.send_message( f'Please head to down to {get_channel(interaction, "pd-bot-hole")} to run this command.', ephemeral=True ) return owner_team = await get_team_by_owner(interaction.user.id) if not owner_team: await interaction.response.send_message( f'I don\'t see a team for you, yet. You can sign up with the `/newteam` command!' ) return p_query = await db_get('packs', params=[ ('team_id', owner_team['id']), ('opened', False) ]) if p_query['count'] == 0: await interaction.response.send_message( f'Looks like you are clean out of packs, friendo. You can earn them by playing PD games or by ' f'donating to the league.' ) return # Group packs by type and customization (e.g. Standard, Standard-Orioles, Standard-2012, Premium) p_count = 0 p_data = { 'Standard': [], 'Premium': [], 'Daily': [], 'MVP': [], 'All Star': [], 'Mario': [], 'Team Choice': [] } logger.debug(f'Parsing packs...') for pack in p_query['packs']: p_group = None logger.debug(f'pack: {pack}') logger.debug(f'pack cardset: {pack["pack_cardset"]}') if pack['pack_team'] is None and pack['pack_cardset'] is None: p_group = pack['pack_type']['name'] # Add to p_data if this is a new pack type if p_group not in p_data: p_data[p_group] = [] elif pack['pack_team'] is not None: if pack['pack_type']['name'] == 'Standard': p_group = f'Standard-Team-{pack["pack_team"]["id"]}-{pack["pack_team"]["sname"]}' elif pack['pack_type']['name'] == 'Premium': p_group = f'Premium-Team-{pack["pack_team"]["id"]}-{pack["pack_team"]["sname"]}' elif pack['pack_type']['name'] == 'Team Choice': p_group = f'Team Choice-Team-{pack["pack_team"]["id"]}-{pack["pack_team"]["sname"]}' elif pack['pack_type']['name'] == 'MVP': p_group = f'MVP-Team-{pack["pack_team"]["id"]}-{pack["pack_team"]["sname"]}' if pack['pack_cardset'] is not None: p_group += f'-Cardset-{pack["pack_cardset"]["id"]}' elif pack['pack_cardset'] is not None: if pack['pack_type']['name'] == 'Standard': p_group = f'Standard-Cardset-{pack["pack_cardset"]["id"]}-{pack["pack_cardset"]["name"]}' elif pack['pack_type']['name'] == 'Premium': p_group = f'Premium-Cardset-{pack["pack_cardset"]["id"]}-{pack["pack_cardset"]["name"]}' elif pack['pack_type']['name'] == 'Team Choice': p_group = f'Team Choice-Cardset-{pack["pack_cardset"]["id"]}-{pack["pack_cardset"]["name"]}' elif pack['pack_type']['name'] == 'All Star': p_group = f'All Star-Cardset-{pack["pack_cardset"]["id"]}-{pack["pack_cardset"]["name"]}' elif pack['pack_type']['name'] == 'MVP': p_group = f'MVP-Cardset-{pack["pack_cardset"]["id"]}-{pack["pack_cardset"]["name"]}' elif pack['pack_type']['name'] == 'Promo Choice': p_group = f'Promo Choice-Cardset-{pack["pack_cardset"]["id"]}-{pack["pack_cardset"]["name"]}' logger.info(f'p_group: {p_group}') if p_group is not None: p_count += 1 if p_group not in p_data: p_data[p_group] = [pack] else: p_data[p_group].append(pack) if p_count == 0: await interaction.response.send_message( f'Looks like you are clean out of packs, friendo. You can earn them by playing PD games or by ' f'donating to the league.' ) return # Display options and ask which group to open embed = get_team_embed(f'Unopened Packs', team=owner_team) embed.description = owner_team['lname'] select_options = [] for key in p_data: if len(p_data[key]) > 0: pretty_name = None # Not a specific pack if '-' not in key: pretty_name = key elif 'Team' in key: pretty_name = f'{key.split("-")[0]} - {key.split("-")[3]}' elif 'Cardset' in key: pretty_name = f'{key.split("-")[0]} - {key.split("-")[3]}' if pretty_name is not None: embed.add_field(name=pretty_name, value=f'Qty: {len(p_data[key])}') select_options.append(discord.SelectOption(label=pretty_name, value=key)) view = SelectView(select_objects=[SelectOpenPack(select_options, owner_team)], timeout=15) await interaction.response.send_message(embed=embed, view=view) async def setup(bot): """Setup function for the Packs cog.""" await bot.add_cog(Packs(bot))