def calc_number(userid, monsterid, time): """Calculates the number of monsters that can be killed in a given time period.""" combat_level = users.xp_to_level(users.read_user(userid, key=users.COMBAT_XP_KEY)) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_dam, player_acc, player_arm = users.get_equipment_stats(equipment) monster_arm = mon.get_attr(monsterid, key=mon.ARMOUR_KEY) monster_xp = mon.get_attr(monsterid, key=mon.XP_KEY) if mon.get_attr(monsterid, key=mon.DRAGON_KEY) and '266' not in equipment: if equipment['7'] == '266' or equipment['7'] == '293': monster_base = 1 else: monster_base = 100 else: monster_base = 1 player_potion = equipment['15'] if player_potion == '427' or player_potion == '430': player_acc = player_acc * 1.1 + 3 if player_potion == '428' or player_potion == '430': player_dam = player_dam * 1.1 + 3 if player_potion == '429' or player_potion == '430': player_arm = player_arm * 1.1 + 3 if player_potion == '431' or player_potion == '434': player_acc = player_acc * 1.15 + 5 if player_potion == '432' or player_potion == '434': player_dam = player_dam * 1.15 + 5 if player_potion == '433' or player_potion == '434': player_arm = player_arm * 1.15 + 5 dam_multiplier = 1 + player_acc / 200 number = math.floor((10 * time * (player_dam * dam_multiplier + combat_level)) / (monster_arm * monster_base * monster_xp)) return number
def calc_number(userid, itemid, time): """Calculates the number of items that can be gathered in a given time period.""" gather_level = users.xp_to_level( users.read_user(userid, key=users.GATHER_XP_KEY)) item_xp = items.get_attr(itemid, key=items.XP_KEY) item_level = items.get_attr(itemid, key=items.LEVEL_KEY) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) if items.TREE_KEY: if int(equipment['13']) > -1: item_multiplier = 2 - ( items.get_attr(equipment['13'], key=items.LEVEL_KEY) / 100) else: item_multiplier = 10 elif items.ROCK_KEY: if int(equipment['14']) > -1: item_multiplier = 2 - ( items.get_attr(equipment['14'], key=items.LEVEL_KEY) / 100) else: item_multiplier = 10 else: item_multiplier = 2 time_multiplier = gather_level / item_level number = math.floor(time * time_multiplier / (item_xp * item_multiplier * ((100 - item_level) / 200))) return number
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 calc_chance(userid, monsterid, number): """Calculates the chance of success of a task.""" equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_arm = users.get_equipment_stats(equipment)[2] monster_acc = mon.get_attr(monsterid, key=mon.ACCURACY_KEY) monster_dam = mon.get_attr(monsterid, key=mon.DAMAGE_KEY) monster_combat = mon.get_attr(monsterid, key=mon.LEVEL_KEY) player_combat = users.xp_to_level(users.read_user(userid, key=users.SLAYER_XP_KEY)) number = int(number) if mon.get_attr(monsterid, key=mon.DRAGON_KEY): if equipment['7'] == '266' or equipment['7'] == '293': monster_base = 1 else: monster_base = 100 else: monster_base = 1 player_potion = equipment['15'] if player_potion == '429' or player_potion == '430': player_arm = player_arm * 1.1 + 3 if player_potion == '433' or player_potion == '434': player_arm = player_arm * 1.15 + 5 c = 1 + monster_combat / 200 d = 1 + player_combat / 99 dam_multiplier = monster_base + monster_acc / 200 chance = round(min(100 * max(0, (2 * d * player_arm) / (number / 50 * monster_dam * dam_multiplier + c)), 100)) return chance
def get_task(userid): """Assigns a user a slayer task provided they are not in the middle of another adventure.""" out = SLAYER_HEADER if not adv.is_on_adventure(userid): user_level = users.xp_to_level(users.read_user(userid, key=users.COMBAT_XP_KEY)) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) 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) mon_level = mon.get_attr(monsterid, key=mon.LEVEL_KEY) # print(f'{monsterid} {task_length/base_time} {chance}') if 0.5 <= task_length / base_time <= 2 and chance >= 20 and mon_level / user_level >= 0.9\ and mon.get_attr(monsterid, key=mon.SLAYER_KEY) is True: 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) task = adv.format_line(0, userid, adv.get_finish_time(task_length), monsterid, monster_name, num_to_kill, chance) adv.write(task) out += print_task(userid) else: out = adv.print_adventure(userid) out += adv.print_on_adventure_error('task') return out
def calc_length(userid, itemid, number): """Calculates the length of gathering a number of an item.""" gather_level = users.xp_to_level( users.read_user(userid, key=users.GATHER_XP_KEY)) item_xp = items.get_attr(itemid, key=items.XP_KEY) item_level = items.get_attr(itemid, key=items.LEVEL_KEY) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) if items.get_attr(itemid, key=items.TREE_KEY): if int(equipment['13']) > -1: item_multiplier = 2 - ( items.get_attr(equipment['13'], key=items.LEVEL_KEY) / 100) else: item_multiplier = 10 elif items.get_attr(itemid, key=items.ROCK_KEY): if int(equipment['14']) > -1: item_multiplier = 2 - ( items.get_attr(equipment['14'], key=items.LEVEL_KEY) / 100) else: item_multiplier = 10 else: item_multiplier = 2 time_multiplier = gather_level / item_level base_time = math.floor(number * item_xp * (100 - item_level) / 200) time = round(item_multiplier * base_time / time_multiplier) return base_time, time
def calc_length(userid, monsterid, number): """Calculates the length of a task.""" combat_level = users.xp_to_level(users.read_user(userid, key=users.COMBAT_XP_KEY)) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_dam, player_acc, player_arm = users.get_equipment_stats(equipment) monster_arm = mon.get_attr(monsterid, key=mon.ARMOUR_KEY) monster_xp = mon.get_attr(monsterid, key=mon.XP_KEY) if mon.get_attr(monsterid, key=mon.DRAGON_KEY) == 1: if equipment['7'] == '266' or equipment['7'] == '293': monster_base = 1 else: monster_base = 100 else: monster_base = 1 player_potion = equipment['15'] if player_potion == '427' or player_potion == '430': player_acc = player_acc * 1.1 + 3 if player_potion == '428' or player_potion == '430': player_dam = player_dam * 1.1 + 3 if player_potion == '429' or player_potion == '430': player_arm = player_arm * 1.1 + 3 if player_potion == '431' or player_potion == '434': player_acc = player_acc * 1.15 + 5 if player_potion == '432' or player_potion == '434': player_dam = player_dam * 1.15 + 5 if player_potion == '433' or player_potion == '434': player_arm = player_arm * 1.15 + 5 c = combat_level dam_multiplier = 1 + player_acc / 200 base_time = math.floor(number * monster_xp / 10) time = round(base_time * monster_arm * monster_base / (player_dam * dam_multiplier + c)) return base_time, time
def print_chance(userid, monsterid, monster_dam=-1, monster_acc=-1, monster_arm=-1, monster_combat=-1, xp=-1, number=100, dragonfire=False): equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_dam, player_acc, player_arm = users.get_equipment_stats(equipment) player_combat = users.xp_to_level(users.read_user(userid, key=users.SLAYER_XP_KEY)) if monster_dam == -1: monster_dam = mon.get_attr(monsterid, key=mon.DAMAGE_KEY) monster_acc = mon.get_attr(monsterid, key=mon.ACCURACY_KEY) monster_arm = mon.get_attr(monsterid, key=mon.ARMOUR_KEY) xp = mon.get_attr(monsterid, key=mon.XP_KEY) monster_combat = mon.get_attr(monsterid, key=mon.LEVEL_KEY) if dragonfire: monster_base = 100 else: monster_base = 1 c = 1 + monster_combat / 200 d = 1 + player_combat / 99 dam_multiplier = monster_base + monster_acc / 200 chance = round(min(100 * max(0, (2 * d * player_arm) / (number / 50 * monster_dam * dam_multiplier + c)), 100)) # chance = round(min(100 * max(0, (player_arm / (monster_dam * dam_multiplier + 1 + monster_combat / 200)) / 2 + player_combat / 200), 100)) dam_multiplier = 1 + player_acc / 200 base_time = math.floor(number * xp / 10) time = round(base_time * (monster_arm * monster_base / (player_dam * dam_multiplier + player_combat))) out = f'level {monster_combat} monster with {monster_dam} dam {monster_acc} acc {monster_arm} arm giving {xp} xp: '\ f'chance: {chance}%, base time: {base_time}, time to kill {number}: {time}, time ratio: {time / base_time}.' return out
def start_gather(userid, item, length=-1, number=-1): """Starts a gathering session.""" out = '' if not adv.is_on_adventure(userid): try: itemid = items.find_by_name(item) length = int(length) number = int(number) except KeyError: return f'Error: {item} is not an item.' except ValueError: return f'Error: {length} is not a valid length of time.' if not items.get_attr(itemid, key=items.GATHER_KEY): return f'Error: you cannot gather item {items.get_attr(itemid)}.' item_name = items.get_attr(itemid) gather_level = users.xp_to_level( users.read_user(userid, key=users.GATHER_XP_KEY)) gather_requirement = items.get_attr(itemid, key=items.LEVEL_KEY) player_potion = users.read_user(userid, key=users.EQUIPMENT_KEY)['15'] if player_potion == '435': boosted_level = gather_level + 3 if player_potion == '436': boosted_level = gather_level + 6 else: boosted_level = gather_level if boosted_level < gather_requirement: return f'Error: {item_name} has a gathering requirement ({gather_requirement}) higher ' \ f'than your gathering level ({gather_level})' quest_req = items.get_attr(itemid, key=items.QUEST_KEY) if quest_req not in set( users.get_completed_quests(userid)) and quest_req > 0: return f'Error: You do not have the required quest to gather this item.' if number > 1000 and gather_level == 99: number = 1000 if number > 500 and gather_level < 99: number = 500 if length > 180: length = 180 if int(number) < 0: number = calc_number(userid, itemid, length * 60) if number > 500: number = 500 elif int(length) < 0: length = math.floor(calc_length(userid, itemid, number)[1] / 60) else: return 'Error: argument missing (number or kill length).' gather = adv.format_line(3, userid, adv.get_finish_time(length * 60), itemid, item_name, number, length) adv.write(gather) out += f'You are now gathering {items.add_plural(number, itemid)} for {length} minutes.' else: out = adv.print_adventure(userid) out += adv.print_on_adventure_error('gathering') return out
def calc_burn(userid, itemid): """Calculates the burn chance for a given food.""" cook_level = users.read_user(userid, key=users.COOK_XP_KEY) cook_req = items.get_attr(itemid, key=items.COOK_KEY) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) c = 10 if equipment['9'] == '493' else 0 chance = max(100 * ((cook_level - cook_req + c) / 20), 20) return 100 - min(100, chance)
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 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 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 calc_number(userid, itemid, time): """Calculates the number of items that can be gathered in a given time period.""" gather_level = users.xp_to_level(users.read_user(userid, key=users.GATHER_XP_KEY)) item_xp = items.get_attr(itemid, key=items.XP_KEY) item_level = items.get_attr(itemid, key=items.LEVEL_KEY) number = math.floor((gather_level * time) / (120 * item_xp * item_level)) return number
def calc_number(userid, monsterid, time): """Calculates the number of monsters that can be killed in a given time period.""" combat_level = users.xp_to_level(users.read_user(userid, key=users.COMBAT_XP_KEY)) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_dam, player_acc, player_arm = users.get_equipment_stats(equipment) monster_arm = mon.get_attr(monsterid, key=mon.ARMOUR_KEY) monster_xp = mon.get_attr(monsterid, key=mon.XP_KEY) if mon.get_attr(monsterid, key=mon.DRAGON_KEY) and '266' not in equipment: monster_base = 100 else: monster_base = 1 dam_multiplier = 1 + player_acc / 200 number = math.floor((10 * time * (player_dam * dam_multiplier + combat_level)) / (monster_arm * monster_base * monster_xp)) return number
def calc_length(userid, monsterid, number): """Calculates the length of a task.""" combat_level = users.xp_to_level(users.read_user(userid, key=users.COMBAT_XP_KEY)) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_dam, player_acc, player_arm = users.get_equipment_stats(equipment) monster_arm = mon.get_attr(monsterid, key=mon.ARMOUR_KEY) monster_xp = mon.get_attr(monsterid, key=mon.XP_KEY) if mon.get_attr(monsterid, key=mon.DRAGON_KEY) and '266' not in equipment: monster_base = 100 else: monster_base = 1 c = combat_level dam_multiplier = 1 + player_acc / 200 base_time = math.floor(number * monster_xp / 10) time = round(base_time * (monster_arm * monster_base / (player_dam * dam_multiplier + c))) return base_time, time
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_display_name(member): """Gets the displayed name of a user.""" if member.nick is None: name = member.name else: name = member.nick if users.read_user(member.id, key=users.IRONMAN_KEY): name += ' (IM)' return name
def calc_chance(userid, monsterid, monster_stats=None): """Calculates the chance of success of a task.""" equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_arm = users.get_equipment_stats(equipment)[2] monster_acc = mon.get_attr(monsterid, key=mon.ACCURACY_KEY) monster_dam = mon.get_attr(monsterid, key=mon.DAMAGE_KEY) monster_combat = mon.get_attr(monsterid, key=mon.LEVEL_KEY) player_combat = users.xp_to_level(users.read_user(userid, key=users.SLAYER_XP_KEY)) if mon.get_attr(monsterid, key=mon.DRAGON_KEY) and '266' not in equipment: monster_base = 100 else: monster_base = 1 c = 1 + monster_combat / 200 d = player_combat / 200 dam_multiplier = monster_base + monster_acc / 200 chance = round(min(100 * max(0, (player_arm / (monster_dam * dam_multiplier + c)) / 2 + d), 100)) return chance
def print_clue_scrolls(userid): """Prints the number of clues a user has completed.""" clue_counts = users.read_user(userid, key=users.CLUES_KEY) out = f'{CLUE_HEADER}' for difficulty in sorted(list(clue_counts.keys())): if clue_counts[difficulty] > 0: out += f'**{DIFFICULTY[int(difficulty)].title()}**: {clue_counts[difficulty]}\n' return out
def calc_length(userid, itemid, number): """Calculates the length of gathering a number of an item.""" gather_level = users.xp_to_level(users.read_user(userid, key=users.GATHER_XP_KEY)) item_xp = items.get_attr(itemid, key=items.XP_KEY) item_level = items.get_attr(itemid, key=items.LEVEL_KEY) time_multiplier = gather_level / item_level base_time = math.floor(number * item_xp / 5) time = round(base_time / time_multiplier) return base_time, time
def print_monster_kills(userid, name): """Prints the number of monsters a user has killed.""" monster_kills = users.read_user(userid, key=users.MONSTERS_KEY) out = f"{users.CHARACTER_HEADER.replace('$NAME', name)}" for monsterid in sorted(list(monster_kills.keys())): if monster_kills[monsterid] > 0: out += f'**{get_attr(monsterid).title()}**: {monster_kills[monsterid]}\n' return out
def get_luck_factor(userid): """Gets the luck factor of a user.""" equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) luck_factor = 1 for itemid in equipment.values(): if int(itemid) > 0: item_luck = get_attr(itemid, key=LUCK_KEY) if item_luck > luck_factor: luck_factor = item_luck return luck_factor
def calc_length(userid, questid): """Calculates the length of success of a quest.""" combat_level = users.xp_to_level(users.read_user(userid, key=users.COMBAT_XP_KEY)) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_dam, player_acc, player_arm = users.get_equipment_stats(equipment) monster_arm = get_attr(questid, key=ARMOUR_KEY) base_time = 60 * get_attr(questid, key=TIME_KEY) if get_attr(questid, key=DRAGON_KEY) and '266' not in equipment: monster_base = 100 else: monster_base = 1 c = combat_level dam_multiplier = 1 + player_acc / 200 time = round(base_time * (monster_arm * monster_base / (player_dam * dam_multiplier + c))) if time < 0.5 * base_time: time = round(0.5 * base_time) if time > 2 * base_time: time = 2 * base_time return time
def calc_chance(userid, questid): """Calculates the chance of success of a quest.""" equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) player_arm = users.get_equipment_stats(equipment)[2] monster_acc = get_attr(questid, key=ACCURACY_KEY) monster_dam = get_attr(questid, key=DAMAGE_KEY) monster_combat = get_attr(questid, key=LEVEL_KEY) player_combat = users.xp_to_level(users.read_user(userid, key=users.SLAYER_XP_KEY)) if get_attr(questid, key=DRAGON_KEY): if equipment['7'] == '266' or equipment['7'] == '293': monster_base = 1 else: monster_base = 100 else: monster_base = 1 c = 1 + monster_combat / 200 d = player_combat / 200 dam_multiplier = monster_base + monster_acc / 200 chance = round(min(100 * max(0, (player_arm / (monster_dam * dam_multiplier + c)) / 2 + d), 100)) return chance
async def starter_gear(self, ctx): """Gives the user a set of bronze armour.""" if ctx.channel.id == SHOP_CHANNEL or ctx.channel.id == COMBAT_CHANNEL: if users.read_user(ctx.author.id, key=users.COMBAT_XP_KEY) == 0: users.update_inventory(ctx.author.id, [63, 66, 69, 70]) await ctx.send( f'Bronze set given to {ctx.author.name}! You can see your items by typing `~inventory` ' f'and equip them by typing `~me equip [item]`. You can see your current stats by typing ' f'`~me`.') else: await ctx.send( f'You are too experienced to get the starter gear, {ctx.author.name}.' )
def get_task(userid): """Assigns a user a slayer task provided they are not in the middle of another adventure.""" out = SLAYER_HEADER if not adv.is_on_adventure(userid): user_level = users.xp_to_level(users.read_user(userid, key=users.COMBAT_XP_KEY)) completed_quests = set(users.get_completed_quests(userid)) equipment = users.read_user(userid, key=users.EQUIPMENT_KEY) 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) mon_level = mon.get_attr(monsterid, key=mon.LEVEL_KEY) # print(f'{monsterid} {task_length/base_time} {chance}') if 0.25 <= task_length / base_time <= 2 and chance >= 20 and mon_level / user_level >= 0.8\ and mon.get_attr(monsterid, key=mon.SLAYER_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." 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 monster_name = mon.get_attr(monsterid) task = adv.format_line(0, userid, adv.get_finish_time(task_length), monsterid, monster_name, num_to_kill, chance) adv.write(task) out += print_task(userid) 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('task') 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
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_kill(userid, monster, length=-1, number=-1): """Lets the user start killing monsters..""" out = f'{SLAYER_HEADER}' if not adv.is_on_adventure(userid): try: monsterid = mon.find_by_name(monster) length = int(length) number = int(number) except KeyError: return f'Error: {monster} is not a monster.' except ValueError: return f'Error: {length} is not a valid length of time.' completed_quests = users.get_completed_quests(userid) quest_req = mon.get_attr(monsterid, key=mon.QUEST_REQ_KEY) if not {quest_req}.issubset(completed_quests) and quest_req != 0: return f'Error: you do not have the required quests to kill this monster.' monster_name = mon.get_attr(monsterid) slayer_level = users.xp_to_level(users.read_user(userid, key=users.SLAYER_XP_KEY)) slayer_requirement = mon.get_attr(monsterid, key=mon.SLAYER_REQ_KEY) if slayer_level < slayer_requirement: return f'Error: {monster_name} has a slayer requirement ({slayer_requirement}) higher ' \ f'than your slayer level ({slayer_level})' if number > 1000 and slayer_level == 99: number = 1000 if number > 500 and slayer_level < 99: number = 500 if length > 180: length = 180 if int(number) < 0: number = calc_number(userid, monsterid, (length + 1) * 60) - 1 if number > 1000 and slayer_level == 99: number = 1000 if number > 500 and slayer_level < 99: number = 500 elif int(length) < 0: length = math.floor(calc_length(userid, monsterid, number)[1] / 60) else: return 'Error: argument missing (number or kill length).' grind = adv.format_line(1, userid, adv.get_finish_time(length * 60), monsterid, monster_name, number, length) adv.write(grind) out += f'You are now killing {mon.add_plural(number, monsterid, with_zero=True)} for {length} minutes. ' else: out = adv.print_adventure(userid) out += adv.print_on_adventure_error('kill') return out