osrs-tools 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +6 -0
  4. package/dist/runescape/model/Item/all/Black2hSword.d.ts +3 -0
  5. package/dist/runescape/model/Item/all/Black2hSword.d.ts.map +1 -0
  6. package/dist/runescape/model/Item/all/Black2hSword.js +21 -0
  7. package/dist/runescape/model/Item/all/BlackChainbody.d.ts +3 -0
  8. package/dist/runescape/model/Item/all/BlackChainbody.d.ts.map +1 -0
  9. package/dist/runescape/model/Item/all/BlackChainbody.js +21 -0
  10. package/dist/runescape/model/Item/all/BlackKiteshield.d.ts +3 -0
  11. package/dist/runescape/model/Item/all/BlackKiteshield.d.ts.map +1 -0
  12. package/dist/runescape/model/Item/all/BlackKiteshield.js +21 -0
  13. package/dist/runescape/model/Item/all/BlackMace.d.ts +3 -0
  14. package/dist/runescape/model/Item/all/BlackMace.d.ts.map +1 -0
  15. package/dist/runescape/model/Item/all/BlackMace.js +21 -0
  16. package/dist/runescape/model/Item/all/BlackMedHelm.d.ts +3 -0
  17. package/dist/runescape/model/Item/all/BlackMedHelm.d.ts.map +1 -0
  18. package/dist/runescape/model/Item/all/BlackMedHelm.js +21 -0
  19. package/dist/runescape/model/Item/all/BlackRobe.d.ts +3 -0
  20. package/dist/runescape/model/Item/all/BlackRobe.d.ts.map +1 -0
  21. package/dist/runescape/model/Item/all/BlackRobe.js +21 -0
  22. package/dist/runescape/model/Item/all/BlackScimitar.d.ts +3 -0
  23. package/dist/runescape/model/Item/all/BlackScimitar.d.ts.map +1 -0
  24. package/dist/runescape/model/Item/all/BlackScimitar.js +21 -0
  25. package/dist/runescape/model/Item/all/BlackSword.d.ts +3 -0
  26. package/dist/runescape/model/Item/all/BlackSword.d.ts.map +1 -0
  27. package/dist/runescape/model/Item/all/BlackSword.js +21 -0
  28. package/dist/runescape/model/Item/all/BlackWarhammer.d.ts +3 -0
  29. package/dist/runescape/model/Item/all/BlackWarhammer.d.ts.map +1 -0
  30. package/dist/runescape/model/Item/all/BlackWarhammer.js +21 -0
  31. package/dist/runescape/model/Item/all/BlueWizardHat.d.ts +3 -0
  32. package/dist/runescape/model/Item/all/BlueWizardHat.d.ts.map +1 -0
  33. package/dist/runescape/model/Item/all/BlueWizardHat.js +21 -0
  34. package/dist/runescape/model/Item/all/BlueWizardRobe.d.ts +3 -0
  35. package/dist/runescape/model/Item/all/BlueWizardRobe.d.ts.map +1 -0
  36. package/dist/runescape/model/Item/all/BlueWizardRobe.js +21 -0
  37. package/dist/runescape/model/Item/all/BronzeArrow.d.ts +3 -0
  38. package/dist/runescape/model/Item/all/BronzeArrow.d.ts.map +1 -0
  39. package/dist/runescape/model/Item/all/BronzeArrow.js +21 -0
  40. package/dist/runescape/model/Item/all/DeathRune.d.ts +3 -0
  41. package/dist/runescape/model/Item/all/DeathRune.d.ts.map +1 -0
  42. package/dist/runescape/model/Item/all/DeathRune.js +21 -0
  43. package/dist/runescape/model/Item/all/DragonLongsword.d.ts +3 -0
  44. package/dist/runescape/model/Item/all/DragonLongsword.d.ts.map +1 -0
  45. package/dist/runescape/model/Item/all/DragonLongsword.js +21 -0
  46. package/dist/runescape/model/Item/all/GreenDHideBody.d.ts +1 -1
  47. package/dist/runescape/model/Item/all/GreenDHideBody.js +7 -7
  48. package/dist/runescape/model/Item/all/GreenDHideChaps.d.ts +3 -0
  49. package/dist/runescape/model/Item/all/GreenDHideChaps.d.ts.map +1 -0
  50. package/dist/runescape/model/Item/all/GreenDHideChaps.js +27 -0
  51. package/dist/runescape/model/Item/all/HardleatherBody.d.ts +3 -0
  52. package/dist/runescape/model/Item/all/HardleatherBody.d.ts.map +1 -0
  53. package/dist/runescape/model/Item/all/HardleatherBody.js +21 -0
  54. package/dist/runescape/model/Item/all/Herring.d.ts +3 -0
  55. package/dist/runescape/model/Item/all/Herring.d.ts.map +1 -0
  56. package/dist/runescape/model/Item/all/Herring.js +21 -0
  57. package/dist/runescape/model/Item/all/IronArrow.d.ts +3 -0
  58. package/dist/runescape/model/Item/all/IronArrow.d.ts.map +1 -0
  59. package/dist/runescape/model/Item/all/IronArrow.js +21 -0
  60. package/dist/runescape/model/Item/all/IronPickaxe.d.ts +3 -0
  61. package/dist/runescape/model/Item/all/IronPickaxe.d.ts.map +1 -0
  62. package/dist/runescape/model/Item/all/IronPickaxe.js +21 -0
  63. package/dist/runescape/model/Item/all/LeatherBody.d.ts +3 -0
  64. package/dist/runescape/model/Item/all/LeatherBody.d.ts.map +1 -0
  65. package/dist/runescape/model/Item/all/LeatherBody.js +21 -0
  66. package/dist/runescape/model/Item/all/LeatherCowl.d.ts +3 -0
  67. package/dist/runescape/model/Item/all/LeatherCowl.d.ts.map +1 -0
  68. package/dist/runescape/model/Item/all/LeatherCowl.js +21 -0
  69. package/dist/runescape/model/Item/all/LeatherVambraces.d.ts +3 -0
  70. package/dist/runescape/model/Item/all/LeatherVambraces.d.ts.map +1 -0
  71. package/dist/runescape/model/Item/all/LeatherVambraces.js +21 -0
  72. package/dist/runescape/model/Item/all/Longbow.d.ts +3 -0
  73. package/dist/runescape/model/Item/all/Longbow.d.ts.map +1 -0
  74. package/dist/runescape/model/Item/all/Longbow.js +21 -0
  75. package/dist/runescape/model/Item/all/OakLongbow.d.ts +3 -0
  76. package/dist/runescape/model/Item/all/OakLongbow.d.ts.map +1 -0
  77. package/dist/runescape/model/Item/all/OakLongbow.js +21 -0
  78. package/dist/runescape/model/Item/all/OakShortbow.d.ts +3 -0
  79. package/dist/runescape/model/Item/all/OakShortbow.d.ts.map +1 -0
  80. package/dist/runescape/model/Item/all/OakShortbow.js +21 -0
  81. package/dist/runescape/model/Item/all/Sardine.d.ts +3 -0
  82. package/dist/runescape/model/Item/all/Sardine.d.ts.map +1 -0
  83. package/dist/runescape/model/Item/all/Sardine.js +21 -0
  84. package/dist/runescape/model/Item/all/Shortbow.d.ts +3 -0
  85. package/dist/runescape/model/Item/all/Shortbow.d.ts.map +1 -0
  86. package/dist/runescape/model/Item/all/Shortbow.js +21 -0
  87. package/dist/runescape/model/Item/all/Shrimps.d.ts +3 -0
  88. package/dist/runescape/model/Item/all/Shrimps.d.ts.map +1 -0
  89. package/dist/runescape/model/Item/all/Shrimps.js +21 -0
  90. package/dist/runescape/model/Item/all/SoulRune.d.ts +3 -0
  91. package/dist/runescape/model/Item/all/SoulRune.d.ts.map +1 -0
  92. package/dist/runescape/model/Item/all/SoulRune.js +21 -0
  93. package/dist/runescape/model/Item/all/StaffOfEarth.d.ts +3 -0
  94. package/dist/runescape/model/Item/all/StaffOfEarth.d.ts.map +1 -0
  95. package/dist/runescape/model/Item/all/StaffOfEarth.js +21 -0
  96. package/dist/runescape/model/Item/all/StaffOfFire.d.ts +3 -0
  97. package/dist/runescape/model/Item/all/StaffOfFire.d.ts.map +1 -0
  98. package/dist/runescape/model/Item/all/StaffOfFire.js +21 -0
  99. package/dist/runescape/model/Item/all/StaffOfWater.d.ts +3 -0
  100. package/dist/runescape/model/Item/all/StaffOfWater.d.ts.map +1 -0
  101. package/dist/runescape/model/Item/all/StaffOfWater.js +21 -0
  102. package/dist/runescape/model/Item/all/SteelAxe.d.ts +3 -0
  103. package/dist/runescape/model/Item/all/SteelAxe.d.ts.map +1 -0
  104. package/dist/runescape/model/Item/all/SteelAxe.js +21 -0
  105. package/dist/runescape/model/Item/all/SteelDagger.d.ts +3 -0
  106. package/dist/runescape/model/Item/all/SteelDagger.d.ts.map +1 -0
  107. package/dist/runescape/model/Item/all/SteelDagger.js +21 -0
  108. package/dist/runescape/model/Item/all/SteelLongsword.d.ts +3 -0
  109. package/dist/runescape/model/Item/all/SteelLongsword.d.ts.map +1 -0
  110. package/dist/runescape/model/Item/all/SteelLongsword.js +21 -0
  111. package/dist/runescape/model/Item/all/SummerPie.d.ts +3 -0
  112. package/dist/runescape/model/Item/all/SummerPie.d.ts.map +1 -0
  113. package/dist/runescape/model/Item/all/SummerPie.js +21 -0
  114. package/dist/runescape/model/Item/all/TunaPotato.d.ts +3 -0
  115. package/dist/runescape/model/Item/all/TunaPotato.d.ts.map +1 -0
  116. package/dist/runescape/model/Item/all/TunaPotato.js +21 -0
  117. package/dist/runescape/model/Item/all/WizardHat.d.ts +3 -0
  118. package/dist/runescape/model/Item/all/WizardHat.d.ts.map +1 -0
  119. package/dist/runescape/model/Item/all/WizardHat.js +21 -0
  120. package/dist/runescape/model/clue/ClueScrollHelper.d.ts +1 -1
  121. package/dist/runescape/model/clue/ClueScrollHelper.d.ts.map +1 -1
  122. package/dist/runescape/model/clue/ClueScrollHelper.js +114 -197
  123. package/dist/runescape/model/clue/ClueScrollRewards.d.ts +17 -40
  124. package/dist/runescape/model/clue/ClueScrollRewards.d.ts.map +1 -1
  125. package/dist/runescape/model/clue/ClueScrollRewards.js +668 -501
  126. package/dist/runescape/model/collection-log/CollectionLog.d.ts +8 -0
  127. package/dist/runescape/model/collection-log/CollectionLog.d.ts.map +1 -0
  128. package/dist/runescape/model/collection-log/CollectionLog.js +124 -0
  129. package/dist/runescape/model/collection-log/CollectionLog.model.d.ts +48 -0
  130. package/dist/runescape/model/collection-log/CollectionLog.model.d.ts.map +1 -0
  131. package/dist/runescape/model/collection-log/CollectionLog.model.js +13 -0
  132. package/dist/runescape/model/collection-log/index.d.ts +4 -0
  133. package/dist/runescape/model/collection-log/index.d.ts.map +1 -0
  134. package/dist/runescape/model/collection-log/index.js +2 -0
  135. package/dist/runescape/model/combat-achievements/CombatAchievement.model.d.ts +37 -0
  136. package/dist/runescape/model/combat-achievements/CombatAchievement.model.d.ts.map +1 -0
  137. package/dist/runescape/model/combat-achievements/CombatAchievement.model.js +17 -0
  138. package/dist/runescape/model/combat-achievements/CombatAchievements.d.ts +8 -0
  139. package/dist/runescape/model/combat-achievements/CombatAchievements.d.ts.map +1 -0
  140. package/dist/runescape/model/combat-achievements/CombatAchievements.js +80 -0
  141. package/dist/runescape/model/combat-achievements/index.d.ts +4 -0
  142. package/dist/runescape/model/combat-achievements/index.d.ts.map +1 -0
  143. package/dist/runescape/model/combat-achievements/index.js +2 -0
  144. package/dist/runescape/model/guilds/HunterGuild.d.ts +18 -0
  145. package/dist/runescape/model/guilds/HunterGuild.d.ts.map +1 -0
  146. package/dist/runescape/model/guilds/HunterGuild.js +65 -0
  147. package/dist/runescape/model/guilds/HunterGuildMaster.d.ts +29 -0
  148. package/dist/runescape/model/guilds/HunterGuildMaster.d.ts.map +1 -0
  149. package/dist/runescape/model/guilds/HunterGuildMaster.js +39 -0
  150. package/dist/runescape/model/guilds/HunterGuildProgress.d.ts +12 -0
  151. package/dist/runescape/model/guilds/HunterGuildProgress.d.ts.map +1 -0
  152. package/dist/runescape/model/guilds/HunterGuildProgress.js +27 -0
  153. package/dist/runescape/model/guilds/HunterRumour.d.ts +23 -0
  154. package/dist/runescape/model/guilds/HunterRumour.d.ts.map +1 -0
  155. package/dist/runescape/model/guilds/HunterRumour.js +43 -0
  156. package/dist/runescape/model/guilds/RumourLocation.d.ts +10 -0
  157. package/dist/runescape/model/guilds/RumourLocation.d.ts.map +1 -0
  158. package/dist/runescape/model/guilds/RumourLocation.js +12 -0
  159. package/dist/runescape/model/guilds/Rumours.d.ts +3 -0
  160. package/dist/runescape/model/guilds/Rumours.d.ts.map +1 -0
  161. package/dist/runescape/model/guilds/Rumours.js +303 -0
  162. package/dist/runescape/model/guilds/hunter/HunterGuild.d.ts +33 -0
  163. package/dist/runescape/model/guilds/hunter/HunterGuild.d.ts.map +1 -0
  164. package/dist/runescape/model/guilds/hunter/HunterGuild.js +107 -0
  165. package/dist/runescape/model/guilds/hunter/HunterGuildMaster.d.ts +52 -0
  166. package/dist/runescape/model/guilds/hunter/HunterGuildMaster.d.ts.map +1 -0
  167. package/dist/runescape/model/guilds/hunter/HunterGuildMaster.js +71 -0
  168. package/dist/runescape/model/guilds/hunter/HunterGuildMasterName.d.ts +21 -0
  169. package/dist/runescape/model/guilds/hunter/HunterGuildMasterName.d.ts.map +1 -0
  170. package/dist/runescape/model/guilds/hunter/HunterGuildMasterName.js +8 -0
  171. package/dist/runescape/model/guilds/hunter/HunterRumour.d.ts +33 -0
  172. package/dist/runescape/model/guilds/hunter/HunterRumour.d.ts.map +1 -0
  173. package/dist/runescape/model/guilds/hunter/HunterRumour.js +52 -0
  174. package/dist/runescape/model/guilds/hunter/RumourLocation.d.ts +48 -0
  175. package/dist/runescape/model/guilds/hunter/RumourLocation.d.ts.map +1 -0
  176. package/dist/runescape/model/guilds/hunter/RumourLocation.js +42 -0
  177. package/dist/runescape/model/guilds/hunter/Rumours.d.ts +11 -0
  178. package/dist/runescape/model/guilds/hunter/Rumours.d.ts.map +1 -0
  179. package/dist/runescape/model/guilds/hunter/Rumours.js +325 -0
  180. package/dist/runescape/model/guilds/hunter/index.d.ts +5 -0
  181. package/dist/runescape/model/guilds/hunter/index.d.ts.map +1 -0
  182. package/dist/runescape/model/guilds/hunter/index.js +4 -0
  183. package/dist/runescape/model/guilds/hunter/types.d.ts +32 -0
  184. package/dist/runescape/model/guilds/hunter/types.d.ts.map +1 -0
  185. package/dist/runescape/model/guilds/hunter/types.js +10 -0
  186. package/dist/runescape/model/guilds/index.d.ts +2 -0
  187. package/dist/runescape/model/guilds/index.d.ts.map +1 -0
  188. package/dist/runescape/model/guilds/index.js +1 -0
  189. package/dist/runescape/model/guilds/types.d.ts +44 -0
  190. package/dist/runescape/model/guilds/types.d.ts.map +1 -0
  191. package/dist/runescape/model/guilds/types.js +21 -0
  192. package/dist/runescape/model/hunter/HunterRumour.d.ts +155 -0
  193. package/dist/runescape/model/hunter/HunterRumour.d.ts.map +1 -0
  194. package/dist/runescape/model/hunter/HunterRumour.js +183 -0
  195. package/dist/runescape/model/hunter/HunterRumours.d.ts +70 -0
  196. package/dist/runescape/model/hunter/HunterRumours.d.ts.map +1 -0
  197. package/dist/runescape/model/hunter/HunterRumours.js +346 -0
  198. package/dist/runescape/model/hunter/index.d.ts +9 -0
  199. package/dist/runescape/model/hunter/index.d.ts.map +1 -0
  200. package/dist/runescape/model/hunter/index.js +9 -0
  201. package/dist/runescape/model/leagues/DemonicPact.d.ts +23 -0
  202. package/dist/runescape/model/leagues/DemonicPact.d.ts.map +1 -0
  203. package/dist/runescape/model/leagues/DemonicPact.js +210 -0
  204. package/dist/runescape/model/leagues/DemonicPact.model.d.ts +103 -0
  205. package/dist/runescape/model/leagues/DemonicPact.model.d.ts.map +1 -0
  206. package/dist/runescape/model/leagues/DemonicPact.model.js +17 -0
  207. package/dist/runescape/model/leagues/DemonicPactClasses.d.ts +539 -0
  208. package/dist/runescape/model/leagues/DemonicPactClasses.d.ts.map +1 -0
  209. package/dist/runescape/model/leagues/DemonicPactClasses.js +1085 -0
  210. package/dist/runescape/model/leagues/DemonicPactPlanningData.d.ts +4 -0
  211. package/dist/runescape/model/leagues/DemonicPactPlanningData.d.ts.map +1 -0
  212. package/dist/runescape/model/leagues/DemonicPactPlanningData.js +174 -0
  213. package/dist/runescape/model/leagues/DemonicPacts.d.ts +4 -0
  214. package/dist/runescape/model/leagues/DemonicPacts.d.ts.map +1 -0
  215. package/dist/runescape/model/leagues/DemonicPacts.js +66 -0
  216. package/dist/runescape/model/leagues/DemonicPactsLeague/DemonicPactsLeagueAreas.d.ts +23 -0
  217. package/dist/runescape/model/leagues/DemonicPactsLeague/DemonicPactsLeagueAreas.d.ts.map +1 -0
  218. package/dist/runescape/model/leagues/DemonicPactsLeague/DemonicPactsLeagueAreas.js +442 -0
  219. package/dist/runescape/model/leagues/LeaguesRegion.model.d.ts +33 -0
  220. package/dist/runescape/model/leagues/LeaguesRegion.model.d.ts.map +1 -0
  221. package/dist/runescape/model/leagues/LeaguesRegion.model.js +14 -0
  222. package/dist/runescape/model/leagues/LeaguesRegions.d.ts +10 -0
  223. package/dist/runescape/model/leagues/LeaguesRegions.d.ts.map +1 -0
  224. package/dist/runescape/model/leagues/LeaguesRegions.js +69 -0
  225. package/dist/runescape/model/leagues/LeaguesRelic.model.d.ts +31 -0
  226. package/dist/runescape/model/leagues/LeaguesRelic.model.d.ts.map +1 -0
  227. package/dist/runescape/model/leagues/LeaguesRelic.model.js +11 -0
  228. package/dist/runescape/model/leagues/LeaguesRelics.d.ts +8 -0
  229. package/dist/runescape/model/leagues/LeaguesRelics.d.ts.map +1 -0
  230. package/dist/runescape/model/leagues/LeaguesRelics.js +237 -0
  231. package/dist/runescape/model/leagues/RagingEchoesLeague/RagingEchoesLeague.d.ts +749 -0
  232. package/dist/runescape/model/leagues/RagingEchoesLeague/RagingEchoesLeague.d.ts.map +1 -0
  233. package/dist/runescape/model/leagues/RagingEchoesLeague/RagingEchoesLeague.js +856 -0
  234. package/dist/runescape/model/leagues/general/Leagues.d.ts +70 -0
  235. package/dist/runescape/model/leagues/general/Leagues.d.ts.map +1 -0
  236. package/dist/runescape/model/leagues/general/Leagues.js +141 -0
  237. package/dist/runescape/model/leagues/index.d.ts +4 -0
  238. package/dist/runescape/model/leagues/index.d.ts.map +1 -0
  239. package/dist/runescape/model/leagues/index.js +3 -0
  240. package/dist/runescape/model/leagues/model.d.ts +32 -0
  241. package/dist/runescape/model/leagues/model.d.ts.map +1 -0
  242. package/dist/runescape/model/leagues/model.js +19 -0
  243. package/dist/runescape/model/skills/Skill.d.ts +22 -0
  244. package/dist/runescape/model/skills/Skill.d.ts.map +1 -0
  245. package/dist/runescape/model/skills/Skill.js +1 -0
  246. package/dist/runescape/model/skills/attack/Attack.d.ts +15 -0
  247. package/dist/runescape/model/skills/attack/Attack.d.ts.map +1 -0
  248. package/dist/runescape/model/skills/attack/Attack.js +19 -0
  249. package/dist/runescape/model/skills/attack/AttackLevelUnlocks.d.ts +6 -0
  250. package/dist/runescape/model/skills/attack/AttackLevelUnlocks.d.ts.map +1 -0
  251. package/dist/runescape/model/skills/attack/AttackLevelUnlocks.js +47 -0
  252. package/dist/runescape/model/skills/attack/index.d.ts +3 -0
  253. package/dist/runescape/model/skills/attack/index.d.ts.map +1 -0
  254. package/dist/runescape/model/skills/attack/index.js +2 -0
  255. package/dist/runescape/model/skills/hunter/Hunter.d.ts +5 -0
  256. package/dist/runescape/model/skills/hunter/Hunter.d.ts.map +1 -0
  257. package/dist/runescape/model/skills/hunter/Hunter.js +6 -0
  258. package/dist/runescape/model/skills/hunter/HunterNpcs.d.ts +1 -0
  259. package/dist/runescape/model/skills/hunter/HunterNpcs.d.ts.map +1 -0
  260. package/dist/runescape/model/skills/hunter/HunterNpcs.js +1 -0
  261. package/dist/runescape/model/skills/hunter/index.d.ts +2 -0
  262. package/dist/runescape/model/skills/hunter/index.d.ts.map +1 -0
  263. package/dist/runescape/model/skills/hunter/index.js +1 -0
  264. package/dist/runescape/model/skills/index.d.ts +3 -0
  265. package/dist/runescape/model/skills/index.d.ts.map +1 -0
  266. package/dist/runescape/model/skills/index.js +2 -0
  267. package/dist/runescape/resources/QuestData.json +5454 -0
  268. package/dist/runescape/resources/diary/diaries.json +1484 -0
  269. package/dist/runescape/resources/diary/diariesArray.json +0 -0
  270. package/dist/runescape/resources/leagues/demonicPacts.leagues7.json +2449 -0
  271. package/dist/runescape/resources/quest/exp.json +1333 -0
  272. package/dist/runescape/resources/quest/questData.json +5790 -0
  273. package/dist/runescape/resources/quest/questDataArray.json +5489 -0
  274. package/dist/runescape/resources/quest/subquestArray.json +58 -0
  275. package/dist/runescape/resources/quest/testObj.json +5682 -0
  276. package/dist/runescape/resources/quest/testarray.json +5589 -0
  277. package/dist/runescape/resources/quests/CooksAssistant.json +34 -0
  278. package/dist/runescape/resources/slayer/slayer.json +3581 -0
  279. package/dist/runescape/resources/slayer/slayerData.json +4431 -0
  280. package/dist/runescape/resources/slayer/tasks/json/Chaeldar.json +348 -0
  281. package/dist/runescape/resources/slayer/tasks/json/Duradel.json +541 -0
  282. package/dist/runescape/resources/slayer/tasks/json/Krystilia.json +2 -0
  283. package/dist/runescape/resources/slayer/tasks/json/Mazchna.json +379 -0
  284. package/dist/runescape/resources/slayer/tasks/json/Neive.json +320 -0
  285. package/dist/runescape/resources/slayer/tasks/json/Spria.json +345 -0
  286. package/dist/runescape/resources/slayer/tasks/json/Tureal.json +341 -0
  287. package/dist/runescape/resources/slayer/tasks/json/Vannaka.json +547 -0
  288. package/package.json +1 -1
@@ -0,0 +1,346 @@
1
+ import { LevelRequirement, QuestRequirement } from "../Requirement";
2
+ import { Skill } from "../account/Skill";
3
+ import { GuildHunterName, HuntingMethod, RumourTier, createHunterLevelRequirement } from "./HunterRumour";
4
+ // ========== Rumour Definitions ==========
5
+ // Each rumour represents a hunter creature that can be assigned.
6
+ // Reference: https://oldschool.runescape.wiki/w/Hunters%27_Rumours#List_of_rumours
7
+ const hunterLevel = (level) => createHunterLevelRequirement(level);
8
+ const tropicalWagtail = {
9
+ creature: "Tropical wagtail",
10
+ hunterRequirement: hunterLevel(19),
11
+ method: HuntingMethod.BirdSnare,
12
+ locations: ["Feldip Hunter area", "The Great Conch", "Tlati Rainforest"],
13
+ requirements: [],
14
+ };
15
+ const wildKebbit = {
16
+ creature: "Wild kebbit",
17
+ hunterRequirement: hunterLevel(23),
18
+ method: HuntingMethod.Deadfall,
19
+ locations: ["Piscatoris Hunter area", "Auburnvale"],
20
+ requirements: [],
21
+ };
22
+ const sapphireGlacialis = {
23
+ creature: "Sapphire glacialis",
24
+ hunterRequirement: hunterLevel(25),
25
+ method: HuntingMethod.ButterflyNet,
26
+ locations: ["Rellekka Hunter area", "Farming Guild", "Mons Gratia"],
27
+ requirements: [],
28
+ };
29
+ const swampLizard = {
30
+ creature: "Swamp lizard",
31
+ hunterRequirement: hunterLevel(29),
32
+ method: HuntingMethod.NetTrap,
33
+ locations: ["Canifis Hunter area", "North-west of Slepe"],
34
+ requirements: [new QuestRequirement("Priest in Peril")],
35
+ };
36
+ const spinedLarupia = {
37
+ creature: "Spined larupia",
38
+ hunterRequirement: hunterLevel(31),
39
+ method: HuntingMethod.SpikedPit,
40
+ locations: ["Feldip Hunter area"],
41
+ requirements: [],
42
+ };
43
+ const barbTailedKebbit = {
44
+ creature: "Barb-tailed kebbit",
45
+ hunterRequirement: hunterLevel(33),
46
+ method: HuntingMethod.Deadfall,
47
+ locations: ["Feldip Hunter area"],
48
+ requirements: [],
49
+ };
50
+ const snowyKnight = {
51
+ creature: "Snowy knight",
52
+ hunterRequirement: hunterLevel(35),
53
+ method: HuntingMethod.ButterflyNet,
54
+ locations: ["Rellekka Hunter area", "Weiss", "Farming Guild", "Mons Gratia"],
55
+ requirements: [],
56
+ };
57
+ const pricklyKebbit = {
58
+ creature: "Prickly kebbit",
59
+ hunterRequirement: hunterLevel(37),
60
+ method: HuntingMethod.Deadfall,
61
+ locations: ["Piscatoris Hunter area"],
62
+ requirements: [],
63
+ };
64
+ const embertailedJerboa = {
65
+ creature: "Embertailed jerboa",
66
+ hunterRequirement: hunterLevel(39),
67
+ method: HuntingMethod.BoxTrap,
68
+ locations: ["West of Hunter Guild", "North-west of the Locus Oasis"],
69
+ requirements: [new QuestRequirement("Eagles' Peak")],
70
+ };
71
+ const hornedGraahk = {
72
+ creature: "Horned graahk",
73
+ hunterRequirement: hunterLevel(41),
74
+ method: HuntingMethod.SpikedPit,
75
+ locations: ["Karamja Hunter area"],
76
+ requirements: [],
77
+ };
78
+ const spottedKebbit = {
79
+ creature: "Spotted kebbit",
80
+ hunterRequirement: hunterLevel(43),
81
+ method: HuntingMethod.Falconry,
82
+ locations: ["Piscatoris falconry area"],
83
+ requirements: [],
84
+ };
85
+ const blackWarlock = {
86
+ creature: "Black warlock",
87
+ hunterRequirement: hunterLevel(45),
88
+ method: HuntingMethod.ButterflyNet,
89
+ locations: ["Feldip Hunter area", "Farming Guild", "Crypt of Tonali hunter area", "Tlati Rainforest", "Shimmering Atoll"],
90
+ requirements: [],
91
+ };
92
+ const orangeSalamander = {
93
+ creature: "Orange salamander",
94
+ hunterRequirement: hunterLevel(47),
95
+ method: HuntingMethod.NetTrap,
96
+ locations: ["The Great Conch", "Uzer Hunter area", "Necropolis Hunter area"],
97
+ requirements: [],
98
+ };
99
+ const razorBackedKebbit = {
100
+ creature: "Razor-backed kebbit",
101
+ hunterRequirement: hunterLevel(49),
102
+ method: HuntingMethod.TrackingKebbit,
103
+ locations: ["Piscatoris Hunter area"],
104
+ requirements: [],
105
+ };
106
+ const sabreToothKebbit = {
107
+ creature: "Sabre-toothed kebbit",
108
+ hunterRequirement: hunterLevel(51),
109
+ method: HuntingMethod.Deadfall,
110
+ locations: ["Rellekka Hunter area"],
111
+ requirements: [],
112
+ };
113
+ const greyChinchompa = {
114
+ creature: "Grey chinchompa",
115
+ hunterRequirement: hunterLevel(53),
116
+ method: HuntingMethod.BoxTrap,
117
+ locations: ["Piscatoris Hunter area", "Kourend Woodland", "Isle of Souls"],
118
+ requirements: [new QuestRequirement("Eagles' Peak")],
119
+ };
120
+ const sabreToothKyatt = {
121
+ creature: "Sabre-toothed kyatt",
122
+ hunterRequirement: hunterLevel(55),
123
+ method: HuntingMethod.SpikedPit,
124
+ locations: ["Rellekka Hunter area"],
125
+ requirements: [],
126
+ };
127
+ const darkKebbit = {
128
+ creature: "Dark kebbit",
129
+ hunterRequirement: hunterLevel(57),
130
+ method: HuntingMethod.Falconry,
131
+ locations: ["Piscatoris falconry area"],
132
+ requirements: [],
133
+ };
134
+ const pyreFox = {
135
+ creature: "Pyre fox",
136
+ hunterRequirement: hunterLevel(57),
137
+ method: HuntingMethod.Deadfall,
138
+ locations: ["Avium Savannah"],
139
+ requirements: [],
140
+ };
141
+ const redSalamander = {
142
+ creature: "Red salamander",
143
+ hunterRequirement: hunterLevel(59),
144
+ method: HuntingMethod.NetTrap,
145
+ locations: ["Ourania Hunter area", "Charred Island"],
146
+ requirements: [],
147
+ };
148
+ const redChinchompa = {
149
+ creature: "Red chinchompa",
150
+ hunterRequirement: hunterLevel(63),
151
+ method: HuntingMethod.BoxTrap,
152
+ locations: ["Chinchompa Island", "Feldip Hunter area", "The Great Conch", "Gwenith Hunter area", "Red chinchompa hunting ground", "Tlati Rainforest"],
153
+ requirements: [new QuestRequirement("Eagles' Peak")],
154
+ };
155
+ const dashingKebbit = {
156
+ creature: "Dashing kebbit",
157
+ hunterRequirement: hunterLevel(69),
158
+ method: HuntingMethod.Falconry,
159
+ locations: ["Piscatoris falconry area"],
160
+ requirements: [],
161
+ };
162
+ const sunlightAntelope = {
163
+ creature: "Sunlight antelope",
164
+ hunterRequirement: hunterLevel(72),
165
+ method: HuntingMethod.SpikedPit,
166
+ locations: ["Avium Savannah"],
167
+ requirements: [],
168
+ };
169
+ const sunlightMoth = {
170
+ creature: "Sunlight moth",
171
+ hunterRequirement: hunterLevel(75),
172
+ method: HuntingMethod.ButterflyNet,
173
+ locations: ["Avium Savannah", "Neypotzli"],
174
+ requirements: [],
175
+ };
176
+ const tecuSalamander = {
177
+ creature: "Tecu salamander",
178
+ hunterRequirement: hunterLevel(79),
179
+ method: HuntingMethod.NetTrap,
180
+ locations: ["Ralos' Rise"],
181
+ requirements: [],
182
+ };
183
+ const herbiboar = {
184
+ creature: "Herbiboar",
185
+ hunterRequirement: hunterLevel(80),
186
+ method: HuntingMethod.TrackingHerbiboar,
187
+ locations: ["Mushroom Forest on Fossil Island"],
188
+ requirements: [new QuestRequirement("Bone Voyage"), new LevelRequirement(Skill.Herblore, 31, false)],
189
+ };
190
+ const moonlightMoth = {
191
+ creature: "Moonlight moth",
192
+ hunterRequirement: hunterLevel(85),
193
+ method: HuntingMethod.ButterflyNet,
194
+ locations: ["The Burrow", "Neypotzli", "Ruins of Tapoyauik", "Tonali Cavern"],
195
+ requirements: [],
196
+ };
197
+ const moonlightAntelope = {
198
+ creature: "Moonlight antelope",
199
+ hunterRequirement: hunterLevel(91),
200
+ method: HuntingMethod.SpikedPit,
201
+ locations: ["The Burrow"],
202
+ requirements: [],
203
+ };
204
+ // ========== All Rumours ==========
205
+ /** All hunter rumours sorted by Hunter level */
206
+ export const ALL_RUMOURS = [
207
+ tropicalWagtail,
208
+ wildKebbit,
209
+ sapphireGlacialis,
210
+ swampLizard,
211
+ spinedLarupia,
212
+ barbTailedKebbit,
213
+ snowyKnight,
214
+ pricklyKebbit,
215
+ embertailedJerboa,
216
+ hornedGraahk,
217
+ spottedKebbit,
218
+ blackWarlock,
219
+ orangeSalamander,
220
+ razorBackedKebbit,
221
+ sabreToothKebbit,
222
+ greyChinchompa,
223
+ sabreToothKyatt,
224
+ darkKebbit,
225
+ pyreFox,
226
+ redSalamander,
227
+ redChinchompa,
228
+ dashingKebbit,
229
+ sunlightAntelope,
230
+ sunlightMoth,
231
+ tecuSalamander,
232
+ herbiboar,
233
+ moonlightMoth,
234
+ moonlightAntelope,
235
+ ];
236
+ // ========== Guild Hunter Definitions ==========
237
+ /**
238
+ * Huntmaster Gilman (Novice) - Can assign all rumours.
239
+ */
240
+ export const Gilman = {
241
+ name: GuildHunterName.Gilman,
242
+ tier: RumourTier.Novice,
243
+ levelRequired: hunterLevel(46),
244
+ rumours: [...ALL_RUMOURS],
245
+ };
246
+ /**
247
+ * Guild Hunter Cervus (Adept) - Has a distinct adept rumour list.
248
+ */
249
+ export const Cervus = {
250
+ name: GuildHunterName.Cervus,
251
+ tier: RumourTier.Adept,
252
+ levelRequired: hunterLevel(57),
253
+ rumours: [swampLizard, hornedGraahk, spottedKebbit, blackWarlock, orangeSalamander, razorBackedKebbit, sabreToothKebbit, greyChinchompa, darkKebbit, pyreFox, redChinchompa, sunlightMoth],
254
+ };
255
+ /**
256
+ * Guild Hunter Ornus (Adept) - Has a distinct adept rumour list.
257
+ */
258
+ export const Ornus = {
259
+ name: GuildHunterName.Ornus,
260
+ tier: RumourTier.Adept,
261
+ levelRequired: hunterLevel(57),
262
+ rumours: [spinedLarupia, snowyKnight, embertailedJerboa, spottedKebbit, orangeSalamander, sabreToothKebbit, sabreToothKyatt, pyreFox, redSalamander, redChinchompa],
263
+ };
264
+ /**
265
+ * Guild Hunter Aco (Expert) - Has a distinct expert rumour list.
266
+ */
267
+ export const Aco = {
268
+ name: GuildHunterName.Aco,
269
+ tier: RumourTier.Expert,
270
+ levelRequired: hunterLevel(72),
271
+ rumours: [orangeSalamander, sabreToothKebbit, greyChinchompa, sabreToothKyatt, darkKebbit, redSalamander, redChinchompa, dashingKebbit, sunlightAntelope, tecuSalamander, moonlightMoth],
272
+ };
273
+ /**
274
+ * Guild Hunter Teco (Expert) - Has a distinct expert rumour list.
275
+ */
276
+ export const Teco = {
277
+ name: GuildHunterName.Teco,
278
+ tier: RumourTier.Expert,
279
+ levelRequired: hunterLevel(72),
280
+ rumours: [sabreToothKebbit, greyChinchompa, sabreToothKyatt, darkKebbit, redSalamander, redChinchompa, dashingKebbit, sunlightAntelope, sunlightMoth, herbiboar],
281
+ };
282
+ /**
283
+ * Guild Hunter Wolf (Master) - Requires completion of At First Light.
284
+ */
285
+ export const Wolf = {
286
+ name: GuildHunterName.Wolf,
287
+ tier: RumourTier.Master,
288
+ levelRequired: hunterLevel(91),
289
+ questRequired: "At First Light",
290
+ rumours: [redSalamander, redChinchompa, dashingKebbit, sunlightAntelope, tecuSalamander, herbiboar, moonlightMoth, moonlightAntelope],
291
+ };
292
+ /** All guild hunters */
293
+ export const ALL_GUILD_HUNTERS = [Gilman, Cervus, Ornus, Aco, Teco, Wolf];
294
+ // ========== Utility Functions ==========
295
+ /**
296
+ * Get a guild hunter by name.
297
+ * @param name - The guild hunter's name (enum or string)
298
+ * @returns The guild hunter, or undefined if not found
299
+ */
300
+ export function getGuildHunterByName(name) {
301
+ return ALL_GUILD_HUNTERS.find((h) => h.name === name);
302
+ }
303
+ /**
304
+ * Get all guild hunters for a specific tier.
305
+ * @param tier - The rumour tier
306
+ * @returns Array of guild hunters for that tier
307
+ */
308
+ export function getGuildHuntersByTier(tier) {
309
+ return ALL_GUILD_HUNTERS.filter((h) => h.tier === tier);
310
+ }
311
+ /**
312
+ * Get the available rumours for a guild hunter, excluding any creatures
313
+ * already assigned as active rumours from other hunters.
314
+ *
315
+ * This implements the "blocking" mechanic: players cannot receive the same
316
+ * task from multiple guild hunters at once. By obtaining a task from one
317
+ * hunter first, it is blocked from appearing with another.
318
+ *
319
+ * Example: If Gilman assigns "Swamp lizard", Cervus cannot assign "Swamp lizard"
320
+ * until the Gilman assignment is completed or reset.
321
+ *
322
+ * @param hunter - The guild hunter to get available rumours for
323
+ * @param activeRumours - Rumours currently assigned from other guild hunters
324
+ * @returns Rumours the hunter can assign, excluding blocked ones
325
+ */
326
+ export function getAvailableRumours(hunter, activeRumours = []) {
327
+ const blockedCreatures = new Set(activeRumours.map((r) => r.creature));
328
+ return hunter.rumours.filter((r) => !blockedCreatures.has(r.creature));
329
+ }
330
+ /**
331
+ * Find a rumour by creature name.
332
+ * @param creature - The creature name to search for (case-insensitive)
333
+ * @returns The matching rumour, or undefined if not found
334
+ */
335
+ export function getRumourByCreature(creature) {
336
+ const lower = creature.toLowerCase();
337
+ return ALL_RUMOURS.find((r) => r.creature.toLowerCase() === lower);
338
+ }
339
+ /**
340
+ * Get all guild hunters that can assign a specific rumour.
341
+ * @param rumour - The rumour to check
342
+ * @returns Array of guild hunters who include this rumour in their list
343
+ */
344
+ export function getHuntersForRumour(rumour) {
345
+ return ALL_GUILD_HUNTERS.filter((h) => h.rumours.some((r) => r.creature === rumour.creature));
346
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Hunter Rumours Module
3
+ * Complete Hunters' Rumours system including guild hunters, rumour data, and utilities.
4
+ * Reference: https://oldschool.runescape.wiki/w/Hunters%27_Rumours
5
+ */
6
+ export { HuntingMethod, RumourTier, HunterLootSackType, GuildHunterName, DROP_RATES, TIER_XP_MODIFIER, HUNTER_LOOT_SACK_INFO, RUMOUR_MILESTONE_UNLOCKS, calculateRumourExperience, createHunterLevelRequirement, getMilestoneUnlocks, openHuntersLootSack, } from './HunterRumour';
7
+ export type { DropRateInfo, HunterRumour, GuildHunter, HunterLootSackInfo, RumourMilestoneUnlock, OpenLootSackResult, } from './HunterRumour';
8
+ export { ALL_RUMOURS, ALL_GUILD_HUNTERS, Gilman, Cervus, Ornus, Aco, Teco, Wolf, getGuildHunterByName, getGuildHuntersByTier, getAvailableRumours, getRumourByCreature, getHuntersForRumour, } from './HunterRumours';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../source/runescape/model/hunter/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,EACzB,4BAA4B,EAC5B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,KAAK,EACL,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Hunter Rumours Module
3
+ * Complete Hunters' Rumours system including guild hunters, rumour data, and utilities.
4
+ * Reference: https://oldschool.runescape.wiki/w/Hunters%27_Rumours
5
+ */
6
+ // Model definitions
7
+ export { HuntingMethod, RumourTier, HunterLootSackType, GuildHunterName, DROP_RATES, TIER_XP_MODIFIER, HUNTER_LOOT_SACK_INFO, RUMOUR_MILESTONE_UNLOCKS, calculateRumourExperience, createHunterLevelRequirement, getMilestoneUnlocks, openHuntersLootSack, } from './HunterRumour';
8
+ // Data and utilities
9
+ export { ALL_RUMOURS, ALL_GUILD_HUNTERS, Gilman, Cervus, Ornus, Aco, Teco, Wolf, getGuildHunterByName, getGuildHuntersByTier, getAvailableRumours, getRumourByCreature, getHuntersForRumour, } from './HunterRumours';
@@ -0,0 +1,23 @@
1
+ import { DemonicPact, DemonicPactScoringContext, DemonicPactTree, CombatStyle, UnlockEvaluation, DemonicPactOptimizerOptions, DemonicPactOptimizationResult } from "./DemonicPact.model";
2
+ export type DemonicPactScorer = (pact: DemonicPact, context: DemonicPactScoringContext) => number;
3
+ export declare function getInitialUnlockedPactIds(tree: DemonicPactTree): string[];
4
+ export declare function getPactsByStyle(tree: DemonicPactTree, style: CombatStyle, includeUniversal?: boolean): DemonicPact[];
5
+ export declare function getPactById(tree: DemonicPactTree, pactId: string): DemonicPact | undefined;
6
+ /**
7
+ * Calculates the total points spent on a given selection of pacts based on their official point costs.
8
+ * @param tree The demonic pact tree containing all pacts.
9
+ * @param unlockedPactIds The IDs of the pacts that have been unlocked.
10
+ * @returns The total points spent on the unlocked pacts.
11
+ */
12
+ export declare function calculateSpentPoints(tree: DemonicPactTree, unlockedPactIds: readonly string[]): number;
13
+ /**
14
+ * Determines if a pact can be unlocked given the current tree state and already unlocked pacts.
15
+ * @param tree
16
+ * @param unlockedPactIds
17
+ * @param pactId
18
+ * @returns
19
+ */
20
+ export declare function canUnlockPact(tree: DemonicPactTree, unlockedPactIds: readonly string[], pactId: string): UnlockEvaluation;
21
+ export declare function getUnlockablePacts(tree: DemonicPactTree, unlockedPactIds: readonly string[], style?: CombatStyle): DemonicPact[];
22
+ export declare function optimizeDemonicPactLoadout(tree: DemonicPactTree, options: DemonicPactOptimizerOptions): DemonicPactOptimizationResult;
23
+ //# sourceMappingURL=DemonicPact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DemonicPact.d.ts","sourceRoot":"","sources":["../../../../source/runescape/model/leagues/DemonicPact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE,eAAe,EAAE,WAAW,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,6BAA6B,EAAgB,MAAM,qBAAqB,CAAC;AAEvM,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,yBAAyB,KAAK,MAAM,CAAC;AAUlG,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAEzE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,UAAO,GAAG,WAAW,EAAE,CAMjH;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE1F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAGtG;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CA8CzH;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,EAAE,CAGhI;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,2BAA2B,GAAG,6BAA6B,CAoFrI"}
@@ -0,0 +1,210 @@
1
+ import { CombatStyle, PactNodeSize } from "./DemonicPact.model";
2
+ const DEFAULT_BEAM_WIDTH = 48;
3
+ export function getInitialUnlockedPactIds(tree) {
4
+ return [tree.rootNodeId];
5
+ }
6
+ export function getPactsByStyle(tree, style, includeUniversal = true) {
7
+ if (style === CombatStyle.Universal) {
8
+ return tree.pacts.filter((pact) => pact.style === CombatStyle.Universal);
9
+ }
10
+ return tree.pacts.filter((pact) => pact.style === style || (includeUniversal && pact.style === CombatStyle.Universal));
11
+ }
12
+ export function getPactById(tree, pactId) {
13
+ return tree.pacts.find((pact) => pact.id === pactId);
14
+ }
15
+ /**
16
+ * Calculates the total points spent on a given selection of pacts based on their official point costs.
17
+ * @param tree The demonic pact tree containing all pacts.
18
+ * @param unlockedPactIds The IDs of the pacts that have been unlocked.
19
+ * @returns The total points spent on the unlocked pacts.
20
+ */
21
+ export function calculateSpentPoints(tree, unlockedPactIds) {
22
+ const unlockedSet = new Set(unlockedPactIds);
23
+ return tree.pacts.filter((pact) => unlockedSet.has(pact.id)).reduce((total, pact) => total + pact.pointCost, 0);
24
+ }
25
+ /**
26
+ * Determines if a pact can be unlocked given the current tree state and already unlocked pacts.
27
+ * @param tree
28
+ * @param unlockedPactIds
29
+ * @param pactId
30
+ * @returns
31
+ */
32
+ export function canUnlockPact(tree, unlockedPactIds, pactId) {
33
+ const unlockedSet = new Set(unlockedPactIds);
34
+ const pact = getPactById(tree, pactId);
35
+ const spent = calculateSpentPoints(tree, unlockedPactIds);
36
+ const pointsRemaining = tree.totalPointsAvailable - spent;
37
+ if (!pact) {
38
+ return { unlockable: false, reason: `Unknown pact id: ${pactId}`, pointsRemaining };
39
+ }
40
+ if (unlockedSet.has(pact.id)) {
41
+ return { unlockable: false, reason: `Pact already unlocked: ${pact.id}`, pointsRemaining };
42
+ }
43
+ if (pact.pointCost > pointsRemaining) {
44
+ return {
45
+ unlockable: false,
46
+ reason: `Not enough points to unlock ${pact.id}`,
47
+ pointsRemaining,
48
+ };
49
+ }
50
+ if (unlockedSet.size === 0) {
51
+ if (pact.id === tree.rootNodeId) {
52
+ return { unlockable: true, pointsRemaining: pointsRemaining - pact.pointCost };
53
+ }
54
+ return {
55
+ unlockable: false,
56
+ reason: `The root pact ${tree.rootNodeId} must be unlocked first`,
57
+ pointsRemaining,
58
+ missingLinkedPactIds: [tree.rootNodeId],
59
+ };
60
+ }
61
+ const linkedUnlockedIds = pact.linkedNodeIds.filter((linkedNodeId) => unlockedSet.has(linkedNodeId));
62
+ if (linkedUnlockedIds.length === 0) {
63
+ return {
64
+ unlockable: false,
65
+ reason: `Pact must connect to an already unlocked pact`,
66
+ pointsRemaining,
67
+ missingLinkedPactIds: pact.linkedNodeIds,
68
+ };
69
+ }
70
+ return { unlockable: true, pointsRemaining: pointsRemaining - pact.pointCost };
71
+ }
72
+ export function getUnlockablePacts(tree, unlockedPactIds, style) {
73
+ const candidates = style ? getPactsByStyle(tree, style) : tree.pacts;
74
+ return candidates.filter((pact) => canUnlockPact(tree, unlockedPactIds, pact.id).unlockable);
75
+ }
76
+ export function optimizeDemonicPactLoadout(tree, options) {
77
+ const pointBudget = options.pointBudget ?? tree.totalPointsAvailable;
78
+ const preferredStyles = options.preferredStyles.length > 0 ? options.preferredStyles : [CombatStyle.Universal];
79
+ const excludedPactIds = new Set(options.excludedPactIds ?? []);
80
+ const requiredPactIds = new Set(options.requiredPactIds ?? []);
81
+ const beamWidth = options.beamWidth ?? DEFAULT_BEAM_WIDTH;
82
+ const startingPactIds = getStartingPactIds(tree, options);
83
+ validateStartingPacts(tree, startingPactIds, pointBudget);
84
+ let states = [
85
+ {
86
+ selectedPactIds: [...startingPactIds],
87
+ unlockOrder: [...startingPactIds],
88
+ score: calculateSelectionScore(tree, startingPactIds, preferredStyles, options.scorer),
89
+ },
90
+ ];
91
+ while (true) {
92
+ const nextStates = new Map();
93
+ let expandedAnyState = false;
94
+ for (const state of states) {
95
+ const unlockablePacts = getUnlockablePacts(tree, state.selectedPactIds).filter((pact) => !excludedPactIds.has(pact.id));
96
+ let expandedState = false;
97
+ for (const pact of unlockablePacts) {
98
+ const nextSelectedPactIds = [...state.selectedPactIds, pact.id];
99
+ const spentPoints = calculateSpentPoints(tree, nextSelectedPactIds);
100
+ if (spentPoints > pointBudget) {
101
+ continue;
102
+ }
103
+ expandedAnyState = true;
104
+ expandedState = true;
105
+ const nextState = {
106
+ selectedPactIds: nextSelectedPactIds,
107
+ unlockOrder: [...state.unlockOrder, pact.id],
108
+ score: state.score + scorePact(tree, pact, state.selectedPactIds, preferredStyles, options.scorer),
109
+ };
110
+ const stateKey = nextSelectedPactIds.join("|");
111
+ const existingState = nextStates.get(stateKey);
112
+ if (!existingState || compareStates(nextState, existingState) < 0) {
113
+ nextStates.set(stateKey, nextState);
114
+ }
115
+ }
116
+ if (!expandedState) {
117
+ const stateKey = state.selectedPactIds.join("|");
118
+ const existingState = nextStates.get(stateKey);
119
+ if (!existingState || compareStates(state, existingState) < 0) {
120
+ nextStates.set(stateKey, state);
121
+ }
122
+ }
123
+ }
124
+ if (!expandedAnyState) {
125
+ break;
126
+ }
127
+ states = [...nextStates.values()].sort(compareStates).slice(0, beamWidth);
128
+ }
129
+ const bestState = [...states].filter((state) => hasRequiredPacts(state.selectedPactIds, requiredPactIds)).sort(compareStates)[0];
130
+ if (!bestState) {
131
+ throw new Error("Unable to satisfy the required pact selection within the provided point budget");
132
+ }
133
+ const spentPoints = calculateSpentPoints(tree, bestState.selectedPactIds);
134
+ return {
135
+ selectedPactIds: [...bestState.selectedPactIds],
136
+ unlockOrder: [...bestState.unlockOrder],
137
+ selectedPacts: bestState.selectedPactIds.map((pactId) => getPactById(tree, pactId)).filter((pact) => Boolean(pact)),
138
+ spentPoints,
139
+ remainingPoints: pointBudget - spentPoints,
140
+ score: bestState.score,
141
+ unlockableNextPacts: getUnlockablePacts(tree, bestState.selectedPactIds).filter((pact) => !excludedPactIds.has(pact.id)),
142
+ };
143
+ }
144
+ function getStartingPactIds(tree, options) {
145
+ const providedPactIds = options.startingPactIds ? [...new Set(options.startingPactIds)] : [];
146
+ if (providedPactIds.length > 0) {
147
+ return providedPactIds;
148
+ }
149
+ if (options.includeRoot === false) {
150
+ return [];
151
+ }
152
+ return getInitialUnlockedPactIds(tree);
153
+ }
154
+ function validateStartingPacts(tree, startingPactIds, pointBudget) {
155
+ const validatedPactIds = [];
156
+ for (const pactId of startingPactIds) {
157
+ const evaluation = canUnlockPact(tree, validatedPactIds, pactId);
158
+ if (!evaluation.unlockable) {
159
+ throw new Error(evaluation.reason ?? `Invalid starting pact: ${pactId}`);
160
+ }
161
+ validatedPactIds.push(pactId);
162
+ }
163
+ const spentPoints = calculateSpentPoints(tree, validatedPactIds);
164
+ if (spentPoints > pointBudget) {
165
+ throw new Error(`Starting pact selection spends ${spentPoints} points, exceeding the ${pointBudget} point budget`);
166
+ }
167
+ }
168
+ function calculateSelectionScore(tree, selectedPactIds, preferredStyles, scorer) {
169
+ let score = 0;
170
+ const runningSelection = [];
171
+ for (const pactId of selectedPactIds) {
172
+ const pact = getPactById(tree, pactId);
173
+ if (!pact) {
174
+ continue;
175
+ }
176
+ score += scorePact(tree, pact, runningSelection, preferredStyles, scorer);
177
+ runningSelection.push(pactId);
178
+ }
179
+ return score;
180
+ }
181
+ function scorePact(tree, pact, selectedPactIds, preferredStyles, scorer) {
182
+ const scoringContext = {
183
+ tree,
184
+ selectedPactIds,
185
+ preferredStyles,
186
+ };
187
+ return scorer ? scorer(pact, scoringContext) : scorePactByStyleAndSize(pact, preferredStyles);
188
+ }
189
+ function scorePactByStyleAndSize(pact, preferredStyles) {
190
+ const styleWeight = preferredStyles.includes(pact.style) ? 7 : pact.style === CombatStyle.Universal ? 4 : 1;
191
+ const sizeWeight = pact.nodeSize === PactNodeSize.Capstone ? 4 : pact.nodeSize === PactNodeSize.Major ? 2 : 1;
192
+ return styleWeight + sizeWeight + pact.linkedNodeIds.length * 0.05;
193
+ }
194
+ function hasRequiredPacts(selectedPactIds, requiredPactIds) {
195
+ for (const pactId of requiredPactIds) {
196
+ if (!selectedPactIds.includes(pactId)) {
197
+ return false;
198
+ }
199
+ }
200
+ return true;
201
+ }
202
+ function compareStates(left, right) {
203
+ if (left.score !== right.score) {
204
+ return right.score - left.score;
205
+ }
206
+ if (left.selectedPactIds.length !== right.selectedPactIds.length) {
207
+ return right.selectedPactIds.length - left.selectedPactIds.length;
208
+ }
209
+ return left.selectedPactIds.join("|").localeCompare(right.selectedPactIds.join("|"));
210
+ }