async def buy_item(self, item_name, **details): customer = details["author"] channel = details["channel"] if item_name in customer.inventory[self.inventory_slot]: raise util.DueUtilException(channel, "You already own that " + self.item_type) item = self.get_item(item_name) if item is None: raise util.DueUtilException(channel, self.item_type.title() + " not found!") if not self.can_buy(customer, item): return True if customer.money - item.price >= 0: customer.money -= item.price customer.inventory[self.inventory_slot].append(item_name) if self.item_equipped_on_buy(customer, item_name): await util.say(channel, ("**%s** bought the %s **%s** for %s" % (customer.name_clean, self.item_type, item.name_clean, util.format_number(item.price, money=True, ull_precision=True)))) else: await util.say(channel, (("**%s** bought the %s **%s** for %s\n" + ":warning: You have not yet set this %s! Do **%sset%s %s** to use this %s") % (customer.name_clean, self.item_type, item.name_clean, util.format_number(item.price, money=True, full_precision=True), self.item_type, details["cmd_key"], self.set_name if hasattr(self, "set_name") else self.item_type, item_name, self.item_type))) customer.save() else: await util.say(channel, ":anger: You can't afford that " + self.item_type + ".")
async def sell_item(self, item_name, **details): player = details["author"] channel = details["channel"] price_divisor = 4 / 3 if item_name not in player.inventory[self.inventory_slot]: raise util.BattleBananaException( channel, self.item_type.title() + " not found!") if item_name == self.default_item: raise util.BattleBananaException( channel, "You can't sell that " + self.item_type + "!") item = self.get_item(item_name) sell_price = item.price // price_divisor setattr(player, self.item_type, self.default_item) player.inventory[self.inventory_slot].remove(item_name) player.money += sell_price await util.say( channel, ("**" + player.name_clean + "** sold the " + self.item_type + " **" + item.name_clean + "** for ``" + util.format_number(sell_price, money=True, full_precision=True) + "``")) player.save()
async def quest_screen(channel, quest): image = quest_info_template.copy() try: image.paste(await resize_avatar(quest, None, 72, 72), (9, 12)) except: pass level = str(math.trunc(quest.level)) attk = str(round(quest.attack, 2)) strg = str(round(quest.strg, 2)) accy = str(round(quest.accy, 2)) reward = util.format_number(quest.money, money=True) draw = ImageDraw.Draw(image) name = get_text_limit_len(draw, quest.name, font, 114) quest_info = quest.info draw.text((88, 38), name, quest.rank_colour, font=font) draw.text((134, 58), " " + str(level), "white", font=font_big) # Fill data width = draw.textsize(attk, font=font)[0] draw.text((203 - width, 123), attk, "white", font=font) width = draw.textsize(strg, font=font)[0] draw.text((203 - width, 151), strg, "white", font=font) width = draw.textsize(accy, font=font)[0] draw.text((203 - width, 178), accy, "white", font=font) weapon_name = get_text_limit_len(draw, quest.weapon.name, font, 136) width = draw.textsize(weapon_name, font=font)[0] draw.text((203 - width, 207), weapon_name, "white", font=font) if quest_info is not None: try: creator = get_text_limit_len(draw, quest_info.creator, font, 119) except TypeError: creator = get_text_limit_len(draw, "bad battlename", font, 119) home = get_text_limit_len(draw, quest_info.home, font, 146) else: creator = "Unknown" home = "Unknown" width = draw.textsize(creator, font=font)[0] draw.text((203 - width, 228), creator, "white", font=font) width = draw.textsize(home, font=font)[0] draw.text((203 - width, 242), home, "white", font=font) width = draw.textsize(reward, font=font_med)[0] draw.text((203 - width, 266), reward, DUE_BLACK, font=font_med) await send_image(channel, image, file_name="questinfo.png", content=":pen_fountain: Here you go.")
async def notify_complete(user_id, transaction, failed=False): await mark_as_completed(transaction) user_id = int(user_id) client = util.clients[0] user = await client.fetch_user(user_id) try: await user.create_dm() embed = Embed(title="Discion Transaction", description="Receipt ID: %s" % (transaction["id"]), type="rich", colour=gconf.DUE_COLOUR) embed.set_footer(text="Keep the receipt in case something goes wrong!") if not failed: payout = int(transaction.get('payout')) amount = float(transaction.get('amount')) source = transaction.get('from') source_id = source.get('id') embed.add_field(name="Exchange amount (%s):" % source_id, value="$" + util.format_number_precise(amount)) embed.add_field(name=f"Result amount ({CURRENCY_CODE}):", value=util.format_number(payout, money=True, full_precision=True)) embed.add_field(name="Receipt:", value="%s/%s/show" % (DISCOINDASH, transaction['id']), inline=False) elif failed: embed.add_field( name=":warning: Your Discoin exchange has been reversed", value= "To exchange to BattleBanana you must be a player and the amount has to be worth at least 1 BBT." ) try: await user.send(embed=embed) except Exception as error: util.logger.error( f"Could not notify the {'successful' if not failed else 'failed'} transaction to the user: %s", error) except Exception as error: util.logger.error("Could not notify discoin complete %s", error)
async def level_up_screen(channel, player, cash): image = level_up_template.copy() level = math.trunc(player.level) try: avatar = await resize_avatar(player, channel.server, 54, 54) image.paste(avatar, (10, 10)) except: pass draw = ImageDraw.Draw(image) draw.text((159, 18), str(level), "white", font=font_big) draw.text((127, 40), util.format_number(cash, money=True), "white", font=font_big) await send_image(channel, image, file_name="level_up.png", content=e.LEVEL_UP + " **" + player.name_clean + "** Level Up!")
async def notify_complete(user_id, transaction, failed=False): client = util.shard_clients[0] user = await client.get_user_info(user_id) try: await client.start_private_message(user) if not failed: amount = int(transaction["amount"]) await util.say(user, (":white_check_mark: You've received ``%s`` from Discoin (receipt %s)!\n" % (util.format_number(amount, full_precision=True, money=True), transaction["receipt"]) + "You can see your full exchange record at <%s/record>." % DISCOIN), client=client) else: await util.say(user, ":warning: Your Discoin exchange has been reversed (receipt %s)!\n" % transaction["receipt"] + "To exchange to DueUtil you must be a player " + "and the amount has to be worth at least 1 DUT.", client=client) except Exception as error: util.logger.error("Could not notify discoin complete %s", error) traceback.print_exc()
async def notify_complete(user_id, transaction, overage=0, failed=False, test='abc'): client = util.shard_clients[0] user = await client.get_user_info(user_id) try: await client.start_private_message(user) if not failed: if overage == 0: amount = int(transaction["payout"]) try: await util.say( user, ":white_check_mark: You've received ``%s`` from Discoin!\n" % (util.format_number( amount, full_precision=True, money=True)), client=client) except: pass else: amount = int(overage) try: await util.say( user, ":white_check_mark: Your transaction would leave you with over 100 million DUT, 10000 DUTC, or 2000 DUP. Your money has been set to its max with the Discoin sent, and the remainder has been refunded.!\n", client=client) except: pass else: try: await util.say( user, ":warning: Your Discoin exchange has been cancelled!\n" + "To exchange to DueUtil you must be a player " + "and the amount has to be worth at least 1 DUT.", client=client) except: pass except Exception as error: util.logger.error("Could not notify discoin complete %s", error) traceback.print_exc()
async def process_votes(): if not util.clients[0].is_ready(): return util.logger.info("Processing Votes.") try: votes = dbconn.conn()["Votes"].find() except Exception as exception: util.logger.error("Failed to fetch votes: %s", exception) return if votes is None: return client = util.clients[0] for vote in votes: if type(vote) == dict: vote_id = vote.get("_id") user_id = int(vote.get("user")) isWeekend = vote.get("weekend") date = vote.get("date") player = players.find_player(user_id) if player is None: dbconn.conn()["Votes"].delete_one({'_id': vote_id}) continue reward = WE_VOTE_REWARD if isWeekend else VOTE_REWARD player.money += reward player.save() client.run_task(notify_complete, user_id, vote, reward) dbconn.conn()["Votes"].delete_one({'_id': vote_id}) embed = Embed(title="New vote", type="rich", colour=gconf.DUE_COLOUR) embed.add_field(name="Voter: ", value=user_id) embed.add_field(name="Reward: ", value=util.format_number(reward, money=True)) embed.add_field(name="Date: ", value=date) util.logger.info("Processed vote for %s", user_id) await util.say(gconf.votes_channel, embed=embed)
async def notify_complete(user_id, vote, reward): client = util.clients[0] try: user = await client.fetch_user(user_id) await user.create_dm() embed = Embed(title="Vote notification", type="rich", colour=gconf.DUE_COLOUR) embed.set_footer(text="Thank you for voting!") embed.add_field(name="Reward: ", value=util.format_number(reward, money=True)) embed.add_field(name="Date: ", value=vote.get("date")) try: await util.say(user, embed=embed) except Exception as error: util.logger.error("Could not notify the successful transaction to the user: %s", error) except Exception as error: util.logger.error("Could not notify vote complete %s", error) traceback.print_exc()
async def stats_screen(channel, player): theme = player.theme if "fontColour" in theme: font_colour = theme["fontColour"] header_colour = font_colour main_colour = font_colour banner_colour = font_colour exp_colour = font_colour side_colour = DUE_BLACK icon_colour = font_colour else: header_colour = theme["headerColour"] main_colour = theme["mainColour"] icon_colour = theme._customization_info.get("iconColour", main_colour) banner_colour = theme["bannerColour"] side_colour = theme["sideColour"] exp_colour = theme["expColour"] image = player.background.image.copy() draw = ImageDraw.Draw(image) profile_screen = profile_parts["screen"][theme["screen"]] paste_alpha(image, profile_screen, (0, 0)) banner = player.banner.image paste_alpha(image, banner, (91, 34)) # draw avatar slot avatar_border = profile_parts["avatar"][theme["avatar"]] paste_alpha(image, avatar_border, (3, 6)) try: image.paste(await resize_avatar(player, channel.server, 80, 80), (9, 12)) except: pass if player.benfont: name = get_text_limit_len(draw, player.name_clean.replace(u"\u2026", "..."), font_epic, 149) draw.text((96, 36), name, player.rank_colour, font=font_epic) else: name = get_text_limit_len(draw, player.name, font, 149) draw.text((96, 36), name, player.rank_colour, font=font) profile_icons = profile_parts["icons"][theme["icons"]] paste_alpha(image, profile_icons, (95, 112)) # Draw exp bar next_level_exp = gamerules.get_exp_for_next_level(player.level) exp_bar_width = player.exp / next_level_exp * 140 draw.rectangle(((96, 70), (240, 82)), theme["expBarColour"][1]) draw.rectangle(((97, 71), (239, 81)), fill=theme["expBarColour"][0]) draw.rectangle(((98, 72), (98 + exp_bar_width, 80)), theme["expBarColour"][1]) exp = "EXP: " + str(math.trunc(player.exp)) + " / " + str(next_level_exp) width = draw.textsize(exp, font=font_tiny)[0] if exp_bar_width >= width + 2: draw.text((98 + exp_bar_width - width, 72), exp, exp_colour, font=font_tiny) elif (140 - exp_bar_width) >= width + 2: draw.text((99 + exp_bar_width, 72), exp, theme["expBarColour"][1], font=font_tiny) else: exp1 = "EXP: " + str(math.trunc(player.exp)) + " /" exp2 = " " + str(next_level_exp) width1 = draw.textsize(exp1, font=font_tiny)[0] width2 = draw.textsize(exp2, font=font_tiny)[0] draw.text((98 + exp_bar_width - width1, 72), exp1, exp_colour, font=font_tiny) draw.text((99 + exp_bar_width, 72), exp2, theme["expBarColour"][1], font=font_tiny) level = str(math.trunc(player.level)) attk = str(round(player.attack, 2)) strg = str(round(player.strg, 2)) accy = str(round(player.accy, 2)) money = util.format_number(player.money, money=True) # Text draw.text((96, 49), "LEVEL " + level, banner_colour, font=font_big) draw.text((94, 87), "INFORMATION", header_colour, font=font_big) draw.text((117, 121), "ATK", icon_colour, font=font) draw.text((117, 149), "STRG", icon_colour, font=font) draw.text((117, 177), "ACCY", icon_colour, font=font) draw.text((117, 204), "CASH", icon_colour, font=font) draw.text((117, 231), "WPN", icon_colour, font=font) draw.text((96, 252), "QUESTS BEAT", main_colour, font=font) draw.text((96, 267), "WAGERS WON", main_colour, font=font) # Player stats width = draw.textsize(attk, font=font)[0] draw.text((241 - width, 122), attk, main_colour, font=font) width = draw.textsize(strg, font=font)[0] draw.text((241 - width, 150), strg, main_colour, font=font) width = draw.textsize(accy, font=font)[0] draw.text((241 - width, 178), accy, main_colour, font=font) width = draw.textsize(money, font=font)[0] draw.text((241 - width, 204), money, main_colour, font=font) width = draw.textsize(str(player.quests_won), font=font)[0] draw.text((241 - width, 253), str(player.quests_won), main_colour, font=font) width = draw.textsize(str(player.wagers_won), font=font)[0] draw.text((241 - width, 267), str(player.wagers_won), main_colour, font=font) wep = get_text_limit_len(draw, player.weapon.name, font, 95) width = draw.textsize(wep, font=font)[0] draw.text((241 - width, 232), wep, main_colour, font=font) # Player awards count = 0 row = 0 for player_award in range(len(player.awards) - 1, -1, -1): if count % 2 == 0: image.paste( awards.get_award(player.awards[player_award]).icon, (18, 121 + 35 * row)) else: image.paste( awards.get_award(player.awards[player_award]).icon, (53, 121 + 35 * row)) row += 1 count += 1 if count == 8: break if len(player.awards) > 8: draw.text((18, 267), "+ " + str(len(player.awards) - 8) + " More", side_colour, font=font) elif len(player.awards) == 0: draw.text((38, 183), "None", side_colour, font=font) await send_image(channel, image, file_name="myinfo.png", content=":pen_fountain: **" + player.get_name_possession_clean() + "** information.")