Advertisement
Guest User

Untitled

a guest
Dec 12th, 2019
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.23 KB | None | 0 0
  1. try:
  2. # notnotmelon 10/17/19
  3. # talisman calcuator aka maximise the damage function with 11 inputs
  4.  
  5. from math import *
  6.  
  7. #------------------------------------#
  8. #--------------FUNCTIONS-------------#
  9. #------------------------------------#
  10.  
  11. # This class is a bit confusing ngl
  12. # It defines one route of one rarity
  13. # For example, if you have 5 rare talisman than one possiblity for this class's data would be (1, 2, 3, 0, 0)
  14. # It's confusing since I use a seperate construct to define the route for all rarities
  15. # That seperate construct is actually just a list of these routes
  16. class route:
  17. def __init__(self, counts, rarity):
  18. self.counts = counts
  19. self.rarity = rarity
  20. self.rarity_str = ["common", "uncommon", "rare", "epic", "legendary"][rarity]
  21. 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)]
  22. self.strength, self.crit_chance, self.crit_dmg = self.stats
  23. def __repr__(self):
  24. result = ""
  25. for name, c in zip(talismans.keys(), self.counts):
  26. if c != 0:
  27. result += "{} {} {}{}, ".format(c, "godly/zealous" if self.rarity < 2 and name == "godly" else name, self.rarity_str, "" if c == 1 else "s")
  28. return result[:-2]
  29. def strength(self):
  30. return self.stats[0]
  31. def crit_damage(self):
  32. return self.stats[2]
  33.  
  34. def bump(lst, idx, x):
  35. lst = lst.copy()
  36. lst[idx] += x
  37. return lst
  38.  
  39. def routes(count, size, rarity):
  40. main = []
  41.  
  42. def helper(count, idx, current):
  43. if count == 0:
  44. main.append(current)
  45. elif idx == size - 1:
  46. main.append(bump(current, idx, count))
  47. else:
  48. if talismans_raw[idx][rarity]:
  49. helper(count - 1, idx, bump(current, idx, 1))
  50. helper(count, idx + 1, current)
  51.  
  52. helper(count, 0, [0] * size)
  53. return [route(x, rarity) for x in main]
  54.  
  55. def print_result(damage, routes):
  56. 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)) + ")")
  57.  
  58. def raw_damage(bouns_str):
  59. return (5 + weapon_dmg + (strength + bouns_str) // 5) * (1 + (bouns_str + strength) / 100.0)
  60.  
  61. def ench_damage(bouns_str):
  62. return raw_damage(bouns_str) * (1 + ench_modifer / 100.0)
  63.  
  64.  
  65. def damage(bouns_str, bonus_crit_dmg):
  66. return ench_damage(bouns_str) * (1 + (bonus_crit_dmg + crit_dmg) / 100.0)
  67.  
  68. def final_damage(routes):
  69. return damage(routes[0].strength + routes[1].strength + routes[2].strength + routes[3].strength + routes[4].strength,
  70. routes[0].crit_dmg + routes[1].crit_dmg + routes[2].crit_dmg + routes[3].crit_dmg + routes[4].crit_dmg)
  71.  
  72. def final_damage_alt(r1, r2, r3, r4, r5):
  73. return damage(r1.strength + r2.strength + r3.strength + r4.strength + r5.strength,
  74. r1.crit_dmg + r2.crit_dmg + r3.crit_dmg + r4.crit_dmg + r5.crit_dmg)
  75.  
  76. #------------------------------------#
  77. #--------------VARIBLES--------------#
  78. #------------------------------------#
  79.  
  80. # Format is (common X, unc X, rare X, epic X), with X substutied with (str, chance, crit dmg)
  81. # Areas with "None" have direct upgrades in other reforges
  82. talismans = {
  83. 'forceful': ((2, 0, 0), (4, 0, 0), (7, 0, 0), (10, 0, 0), (15, 0, 0)),
  84. 'itchy': ((1, 0, 3), (2, 0, 5), (2, 0, 8), (3, 0, 12), (5, 0, 15)),
  85. #'unpleasant': ((0, 1, 1), None, (0, 3, 2), (0, 6, 3), (0, 8, 5)), -- too laggy not worth keeping
  86. 'strong': (None, None, (4, 0, 4), (7, 0, 7), (10, 0, 10)),
  87. 'godly': ((1, 1, 1), (2, 2, 2), (4, 2, 3), (7, 3, 6), (10, 5, 8)),
  88. }
  89.  
  90. red_claw = {'none': 0, 'talisman': 1, 'ring': 3, 'artifact': 5}
  91.  
  92. print("Welcome to notnotmelon's talisman optimiser! Make sure you follow each prompt exactly and make sure you:")
  93.  
  94. talismans_raw = list(talismans.values())
  95. for i, rule in enumerate(["Put all your talismans away (don't forget the piggy bank)",
  96. "You don't have any potion effects",
  97. "Use /sbmenu while holding your sword for accurate stats",
  98. "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"]):
  99. print(" " + str(i + 1) + ". " + rule)
  100. bow = input("Are you using a sword or a bow? valid inputs are: SWORD or BOW ").lower() == "bow"
  101. if not bow:
  102. 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")
  103. weapon_dmg = int(input("What is the damage stat on the weapon's tooltip? "))
  104. (strength, chance, crit_dmg) = [int(input('What is your ' + stat + '? ')) for stat in ['strength', 'crit chance', 'crit damage']]
  105. counts = [int(input('How many ' + rarity + ' talismen do you use? ')) for rarity in ['common', 'uncommon', 'rare', 'epic', 'legendary']]
  106. combat = int(input('What is your combat level? '))
  107. crit_goal = int(input('Do you want 80 or 100 crit chance? ')) - chance
  108.  
  109. use_crit = True
  110. if crit_goal <= 0:
  111. print("It looks like you already meet your crit goal, so that value will not be used in the calculations (will also take longer)")
  112. use_crit = False
  113. crit_goal = 0
  114.  
  115. crystals = False
  116. red_claw = red_claw[input("Which red claw talisman do you use? valid inputs are: TALISMAN, RING, ARTIFACT, or NONE ").lower()]
  117. if input("Do you have the day and night crystals? valid inputs are YES or NO ").lower() == "yes":
  118. strength += 5
  119. crystals = True
  120. crit_dmg += red_claw
  121.  
  122. mob_specfic = [["dragon hunter", 8]] if bow else [
  123. ["smite", 8],
  124. ["bane of arthropods", 8],
  125. ["impaling", 12.5],
  126. ["cubism", 10],
  127. ["ender slayer", 12]
  128. ]
  129. ench_modifer = combat * 4 + 25
  130. sharpness = True
  131. for ench, boost in mob_specfic:
  132. using = "yes" == input("Is the mob you are fighting affected by " + ench + "? valid inputs are: YES or NO ").lower()
  133. if using:
  134. ench_modifer += int(input("What level of " + ench + " do you have? ")) * boost
  135. if ench == "smite" or ench == "bane of arthropods":
  136. sharpness = False
  137. if bow:
  138. ench_modifer += 8 * int(input("What level of power do you have? "))
  139. ench_modifer += 6 # Snipe
  140. else:
  141. if sharpness:
  142. ench_modifer += 5 * int(input("What level of sharpness do you have? "))
  143. 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)
  144.  
  145. route_set = [routes(counts[i], len(talismans), i) for i in range(5)]
  146.  
  147. #------------------------------------#
  148. #---------------ALGORITHM------------#
  149. #------------------------------------#
  150.  
  151. #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]
  152. progress = len(route_set[0])
  153. last = 0
  154. if use_crit:
  155. all_routes_to_max_crit = []
  156. # 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
  157. s1, s2, s3, s4, s5 = route_set
  158. for i, r1 in enumerate(s1):
  159. percent_finished = i * 100 // progress
  160. if percent_finished > last:
  161. print(last, "%")
  162. last = percent_finished
  163. cc1 = r1.crit_chance
  164. for r2 in s2:
  165. cc2 = r2.crit_chance + cc1
  166. for r3 in s3:
  167. cc3 = r3.crit_chance + cc2
  168. for r4 in s4:
  169. cc4 = r4.crit_chance + cc3
  170. for r5 in s5:
  171. if cc4 + r5.crit_chance == crit_goal:
  172. all_routes_to_max_crit.append([r1, r2, r3, r4, r5])
  173.  
  174. print("Your results are almost ready, performing final calculations...")
  175.  
  176. if len(all_routes_to_max_crit) == 0:
  177. print("There is no possible combination that reaches the desired crit chance, try to get more talismen or level up your combat skill")
  178. else:
  179. max1 = [0, None]
  180. max2 = [0, None]
  181. max3 = [0, None]
  182. for routes in all_routes_to_max_crit:
  183. d = final_damage(routes)
  184. if max1[0] < d:
  185. max3 = max2
  186. max2 = max1
  187. max1 = [d, routes]
  188. elif max2[0] < d:
  189. max3 = max2
  190. max2 = [d, routes]
  191. elif max3[0] < d:
  192. max3 = [d, routes]
  193. print("The 3 best sets of talisman reforges are:")
  194. print_result(*max1)
  195. print_result(*max2)
  196. print_result(*max3)
  197. else:
  198. max_dmg = 0
  199. max_routes = None
  200. for i, r1 in enumerate(route_set[0]):
  201. percent_finished = i * 100 // progress
  202. if percent_finished > last:
  203. print(last, "%")
  204. last = percent_finished
  205. for r2 in route_set[1]:
  206. for r3 in route_set[2]:
  207. for r4 in route_set[3]:
  208. for r5 in route_set[4]:
  209. if max_dmg < final_damage_alt(r1, r2, r3, r4, r5):
  210. max_dmg = final_damage_alt(r1, r2, r3, r4, r5)
  211. max_routes = [r1, r2, r3, r4, r5]
  212. print("The best set of talisman reforges are:")
  213. print_result(max_dmg, max_routes)
  214.  
  215. #------------------------------------#
  216. #--------------OUTPUT----------------#
  217. #------------------------------------#
  218.  
  219. print("\nUsing the current meta (itchy on rares, epics, legendaries, and commons) (godly on uncommons until 80%cc) would give you:")
  220. # You could either use all of your crit goal or all of your unc talismans
  221. unc_needed = min(counts[1], crit_goal // 2)
  222. com_needed = min(counts[0], crit_goal - unc_needed * 2)
  223. meta_routes = [route((0, counts[0] - com_needed, 0, com_needed), 0),
  224. route((0, counts[1] - unc_needed, 0, unc_needed), 1),
  225. route((0, counts[2], 0, 0), 2),
  226. route((0, counts[3], 0, 0), 3),
  227. route((0, counts[4], 0, 0), 4)]
  228. print_result(final_damage(meta_routes), meta_routes)
  229. cc_boost = com_needed + unc_needed * 2
  230. if cc_boost < crit_goal:
  231. print("This setup would also only give ", cc_boost + chance, "% crit chance", sep = "")
  232.  
  233. print("\nYou should be doing", damage(-5 if crystals else 0, -red_claw), "without any talismen")
  234.  
  235. # Yeah the current meta is trash lol
  236. except Exception as e:
  237. print(e)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement