Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- try:
- # notnotmelon 10/17/19
- # talisman calcuator aka maximise the damage function with 11 inputs
- from math import *
- #------------------------------------#
- #--------------FUNCTIONS-------------#
- #------------------------------------#
- # This class is a bit confusing ngl
- # It defines one route of one rarity
- # For example, if you have 5 rare talisman than one possiblity for this class's data would be (1, 2, 3, 0, 0)
- # It's confusing since I use a seperate construct to define the route for all rarities
- # That seperate construct is actually just a list of these routes
- class route:
- def __init__(self, counts, rarity):
- self.counts = counts
- self.rarity = rarity
- self.rarity_str = ["common", "uncommon", "rare", "epic", "legendary"][rarity]
- self.stats = [sum(talismans_raw[y][rarity][x] * counts[y] if talismans_raw[y][rarity] else 0 for y in range(len(talismans_raw))) for x in range(3)]
- self.strength, self.crit_chance, self.crit_dmg = self.stats
- def __repr__(self):
- result = ""
- for name, c in zip(talismans.keys(), self.counts):
- if c != 0:
- result += "{} {} {}{}, ".format(c, "godly/zealous" if self.rarity < 2 and name == "godly" else name, self.rarity_str, "" if c == 1 else "s")
- return result[:-2]
- def strength(self):
- return self.stats[0]
- def crit_damage(self):
- return self.stats[2]
- def bump(lst, idx, x):
- lst = lst.copy()
- lst[idx] += x
- return lst
- def routes(count, size, rarity):
- main = []
- def helper(count, idx, current):
- if count == 0:
- main.append(current)
- elif idx == size - 1:
- main.append(bump(current, idx, count))
- else:
- if talismans_raw[idx][rarity]:
- helper(count - 1, idx, bump(current, idx, 1))
- helper(count, idx + 1, current)
- helper(count, 0, [0] * size)
- return [route(x, rarity) for x in main]
- def print_result(damage, routes):
- print("{:0.2f}".format(damage), routes, "(str:", strength + sum(r.strength for r in routes), "crit damage:", crit_dmg + sum(r.crit_dmg for r in routes), "crit chance:", str(chance + sum(r.crit_chance for r in routes)) + ")")
- def raw_damage(bouns_str):
- return (5 + weapon_dmg + (strength + bouns_str) // 5) * (1 + (bouns_str + strength) / 100.0)
- def ench_damage(bouns_str):
- return raw_damage(bouns_str) * (1 + ench_modifer / 100.0)
- def damage(bouns_str, bonus_crit_dmg):
- return ench_damage(bouns_str) * (1 + (bonus_crit_dmg + crit_dmg) / 100.0)
- def final_damage(routes):
- return damage(routes[0].strength + routes[1].strength + routes[2].strength + routes[3].strength + routes[4].strength,
- routes[0].crit_dmg + routes[1].crit_dmg + routes[2].crit_dmg + routes[3].crit_dmg + routes[4].crit_dmg)
- def final_damage_alt(r1, r2, r3, r4, r5):
- return damage(r1.strength + r2.strength + r3.strength + r4.strength + r5.strength,
- r1.crit_dmg + r2.crit_dmg + r3.crit_dmg + r4.crit_dmg + r5.crit_dmg)
- #------------------------------------#
- #--------------VARIBLES--------------#
- #------------------------------------#
- # Format is (common X, unc X, rare X, epic X), with X substutied with (str, chance, crit dmg)
- # Areas with "None" have direct upgrades in other reforges
- talismans = {
- 'forceful': ((2, 0, 0), (4, 0, 0), (7, 0, 0), (10, 0, 0), (15, 0, 0)),
- 'itchy': ((1, 0, 3), (2, 0, 5), (2, 0, 8), (3, 0, 12), (5, 0, 15)),
- #'unpleasant': ((0, 1, 1), None, (0, 3, 2), (0, 6, 3), (0, 8, 5)), -- too laggy not worth keeping
- 'strong': (None, None, (4, 0, 4), (7, 0, 7), (10, 0, 10)),
- 'godly': ((1, 1, 1), (2, 2, 2), (4, 2, 3), (7, 3, 6), (10, 5, 8)),
- }
- red_claw = {'none': 0, 'talisman': 1, 'ring': 3, 'artifact': 5}
- print("Welcome to notnotmelon's talisman optimiser! Make sure you follow each prompt exactly and make sure you:")
- talismans_raw = list(talismans.values())
- for i, rule in enumerate(["Put all your talismans away (don't forget the piggy bank)",
- "You don't have any potion effects",
- "Use /sbmenu while holding your sword for accurate stats",
- "Know that the reforges for the feather, potion, bat, intimidation, sea creature, and candy artifacts don't stack with the reforges of the rings/talismen of the same family"]):
- print(" " + str(i + 1) + ". " + rule)
- bow = input("Are you using a sword or a bow? valid inputs are: SWORD or BOW ").lower() == "bow"
- if not bow:
- print("This calculator optimizes your damage for a specific type of mob. Before you use the calculator, think about which mob you damage most often with your sword")
- weapon_dmg = int(input("What is the damage stat on the weapon's tooltip? "))
- (strength, chance, crit_dmg) = [int(input('What is your ' + stat + '? ')) for stat in ['strength', 'crit chance', 'crit damage']]
- counts = [int(input('How many ' + rarity + ' talismen do you use? ')) for rarity in ['common', 'uncommon', 'rare', 'epic', 'legendary']]
- combat = int(input('What is your combat level? '))
- crit_goal = int(input('Do you want 80 or 100 crit chance? ')) - chance
- use_crit = True
- if crit_goal <= 0:
- print("It looks like you already meet your crit goal, so that value will not be used in the calculations (will also take longer)")
- use_crit = False
- crit_goal = 0
- crystals = False
- red_claw = red_claw[input("Which red claw talisman do you use? valid inputs are: TALISMAN, RING, ARTIFACT, or NONE ").lower()]
- if input("Do you have the day and night crystals? valid inputs are YES or NO ").lower() == "yes":
- strength += 5
- crystals = True
- crit_dmg += red_claw
- mob_specfic = [["dragon hunter", 8]] if bow else [
- ["smite", 8],
- ["bane of arthropods", 8],
- ["impaling", 12.5],
- ["cubism", 10],
- ["ender slayer", 12]
- ]
- ench_modifer = combat * 4 + 25
- sharpness = True
- for ench, boost in mob_specfic:
- using = "yes" == input("Is the mob you are fighting affected by " + ench + "? valid inputs are: YES or NO ").lower()
- if using:
- ench_modifer += int(input("What level of " + ench + " do you have? ")) * boost
- if ench == "smite" or ench == "bane of arthropods":
- sharpness = False
- if bow:
- ench_modifer += 8 * int(input("What level of power do you have? "))
- ench_modifer += 6 # Snipe
- else:
- if sharpness:
- ench_modifer += 5 * int(input("What level of sharpness do you have? "))
- ench_modifer += (100 if input('Are you trying to oneshot lots of enemies or are you fighting a boss? (For first strike and execute) valid inputs are: ONESHOT or BOSS ').lower() == 'oneshot' else 50)
- route_set = [routes(counts[i], len(talismans), i) for i in range(5)]
- #------------------------------------#
- #---------------ALGORITHM------------#
- #------------------------------------#
- #all_routes_to_max_crit = [x for x in product(*route_set) if crit_goal == x[0].crit_chance + x[1].crit_chance + x[2].crit_chance + x[3].crit_chance]
- progress = len(route_set[0])
- last = 0
- if use_crit:
- all_routes_to_max_crit = []
- # This is the most time consuming part of the algorithm, it sifts through millions of possible routes and pulls out the few that manage to reach the crit goal
- s1, s2, s3, s4, s5 = route_set
- for i, r1 in enumerate(s1):
- percent_finished = i * 100 // progress
- if percent_finished > last:
- print(last, "%")
- last = percent_finished
- cc1 = r1.crit_chance
- for r2 in s2:
- cc2 = r2.crit_chance + cc1
- for r3 in s3:
- cc3 = r3.crit_chance + cc2
- for r4 in s4:
- cc4 = r4.crit_chance + cc3
- for r5 in s5:
- if cc4 + r5.crit_chance == crit_goal:
- all_routes_to_max_crit.append([r1, r2, r3, r4, r5])
- print("Your results are almost ready, performing final calculations...")
- if len(all_routes_to_max_crit) == 0:
- print("There is no possible combination that reaches the desired crit chance, try to get more talismen or level up your combat skill")
- else:
- max1 = [0, None]
- max2 = [0, None]
- max3 = [0, None]
- for routes in all_routes_to_max_crit:
- d = final_damage(routes)
- if max1[0] < d:
- max3 = max2
- max2 = max1
- max1 = [d, routes]
- elif max2[0] < d:
- max3 = max2
- max2 = [d, routes]
- elif max3[0] < d:
- max3 = [d, routes]
- print("The 3 best sets of talisman reforges are:")
- print_result(*max1)
- print_result(*max2)
- print_result(*max3)
- else:
- max_dmg = 0
- max_routes = None
- for i, r1 in enumerate(route_set[0]):
- percent_finished = i * 100 // progress
- if percent_finished > last:
- print(last, "%")
- last = percent_finished
- for r2 in route_set[1]:
- for r3 in route_set[2]:
- for r4 in route_set[3]:
- for r5 in route_set[4]:
- if max_dmg < final_damage_alt(r1, r2, r3, r4, r5):
- max_dmg = final_damage_alt(r1, r2, r3, r4, r5)
- max_routes = [r1, r2, r3, r4, r5]
- print("The best set of talisman reforges are:")
- print_result(max_dmg, max_routes)
- #------------------------------------#
- #--------------OUTPUT----------------#
- #------------------------------------#
- print("\nUsing the current meta (itchy on rares, epics, legendaries, and commons) (godly on uncommons until 80%cc) would give you:")
- # You could either use all of your crit goal or all of your unc talismans
- unc_needed = min(counts[1], crit_goal // 2)
- com_needed = min(counts[0], crit_goal - unc_needed * 2)
- meta_routes = [route((0, counts[0] - com_needed, 0, com_needed), 0),
- route((0, counts[1] - unc_needed, 0, unc_needed), 1),
- route((0, counts[2], 0, 0), 2),
- route((0, counts[3], 0, 0), 3),
- route((0, counts[4], 0, 0), 4)]
- print_result(final_damage(meta_routes), meta_routes)
- cc_boost = com_needed + unc_needed * 2
- if cc_boost < crit_goal:
- print("This setup would also only give ", cc_boost + chance, "% crit chance", sep = "")
- print("\nYou should be doing", damage(-5 if crystals else 0, -red_claw), "without any talismen")
- # Yeah the current meta is trash lol
- except Exception as e:
- print(e)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement