def craft(userid, recipe, n=1): """Crafts (a given number of) an item.""" try: recipeid = find_by_name(recipe) except KeyError: return f'Error: cannot find recipe that crafts {recipe}.' name = items.get_attr(recipeid) artisan_level = users.xp_to_level(users.read_user(userid, key=users.ARTISAN_XP_KEY)) artisan_req = get_attr(recipeid, key=LEVEL_REQ_KEY) if artisan_level < artisan_req: return f'Error: {name} has a gathering requirement ({artisan_req}) ' \ f'higher than your artisan level ({artisan_level}).' inputs = get_attr(recipeid) loot = [] for itemid in list(inputs.keys()): if users.item_in_inventory(userid, itemid, number=n * inputs[itemid]): loot.extend((n * inputs[itemid]) * [itemid]) else: return f'Error: you do not have enough items to make {n} {items.add_plural(recipeid)} ' \ f'({n * inputs[itemid]} {items.add_plural(itemid)}).' users.update_inventory(userid, loot, remove=True) users.update_inventory(userid, n * [recipeid]) xp = n * items.get_attr(recipeid, key=items.XP_KEY) users.update_user(userid, xp, key=users.ARTISAN_XP_KEY) xp_formatted = '{:,}'.format(xp) return f'Successfully crafted {n} {items.add_plural(recipeid)}! You have also gained {xp_formatted} artisan xp!'
def get_kill_result(person, *args): """Determines the loot of a monster grind.""" try: monsterid, monster_name, num_to_kill, length = args[0] except ValueError as e: print(e) raise ValueError out = '' users.add_counter(person.id, monsterid, num_to_kill) if mon.get_attr(monsterid, key=mon.SLAYER_KEY): factor = 0.75 else: factor = 1 factor *= items.get_luck_factor(person.id) loot = mon.get_loot(monsterid, int(num_to_kill), factor=factor) users.update_inventory(person.id, loot) out += print_loot(loot, person, monster_name, num_to_kill) xp_gained = mon.get_attr(monsterid, key=mon.XP_KEY) * int(num_to_kill) cb_level_before = users.xp_to_level(users.read_user(person.id, users.COMBAT_XP_KEY)) users.update_user(person.id, xp_gained, users.COMBAT_XP_KEY) cb_level_after = users.xp_to_level(users.read_user(person.id, users.COMBAT_XP_KEY)) combat_xp_formatted = '{:,}'.format(xp_gained) out += f'\nYou have also gained {combat_xp_formatted} combat xp' if cb_level_after > cb_level_before: out += f' and {cb_level_after - cb_level_before} combat levels' out += '.' users.remove_potion(person.id) return out
def get_result(person, *args): """Determines the success and loot of a slayer task.""" try: monsterid, monster_name, num_to_kill, chance = args[0] except ValueError as e: print(e) raise ValueError out = '' if adv.is_success(calc_chance(person.id, monsterid)): loot = mon.get_loot(monsterid, int(num_to_kill)) users.update_inventory(person.id, loot) out += print_loot(loot, person, monster_name, num_to_kill) xp_gained = mon.get_attr(monsterid, key=mon.XP_KEY) * int(num_to_kill) users.update_user(person.id, xp_gained, users.SLAYER_XP_KEY) users.update_user(person.id, round(0.7 * xp_gained), users.COMBAT_XP_KEY) slayer_xp_formatted = '{:,}'.format(xp_gained) combat_xp_formatted = '{:,}'.format(round(0.7 * xp_gained)) out += f'\nYou have also gained {slayer_xp_formatted} slayer xp and {combat_xp_formatted} combat xp.' else: xp_gained = round(mon.get_attr(monsterid, key=mon.XP_KEY) * int(num_to_kill) / 4) users.update_user(person.id, xp_gained, users.SLAYER_XP_KEY) users.update_user(person.id, round(0.7 * xp_gained), users.COMBAT_XP_KEY) slayer_xp_formatted = '{:,}'.format(xp_gained) combat_xp_formatted = '{:,}'.format(round(0.7 * xp_gained)) out += f'{person.mention}, your slayer task of {num_to_kill} {mon.add_plural(monsterid)} has failed.\n'\ f'You have received {slayer_xp_formatted} slayer xp and {combat_xp_formatted} combat xp.' return out
def cook(userid, food, n=1): """Cooks (a given number of) an item.""" try: foodid = find_by_name(food, cook=True) except KeyError: return f'Cannot find food called {food} that can be cooked.' except TypeError: return f'Cannot cook {food}.' name = items.get_attr(foodid) cooking_level = users.get_level(userid, key=users.COOK_XP_KEY) cooking_req = get_attr(foodid, key=COOKING_REQ_KEY) if cooking_level < cooking_req: return f'{name} has a cooking requirement ({cooking_req}) higher than your cooking level ({cooking_level}).' burn_chance = calc_burn(userid, foodid) num_cooked = 0 if burn_chance == 0: num_cooked = n else: for _ in range(n): if random.randint(1, 100) > burn_chance: num_cooked += 1 inputs = get_attr(foodid) food_input = [] for itemid in list(inputs.keys()): if users.item_in_inventory(userid, itemid, number=num_cooked * inputs[itemid]): food_input.extend((num_cooked * inputs[itemid]) * [itemid]) else: return f'Error: you do not have enough items to make {items.add_plural(n, foodid)} ' \ f'({items.add_plural(n * inputs[itemid], itemid)}).' users.update_inventory(userid, food_input, remove=True) users.update_inventory(userid, num_cooked * [foodid]) users.update_inventory(userid, (n - num_cooked) * ['469']) xp = XP_FACTOR * num_cooked * items.get_attr(foodid, key=items.XP_KEY) users.update_user(userid, xp, key=users.COOK_XP_KEY) level_after = users.xp_to_level(users.read_user(userid, users.COOK_XP_KEY)) xp_formatted = '{:,}'.format(xp) out = f'After cooking {items.add_plural(n, foodid)}, you successfully cook ' \ f'{num_cooked} and burn {n - num_cooked}! ' \ f'You have also gained {xp_formatted} cooking xp! ' if level_after > cooking_level: out += f'You have also gained {level_after - cooking_level} cooking levels!' return out
def get_reaper_result(person, *args): """Determines the success and loot of a reaper task.""" try: monsterid, monster_name, num_to_kill, chance = args[0] except ValueError as e: print(e) raise ValueError out = '' users.add_counter(person.id, monsterid, num_to_kill) if adv.is_success(calc_chance(person.id, monsterid, num_to_kill)): users.remove_potion(person.id) factor = 0.7 * items.get_luck_factor(person.id) loot = mon.get_loot(monsterid, int(num_to_kill), factor=factor) loot['291'] = 1 users.update_inventory(person.id, loot) out += print_loot(loot, person, monster_name, num_to_kill) xp_gained = XP_FACTOR * mon.get_attr(monsterid, key=mon.XP_KEY) * int(num_to_kill) cb_level_before = users.xp_to_level(users.read_user(person.id, users.COMBAT_XP_KEY)) slay_level_before = users.xp_to_level(users.read_user(person.id, users.SLAYER_XP_KEY)) users.update_user(person.id, xp_gained, users.SLAYER_XP_KEY) users.update_user(person.id, round(0.7 * xp_gained), users.COMBAT_XP_KEY) cb_level_after = users.xp_to_level(users.read_user(person.id, users.COMBAT_XP_KEY)) slay_level_after = users.xp_to_level(users.read_user(person.id, users.SLAYER_XP_KEY)) slayer_xp_formatted = '{:,}'.format(xp_gained) combat_xp_formatted = '{:,}'.format(round(0.7 * xp_gained)) out += f'\nYou have also gained {slayer_xp_formatted} slayer xp and {combat_xp_formatted} combat xp. ' if cb_level_after > cb_level_before: out += f'In addition, you have gained {cb_level_after - cb_level_before} combat levels. ' if slay_level_after > slay_level_before: out += f'Also, as well, you have gained {slay_level_after - slay_level_before} slayer levels. ' else: users.remove_potion(person.id) factor = int(chance)/170 * items.get_luck_factor(person.id) loot = mon.get_loot(monsterid, int(num_to_kill), factor=factor) loot.append('291') users.update_inventory(person.id, loot) out += print_loot(loot, person, monster_name, num_to_kill) xp_gained = round(XP_FACTOR * mon.get_attr(monsterid, key=mon.XP_KEY) * int(num_to_kill) * factor) cb_level_before = users.xp_to_level(users.read_user(person.id, users.COMBAT_XP_KEY)) slay_level_before = users.xp_to_level(users.read_user(person.id, users.SLAYER_XP_KEY)) users.update_user(person.id, xp_gained, users.SLAYER_XP_KEY) users.update_user(person.id, round(0.7 * xp_gained), users.COMBAT_XP_KEY) cb_level_after = users.xp_to_level(users.read_user(person.id, users.COMBAT_XP_KEY)) slay_level_after = users.xp_to_level(users.read_user(person.id, users.SLAYER_XP_KEY)) slayer_xp_formatted = '{:,}'.format(xp_gained) combat_xp_formatted = '{:,}'.format(round(0.7 * xp_gained)) out += f'\nYou have received lower loot and experience because you have died.'\ f'\nYou have received {slayer_xp_formatted} slayer xp and {combat_xp_formatted} combat xp. ' if cb_level_after > cb_level_before: out += f'Also, you have gained {cb_level_after - cb_level_before} combat levels. ' if slay_level_after > slay_level_before: out += f'In addition, you have gained {slay_level_after - slay_level_before} slayer levels. ' return out
def get_gather(person, *args): try: itemid, item_name, number, length = args[0] except ValueError as e: print(e) raise ValueError loot = int(number) * [itemid] xp = int(number) * items.get_attr(itemid, key=items.XP_KEY) users.update_inventory(person.id, loot) users.update_user(person.id, xp, key=users.GATHER_XP_KEY) xp_formatted = '{:,}'.format(xp) out = f'{GATHER_HEADER}' \ f'{person.mention}, you gathering session has finished! You have gathered ' \ f'{number} {items.add_plural(itemid)} and have gained {xp_formatted} gathering xp!' return out
def craft(userid, recipe, n=1): """Crafts (a given number of) an item.""" try: recipeid = find_by_name(recipe.lower()) except KeyError: return f'Cannot find recipe that crafts {recipe}.' except TypeError: return f'Cannot craft {recipe}.' name = items.get_attr(recipeid) artisan_level = users.get_level(userid, key=users.ARTISAN_XP_KEY) artisan_req = get_attr(recipeid, key=ARTISAN_REQ_KEY) if artisan_level < artisan_req: return f'Error: {name} has a artisan requirement ({artisan_req}) ' \ f'higher than your artisan level ({artisan_level}).' inputs = get_attr(recipeid) recipe_input = [] for itemid in list(inputs.keys()): if users.item_in_inventory(userid, itemid, number=n * inputs[itemid]): recipe_input.extend((n * inputs[itemid]) * [itemid]) else: return f'Error: you do not have enough items to make {items.add_plural(n, recipeid)} ' \ f'({items.add_plural(n * inputs[itemid], itemid)}).' bonus = 0 if artisan_level == 99: for _ in range(n): if random.randint(1, 20) == 1: bonus += 1 equipment = users.read_user(userid, users.EQUIPMENT_KEY) goldsmith_bonus = 2 if equipment['9'] == '494' and recipeid == '59' else 1 users.update_inventory(userid, recipe_input, remove=True) users.update_inventory(userid, (n + bonus) * [recipeid]) xp = XP_FACTOR * goldsmith_bonus * n * items.get_attr(recipeid, key=items.XP_KEY) users.update_user(userid, xp, key=users.ARTISAN_XP_KEY) level_after = users.xp_to_level( users.read_user(userid, users.ARTISAN_XP_KEY)) xp_formatted = '{:,}'.format(xp) out = f'Successfully crafted {items.add_plural(n, recipeid)}! You have also gained {xp_formatted} artisan xp! ' if bonus > 0: out += f'Due to your 99 artisan perk, you have also created an extra {items.add_plural(bonus, recipeid)}! ' if level_after > artisan_level: out += f'You have also gained {level_after - artisan_level} artisan levels!' return out
def get_reaper_task(userid): """Assigns a user a reaper task provided they are not in the middle of another adventure.""" out = SLAYER_HEADER if users.get_level(userid, key=users.SLAYER_XP_KEY) < 50: out += "Your slayer level is too low to start a reaper task. You need at least 50 slayer." return out print(users.read_user(userid, key=users.LAST_REAPER_KEY)) if datetime.datetime.fromtimestamp(users.read_user(userid, key=users.LAST_REAPER_KEY)).date() \ >= datetime.date.today(): out += 'You have already done a reaper task today. Please come back tomorrow for another one.' return out if not adv.is_on_adventure(userid): completed_quests = set(users.get_completed_quests(userid)) for _ in range(1000): monsterid = mon.get_random(slayer_level=users.xp_to_level(users.read_user(userid, key=users.SLAYER_XP_KEY))) num_to_kill = mon.get_task_length(monsterid) base_time, task_length = calc_length(userid, monsterid, num_to_kill) chance = calc_chance(userid, monsterid, num_to_kill) # print(f'{monsterid} {task_length/base_time} {chance}') if 0.25 <= task_length / base_time <= 2 and chance >= 20 \ and mon.get_attr(monsterid, key=mon.BOSS_KEY) is True\ and ({mon.get_attr(monsterid, key=mon.QUEST_REQ_KEY)}.issubset(completed_quests) or mon.get_attr(monsterid, key=mon.QUEST_REQ_KEY) == 0): break else: return "Error: gear too low to fight any monsters. Please equip some better gear and try again. " \ "If you are new, type `~starter` to get a bronze kit." monster_name = mon.get_attr(monsterid) cb_perk = False if users.read_user(userid, key=users.COMBAT_XP_KEY) == 99 and random.randint(1, 20) == 1: task_length *= 0.7 cb_perk = True task = adv.format_line(5, userid, adv.get_finish_time(task_length), monsterid, monster_name, num_to_kill, chance) adv.write(task) users.update_user(userid, datetime.date.today(), key=users.LAST_REAPER_KEY) out += print_task(userid, reaper=True) if cb_perk is True: out += 'Your time has been reduced by 30% due to your combat perk!' else: out = adv.print_adventure(userid) out += adv.print_on_adventure_error('reaper task') return out
def get_kill_result(person, *args): """Determines the loot of a monster grind.""" try: monsterid, monster_name, num_to_kill, length = args[0] except ValueError as e: print(e) raise ValueError out = '' if mon.get_attr(monsterid, key=mon.SLAYER_KEY): factor = 0.75 else: factor = 1 loot = mon.get_loot(monsterid, int(num_to_kill), factor=factor) users.update_inventory(person.id, loot) out += print_loot(loot, person, monster_name, num_to_kill) xp_gained = mon.get_attr(monsterid, key=mon.XP_KEY) * int(num_to_kill) users.update_user(person.id, xp_gained, users.COMBAT_XP_KEY) combat_xp_formatted = '{:,}'.format(xp_gained) out += f'\nYou have also gained {combat_xp_formatted} combat xp.' return out
def drink(userid, name): try: itemid = find_by_name(name) except KeyError: return f'Error: {name} does not exist.' item_name = get_attr(itemid) is_pot = get_attr(itemid, key=POT_KEY) if is_pot: if users.item_in_inventory(userid, itemid): users.update_inventory(userid, [itemid], remove=True) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) equipment['15'] = str(itemid) users.update_user(userid, equipment, key=users.EQUIPMENT_KEY) else: return f"You do not have any {add_plural(0, itemid)} in your inventory." else: return f"{item_name} isn't a potion!" out = f'You drank the {item_name}! Your stats will be increased for your next adventure.' return out
def get_result(person, *args): """Gets the result of a quest.""" try: questid, chance = args[0] except ValueError as e: print(e) raise ValueError out = f'{QUEST_HEADER}**{person.mention}, here is the result of your quest, {get_attr(questid)}**:\n' if adv.is_success(calc_chance(person.id, questid)): out += f'*{get_attr(questid, key=SUCCESS_KEY)}*\n\n' reward = get_attr(questid, key=REWARD_KEY) out += f'**Reward**:\n' loot = [] for itemid in reward: loot.extend(reward[itemid] * [itemid]) out += f'{reward[itemid]} {items.get_attr(itemid)}\n' users.update_inventory(person.id, loot) users.update_user(person.id, questid, key=users.QUESTS_KEY) else: out += f'*{get_attr(questid, key=FAILURE_KEY)}*' return out
def get_gather(person, *args): try: itemid, item_name, number, length = args[0] except ValueError as e: print(e) raise ValueError loot = int(number) * [itemid] xp = XP_FACTOR * int(number) * items.get_attr(itemid, key=items.XP_KEY) users.update_inventory(person.id, loot) gather_level_before = users.xp_to_level( users.read_user(person.id, users.GATHER_XP_KEY)) users.update_user(person.id, xp, key=users.GATHER_XP_KEY) gather_level_after = users.xp_to_level( users.read_user(person.id, users.GATHER_XP_KEY)) xp_formatted = '{:,}'.format(xp) out = f'{GATHER_HEADER}' \ f'{person.mention}, your gathering session has finished! You have gathered ' \ f'{items.add_plural(number, itemid)} and have gained {xp_formatted} gathering xp! ' if gather_level_after > gather_level_before: out += f'In addition, you have gained {gather_level_after - gather_level_before} gathering levels!' users.remove_potion(person.id) return out
async def ironman(self, ctx): """Lets a user become an ironman, by the way.""" out = ':tools: __**IRONMAN**__ :tools:\n' \ 'If you want to become an ironman, please react to this post with a :thumbsup:. ' \ 'This will **RESET** your account and give you the ironman role. ' \ 'You will be unable to trade with other players or gamble. ' \ 'In return, you will be able to proudly display your status as an ironman, by the way.' msg = await ctx.send(out) await msg.add_reaction('\N{THUMBS UP SIGN}') while True: try: reaction, user = await self.bot.wait_for('reaction_add', timeout=60) if str( reaction.emoji ) == '👍' and user == ctx.author and reaction.message.id == msg.id: users.reset_account(ctx.author.id) users.update_user(ctx.author.id, True, key=users.IRONMAN_KEY) ironman_role = discord.utils.get(ctx.guild.roles, name="Ironman") await ctx.author.add_roles( ironman_role, reason='Wanted to become an ironmeme.') name = get_display_name(ctx.author) await msg.edit( content= f':tools: __**IRONMAN**__ :tools:\nCongratulations, {name}, you are now ' 'an ironman!') return except asyncio.TimeoutError: await msg.edit( content= f'Your request has timed out. Please retype the command to try again.' ) return