async def result(self, context): embed = embeds.create(title='Last Lottery Result') if self.last_result and not self.announcing: embed.description = '```%s```' % self.last_result embed.timestamp = self.last_result.timestamp user = context.author player = data.get_player(user) tickets = player.last_tickets if not tickets: your_tickets = 'No tickets bought last time.' else: your_tickets = [] for t in tickets.keys(): prize = self.last_result.get_ticket_prize(t) if not prize: prize = 'No Prize', 0 tickets[t] = prize tickets = { t: p for t, p in sorted(tickets.items(), key=lambda item: item[1][1], reverse=True) } for t, prize in tickets.items(): prize = lotto.get_prize_name(prize) your_tickets += [f'{t:02} - {prize}'] your_tickets = '\n'.join(your_tickets) your_tickets = f'```{your_tickets}```' embed.add_field(name='Your Tickets', value=your_tickets) else: embed.description = TRY_AGAIN_LATER await context.send(embed=embed)
async def buy(self, context, coins, *tickets): user = context.author if not tickets: await self.send_instruction(context) return coins = ticket_parser.parse_coins(coins) tip = None if SIX_ZEROES in str(coins): tip = E_TIP coins_str = str(coins).lower() player = data.get_player(user) balance = player.balance if coins_str in [ALL, HALF]: if balance == 0: balance = player.get_income() if coins_str == ALL: coins = balance elif coins_str == HALF: coins = balance / 2 elif coins == None: await self.send_instruction(context) return try: new_tickets = ticket_parser.parse_list(tickets) except ValueError as e: response = f'{user.mention}\n' response += '\n'.join(e.args) await context.send(response) return ticket_count = len(new_tickets) total_cost = coins * ticket_count divided_cost = math.floor(coins // ticket_count) if total_cost > balance and divided_cost <= balance: coins = divided_cost if coins <= 0: await context.send(MORE_THAN_ZERO) return was_announcing = self.announcing if self.announcing: response = f'{user.mention}\n{WAIT_FOR_RESULT}' await context.send(response) while self.announcing: await asyncio.sleep(1) order = data.add_ticket_order(user, coins, new_tickets) await self.send_ticket_order_embed(context, user, order, was_announcing, tip) if player.balance == 0: await self.bot.get_cog(cogs.ECONOMY).income(context)
def for_winner(user, winning_tickets): player = data.get_player(user) winner_embed = create(title=YOU_WON, color=colors.random()) winner_embed.set_thumbnail(url=user.avatar_url) for prize, tickets in zip(lotto.PRIZES, winning_tickets): prize_name = lotto.get_prize_name(prize) _, multi = prize values = [] for number, worth in tickets[::-1]: prize_coins = worth * multi worth = as_coins(worth, suffix=False) prize_coins = as_coins(prize_coins) value = f'`{number:02}`: {worth} → {prize_coins}' values.append(value) if values: field = dict(name=prize_name, value='\n'.join(values)) winner_embed.add_field(**field) total_spendings = player.get_total_spendings() initial_balance = player.balance + total_spendings - player.total_winnings change = player.total_winnings - total_spendings sign = '+' if change >= 0 else '' value = (f' {as_coins(initial_balance)}\n' f'-{as_coins(total_spendings)}\n' f'+{as_coins(player.total_winnings)}\n' f'({sign}{as_coins(change)})\n' f'={as_coins(player.balance)}') winner_embed.add_field(name=BALANCE, value=value) winner_embed.title += ' ' + (WELL_KINDA if change <= 0 else CONGRATS) return winner_embed
def for_paid_tickets(user, next_draw=None): player = data.get_player(user) title = TICKETS_OF + user.name embed = create(title=title, color=discord.Color.green()) tickets_by_price = player.group_paid_tickets() for price, tickets in tickets_by_price.items(): desc = ticket_parser.format_as_description(tickets) embed.add_field(name=as_coins(price), value=desc) spendings = player.get_total_spendings() balance_before = player.balance + spendings balance_value = (f'{as_coins(balance_before)}\n' f'-{as_coins(spendings)}\n' f'={as_coins(player.balance)}') embed.add_field(name=BALANCE, value=balance_value) embed.add_field(name=REACTIONS, value=CLOSE_FIELD) if next_draw: embed.timestamp = next_draw footer_text = NEXT_DRAW_AT if next_draw else None embed.set_footer(text=footer_text, icon_url=user.avatar_url) return embed
async def income(self, context): user = context.author player = data.get_player(user) income = player.get_income() low_coins = player.balance < income tickets_bought = player.paid_tickets title = None eligible = low_coins and not tickets_bought if eligible: await self.bot.get_cog(cogs.LEVEL_SYSTEM ).add_xp(context, user, level.INCOME_XP) if player.level_up: income = player.get_income() player.add_to_balance(income - player.balance) embed = self.get_balance_embed(user) title = HERES_SOME_COINS else: embed = self.get_balance_embed(user) if low_coins and tickets_bought: title = WAIT_FOR_RESULT else: title = COME_BACK embed.set_author(name=title) await context.send(embed=embed) if eligible: await self.bot.get_cog(cogs.LOTTERY ).update_ticket_order_embeds(user)
def player_can_buy(self, user_or_player, order): if type(user_or_player) is Player: player = user_or_player else: user = user_or_player player = data.get_player(user) return player.can_buy(order) and not self.announcing
async def balance(self, context, member=None): user = await cogs.convert_to_user(context, member) if not user: return player = data.get_player(user) income = player.get_income() embed = self.get_balance_embed(user) if user == context.author and player.balance < income: embed.description += '\n' + lotto.INCOME_TIP + as_coins(income) await context.send(embed=embed)
def for_ticket_order(user, order, announcing=False): player = data.get_player(user) title = TICKET_ORDER_OF + user.name description = ticket_parser.format_as_description(order.tickets) can_buy = player.can_buy(order) and not announcing color = CAN_BUY_COLOR if can_buy else CANNOT_BUY_COLOR embed = create(title=title, description=description, color=color, footer_user=user) total_cost = order.total_cost() cost_value = (f'{UNIT_COST}: {as_coins(order.coins)}\n' f'{TOTAL_COST}: {as_coins(total_cost)}') if order.coins == total_cost: cost_value = cost_value.split('\n')[1] embed.add_field(name=COST, value=cost_value) balance = player.balance balance_after = balance - total_cost balance_value = (f'{NOW}: {as_coins(balance)}\n' f'{AFTER}: {as_coins(balance_after)}') embed.add_field(name=BALANCE, value=balance_value) reactions = '' if can_buy: reactions += BUY_FIELD + '\n' reactions += CANCEL_FIELD embed.add_field(name=REACTIONS, value=reactions) if not can_buy: reason = '' if not player.can_hold_more_tickets(order): reason = MAX_TICKET_COUNT % player.get_max_tickets() elif not player.can_afford(order): reason = CANNOT_AFFORD % as_coins(-balance_after) income = player.get_income() if balance < income: reason += '\n' + lotto.INCOME_TIP + as_coins(income) elif announcing: reason = RESULT_ANNOUNCING embed.add_field(name=CANNOT_BUY_FIELD, value=reason) return embed
def for_level(user): player = data.get_player(user) lvl = player.get_level() next_lvl = lvl + 1 xp = player.xp gap = level.gap(lvl) total_xp_last_lvl = level.xp_for_level(lvl - 1) xp_this_lvl = xp - total_xp_last_lvl embed = create(footer_user=user) embed.description = f'**Level {lvl}**: `{xp_this_lvl}/{gap} XP`' return embed
async def on_reaction_add(self, reaction, user): if self.should_ignore_reaction(reaction, user): return message = reaction.message embed = message.embeds[0] player = data.get_player(user) if str(reaction) == emotes.X: await self.cancel_order(player, message) elif str(reaction) == emotes.MONEY_WINGS: if self.announcing: return self.schedule_next_draw(message) await self.buy_order(user, message) await self.wait_to_draw()
async def buy_order(self, user, message): player = data.get_player(user) order = player.find_order_by_message(message) if order: if not player.paid_tickets: await self.bot.get_cog(cogs.LEVEL_SYSTEM ).add_xp(message.channel, player, level.BUY_XP) player.buy_ticket_order(order) player.remove_order(message) embed = embeds.for_paid_tickets(user, self.next_draw) await message.edit(embed=embed) await message.remove_reaction(emotes.MONEY_WINGS, self.bot.user) await self.update_ticket_order_embeds(user)
async def tickets(self, context, member=None): user = await cogs.convert_to_user(context, member) if not user: return player = data.get_player(user) if player.paid_tickets or player.ticket_orders: embed = embeds.for_paid_tickets(user, self.next_draw) message = await context.send(embed=embed) await message.add_reaction(emotes.X) if user != context.author: return for order in player.ticket_orders: await self.send_ticket_order_embed(context, user, order) else: response = f'{user.mention}\n{YOU_NO_TICKETS}' if user == context.author \ else f'**{user.name}** {THEY_NO_TICKETS}' await context.send(response)
async def add_xp(self, context, user_or_player, xp:int): user = data.get_user(self.bot, user_or_player) player = data.get_player(user_or_player) player.clear_level_up() player._add_xp(xp) if player.level_up: lines = [LEVEL_UP % player.level_up] old_max, new_max = map(lotto.get_max_tickets_for, player.level_up) if new_max > old_max: lines += [CAN_BUY % new_max] embed = embeds.for_level(user) lines += [embed.description] lines += [INCOME + as_coins(player.get_income(), backtick=True, suffix=False)] embed.description = '\n'.join(lines) await context.send(embed=embed)
async def update_ticket_order_embeds(self, user): player = data.get_player(user) for order in player.ticket_orders: message = order.message if not message: continue message = discord.utils.get(self.bot.cached_messages, id=message.id) order.message = message new_embed = embeds.for_ticket_order(user, order, self.announcing) await message.edit(embed=new_embed) can_buy = self.player_can_buy(player, order) has_buy_reaction = discord.utils.get(message.reactions, emoji=emotes.MONEY_WINGS) if can_buy and not has_buy_reaction: await message.remove_reaction(emotes.X, self.bot.user) await message.add_reaction(emotes.MONEY_WINGS) await message.add_reaction(emotes.X) elif not can_buy and has_buy_reaction: await message.remove_reaction(emotes.MONEY_WINGS, self.bot.user)