@blizzhackers/d2data 2.0.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 (185) hide show
  1. package/.eslintrc.js +59 -0
  2. package/LICENSE +21 -0
  3. package/README.md +12 -0
  4. package/_config.yml +1 -0
  5. package/compile.js +789 -0
  6. package/docs/Avqest.ttf +0 -0
  7. package/docs/_config.yml +1 -0
  8. package/docs/armor.js +134 -0
  9. package/docs/css/d2font.css +10 -0
  10. package/docs/drops/.vscode/extensions.json +3 -0
  11. package/docs/drops/README.md +7 -0
  12. package/docs/drops/dist/assets/index.12ae3c90.js +6675 -0
  13. package/docs/drops/dist/index.html +24 -0
  14. package/docs/drops/index.html +23 -0
  15. package/docs/drops/package-lock.json +1143 -0
  16. package/docs/drops/package.json +17 -0
  17. package/docs/drops/src/App.vue +870 -0
  18. package/docs/drops/src/main.js +4 -0
  19. package/docs/drops/vite.config.js +8 -0
  20. package/docs/drops.html +10 -0
  21. package/docs/effort.css +118 -0
  22. package/docs/effort.js +367 -0
  23. package/docs/elem-effort.html +130 -0
  24. package/docs/images/0-0.svg +18 -0
  25. package/docs/images/0-1.svg +17 -0
  26. package/docs/images/0-2.svg +17 -0
  27. package/docs/images/1-0.svg +18 -0
  28. package/docs/images/1-1.svg +18 -0
  29. package/docs/images/1-2.svg +17 -0
  30. package/docs/images/2-0.svg +17 -0
  31. package/docs/images/2-1.svg +11 -0
  32. package/docs/images/2-2.svg +18 -0
  33. package/docs/images/3-0.svg +17 -0
  34. package/docs/images/3-1.svg +18 -0
  35. package/docs/images/3-2.svg +18 -0
  36. package/docs/images/4-0.svg +18 -0
  37. package/docs/images/4-1.svg +18 -0
  38. package/docs/images/4-2.svg +18 -0
  39. package/docs/images/5-0.svg +18 -0
  40. package/docs/images/5-1.svg +18 -0
  41. package/docs/images/5-2.svg +14 -0
  42. package/docs/images/6-0.svg +17 -0
  43. package/docs/images/6-1.svg +17 -0
  44. package/docs/images/6-2.svg +17 -0
  45. package/docs/images/AmSkillicon.png +0 -0
  46. package/docs/images/AsSkillicon.png +0 -0
  47. package/docs/images/BaSkillicon.png +0 -0
  48. package/docs/images/DrSkillicon.png +0 -0
  49. package/docs/images/NeSkillicon.png +0 -0
  50. package/docs/images/PaSkillicon.png +0 -0
  51. package/docs/images/Skillicon.png +0 -0
  52. package/docs/images/SoSkillicon.png +0 -0
  53. package/docs/index.md +5 -0
  54. package/docs/items.html +170 -0
  55. package/docs/leveling/.vscode/extensions.json +3 -0
  56. package/docs/leveling/README.md +7 -0
  57. package/docs/leveling/dist/assets/index.f9765357.js +1 -0
  58. package/docs/leveling/dist/index.html +24 -0
  59. package/docs/leveling/index.html +23 -0
  60. package/docs/leveling/package-lock.json +1143 -0
  61. package/docs/leveling/package.json +17 -0
  62. package/docs/leveling/src/App.vue +526 -0
  63. package/docs/leveling/src/main.js +4 -0
  64. package/docs/leveling/vite.config.js +8 -0
  65. package/docs/runewords/.vscode/extensions.json +3 -0
  66. package/docs/runewords/README.md +7 -0
  67. package/docs/runewords/dist/assets/index.0838f27c.js +6673 -0
  68. package/docs/runewords/dist/assets/index.73bf3e23.css +1 -0
  69. package/docs/runewords/dist/index.html +25 -0
  70. package/docs/runewords/index.html +23 -0
  71. package/docs/runewords/package-lock.json +1143 -0
  72. package/docs/runewords/package.json +17 -0
  73. package/docs/runewords/src/App.vue +781 -0
  74. package/docs/runewords/src/main.js +4 -0
  75. package/docs/runewords/src/modorder.json +234 -0
  76. package/docs/runewords/vite.config.js +8 -0
  77. package/docs/skills.css +1250 -0
  78. package/docs/skills.html +63 -0
  79. package/docs/skills.js +2192 -0
  80. package/docs/vue-setup.js +12 -0
  81. package/docs/weapons.js +149 -0
  82. package/font-example.html +34 -0
  83. package/json/.gitkeep +0 -0
  84. package/json/actinfo.json +116 -0
  85. package/json/armor.json +17232 -0
  86. package/json/armtype.json +17 -0
  87. package/json/atomic.json +1026 -0
  88. package/json/automagic.json +696 -0
  89. package/json/automap.json +40732 -0
  90. package/json/belts.json +743 -0
  91. package/json/bodylocs.json +52 -0
  92. package/json/books.json +34 -0
  93. package/json/charstats.json +525 -0
  94. package/json/colors.json +107 -0
  95. package/json/compcode.json +577 -0
  96. package/json/composit.json +82 -0
  97. package/json/cubemain.json +2112 -0
  98. package/json/cubemod.json +57 -0
  99. package/json/difficultylevels.json +110 -0
  100. package/json/elemtypes.json +62 -0
  101. package/json/events.json +72 -0
  102. package/json/experience.json +1214 -0
  103. package/json/gamble.json +520 -0
  104. package/json/gems.json +1868 -0
  105. package/json/hireling.json +7640 -0
  106. package/json/hitclass.json +67 -0
  107. package/json/inventory.json +2148 -0
  108. package/json/itemratio.json +134 -0
  109. package/json/items.json +54705 -0
  110. package/json/itemstatcost.json +5503 -0
  111. package/json/itemtypes.json +2567 -0
  112. package/json/levels.json +15515 -0
  113. package/json/localestrings-chi.json +8717 -0
  114. package/json/localestrings-deu.json +8717 -0
  115. package/json/localestrings-eng.json +8722 -0
  116. package/json/localestrings-esp.json +8717 -0
  117. package/json/localestrings-fra.json +8718 -0
  118. package/json/localestrings-ita.json +8717 -0
  119. package/json/localestrings-kor.json +8715 -0
  120. package/json/localestrings-pol.json +8716 -0
  121. package/json/lowqualityitems.json +6 -0
  122. package/json/lvlmaze.json +910 -0
  123. package/json/lvlprest.json +28595 -0
  124. package/json/lvlsub.json +824 -0
  125. package/json/lvltypes.json +1377 -0
  126. package/json/lvlwarp.json +1515 -0
  127. package/json/magicprefix.json +12349 -0
  128. package/json/magicsuffix.json +13833 -0
  129. package/json/misc.json +11602 -0
  130. package/json/misscalc.json +217 -0
  131. package/json/missiles.json +23871 -0
  132. package/json/monai.json +1111 -0
  133. package/json/moncountest.json +642 -0
  134. package/json/monequip.json +361 -0
  135. package/json/monlvl.json +3665 -0
  136. package/json/monmode.json +98 -0
  137. package/json/monplace.json +39 -0
  138. package/json/monpopulationest.json +17383 -0
  139. package/json/monpreset.json +922 -0
  140. package/json/monprop.json +144 -0
  141. package/json/monseq.json +5211 -0
  142. package/json/monsounds.json +2530 -0
  143. package/json/monstats.json +66101 -0
  144. package/json/monstats2.json +34882 -0
  145. package/json/montype.json +274 -0
  146. package/json/monumod.json +504 -0
  147. package/json/npc.json +232 -0
  148. package/json/objects.json +87041 -0
  149. package/json/objgroup.json +3733 -0
  150. package/json/objmode.json +42 -0
  151. package/json/objpreset.json +2906 -0
  152. package/json/objtype.json +2457 -0
  153. package/json/overlay.json +8008 -0
  154. package/json/pettype.json +226 -0
  155. package/json/playerclass.json +39 -0
  156. package/json/plrmode.json +122 -0
  157. package/json/plrtype.json +39 -0
  158. package/json/properties.json +2823 -0
  159. package/json/qualityitems.json +149 -0
  160. package/json/rareprefix.json +296 -0
  161. package/json/raresuffix.json +921 -0
  162. package/json/runes.json +3280 -0
  163. package/json/setitems.json +3871 -0
  164. package/json/sets.json +1001 -0
  165. package/json/shrines.json +319 -0
  166. package/json/skillcalc.json +457 -0
  167. package/json/skilldesc.json +7532 -0
  168. package/json/skills.json +16717 -0
  169. package/json/soundenviron.json +2862 -0
  170. package/json/sounds.json +446543 -0
  171. package/json/states.json +1578 -0
  172. package/json/storepage.json +22 -0
  173. package/json/superuniques.json +1405 -0
  174. package/json/tcprecalc.json +29302 -0
  175. package/json/treasureclassex.json +14932 -0
  176. package/json/treasureclassgroupsex.json +711 -0
  177. package/json/uniqueappellation.json +27 -0
  178. package/json/uniqueitems.json +14171 -0
  179. package/json/uniqueprefix.json +55 -0
  180. package/json/uniquesuffix.json +71 -0
  181. package/json/wanderingmon.json +3 -0
  182. package/json/weapons.json +25875 -0
  183. package/objext.js +53 -0
  184. package/package.json +16 -0
  185. package/string.js +42 -0
package/docs/skills.js ADDED
@@ -0,0 +1,2192 @@
1
+ // eslint-disable-next-line no-unused-vars
2
+ /* global Vue app */
3
+ let encode = arr => {
4
+ arr = arr.map(obj => {
5
+ let ret = {};
6
+
7
+ Object.keys(obj).forEach(key => {
8
+ // eslint-disable-next-line eqeqeq
9
+ if (key === 0 || key === '0' || (key | 0) != key || obj[key]) {
10
+ ret[key] = obj[key];
11
+ }
12
+ });
13
+
14
+ return ret;
15
+ });
16
+
17
+ return btoa(JSON.stringify(arr));
18
+ }, decode = str => {
19
+ str = atob(str);
20
+
21
+ return str ? JSON.parse(str) : [];
22
+ };
23
+
24
+ (async function () {
25
+ let clamp = (a, v, b) => (v < a ? a : (v > b ? b : v));
26
+
27
+ window.app = new Vue({
28
+ el: '#skillapp',
29
+ data: {
30
+ d2: {
31
+ skills: await (fetch('https://raw.githubusercontent.com/blizzhackers/d2data/master/json/skills.json').then(res => res.json())),
32
+ },
33
+ classes: [
34
+ {
35
+ name: 'Amazon',
36
+ tabs: [
37
+ {
38
+ name: 'Bow and Crossbow',
39
+ skills: [
40
+ null, { id: 6 }, { id: 7 },
41
+ { id: 11 }, { id: 12 }, null,
42
+ null, null, { id: 16 },
43
+ { id: 21 }, { id: 22 }, null,
44
+ null, { id: 26 }, { id: 27 },
45
+ { id: 31 }, null, null,
46
+ ],
47
+ },
48
+ {
49
+ name: 'Passive and Magic',
50
+ skills: [
51
+ { id: 8 }, null, { id: 9 },
52
+ null, { id: 13 }, null,
53
+ { id: 17 }, { id: 18 }, null,
54
+ null, null, { id: 23 },
55
+ { id: 28 }, { id: 29 }, null,
56
+ { id: 32 }, null, { id: 33 },
57
+ ],
58
+ },
59
+ {
60
+ name: 'Javelin and Spear',
61
+ skills: [
62
+ { id: 10 }, null, null,
63
+ null, { id: 14 }, { id: 15 },
64
+ { id: 19 }, null, { id: 20 },
65
+ null, { id: 24 }, { id: 25 },
66
+ { id: 30 }, null, null,
67
+ null, { id: 34 }, { id: 35 },
68
+ ],
69
+ },
70
+ ],
71
+ },
72
+ {
73
+ name: 'Assassin',
74
+ tabs: [
75
+ {
76
+ name: 'Traps',
77
+ skills: [
78
+ null, { id: 251 }, null,
79
+ { id: 256 }, null, { id: 257 },
80
+ { id: 261 }, { id: 262 }, null,
81
+ null, null, { id: 266 },
82
+ { id: 271 }, { id: 272 }, null,
83
+ { id: 276 }, null, { id: 277 },
84
+ ],
85
+ },
86
+ {
87
+ name: 'Shadow Disciplines',
88
+ skills: [
89
+ null, { id: 252 }, { id: 253 },
90
+ { id: 258 }, null, null,
91
+ null, { id: 263 }, { id: 264 },
92
+ { id: 267 }, { id: 268 }, null,
93
+ null, null, { id: 273 },
94
+ { id: 278 }, { id: 279 }, null,
95
+ ],
96
+ },
97
+ {
98
+ name: 'Martial Arts',
99
+ skills: [
100
+ null, { id: 254 }, { id: 255 },
101
+ { id: 259 }, null, { id: 260 },
102
+ null, { id: 265 }, null,
103
+ { id: 269 }, null, { id: 270 },
104
+ { id: 274 }, null, { id: 275 },
105
+ null, { id: 280 }, null,
106
+ ],
107
+ },
108
+ ],
109
+ },
110
+ {
111
+ name: 'Barbarian',
112
+ tabs: [
113
+ {
114
+ name: 'Combat Skills',
115
+ skills: [
116
+ null, { id: 126 }, null,
117
+ { id: 132 }, null, { id: 133 },
118
+ null, { id: 139 }, { id: 140 },
119
+ { id: 143 }, { id: 144 }, null,
120
+ null, null, { id: 147 },
121
+ { id: 151 }, { id: 152 }, null,
122
+ ],
123
+ },
124
+ {
125
+ name: 'Combat Masteries',
126
+ skills: [
127
+ { id: 127 }, { id: 128 }, { id: 129 },
128
+ { id: 134 }, { id: 135 }, { id: 136 },
129
+ { id: 141 }, null, null,
130
+ null, null, { id: 145 },
131
+ { id: 148 }, null, null,
132
+ null, null, { id: 153 },
133
+ ],
134
+ },
135
+ {
136
+ name: 'Warcries',
137
+ skills: [
138
+ { id: 130 }, null, { id: 131 },
139
+ { id: 137 }, { id: 138 }, null,
140
+ null, null, { id: 142 },
141
+ { id: 146 }, null, null,
142
+ null, { id: 149 }, { id: 150 },
143
+ { id: 154 }, { id: 155 }, null,
144
+ ],
145
+ },
146
+ ],
147
+ },
148
+ {
149
+ name: 'Druid',
150
+ tabs: [
151
+ {
152
+ name: 'Summoning',
153
+ skills: [
154
+ null, { id: 221 }, { id: 222 },
155
+ { id: 226 }, { id: 227 }, null,
156
+ null, null, { id: 231 },
157
+ { id: 236 }, { id: 237 }, null,
158
+ null, null, { id: 241 },
159
+ { id: 246 }, { id: 247 }, null,
160
+ ],
161
+ },
162
+ {
163
+ name: 'Shapeshifting',
164
+ skills: [
165
+ { id: 223 }, { id: 224 }, null,
166
+ null, null, { id: 228 },
167
+ { id: 232 }, null, { id: 233 },
168
+ { id: 238 }, { id: 239 }, null,
169
+ null, { id: 242 }, { id: 243 },
170
+ { id: 248 }, null, null,
171
+ ],
172
+ },
173
+ {
174
+ name: 'Elemental',
175
+ skills: [
176
+ { id: 225 }, null, null,
177
+ { id: 229 }, null, { id: 230 },
178
+ { id: 234 }, null, { id: 235 },
179
+ null, { id: 240 }, null,
180
+ { id: 244 }, { id: 245 }, null,
181
+ { id: 249 }, { id: 250 }, null,
182
+ ],
183
+ },
184
+ ],
185
+ },
186
+ {
187
+ name: 'Necromancer',
188
+ tabs: [
189
+ {
190
+ name: 'Curses',
191
+ skills: [
192
+ null, { id: 66 }, null,
193
+ { id: 71 }, null, { id: 72 },
194
+ null, { id: 76 }, { id: 77 },
195
+ { id: 81 }, { id: 82 }, null,
196
+ { id: 86 }, null, { id: 87 },
197
+ null, { id: 91 }, null,
198
+ ],
199
+ },
200
+ {
201
+ name: 'Poison and Bone',
202
+ skills: [
203
+ null, { id: 67 }, { id: 68 },
204
+ { id: 73 }, { id: 74 }, null,
205
+ null, null, { id: 78 },
206
+ { id: 83 }, { id: 84 }, null,
207
+ null, null, { id: 88 },
208
+ { id: 92 }, { id: 93 }, null,
209
+ ],
210
+ },
211
+ {
212
+ name: 'Summoning',
213
+ skills: [
214
+ { id: 69 }, null, { id: 70 },
215
+ null, { id: 75 }, null,
216
+ { id: 79 }, null, { id: 80 },
217
+ null, { id: 85 }, null,
218
+ { id: 89 }, { id: 90 }, null,
219
+ null, { id: 94 }, { id: 95 },
220
+ ],
221
+ },
222
+ ],
223
+ },
224
+ {
225
+ name: 'Paladin',
226
+ tabs: [
227
+ {
228
+ name: 'Combat Skills',
229
+ skills: [
230
+ { id: 96 }, null, { id: 97 },
231
+ null, { id: 101 }, null,
232
+ { id: 106 }, null, { id: 107 },
233
+ { id: 111 }, { id: 112 }, null,
234
+ { id: 116 }, null, { id: 117 },
235
+ null, { id: 121 }, null,
236
+ ],
237
+ },
238
+ {
239
+ name: 'Offensive Auras',
240
+ skills: [
241
+ { id: 98 }, null, null,
242
+ null, { id: 102 }, { id: 103 },
243
+ { id: 108 }, null, null,
244
+ { id: 113 }, { id: 114 }, null,
245
+ null, { id: 118 }, { id: 119 },
246
+ { id: 122 }, null, { id: 123 },
247
+ ],
248
+ },
249
+ {
250
+ name: 'Defensive Auras',
251
+ skills: [
252
+ { id: 99 }, null, { id: 100 },
253
+ null, { id: 104 }, { id: 105 },
254
+ { id: 109 }, null, { id: 110 },
255
+ null, { id: 115 }, null,
256
+ { id: 120 }, null, null,
257
+ null, { id: 124 }, { id: 125 },
258
+ ],
259
+ },
260
+ ],
261
+ },
262
+ {
263
+ name: 'Sorceress',
264
+ tabs: [
265
+ {
266
+ name: 'Fire',
267
+ skills: [
268
+ null, { id: 36 }, { id: 37 },
269
+ { id: 41 }, null, null,
270
+ { id: 46 }, { id: 47 }, null,
271
+ { id: 51 }, null, { id: 52 },
272
+ null, { id: 56 }, null,
273
+ null, { id: 61 }, { id: 62 },
274
+ ],
275
+ },
276
+ {
277
+ name: 'Lightning',
278
+ skills: [
279
+ null, { id: 38 }, null,
280
+ { id: 42 }, null, { id: 43 },
281
+ { id: 48 }, { id: 49 }, null,
282
+ null, { id: 53 }, { id: 54 },
283
+ { id: 57 }, null, { id: 58 },
284
+ null, { id: 63 }, null,
285
+ ],
286
+ },
287
+ {
288
+ name: 'Cold',
289
+ skills: [
290
+ null, { id: 39 }, { id: 40 },
291
+ { id: 44 }, { id: 45 }, null,
292
+ null, null, { id: 50 },
293
+ null, { id: 55 }, null,
294
+ { id: 59 }, null, { id: 60 },
295
+ { id: 64 }, { id: 65 }, null,
296
+ ],
297
+ },
298
+ ],
299
+ },
300
+ ],
301
+ skills: {
302
+ // Synergy is visual only, since I haven't
303
+ // found how the game defines these for display.
304
+ '6': {
305
+ 'name': 'Magic Arrow',
306
+ 'desc': 'creates a magical arrow or bolt that does extra damage',
307
+ },
308
+ '7': {
309
+ 'name': 'Fire Arrow',
310
+ 'desc': 'magically enhances your arrows or bolts with fire',
311
+ 'synergy': [
312
+ [16, '+12%'],
313
+ ],
314
+ },
315
+ '8': {
316
+ 'name': 'Inner Sight',
317
+ 'desc': 'illuminates nearby enemies making them easier to hit for you and your party',
318
+ },
319
+ '9': {
320
+ 'name': 'Critical Strike',
321
+ 'desc': 'PASSIVE\nyour attacks have a chance to do double damage',
322
+ },
323
+ '10': {
324
+ 'name': 'Jab',
325
+ 'desc': 'attacks with a series of rapid thrusts using a javelin or spear class weapon',
326
+ },
327
+ '11': {
328
+ 'name': 'Cold Arrow',
329
+ 'desc': 'magically enhances your arrows or bolts by adding cold damage and a slowing effect\ncold arrows only do half of their regular damage',
330
+ 'synergy': [
331
+ [21, '+12%'],
332
+ ],
333
+ },
334
+ '12': {
335
+ 'name': 'Multiple Shot',
336
+ 'desc': 'magically splits one arrow or bolt into many',
337
+ },
338
+ '13': {
339
+ 'name': 'Dodge',
340
+ 'desc': 'PASSIVE\nyou have a chance to dodge a melee attack when attacking or standing still',
341
+ },
342
+ '14': {
343
+ 'name': 'Power Strike',
344
+ 'desc': 'adds lightning damage to attacks with javelin and spear class weapons',
345
+ 'synergy': [
346
+ [20, '+10%'],
347
+ [24, '+10%'],
348
+ [34, '+10%'],
349
+ [35, '+10%'],
350
+ ],
351
+ },
352
+ '15': {
353
+ 'name': 'Poison Javelin',
354
+ 'desc': 'magically enhances your javelin to leave a trail of poison clouds',
355
+ 'synergy': [
356
+ [25, '+12%'],
357
+ ],
358
+ },
359
+ '16': {
360
+ 'name': 'Exploding Arrow',
361
+ 'desc': 'enchants an arrow or bolt that explodes on contact, damaging all nearby enemies',
362
+ 'synergy': [
363
+ [7, '+12%'],
364
+ ],
365
+ },
366
+ '17': {
367
+ 'name': 'Slow Missiles',
368
+ 'desc': 'illuminates nearby enemies and slows their ranged attacks',
369
+ },
370
+ '18': {
371
+ 'name': 'Avoid',
372
+ 'desc': 'PASSIVE\nyou have a chance to dodge enemy missiles when attacking or standing still',
373
+ },
374
+ '19': {
375
+ 'name': 'Impale',
376
+ 'desc': 'increases attack damage but rapidly degrades the weapon',
377
+ },
378
+ '20': {
379
+ 'name': 'Lightning Bolt',
380
+ 'desc': 'magically converts your javelin into a bolt of lightning',
381
+ 'synergy': [
382
+ [14, '+3%'],
383
+ [24, '+3%'],
384
+ [34, '+3%'],
385
+ [35, '+3%'],
386
+ ],
387
+ },
388
+ '21': {
389
+ 'name': 'Ice Arrow',
390
+ 'desc': 'magically enhances your arrow or bolt to freeze your enemies',
391
+ 'synergy': [
392
+ [11, '+8%'],
393
+ [31, '+5% Freeze Len.'],
394
+ ],
395
+ },
396
+ '22': {
397
+ 'name': 'Guided Arrow',
398
+ 'desc': 'enhances your arrows and bolts to track your target or seek one of its own always hits',
399
+ },
400
+ '23': {
401
+ 'name': 'Penetrate',
402
+ 'desc': 'PASSIVE\nincreases your attack rating',
403
+ },
404
+ '24': {
405
+ 'name': 'Charged Strike',
406
+ 'desc': 'adds lightning damage to javelin and spear class weapons and releases charged bolts upon impact',
407
+ 'synergy': [
408
+ [14, '+10%'],
409
+ [20, '+10%'],
410
+ [34, '+10%'],
411
+ [35, '+10%'],
412
+ ],
413
+ },
414
+ '25': {
415
+ 'name': 'Plague Javelin',
416
+ 'desc': 'magically enhances your javelin to release expanding clouds of poison upon impact',
417
+ 'synergy': [
418
+ [15, '+10%'],
419
+ ],
420
+ },
421
+ '26': {
422
+ 'name': 'Strafe',
423
+ 'desc': 'magically splits one arrow into several that target multiple nearby enemies',
424
+ },
425
+ '27': {
426
+ 'name': 'Immolation Arrow',
427
+ 'desc': 'enhances arrows or bolts to cause severe fire damage and creates a pyre upon impact',
428
+ 'synergy': [
429
+ [16, '+10%'],
430
+ [7, '+5% Fire DPS'],
431
+ ],
432
+ },
433
+ '28': {
434
+ 'name': 'Decoy',
435
+ 'desc': 'creates a duplicate of yourself that draws fire from enemies',
436
+ },
437
+ '29': {
438
+ 'name': 'Evade',
439
+ 'desc': 'PASSIVE\nyou have a chance to dodge a melee or missile attack when walking or running',
440
+ },
441
+ '30': {
442
+ 'name': 'Fend',
443
+ 'desc': 'attacks all adjacent targets',
444
+ },
445
+ '31': {
446
+ 'name': 'Freezing Arrow',
447
+ 'desc': 'magically enhances an arrow or bolt to freeze entire groups of monsters',
448
+ 'synergy': [
449
+ [11, '+12%'],
450
+ [21, '+5% Freeze Len.'],
451
+ ],
452
+ },
453
+ '32': {
454
+ 'name': 'Valkyrie',
455
+ 'desc': 'summons a powerful Valkyrie ally',
456
+ 'synergy': [
457
+ [28, '+20% Life'],
458
+ [23, '+40 Attack Rating'],
459
+ [9],
460
+ [13],
461
+ [18],
462
+ [29],
463
+ ],
464
+ },
465
+ '33': {
466
+ 'name': 'Pierce',
467
+ 'desc': 'PASSIVE\nyour missiles have a chance to pass through enemies that they hit',
468
+ },
469
+ '34': {
470
+ 'name': 'Lightning Strike',
471
+ 'desc': 'adds lightning damage to javelin and spear class weapons and releases chain lightning upon impact',
472
+ 'synergy': [
473
+ [14, '+8%'],
474
+ [20, '+8%'],
475
+ [24, '+8%'],
476
+ [35, '+8%'],
477
+ ],
478
+ },
479
+ '35': {
480
+ 'name': 'Lightning Fury',
481
+ 'desc': 'changes a thrown javelin into a powerful bolt of lightning that splits on impact',
482
+ 'synergy': [
483
+ [14, '+1%'],
484
+ [20, '+1%'],
485
+ [24, '+1%'],
486
+ [34, '+1%'],
487
+ ],
488
+ },
489
+ '36': {
490
+ 'name': 'Fire Bolt',
491
+ 'desc': 'creates a magical flaming missile',
492
+ },
493
+ '37': {
494
+ 'name': 'Warmth',
495
+ 'desc': 'PASSIVE\nincreases the rate at which you recover mana',
496
+ },
497
+ '38': {
498
+ 'name': 'Charged Bolt',
499
+ 'desc': 'creates multiple, randomly directed bolts of electrical energy',
500
+ },
501
+ '39': {
502
+ 'name': 'Ice Bolt',
503
+ 'desc': 'creates a magical bolt of ice that damages and slows your enemies',
504
+ },
505
+ '40': {
506
+ 'name': 'Frozen Armor',
507
+ 'desc': 'increases your defense rating and freezes enemies that hit you',
508
+ },
509
+ '41': {
510
+ 'name': 'Inferno',
511
+ 'desc': 'creates a continuous jet of flame to scorch your enemies',
512
+ },
513
+ '42': {
514
+ 'name': 'Static Field',
515
+ 'desc': 'creates an electrical field that reduces life of all nearby enemies',
516
+ },
517
+ '43': {
518
+ 'name': 'Telekinesis',
519
+ 'desc': 'uses the power of your mind to pick up items, use objects, and knock back enemies',
520
+ },
521
+ '44': {
522
+ 'name': 'Frost Nova',
523
+ 'desc': 'creates an expanding ring of ice that damages and slows all nearby enemies',
524
+ },
525
+ '45': {
526
+ 'name': 'Ice Blast',
527
+ 'desc': 'creates a magical sphere of ice that damages and freezes your enemy',
528
+ },
529
+ '46': {
530
+ 'name': 'Blaze',
531
+ 'desc': 'creates a wall of fire in your wake to scorch your enemies',
532
+ },
533
+ '47': {
534
+ 'name': 'Fire Ball',
535
+ 'desc': 'creates an explosive sphere of fiery death to engulf your enemies',
536
+ },
537
+ '48': {
538
+ 'name': 'Nova',
539
+ 'desc': 'creates an expanding ring of lightning to shock nearby enemies',
540
+ },
541
+ '49': {
542
+ 'name': 'Lightning',
543
+ 'desc': 'creates a powerful lightning bolt to lay waste to your enemies',
544
+ },
545
+ '50': {
546
+ 'name': 'Shiver Armor',
547
+ 'desc': 'increases your defense rating freezes and damages enemies that hit you',
548
+ },
549
+ '51': {
550
+ 'name': 'Fire Wall',
551
+ 'desc': 'creates a wall of flame that blocks or burns your enemies',
552
+ },
553
+ '52': {
554
+ 'name': 'Enchant',
555
+ 'desc': 'enchants equipped weapon of targeted character or minion adds fire damage to melee weapons adds one-third fire damage to ranged weapons',
556
+ },
557
+ '53': {
558
+ 'name': 'Chain Lightning',
559
+ 'desc': 'creates a bolt of lightning that arcs through several targets',
560
+ },
561
+ '54': {
562
+ 'name': 'Teleport',
563
+ 'desc': 'instantly moves to a destination within your line of sight',
564
+ },
565
+ '55': {
566
+ 'name': 'Glacial Spike',
567
+ 'desc': 'creates a magical ice comet that freezes or kills nearby enemies',
568
+ },
569
+ '56': {
570
+ 'name': 'Meteor',
571
+ 'desc': 'summons a meteor from the heavens to crush and incinerate your enemies',
572
+ },
573
+ '57': {
574
+ 'name': 'Thunder Storm',
575
+ 'desc': 'summons a deadly thunderstorm that strikes your enemies with bolts of lightning',
576
+ },
577
+ '58': {
578
+ 'name': 'Energy Shield',
579
+ 'desc': 'creates a magical shield that consumes mana instead of health when you take damage',
580
+ },
581
+ '59': {
582
+ 'name': 'Blizzard',
583
+ 'desc': 'summons massive shards of ice to destroy your enemies',
584
+ },
585
+ '60': {
586
+ 'name': 'Chilling Armor',
587
+ 'desc': 'increases defense and discharges an ice bolt in retaliation against ranged attackers',
588
+ },
589
+ '61': {
590
+ 'name': 'Fire Mastery',
591
+ 'desc': 'PASSIVE\nincreases all damage caused by your fire spells',
592
+ },
593
+ '62': {
594
+ 'name': 'Hydra',
595
+ 'desc': 'summons a multi-headed beast of flame to reduce your enemies to ashes',
596
+ },
597
+ '63': {
598
+ 'name': 'Lightning Mastery',
599
+ 'desc': 'PASSIVE\nincreases all damage caused by your lightning spells',
600
+ },
601
+ '64': {
602
+ 'name': 'Frozen Orb',
603
+ 'desc': 'creates a magical globe that sprays a torrent of ice bolts to lay waste to your enemies',
604
+ },
605
+ '65': {
606
+ 'name': 'Cold Mastery',
607
+ 'desc': 'PASSIVE\nincreases the damage of your cold attacks by piercing enemies resistances to cold',
608
+ },
609
+ '66': {
610
+ 'name': 'Amplify Damage',
611
+ 'desc': 'curses a group of enemies, increasing the non-magic damage they receive',
612
+ },
613
+ '67': {
614
+ 'name': 'Teeth',
615
+ 'desc': 'fires a barrage of summoned barbed teeth',
616
+ },
617
+ '68': {
618
+ 'name': 'Bone Armor',
619
+ 'desc': 'creates an orbiting shield of bone that absorbs melee damage',
620
+ },
621
+ '69': {
622
+ 'name': 'Skeleton Mastery',
623
+ 'desc': 'PASSIVE\nincreases life and damage of raised skeletons and revived creatures',
624
+ },
625
+ '70': {
626
+ 'name': 'Raise Skeleton',
627
+ 'desc': 'cast on the corpse of a slain monster, this raises a skeleton warrior that fights for you',
628
+ },
629
+ '71': {
630
+ 'name': 'Dim Vision',
631
+ 'desc': 'curses a group of monsters, reducing their vision radius',
632
+ },
633
+ '72': {
634
+ 'name': 'Weaken',
635
+ 'desc': 'curses a group of enemies, reducing the amount of damage they inflict',
636
+ },
637
+ '73': {
638
+ 'name': 'Poison Dagger',
639
+ 'desc': 'adds poison to your dagger attacks',
640
+ },
641
+ '74': {
642
+ 'name': 'Corpse Explosion',
643
+ 'desc': 'cast on the corpse of a slain monster, it explodes, damaging nearby enemies',
644
+ },
645
+ '75': {
646
+ 'name': 'Clay Golem',
647
+ 'desc': 'creates a golem from the earth to fight by your side',
648
+ },
649
+ '76': {
650
+ 'name': 'Iron Maiden',
651
+ 'desc': 'curses a group of enemies, causing them to damage themselves when damaging others',
652
+ },
653
+ '77': {
654
+ 'name': 'Terror',
655
+ 'desc': 'curses a group of monsters, causing them to flee in terror',
656
+ },
657
+ '78': {
658
+ 'name': 'Bone Wall',
659
+ 'desc': 'creates an impassable barrier of bone and debris',
660
+ },
661
+ '79': {
662
+ 'name': 'Golem Mastery',
663
+ 'desc': 'Enhances Speed and Life of all your Golems',
664
+ },
665
+ '80': {
666
+ 'name': 'Raise Skeletal Mage',
667
+ 'desc': 'cast on the corpse of a slain monster, this raises a skeleton mage that fights for you',
668
+ },
669
+ '81': {
670
+ 'name': 'Confuse',
671
+ 'desc': 'curses a monster to force it to attack random targets',
672
+ },
673
+ '82': {
674
+ 'name': 'Life Tap',
675
+ 'desc': 'curses a group of monsters so that damaging them gives the attacker life',
676
+ },
677
+ '83': {
678
+ 'name': 'Poison Explosion',
679
+ 'desc': 'cast on the corpse of a slain monster, toxic gas is released that poisons nearby monsters',
680
+ },
681
+ '84': {
682
+ 'name': 'Bone Spear',
683
+ 'desc': 'summons a deadly spike of bone to impale your enemies',
684
+ },
685
+ '85': {
686
+ 'name': 'Blood Golem',
687
+ 'desc': 'creates a golem that shares with you the life it steals and damage it receives',
688
+ },
689
+ '86': {
690
+ 'name': 'Attract',
691
+ 'desc': 'curses a monster to become the target of all nearby monsters this curse may not be overridden by another curse',
692
+ },
693
+ '87': {
694
+ 'name': 'Decrepify',
695
+ 'desc': 'curses a group of enemies to make them slow, weak and take amplified damage',
696
+ },
697
+ '88': {
698
+ 'name': 'Bone Prison',
699
+ 'desc': 'creates a barrier of fossilized bone around your target',
700
+ },
701
+ '89': {
702
+ 'name': 'Summon Resist',
703
+ 'desc': 'PASSIVE\nincreases the resistances of all summoned creatures',
704
+ },
705
+ '90': {
706
+ 'name': 'Iron Golem',
707
+ 'desc': 'transforms a metallic item into a golem that gains the properties of the item',
708
+ },
709
+ '91': {
710
+ 'name': 'Lower Resist',
711
+ 'desc': 'curses an enemy to take more damage from all magical attacks lowers resistances of monsters lowers maximum resistances of hostile players',
712
+ },
713
+ '92': {
714
+ 'name': 'Poison Nova',
715
+ 'desc': 'emits an expanding ring of concentrated poison',
716
+ },
717
+ '93': {
718
+ 'name': 'Bone Spirit',
719
+ 'desc': 'releases a spirit of the restless undead that tracks its target or finds one of its own',
720
+ },
721
+ '94': {
722
+ 'name': 'Fire Golem',
723
+ 'desc': 'creates a golem that converts the damage it receives from fire into life',
724
+ },
725
+ '95': {
726
+ 'name': 'Revive',
727
+ 'desc': 'returns a monster to life to fight by your side',
728
+ },
729
+ '96': {
730
+ 'name': 'Sacrifice',
731
+ 'desc': 'increased accuracy and damage at the cost of life',
732
+ },
733
+ '97': {
734
+ 'name': 'Smite',
735
+ 'desc': 'temporarily stun your enemy by bashing it with your shield',
736
+ },
737
+ '98': {
738
+ 'name': 'Might',
739
+ 'desc': 'when active, aura increases the damage done by you and your party',
740
+ },
741
+ '99': {
742
+ 'name': 'Prayer',
743
+ 'desc': 'when active, aura slowly regenerates the life of you and your party',
744
+ },
745
+ '100': {
746
+ 'name': 'Resist Fire',
747
+ 'desc': 'when active, aura decreases fire damage done to you and your party',
748
+ },
749
+ '101': {
750
+ 'name': 'Holy Bolt',
751
+ 'desc': 'a bolt of divine energy that damages undead enemies or heals allies',
752
+ },
753
+ '102': {
754
+ 'name': 'Holy Fire',
755
+ 'desc': 'when active, aura damages nearby enemies with heavenly flames',
756
+ },
757
+ '103': {
758
+ 'name': 'Thorns',
759
+ 'desc': 'when active, aura reflects damage done to you back at your attacker',
760
+ },
761
+ '104': {
762
+ 'name': 'Defiance',
763
+ 'desc': 'when active, aura increases the defense rating of you and your party',
764
+ },
765
+ '105': {
766
+ 'name': 'Resist Cold',
767
+ 'desc': 'when active, aura decreases cold damage done to you and your party',
768
+ },
769
+ '106': {
770
+ 'name': 'Zeal',
771
+ 'desc': 'allows you to attack multiple adjacent enemies with a single attack',
772
+ },
773
+ '107': {
774
+ 'name': 'Charge',
775
+ 'desc': 'charge into battle and attack an enemy',
776
+ },
777
+ '108': {
778
+ 'name': 'Blessed Aim',
779
+ 'desc': 'when active, aura increases the attack rating for you and your party',
780
+ },
781
+ '109': {
782
+ 'name': 'Cleansing',
783
+ 'desc': 'when active, aura reduces the length of time you and your party will remain poisoned or cursed',
784
+ },
785
+ '110': {
786
+ 'name': 'Resist Lightning',
787
+ 'desc': 'when active, aura decreases lightning damage done to you and your party',
788
+ },
789
+ '111': {
790
+ 'name': 'Vengeance',
791
+ 'desc': 'fire, lightning and cold damage are added to each successful attack',
792
+ },
793
+ '112': {
794
+ 'name': 'Blessed Hammer',
795
+ 'desc': 'summons an ethereal hammer that spirals outwards damaging enemies it hits\n150 Percent Damage to Undead',
796
+ },
797
+ '113': {
798
+ 'name': 'Concentration',
799
+ 'desc': 'when active, aura increases the damage and decreases the chance that the attack will be interrupted for you and your party ',
800
+ },
801
+ '114': {
802
+ 'name': 'Holy Freeze',
803
+ 'desc': 'when active, aura freezes nearby monsters',
804
+ },
805
+ '115': {
806
+ 'name': 'Vigor',
807
+ 'desc': 'when active, aura increases stamina recovery rate, maximum stamina and movement speed for you and your party',
808
+ },
809
+ '116': {
810
+ 'name': 'Conversion',
811
+ 'desc': 'converts monsters to fight against other foul demons and beasts',
812
+ },
813
+ '117': {
814
+ 'name': 'Holy Shield',
815
+ 'desc': 'enhances your shield with divine power',
816
+ },
817
+ '118': {
818
+ 'name': 'Holy Shock',
819
+ 'desc': 'when active, aura causes pulses of electricity to damage nearby enemies adds lightning damage to your attack',
820
+ },
821
+ '119': {
822
+ 'name': 'Sanctuary',
823
+ 'desc': 'when active, aura damages the undead and knocks them back',
824
+ },
825
+ '120': {
826
+ 'name': 'Meditation',
827
+ 'desc': 'when active, aura increases mana recovery for you and your party',
828
+ },
829
+ '121': {
830
+ 'name': 'Fist of the Heavens',
831
+ 'desc': 'lightning strikes your target as holy bolts seek out nearby enemies',
832
+ },
833
+ '122': {
834
+ 'name': 'Fanaticism',
835
+ 'desc': 'when active, aura increases damage, attack speed, and attack rating for you and your party',
836
+ },
837
+ '123': {
838
+ 'name': 'Conviction',
839
+ 'desc': 'when active, aura reduces the defenses and resistances of nearby enemies',
840
+ },
841
+ '124': {
842
+ 'name': 'Redemption',
843
+ 'desc': 'when active, aura attempts to redeem the souls of slain enemies to give you life and mana',
844
+ },
845
+ '125': {
846
+ 'name': 'Salvation',
847
+ 'desc': 'when active, aura decreases fire, cold and lightning damage done to you and your party',
848
+ },
849
+ '126': {
850
+ 'name': 'Bash',
851
+ 'desc': 'powerful blow that increases the damage done to enemies and knocks them back',
852
+ },
853
+ '127': {
854
+ 'name': 'Sword Mastery',
855
+ 'desc': 'PASSIVE\nimproves sword fighting skill',
856
+ },
857
+ '128': {
858
+ 'name': 'Axe Mastery',
859
+ 'desc': 'PASSIVE\nimproves axe fighting skill',
860
+ },
861
+ '129': {
862
+ 'name': 'Mace Mastery',
863
+ 'desc': 'PASSIVE\nimproves mace fighting skill',
864
+ },
865
+ '130': {
866
+ 'name': 'Howl',
867
+ 'desc': 'sends nearby monsters scrambling away in fear',
868
+ },
869
+ '131': {
870
+ 'name': 'Find Potion',
871
+ 'desc': 'use on the corpse of a slain monster for a chance to find a potion',
872
+ },
873
+ '132': {
874
+ 'name': 'Leap',
875
+ 'desc': 'leaps away from danger or into the fray',
876
+ },
877
+ '133': {
878
+ 'name': 'Double Swing',
879
+ 'desc': 'when two weapons are equipped attacks two targets if possible, or one target twice',
880
+ },
881
+ '134': {
882
+ 'name': 'Pole Arm Mastery',
883
+ 'desc': 'PASSIVE\nimproves pole arm skill',
884
+ },
885
+ '135': {
886
+ 'name': 'Throwing Mastery',
887
+ 'desc': 'PASSIVE\nimproves thrown weapon skill',
888
+ },
889
+ '136': {
890
+ 'name': 'Spear Mastery',
891
+ 'desc': 'PASSIVE\nimproves spear fighting skill',
892
+ },
893
+ '137': {
894
+ 'name': 'Taunt',
895
+ 'desc': 'enrages a monster into relentlessly attacking',
896
+ },
897
+ '138': {
898
+ 'name': 'Shout',
899
+ 'desc': 'warns of impending danger and improves the defense rating of you and your party',
900
+ },
901
+ '139': {
902
+ 'name': 'Stun',
903
+ 'desc': 'stuns your target for a short time and increases your attack rating',
904
+ },
905
+ '140': {
906
+ 'name': 'Double Throw',
907
+ 'desc': 'allows you to throw two different throwing weapons at the same time',
908
+ },
909
+ '141': {
910
+ 'name': 'Increased Stamina',
911
+ 'desc': 'PASSIVE\nincreases your stamina',
912
+ },
913
+ '142': {
914
+ 'name': 'Find Item',
915
+ 'desc': 'use on the corpse of a slain monster to find hidden treasures',
916
+ },
917
+ '143': {
918
+ 'name': 'Leap Attack',
919
+ 'desc': 'leaps to and attacks target enemy in one swift assault',
920
+ },
921
+ '144': {
922
+ 'name': 'Concentrate',
923
+ 'desc': 'attack that is not interruptible and improves attack and defense rating',
924
+ },
925
+ '145': {
926
+ 'name': 'Iron Skin',
927
+ 'desc': 'PASSIVE\nimproves defense rating',
928
+ },
929
+ '146': {
930
+ 'name': 'Battle Cry',
931
+ 'desc': 'fearsome cry that decreases enemies defense rating and damage',
932
+ },
933
+ '147': {
934
+ 'name': 'Frenzy',
935
+ 'desc': 'allows you to swing two weapons at once each successful attack increases your overall speed requires you to equip two weapons',
936
+ },
937
+ '148': {
938
+ 'name': 'Increased Speed',
939
+ 'desc': 'PASSIVE\nincreases walk and run speed',
940
+ },
941
+ '149': {
942
+ 'name': 'Battle Orders',
943
+ 'desc': 'improves the maximum mana, life and stamina of you and your party',
944
+ },
945
+ '150': {
946
+ 'name': 'Grim Ward',
947
+ 'desc': 'use on the corpse of a slain monster to create a frightening totem that causes nearby monsters to flee',
948
+ },
949
+ '151': {
950
+ 'name': 'Whirlwind',
951
+ 'desc': 'a whirling dance of death that cuts a path through the legions of your enemies',
952
+ },
953
+ '152': {
954
+ 'name': 'Berserk',
955
+ 'desc': 'a powerful but reckless attack that increases damage and attack rating but decreases defense rating',
956
+ },
957
+ '153': {
958
+ 'name': 'Natural Resistance',
959
+ 'desc': 'PASSIVE\nincreases natural resistances to elemental and poison damage',
960
+ },
961
+ '154': {
962
+ 'name': 'War Cry',
963
+ 'desc': 'injures and stuns all nearby enemies',
964
+ },
965
+ '155': {
966
+ 'name': 'Battle Command',
967
+ 'desc': 'increases all current skill levels for you and your party',
968
+ },
969
+ '221': {
970
+ 'name': 'Raven',
971
+ 'desc': 'summon ravens to peck out the eyes of your enemies',
972
+ },
973
+ '222': {
974
+ 'name': 'Poison Creeper',
975
+ 'desc': 'summon a vine that spreads disease to all it contacts',
976
+ },
977
+ '223': {
978
+ 'name': 'Werewolf',
979
+ 'desc': 'transform into a werewolf',
980
+ },
981
+ '224': {
982
+ 'name': 'Lycanthropy',
983
+ 'desc': 'PASSIVE\nimproves duration and life when in werewolf or werebear form',
984
+ },
985
+ '225': {
986
+ 'name': 'Firestorm',
987
+ 'desc': 'unleash fiery chaos to burn your enemies',
988
+ },
989
+ '226': {
990
+ 'name': 'Oak Sage',
991
+ 'desc': 'summon a spirit pet that increases life for you and your party',
992
+ },
993
+ '227': {
994
+ 'name': 'Summon Spirit Wolf',
995
+ 'desc': 'summon a wolf with teleporting ability to fight by your side',
996
+ },
997
+ '228': {
998
+ 'name': 'Werebear',
999
+ 'desc': 'transform into a werebear',
1000
+ },
1001
+ '229': {
1002
+ 'name': 'Molten Boulder',
1003
+ 'desc': 'launch a boulder of flaming hot magma that knocks back your enemies',
1004
+ },
1005
+ '230': {
1006
+ 'name': 'Arctic Blast',
1007
+ 'desc': 'blast a continuous jet of ice to burn your enemies with frost',
1008
+ },
1009
+ '231': {
1010
+ 'name': 'Carrion Vine',
1011
+ 'desc': 'summon a vine that eats corpses and replenishes your life',
1012
+ },
1013
+ '232': {
1014
+ 'name': 'Feral Rage',
1015
+ 'desc': 'when in werewolf form, go into a frenzied rage to steal increasing amounts of life from your enemies with successive hits',
1016
+ },
1017
+ '233': {
1018
+ 'name': 'Maul',
1019
+ 'desc': 'when in werebear form, maul your enemies for increasing extra damage with successive hits',
1020
+ },
1021
+ '234': {
1022
+ 'name': 'Fissure',
1023
+ 'desc': 'open volcanic vents below your enemies, burning them to a crisp',
1024
+ },
1025
+ '235': {
1026
+ 'name': 'Cyclone Armor',
1027
+ 'desc': 'shield yourself from damage caused by fire, cold, and lightning',
1028
+ },
1029
+ '236': {
1030
+ 'name': 'Heart of Wolverine',
1031
+ 'desc': 'summon a spirit pet that adds to the damage and attack rating of you and your party',
1032
+ },
1033
+ '237': {
1034
+ 'name': 'Summon Dire Wolf',
1035
+ 'desc': 'summon a wolf that becomes enraged, eating corpses to increase damage it does to enemies',
1036
+ },
1037
+ '238': {
1038
+ 'name': 'Rabies',
1039
+ 'desc': 'when in werewolf form, bite your enemies to inflict them with disease that spreads to other monsters',
1040
+ },
1041
+ '239': {
1042
+ 'name': 'Fire Claws',
1043
+ 'desc': 'when in werewolf or werebear form, maul your enemies with a fiery claw attack',
1044
+ },
1045
+ '240': {
1046
+ 'name': 'Twister',
1047
+ 'desc': 'release several small whirlwinds that cut a path through your enemies',
1048
+ },
1049
+ '241': {
1050
+ 'name': 'Solar Creeper',
1051
+ 'desc': 'summon a vine that eats corpses and replenishes your mana',
1052
+ },
1053
+ '242': {
1054
+ 'name': 'Hunger',
1055
+ 'desc': 'when in werewolf or werebear form, bite your enemies to gain life and mana',
1056
+ },
1057
+ '243': {
1058
+ 'name': 'Shock Wave',
1059
+ 'desc': 'when in werebear form, stomp to create a shock wave that stuns nearby enemies',
1060
+ },
1061
+ '244': {
1062
+ 'name': 'Volcano',
1063
+ 'desc': 'summon forth a volcano to rain death and destruction over your enemies',
1064
+ },
1065
+ '245': {
1066
+ 'name': 'Tornado',
1067
+ 'desc': 'create a funnel of wind and debris to blast your enemies',
1068
+ },
1069
+ '246': {
1070
+ 'name': 'Spirit of Barbs',
1071
+ 'desc': 'summon spirit pet that reflects damage taken by you and your party back at your enemies',
1072
+ },
1073
+ '247': {
1074
+ 'name': 'Summon Grizzly',
1075
+ 'desc': 'summon a ferocious grizzly bear',
1076
+ },
1077
+ '248': {
1078
+ 'name': 'Fury',
1079
+ 'desc': 'when in werewolf form, attack either multiple adjacent targets or one target multiple times',
1080
+ },
1081
+ '249': {
1082
+ 'name': 'Armageddon',
1083
+ 'desc': 'create a meteor shower to rain fiery destruction on nearby enemies',
1084
+ },
1085
+ '250': {
1086
+ 'name': 'Hurricane',
1087
+ 'desc': 'create a massive storm of wind and debris to pound your enemies to bits',
1088
+ },
1089
+ '251': {
1090
+ 'name': 'Fire Blast',
1091
+ 'desc': 'throw a fire bomb to blast your enemies to bits',
1092
+ 'synergy': [
1093
+ [256, '+9%'],
1094
+ [261, '+9%'],
1095
+ [262, '+9%'],
1096
+ [271, '+9%'],
1097
+ [272, '+9%'],
1098
+ [276, '+9%'],
1099
+ ],
1100
+ },
1101
+ '252': {
1102
+ 'name': 'Claw Mastery',
1103
+ 'desc': 'PASSIVE\nimproves your skill with claw-class weapons',
1104
+ },
1105
+ '253': {
1106
+ 'name': 'Psychic Hammer',
1107
+ 'desc': 'use the power of your mind to create a psychic blast to crush and knock back your enemies',
1108
+ },
1109
+ '254': {
1110
+ 'name': 'Tiger Strike',
1111
+ 'desc': 'CHARGE-UP SKILL\nconsecutive hits add damage bonuses to finishing moves must use a dragon finishing move or normal attack to release charges',
1112
+ },
1113
+ '255': {
1114
+ 'name': 'Dragon Talon',
1115
+ 'desc': 'FINISHING MOVE\nkick your enemies out of your way adds charged-up bonuses to the kick',
1116
+ },
1117
+ '256': {
1118
+ 'name': 'Shock Web',
1119
+ 'desc': 'throw a web of lightning to shock your enemies',
1120
+ 'synergy': [
1121
+ [261, '+11%'],
1122
+ [271, '+11%'],
1123
+ [276, '+11%'],
1124
+ [251, '+1/3 Missile'],
1125
+ ],
1126
+ },
1127
+ '257': {
1128
+ 'name': 'Blade Sentinel',
1129
+ 'desc': 'set a spinning blade to patrol between you and target point',
1130
+ },
1131
+ '258': {
1132
+ 'name': 'Burst of Speed',
1133
+ 'desc': 'increases attack and movement speed for a period of time',
1134
+ },
1135
+ '259': {
1136
+ 'name': 'Fists of Fire',
1137
+ 'desc': 'CHARGE-UP SKILL\nconsecutive hits add fire damage to finishing moves can only be used with claw-class weapons must use a dragon finishing move or normal attack to release charges',
1138
+ 'synergy': [
1139
+ [280, '+12%'],
1140
+ ],
1141
+ },
1142
+ '260': {
1143
+ 'name': 'Dragon Claw',
1144
+ 'desc': 'FINISHING MOVE\nslice and dice your enemies with your dual claw-class weapons adds charged-up bonuses to both claw attacks',
1145
+ },
1146
+ '261': {
1147
+ 'name': 'Charged Bolt Sentry',
1148
+ 'desc': 'a trap that emits charged bolts at enemies that pass near',
1149
+ 'synergy': [
1150
+ [271, '+6%'],
1151
+ [251, '+6%'],
1152
+ [276, '+6%'],
1153
+ [271, '+1/4 Shot'],
1154
+ [256, '+1/3 Missile'],
1155
+ ],
1156
+ },
1157
+ '262': {
1158
+ 'name': 'Wake of Fire',
1159
+ 'desc': 'a trap that emits waves of fire',
1160
+ 'synergy': [
1161
+ [251, '+8%'],
1162
+ [272, '+8%'],
1163
+ ],
1164
+ },
1165
+ '263': {
1166
+ 'name': 'Weapon Block',
1167
+ 'desc': 'PASSIVE\nchance to block when you are using dual claw-class weapons',
1168
+ },
1169
+ '264': {
1170
+ 'name': 'Cloak of Shadows',
1171
+ 'desc': 'cast a shadow to blind nearby enemies lowering their defenses for a period of time',
1172
+ },
1173
+ '265': {
1174
+ 'name': 'Cobra Strike',
1175
+ 'desc': 'CHARGE-UP SKILL\nconsecutive hits add life and mana stealing to finishing moves must use a dragon finishing move or normal attack to release charges',
1176
+ },
1177
+ '266': {
1178
+ 'name': 'Blade Fury',
1179
+ 'desc': 'throw spinning blades to slice up your enemies',
1180
+ },
1181
+ '267': {
1182
+ 'name': 'Fade',
1183
+ 'desc': 'raise all resistances and resist curses for a period of time',
1184
+ },
1185
+ '268': {
1186
+ 'name': 'Shadow Warrior',
1187
+ 'desc': 'summon a shadow of yourself that mimics your skills and fights by your side',
1188
+ },
1189
+ '269': {
1190
+ 'name': 'Claws of Thunder',
1191
+ 'desc': 'CHARGE-UP SKILL\nconsecutive hits add lightning damage to finishing moves can only be used with claw-class weapons must use a dragon finishing move or normal attack to release charges',
1192
+ 'synergy': [
1193
+ [280, '+8%'],
1194
+ ],
1195
+ },
1196
+ '270': {
1197
+ 'name': 'Dragon Tail',
1198
+ 'desc': 'FINISHING MOVE\nknock back your enemies with an explosive kick adds charged-up bonuses to the kick',
1199
+ },
1200
+ '271': {
1201
+ 'name': 'Lightning Sentry',
1202
+ 'desc': 'a trap that shoots lightning to scorch passing enemies',
1203
+ 'synergy': [
1204
+ [256, '+12%'],
1205
+ [261, '+12%'],
1206
+ [276, '+12%'],
1207
+ ],
1208
+ },
1209
+ '272': {
1210
+ 'name': 'Wake of Inferno',
1211
+ 'desc': 'trap that sprays fire at passing enemies',
1212
+ 'synergy': [
1213
+ [251, '+10%'],
1214
+ [276, '+10%'],
1215
+ [262, '+7%'],
1216
+ [262, '+1/2 Yard'],
1217
+ ],
1218
+ },
1219
+ '273': {
1220
+ 'name': 'Mind Blast',
1221
+ 'desc': 'using the power of your mind stun a group of enemies and convert the feeble-minded',
1222
+ },
1223
+ '274': {
1224
+ 'name': 'Blades of Ice',
1225
+ 'desc': 'CHARGE-UP SKILL\nconsecutive hits add cold damage to finishing moves can only be used with claw-class weapons must use a dragon finishing move or normal attack to release charges',
1226
+ 'synergy': [
1227
+ [280, '+8%'],
1228
+ ],
1229
+ },
1230
+ '275': {
1231
+ 'name': 'Dragon Flight',
1232
+ 'desc': 'FINISHING MOVE\nteleport to your enemies and destroy them with a kick adds charged-up bonuses to the kick',
1233
+ },
1234
+ '276': {
1235
+ 'name': 'Death Sentry',
1236
+ 'desc': 'trap that shoots lightning at your enemies or explodes nearby corpses laying waste to more enemies',
1237
+ 'synergy': [
1238
+ [271, '+12%'],
1239
+ [251, '+1/3 Shot'],
1240
+ ],
1241
+ },
1242
+ '277': {
1243
+ 'name': 'Blade Shield',
1244
+ 'desc': 'spinning blades slice enemies who stray too close',
1245
+ },
1246
+ '278': {
1247
+ 'name': 'Venom',
1248
+ 'desc': 'add poison damage to your weapons',
1249
+ },
1250
+ '279': {
1251
+ 'name': 'Shadow Master',
1252
+ 'desc': 'summon a powerful shadow of yourself to fight by your side',
1253
+ },
1254
+ '280': {
1255
+ 'name': 'Phoenix Strike',
1256
+ 'desc': 'CHARGE-UP SKILL\nadds elemental novas to finishing moves must use a dragon finishing move or normal attack to release charges',
1257
+ 'synergy': [
1258
+ [259, '+10% Fire'],
1259
+ [269, '+13% Lightning'],
1260
+ [274, '+10% Cold'],
1261
+ [259, '+6% Avg. Fire DPS'],
1262
+ ],
1263
+ }
1264
+ },
1265
+ skillMult: {
1266
+ 15: 25,
1267
+ 25: 25,
1268
+ 41: 25,
1269
+ 46: 75,
1270
+ 51: 75,
1271
+ 73: 25,
1272
+ 83: 25,
1273
+ 92: 25,
1274
+ 222: 25,
1275
+ 225: 75,
1276
+ 230: 25,
1277
+ 238: 25,
1278
+ 272: 25 / 3,
1279
+ 278: 25,
1280
+ },
1281
+ typeMap: {
1282
+ phy: 'Physical',
1283
+ fire: 'Fire',
1284
+ ltng: 'Lightning',
1285
+ cold: 'Cold',
1286
+ pois: 'Poison',
1287
+ stun: 'Physical',
1288
+ mag: 'Magic',
1289
+ },
1290
+ skillsLookup: {},
1291
+ builds: [],
1292
+ currentBuild: 0,
1293
+ },
1294
+ computed: {
1295
+ totalPoints () {
1296
+ return Object.keys(this.skills).reduce((total, id) => total + this.builds[this.currentBuild][id], 0);
1297
+ },
1298
+ },
1299
+ watch: {
1300
+ builds: {
1301
+ handler () {
1302
+ window.location.hash = encode(this.builds);
1303
+ },
1304
+ deep: true,
1305
+ },
1306
+ },
1307
+ methods: {
1308
+ addBuild (build = {}) {
1309
+ build.currentClass |= 0;
1310
+ build.name = build.name || '';
1311
+
1312
+ Object.keys(this.skills).forEach(key => {
1313
+ build[key] |= 0;
1314
+ });
1315
+
1316
+ this.builds.push(build);
1317
+ this.currentBuild = this.builds.length - 1;
1318
+ },
1319
+ delBuild (index, e) {
1320
+ e.stopPropagation();
1321
+
1322
+ if (index && window.confirm('Do you wish to delete Build ' + (index + 1 + '?'))) {
1323
+ this.currentBuild = Math.min(this.currentBuild, this.builds.length - 2);
1324
+ this.builds.splice(index, 1);
1325
+ }
1326
+ },
1327
+ setReqs (id) {
1328
+ if (this.builds[this.currentBuild][id]) {
1329
+ this.skills[id].req.forEach(reqid => {
1330
+ if (this.builds[this.currentBuild][reqid] < 1) {
1331
+ this.builds[this.currentBuild][reqid]++;
1332
+ }
1333
+
1334
+ this.setReqs(reqid);
1335
+ });
1336
+ }
1337
+ },
1338
+ skillCheck (id) {
1339
+ if (this.skills[id].dep.reduce((t, depid) => {
1340
+ return t + this.builds[this.currentBuild][depid];
1341
+ }, 0)) {
1342
+ this.builds[this.currentBuild][id] = clamp(1, (this.builds[this.currentBuild][id] | 0), 60);
1343
+ } else {
1344
+ this.builds[this.currentBuild][id] = clamp(0, (this.builds[this.currentBuild][id] | 0), 60);
1345
+ }
1346
+
1347
+ this.setReqs(id);
1348
+ },
1349
+ skillClick (id, left, e) {
1350
+ e.preventDefault();
1351
+ e.stopPropagation();
1352
+ this.builds[this.currentBuild][id] = clamp(0, (this.builds[this.currentBuild][id] | 0) + (left ? 1 : -1), 60);
1353
+ this.skillCheck(id);
1354
+ },
1355
+ resetSkills () {
1356
+ if (this.totalPoints && window.confirm('Reset all skills for the current build?')) {
1357
+ Object.keys(this.skills).forEach(key => {
1358
+ this.builds[this.currentBuild][key] = 0;
1359
+ });
1360
+ }
1361
+ },
1362
+ renameBuild (buildIndex) {
1363
+ let ret = prompt('Enter a build name: ', this.builds[buildIndex].name || buildIndex);
1364
+
1365
+ if (ret) {
1366
+ this.builds[buildIndex].name = ret;
1367
+ }
1368
+ },
1369
+ diminishedValue (lvl, a, b) {
1370
+ return (b - a) * Math.floor(110 * lvl / (lvl + 6)) / 100 + a;
1371
+ },
1372
+ getSkillValue (id, value) {
1373
+ let v = p => this.getSkillValue(id, p);
1374
+
1375
+ switch (value) {
1376
+ case 'blvl':
1377
+ return this.builds[this.currentBuild][id] || 0;
1378
+ case 'lvl':
1379
+ return this.builds[this.currentBuild][id] || 0;
1380
+ case 'par1':
1381
+ return this.d2.skills[id].Param1 || 0;
1382
+ case 'par2':
1383
+ return this.d2.skills[id].Param2 || 0;
1384
+ case 'par3':
1385
+ return this.d2.skills[id].Param3 || 0;
1386
+ case 'par4':
1387
+ return this.d2.skills[id].Param4 || 0;
1388
+ case 'par5':
1389
+ return this.d2.skills[id].Param5 || 0;
1390
+ case 'par6':
1391
+ return this.d2.skills[id].Param6 || 0;
1392
+ case 'par7':
1393
+ return this.d2.skills[id].Param7 || 0;
1394
+ case 'par8':
1395
+ return this.d2.skills[id].Param8 || 0;
1396
+ case 'ln12':
1397
+ return v('par1') + (v('lvl') - 1) * v('par2');
1398
+ case 'ln34':
1399
+ return v('par3') + (v('lvl') - 1) * v('par4');
1400
+ case 'ln56':
1401
+ return v('par5') + (v('lvl') - 1) * v('par6');
1402
+ case 'ln78':
1403
+ return v('par7') + (v('lvl') - 1) * v('par8');
1404
+ case 'dm12':
1405
+ return this.diminishedValue(v('lvl'), v('par1'), v('par2')) | 0;
1406
+ case 'dm34':
1407
+ return this.diminishedValue(v('lvl'), v('par3'), v('par4')) | 0;
1408
+ case 'dm56':
1409
+ return this.diminishedValue(v('lvl'), v('par5'), v('par6')) | 0;
1410
+ case 'dm78':
1411
+ return this.diminishedValue(v('lvl'), v('par7'), v('par8')) | 0;
1412
+ case 'toht':
1413
+ return (this.d2.skills[id].ToHit || 0) + (v('lvl') - 1) * (this.d2.skills[id].LevToHit || 0);
1414
+ case 'mana':
1415
+ return Math.max((this.d2.skills[id].minmana || 0), (((this.d2.skills[id].mana || 0) + (this.d2.skills[id].lvlmana || 0) * (v('lvl') - 1)) << (this.d2.skills[id].manashift || 0)) / 256);
1416
+ default:
1417
+ debugger;
1418
+ throw new Error('[' + id + '] Unknown value: ' + value);
1419
+ }
1420
+ },
1421
+ evalSkillFormula (ast) {
1422
+ switch (ast[0]) {
1423
+ case '+':
1424
+ return this.evalSkillFormula(ast[1]) + this.evalSkillFormula(ast[2]);
1425
+
1426
+ case '-':
1427
+ return this.evalSkillFormula(ast[1]) - this.evalSkillFormula(ast[2]);
1428
+
1429
+ case '*':
1430
+ return this.evalSkillFormula(ast[1]) * this.evalSkillFormula(ast[2]);
1431
+
1432
+ case '/':
1433
+ return this.evalSkillFormula(ast[1]) / this.evalSkillFormula(ast[2]);
1434
+
1435
+ case 'key':
1436
+ return this.getSkillValue(ast[1], ast[2]);
1437
+
1438
+ case 'call': {
1439
+ let params = ast.slice(2).map(v => this.evalSkillFormula(v));
1440
+
1441
+ switch (ast[1]) {
1442
+ case 'skill':
1443
+ return params[0];
1444
+ case 'min':
1445
+ return Math.min(...params);
1446
+ case 'max':
1447
+ return Math.max(...params);
1448
+ default:
1449
+ throw new Error('Unknown call: ' + ast[1]);
1450
+ }
1451
+ }
1452
+
1453
+ case 'value':
1454
+ return ast[1];
1455
+
1456
+ default:
1457
+ throw new Error('Unknown ast node: ' + ast[0]);
1458
+ }
1459
+ },
1460
+ parseSkillFormula (formula, id) {
1461
+ while (formula[0] === '"') {
1462
+ formula = formula.slice(1);
1463
+ }
1464
+
1465
+ while (formula[formula.length - 1] === '"') {
1466
+ formula = formula.slice(0, -1);
1467
+ }
1468
+
1469
+ let tokens = formula.match(/'[^']+'|[a-zA-Z0-9]+|[\S]/g), app = this, pos = 0, accept, call, skillValue, number, value, parenthesis, product, addition, expression;
1470
+
1471
+ accept = function (...expectations) {
1472
+ if (pos + expectations.length > tokens.length) {
1473
+ return null;
1474
+ }
1475
+
1476
+ for (let c = 0; c < expectations.length; c++) {
1477
+ switch (typeof expectations[c]) {
1478
+ case 'function':
1479
+ if (!expectations[c](tokens[pos + c])) {
1480
+ return null;
1481
+ }
1482
+
1483
+ break;
1484
+ case 'string':
1485
+ expectations[c] = [expectations[c]];
1486
+ case 'object':
1487
+ if (expectations[c].test) {
1488
+ if (!expectations[c].test(tokens[pos + c])) {
1489
+ return null;
1490
+ }
1491
+ } else if (expectations[c].includes) {
1492
+ if (!expectations[c].includes(tokens[pos + c])) {
1493
+ return null;
1494
+ }
1495
+ }
1496
+
1497
+ break;
1498
+ default:
1499
+ return null;
1500
+ }
1501
+ }
1502
+
1503
+ let ret = tokens.slice(pos, pos + expectations.length);
1504
+
1505
+ pos += expectations.length;
1506
+
1507
+ return ret.length === 1 ? ret[0] : ret;
1508
+ };
1509
+
1510
+ call = function (name) {
1511
+ let old = pos;
1512
+
1513
+ if (accept('(')) {
1514
+ let params = [], tmp = expression();
1515
+
1516
+ while (tmp) {
1517
+ params.push(tmp);
1518
+
1519
+ if (!accept(',')) {
1520
+ break;
1521
+ }
1522
+
1523
+ tmp = expression();
1524
+ }
1525
+
1526
+ if (accept(')')) {
1527
+ return ['call', name, ...params];
1528
+ }
1529
+ }
1530
+
1531
+ pos = old;
1532
+
1533
+ return null;
1534
+ };
1535
+
1536
+ skillValue = function () {
1537
+ if (tokens[pos][0] === '\'') {
1538
+ let old = pos, skillId = +app.skillsLookup[tokens[pos++].slice(1, -1)];
1539
+
1540
+ if (accept('.')) {
1541
+ let name = tokens[pos++];
1542
+
1543
+ return ['key', skillId, name];
1544
+ }
1545
+
1546
+ pos = old;
1547
+ }
1548
+
1549
+ return null;
1550
+ };
1551
+
1552
+ number = function () {
1553
+ if (/[0-9]/.test(tokens[pos][0])) {
1554
+ return ['value', +tokens[pos++]];
1555
+ }
1556
+
1557
+ return null;
1558
+ };
1559
+
1560
+ value = function () {
1561
+ let ret = number() || skillValue();
1562
+
1563
+ if (ret) {
1564
+ return ret;
1565
+ }
1566
+
1567
+ let name = tokens[pos++];
1568
+
1569
+ return call(name) || ['key', id, name];
1570
+ };
1571
+
1572
+ parenthesis = function () {
1573
+ let old = pos;
1574
+
1575
+ if (accept('(')) {
1576
+ let ret = expression();
1577
+
1578
+ if (ret && accept(')')) {
1579
+ return ret;
1580
+ }
1581
+ }
1582
+
1583
+ pos = old;
1584
+
1585
+ return value();
1586
+ };
1587
+
1588
+ product = function () {
1589
+ let a = parenthesis(), old = pos;
1590
+
1591
+ if (a) {
1592
+ let op = accept(/[*/]/);
1593
+
1594
+ if (op) {
1595
+ let b = product();
1596
+
1597
+ if (b) {
1598
+ return [op, a, b];
1599
+ }
1600
+ }
1601
+ }
1602
+
1603
+ pos = old;
1604
+
1605
+ return a;
1606
+ };
1607
+
1608
+ addition = function () {
1609
+ let a = product(), old = pos;
1610
+
1611
+ if (a) {
1612
+ let op = accept(/[+-]/);
1613
+
1614
+ if (op) {
1615
+ let b = addition();
1616
+
1617
+ if (b) {
1618
+ return [op, a, b];
1619
+ }
1620
+ }
1621
+ }
1622
+
1623
+ pos = old;
1624
+
1625
+ return a;
1626
+ };
1627
+
1628
+ expression = function () {
1629
+ return addition();
1630
+ };
1631
+
1632
+ return expression();
1633
+ },
1634
+ calculateFormula (id, formula) {
1635
+ return this.evalSkillFormula(this.parseSkillFormula(formula, id));
1636
+ },
1637
+ calculateFormulaKey (id, key) {
1638
+ if (this.d2.skills[id][key]) {
1639
+ return this.calculateFormula(id, this.d2.skills[id][key]);
1640
+ }
1641
+
1642
+ return 0;
1643
+ },
1644
+ stagedDamage: function (l, a, b, c, d, e, f, hitshift = 0, mult = 1) {
1645
+ l = l || 0;
1646
+ a = a || 0;
1647
+ b = b || 0;
1648
+ c = c || 0;
1649
+ d = d || 0;
1650
+ e = e || 0;
1651
+ f = f || 0;
1652
+ hitshift = hitshift || 0;
1653
+ mult = mult || 0;
1654
+
1655
+ if (l > 28) {
1656
+ a += f * (l - 28);
1657
+ l = 28;
1658
+ }
1659
+
1660
+ if (l > 22) {
1661
+ a += e * (l - 22);
1662
+ l = 22;
1663
+ }
1664
+
1665
+ if (l > 16) {
1666
+ a += d * (l - 16);
1667
+ l = 16;
1668
+ }
1669
+
1670
+ if (l > 8) {
1671
+ a += c * (l - 8);
1672
+ l = 8;
1673
+ }
1674
+
1675
+ a += b * (Math.max(0, l) - 1);
1676
+
1677
+ return (mult * a) << hitshift;
1678
+ },
1679
+ skillMastery (element) {
1680
+ switch (element) {
1681
+ case 'fire':
1682
+ if (this.builds[this.currentBuild][61]) {
1683
+ return this.calculateFormulaKey(61, 'passivecalc1');
1684
+ }
1685
+
1686
+ break;
1687
+ case 'ltng':
1688
+ if (this.builds[this.currentBuild][63]) {
1689
+ return this.calculateFormulaKey(63, 'passivecalc1');
1690
+ }
1691
+
1692
+ break;
1693
+ default:
1694
+ return 0;
1695
+ }
1696
+
1697
+ return 0;
1698
+ },
1699
+ skillPierce (element) {
1700
+ switch (element) {
1701
+ case 'cold':
1702
+ if (this.builds[this.currentBuild][65]) {
1703
+ return this.calculateFormulaKey(65, 'passivecalc1');
1704
+ }
1705
+
1706
+ break;
1707
+ default:
1708
+ return 0;
1709
+ }
1710
+
1711
+ return 0;
1712
+ },
1713
+ skillEffect (id, lvl) {
1714
+ let args = {}, ret = {};
1715
+
1716
+ if (!this.d2.skills[id].EType && this.d2.skills[id].EMin) {
1717
+ args.min = [this.d2.skills[id].EMin, this.d2.skills[id].EMinLev1, this.d2.skills[id].EMinLev2, this.d2.skills[id].EMinLev3, this.d2.skills[id].EMinLev4, this.d2.skills[id].EMinLev5, this.d2.skills[id].HitShift, this.skillMult[id] || 1];
1718
+ }
1719
+
1720
+ if (!this.d2.skills[id].EType && this.d2.skills[id].EMax) {
1721
+ args.max = [this.d2.skills[id].EMax, this.d2.skills[id].EMaxLev1, this.d2.skills[id].EMaxLev2, this.d2.skills[id].EMaxLev3, this.d2.skills[id].EMaxLev4, this.d2.skills[id].EMaxLev5, this.d2.skills[id].HitShift, this.skillMult[id] || 1];
1722
+ }
1723
+
1724
+ Object.keys(args).forEach(key => {
1725
+ ret[key] = this.stagedDamage(lvl, ...args[key]) >> 8;
1726
+ });
1727
+
1728
+ return ret;
1729
+ },
1730
+ skillDamage: function (id, lvl, ignoreMastery = false, args = null) {
1731
+ let ret = {};
1732
+
1733
+ if (!args && this.d2.skills[id] && lvl > 0) {
1734
+ args = {};
1735
+
1736
+ if ((this.d2.skills[id].MaxDam || this.d2.skills[id].MinDam) && id !== 249) {
1737
+ args.phy = args.phy || {};
1738
+ args.phy.min = [this.d2.skills[id].MinDam, this.d2.skills[id].MinLevDam1, this.d2.skills[id].MinLevDam2, this.d2.skills[id].MinLevDam3, this.d2.skills[id].MinLevDam4, this.d2.skills[id].MinLevDam5, this.d2.skills[id].HitShift, this.skillMult[id] || 1];
1739
+ }
1740
+
1741
+ if ((this.d2.skills[id].MaxDam || this.d2.skills[id].MinDam) && id !== 249) {
1742
+ args.phy = args.phy || {};
1743
+ args.phy.max = [this.d2.skills[id].MaxDam, this.d2.skills[id].MaxLevDam1, this.d2.skills[id].MaxLevDam2, this.d2.skills[id].MaxLevDam3, this.d2.skills[id].MaxLevDam4, this.d2.skills[id].MaxLevDam5, this.d2.skills[id].HitShift, this.skillMult[id] || 1];
1744
+ }
1745
+
1746
+ if (this.d2.skills[id].EType && this.d2.skills[id].EMin) {
1747
+ args[this.d2.skills[id].EType] = args[this.d2.skills[id].EType] || {};
1748
+ args[this.d2.skills[id].EType].min = [this.d2.skills[id].EMin, this.d2.skills[id].EMinLev1, this.d2.skills[id].EMinLev2, this.d2.skills[id].EMinLev3, this.d2.skills[id].EMinLev4, this.d2.skills[id].EMinLev5, this.d2.skills[id].HitShift, this.skillMult[id] || 1];
1749
+ }
1750
+
1751
+ if (this.d2.skills[id].EType && this.d2.skills[id].EMax) {
1752
+ args[this.d2.skills[id].EType] = args[this.d2.skills[id].EType] || {};
1753
+ args[this.d2.skills[id].EType].max = [this.d2.skills[id].EMax, this.d2.skills[id].EMaxLev1, this.d2.skills[id].EMaxLev2, this.d2.skills[id].EMaxLev3, this.d2.skills[id].EMaxLev4, this.d2.skills[id].EMaxLev5, this.d2.skills[id].HitShift, this.skillMult[id] || 1];
1754
+ }
1755
+ }
1756
+
1757
+ if (args) {
1758
+ let psyn = this.calculateFormulaKey(id, 'DmgSymPerCalc') / 100 + 1, esyn = this.calculateFormulaKey(id, 'EDmgSymPerCalc') / 100 + 1;
1759
+
1760
+ Object.keys(args).forEach(element => {
1761
+ ret[element] = ret[element] || {};
1762
+
1763
+ Object.keys(args[element]).forEach(key => {
1764
+ ret[element][key] = this.stagedDamage(lvl, ...args[element][key]);
1765
+ });
1766
+ });
1767
+
1768
+ switch (id) {
1769
+ case 94:
1770
+ {
1771
+ let hfdmg = this.skillDamage(102, lvl + 7, true);
1772
+
1773
+ if (this.d2.skills[id].EMin) {
1774
+ ret[this.d2.skills[id].EType].min += (hfdmg.fire.min * 256);
1775
+ }
1776
+
1777
+ if (this.d2.skills[id].EMax) {
1778
+ ret[this.d2.skills[id].EType].max += (hfdmg.fire.max * 256);
1779
+ }
1780
+ }
1781
+
1782
+ break;
1783
+ case 102: // holy fire
1784
+ if (this.d2.skills[id].EMin) {
1785
+ ret[this.d2.skills[id].EType].min *= 6; // weapon damage is 6x the aura damage
1786
+ }
1787
+
1788
+ if (this.d2.skills[id].EMax) {
1789
+ ret[this.d2.skills[id].EType].max *= 6;
1790
+ }
1791
+
1792
+ break;
1793
+ case 114: // holy freeze
1794
+ if (this.d2.skills[id].EMin) {
1795
+ ret[this.d2.skills[id].EType].min *= 5; // weapon damage is 5x the aura damage
1796
+ }
1797
+
1798
+ if (this.d2.skills[id].EMax) {
1799
+ ret[this.d2.skills[id].EType].max *= 5;
1800
+ }
1801
+
1802
+ break;
1803
+ case 118: // holy shock
1804
+ if (this.d2.skills[id].EMax) {
1805
+ ret[this.d2.skills[id].EType].max *= 6; // weapon damage is 6x the aura damage
1806
+ }
1807
+
1808
+ break;
1809
+ //case 24: // charged strike
1810
+ // ret[this.d2.skills[id].EType].max *= 3 + ((lvl / 5) | 0);
1811
+ case 227:
1812
+ case 237:
1813
+ case 247:
1814
+ if (this.builds[this.currentBuild][247]) {
1815
+ psyn += 0.15 + 0.10 * this.builds[this.currentBuild][247];
1816
+ }
1817
+
1818
+ break;
1819
+ default:
1820
+ break;
1821
+ }
1822
+
1823
+ Object.keys(ret).forEach(element => {
1824
+ Object.keys(ret[element]).forEach(key => {
1825
+ if (element === 'phy') {
1826
+ ret.phy[key] *= psyn;
1827
+ } else if (key !== 'min' || (this.d2.skills[id].EMinLev1 || this.d2.skills[id].EMinLev2 || this.d2.skills[id].EMinLev3 || this.d2.skills[id].EMinLev4 || this.d2.skills[id].EMinLev5)) {
1828
+ ret[element][key] *= esyn;
1829
+ }
1830
+
1831
+ if (!ignoreMastery) {
1832
+ ret[element][key] *= 1 + this.skillMastery(element) / 100;
1833
+ }
1834
+
1835
+ ret[element][key] >>= 8;
1836
+ });
1837
+ });
1838
+ }
1839
+
1840
+ return ret;
1841
+ },
1842
+ skillDesc: function (id) {
1843
+ let ret = [], lvl = this.builds[this.currentBuild][id];
1844
+
1845
+ let renderStagedDamage = (suffix = '') => {
1846
+ let dmg = this.skillDamage(id, lvl);
1847
+
1848
+ for (let type in dmg) {
1849
+ let obj = { type, desc: (this.typeMap[type] || type) + ' damage: ' };
1850
+
1851
+ if (isFinite(dmg[type].min) && isFinite(dmg[type].max)) {
1852
+ obj.desc += dmg[type].min + '-' + dmg[type].max;
1853
+ } else if (isFinite(dmg[type].min)) {
1854
+ obj.desc += dmg[type].min + ' Min';
1855
+ } else if (isFinite(dmg[type].max)) {
1856
+ obj.desc += dmg[type].max + ' Max';
1857
+ }
1858
+
1859
+ if (type === 'pois') {
1860
+ obj.desc += ' / sec';
1861
+ }
1862
+
1863
+ if (suffix.length) {
1864
+ obj.desc += ' ' + suffix;
1865
+ }
1866
+
1867
+ ret.push(obj);
1868
+ }
1869
+ };
1870
+
1871
+ if (lvl > 0) {
1872
+ switch (id) {
1873
+ // Simple Passive Chances
1874
+ case 9:
1875
+ case 13:
1876
+ case 18:
1877
+ case 29:
1878
+ case 33:
1879
+ ret.push({type: 'phy', desc: this.calculateFormulaKey(id, 'passivecalc1') + '% Chance'});
1880
+ break;
1881
+
1882
+ // Simple Damage Skills
1883
+ case 10:
1884
+ case 22:
1885
+ {
1886
+ let dmg = this.calculateFormulaKey(id, 'calc1');
1887
+
1888
+ if (dmg > 0) {
1889
+ ret.push({type: 'phy', desc: '+' + dmg + '% Damage'});
1890
+ } else if (dmg < 0) {
1891
+ ret.push({type: 'phy', desc: dmg + '% Damage'});
1892
+ }
1893
+ }
1894
+
1895
+ break;
1896
+
1897
+ case 30:
1898
+ {
1899
+ let dmg = this.calculateFormulaKey(id, 'calc2');
1900
+
1901
+ if (dmg > 0) {
1902
+ ret.push({type: 'phy', desc: '+' + dmg + '% Damage'});
1903
+ } else if (dmg < 0) {
1904
+ ret.push({type: 'phy', desc: dmg + '% Damage'});
1905
+ }
1906
+ }
1907
+
1908
+ break;
1909
+
1910
+ // Special Cases
1911
+ case 6: // Magic Arrow
1912
+ {
1913
+ let dmg = this.skillDamage(id, lvl).phy.min;
1914
+ ret.push({type: 'mag', desc: '+' + lvl + '% Physical to Magic'});
1915
+ ret.push({type: 'phy', desc: '+' + dmg + ' Damage'});
1916
+ }
1917
+
1918
+ break;
1919
+ case 7: // Fire Arrow
1920
+ ret.push({type: 'fire', desc: '+' + (1 + lvl * 2) + '% Physical to Fire'});
1921
+ renderStagedDamage();
1922
+
1923
+ break;
1924
+ case 8: // Inner Sight
1925
+ ret.push({type: 'phy', desc: '-' + this.skillEffect(id, lvl).min + ' Enemy Defense'});
1926
+ break;
1927
+ case 11: // Cold Arrow
1928
+ ret.push({type: 'cold', desc: '+' + (1 + lvl * 2) + '% Physical to Cold'});
1929
+ renderStagedDamage();
1930
+ break;
1931
+ case 12: // Multiple Shot
1932
+ ret.push({type: 'phy', desc: '3/4 Weapon Damage'});
1933
+ ret.push({type: 'phy', desc: this.calculateFormulaKey(id, 'calc1') + ' Arrows'});
1934
+ break;
1935
+ case 17: // Slow Missiles
1936
+ ret.push({type: 'phy', desc: 'Slow Missiles by ' + this.calculateFormulaKey(id, 'aurastatcalc1') + '%'});
1937
+ ret.push({type: 'phy', desc: 'Duration: ' + (this.calculateFormulaKey(id, 'auralencalc') / 25) + ' Sec.'});
1938
+ ret.push({type: 'phy', desc: 'Range: ' + (Math.round(this.calculateFormulaKey(id, 'aurarangecalc') * 20 / 3) / 10) + ' Yards'});
1939
+ break;
1940
+ case 19: // Impale
1941
+ {
1942
+ ret.push({type: 'phy', desc: '+' + this.calculateFormulaKey(id, 'calc1') + '% Damage'});
1943
+ ret.push({type: 'phy', desc: this.calculateFormulaKey(id, 'calc2') + '% Durability Loss Chance'});
1944
+ }
1945
+
1946
+ break;
1947
+ case 20: // Lightning Bolt
1948
+ ret.push({type: 'phy', desc: '3/4 Weapon Damage'});
1949
+ ret.push({type: 'ltng', desc: '100% Physical to Lightning'});
1950
+ renderStagedDamage();
1951
+ break;
1952
+ case 21: // Ice Arrow
1953
+ renderStagedDamage();
1954
+
1955
+ {
1956
+ let len = this.stagedDamage(lvl, this.d2.skills[id].ELen, this.d2.skills[id].ELevLen1, this.d2.skills[id].ELevLen2, this.d2.skills[id].ELevLen3, 0, 0, this.d2.skills[id].HitShift, 1);
1957
+ let syn = (1 + this.calculateFormulaKey(id, 'ELenSymPerCalc') / 100);
1958
+ len = Math.round(((len * syn) >> 8) / 2.5) / 10;
1959
+ ret.push({type: 'phy', desc: 'Freeze: ' + len + ' Sec.'});
1960
+ }
1961
+
1962
+ break;
1963
+ case 31: // Freezing Arrow
1964
+ renderStagedDamage();
1965
+ ret.push({type: 'phy', desc: 'Radius: ' + (Math.round(this.calculateFormulaKey(id, 'calc1') * 20 / 3) / 10) + ' Yards'});
1966
+ ret.push({type: 'phy', desc: 'Freeze: ' + (Math.round((this.d2.skills[id].ELen * (1 + this.calculateFormulaKey(id, 'ELenSymPerCalc') / 100)) / 2.5) / 10) + ' Sec.'});
1967
+ break;
1968
+ case 23: // Penetrate
1969
+ ret.push({type: 'phy', desc: '+' + this.calculateFormulaKey(id, 'passivecalc1') + '% Attack Rating'});
1970
+ break;
1971
+ case 24: // Charged Strike
1972
+ renderStagedDamage();
1973
+ ret.push({type: 'phy', desc: (this.calculateFormulaKey(id, 'calc1') | 0) + ' Charged Bolts'});
1974
+ break;
1975
+ case 26: // Strafe
1976
+ ret.push({type: 'phy', desc: '3/4 Weapon Damage'});
1977
+ ret.push({type: 'phy', desc: '+' + this.calculateFormulaKey(id, 'calc2') + '% Damage'});
1978
+ ret.push({type: 'phy', desc: this.calculateFormulaKey(id, 'calc1') + ' Arrows'});
1979
+ break;
1980
+ case 28: // Decoy (Dopplezon)
1981
+ ret.push({type: 'phy', desc: 'HP: ' + Math.round(this.calculateFormulaKey(id, 'calc3') * (1 + this.calculateFormulaKey(id, 'calc1') / 100)) + '% of Caster'});
1982
+ ret.push({type: 'phy', desc: 'Resists: +' + this.calculateFormulaKey(id, 'aurastatcalc1') + '%'});
1983
+ ret.push({type: 'phy', desc: 'Duration: ' + (this.calculateFormulaKey(id, 'calc2') / 25) + ' Sec.'});
1984
+ break;
1985
+ case 32: // Valkyrie
1986
+ ret.push({type: 'phy', desc: 'HP: ' + Math.round(440 * (1 + this.calculateFormulaKey(id, 'calc1') / 100))});
1987
+ ret.push({type: 'phy', desc: 'Defense/Damage: +' + this.calculateFormulaKey(id, 'passivecalc1') + '%/+' + (this.calculateFormulaKey(id, 'aurastatcalc1') - 25) + '%'});
1988
+ ret.push({type: 'phy', desc: 'DEX/Resists: ' + this.calculateFormulaKey(id, 'aurastatcalc2') + '/' + this.calculateFormulaKey(id, 'aurastatcalc3') + '%'});
1989
+ ret.push({type: 'phy', desc: '+' + this.calculateFormulaKey(id, 'ToHitCalc') + ' Attack Rating'});
1990
+ ret.push({type: 'phy', desc: 'iLvl: ' + this.calculateFormulaKey(id, 'calc2')});
1991
+ break;
1992
+ case 34: // Lightning Strike
1993
+ renderStagedDamage();
1994
+ ret.push({type: 'phy', desc: (this.calculateFormulaKey(id, 'calc2') | 0) + ' Hits'});
1995
+ break;
1996
+ case 35: // Lightning Fury
1997
+ renderStagedDamage();
1998
+ ret.push({type: 'phy', desc: (this.calculateFormulaKey(id, 'calc1') | 0) + ' Bolts'});
1999
+ break;
2000
+ case 58: // Energy Shield
2001
+ ret.push({type: 'phy', desc: Math.min(95, this.skillEffect(id, lvl).min) + '% Damage Absorbed'});
2002
+ break;
2003
+ case 61: // Fire mastery
2004
+ ret.push({type: 'fire', desc: '+' + this.calculateFormulaKey(id, 'passivecalc1') + '% Fire Damage'});
2005
+ break;
2006
+ case 63: // Lightning mastery
2007
+ ret.push({type: 'ltng', desc: '+' + this.calculateFormulaKey(id, 'passivecalc1') + '% Lightning Damage'});
2008
+ break;
2009
+ case 65: // Cold Mastery
2010
+ ret.push({type: 'cold', desc: '-' + this.calculateFormulaKey(id, 'passivecalc1') + '% Enemy Cold Resist'});
2011
+ break;
2012
+ case 126: // Bash
2013
+ ret.push({type: 'phy', desc: '+' + this.calculateFormulaKey(id, 'calc1') + '% Damage'});
2014
+ ret.push({type: 'phy', desc: '+' + this.calculateFormulaKey(id, 'calc2') + ' Damage'});
2015
+ break;
2016
+ case 254: // Tiger Strike
2017
+ ret.push({ type: 'phy', desc: [
2018
+ 'Charge 1: +' + this.calculateFormula(id, 'ln12') + '% Damage',
2019
+ 'Charge 2: +' + this.calculateFormula(id, 'ln12 * 2') + '% Damage',
2020
+ 'Charge 3: +' + this.calculateFormula(id, 'ln12 * 3') + '% Damage',
2021
+ ].join('\n') });
2022
+ break;
2023
+ case 259: // Fire Claws
2024
+ {
2025
+ let dmg = this.skillDamage(id, lvl).fire, edmg = this.skillDamage(id, lvl, false, {
2026
+ fire: {
2027
+ min: [9, 8, 15.5, 25, 34.5, 46.85, 8, 1],
2028
+ max: [15, 8, 15.5, 26.5, 37.5, 50, 8, 1],
2029
+ },
2030
+ }).fire;
2031
+
2032
+ ret.push({ type: 'fire', desc: [
2033
+ 'Charge 1: ' + dmg.min + '-' + dmg.max + ' Fire Damage',
2034
+ 'Charge 2: 2.6 Yard Explosion',
2035
+ 'Charge 3: ' + edmg.min + '-' + edmg.max + ' Fire Explosion Damage',
2036
+ ].join('\n') });
2037
+ }
2038
+
2039
+ break;
2040
+ case 265: // Cobra Strike
2041
+
2042
+ ret.push({type: 'phy', desc: [
2043
+ 'Charge 1: +' + this.calculateFormula(id, 'ln12') + '% Life Leech',
2044
+ 'Charge 2: +' + this.calculateFormula(id, 'ln12') + '% Life/Mana Leech',
2045
+ 'Charge 3: +' + this.calculateFormula(id, 'ln12 * 2') + '% Life/Mana Leech',
2046
+ ].join('\n')});
2047
+ break;
2048
+ case 269: // Claws of Thunder
2049
+ {
2050
+ let dmg = this.skillDamage(id, lvl).ltng, ndmg = this.skillDamage(id, lvl, false, {
2051
+ ltng: {
2052
+ max: [30, 15, 25, 35, 45, 65, 8, 1],
2053
+ },
2054
+ }).ltng, bdmg = this.skillDamage(id, lvl, false, {
2055
+ ltng: {
2056
+ max: [40, 20, 40, 60, 80, 100, 8, 1],
2057
+ },
2058
+ }).ltng;
2059
+
2060
+ ret.push({ type: 'ltng', desc: [
2061
+ 'Charge 1: ' + dmg.min + '-' + dmg.max + ' Lightning Damage',
2062
+ 'Charge 2: 1-' + ndmg.max + ' Nova Damage',
2063
+ 'Charge 3: 1-' + bdmg.max + ' Charged Bolt Damage',
2064
+ ].join('\n') });
2065
+ }
2066
+
2067
+ break;
2068
+ case 274: // Blades of Ice
2069
+ {
2070
+ let dmg = this.skillDamage(id, lvl).cold;
2071
+
2072
+ ret.push({ type: 'cold', desc: [
2073
+ 'Charge 1: ' + dmg.min + '-' + dmg.max + ' Cold Damage',
2074
+ 'Charge 2: 4 Yard Explosion',
2075
+ 'Charge 3: ' + (Math.round(40 + 4 * (lvl - 1)) / 10) + ' Second Freeze',
2076
+ ].join('\n') });
2077
+ }
2078
+
2079
+ break;
2080
+ case 280: // Phoenix Strike (Royal Strike)
2081
+ {
2082
+ let dmg = this.skillDamage(id, lvl, false, {
2083
+ fire: {
2084
+ min: [20, 10, 19, 29, 38, 46, 8, 1],
2085
+ max: [40, 10, 21, 33, 42, 50, 8, 1],
2086
+ },
2087
+ ltng: {
2088
+ max: [40, 20, 40, 60, 80, 100, 8, 1],
2089
+ },
2090
+ cold: {
2091
+ min: [16, 4, 8, 12, 20, 28, 8, 1],
2092
+ max: [32, 4, 8, 13, 21, 29, 8, 1],
2093
+ }
2094
+ });
2095
+
2096
+ ret.push({ type: 'fire', desc: 'Charge 1: ' + dmg.fire.min + '-' + dmg.fire.max + ' Meteor' });
2097
+ ret.push({ type: 'ltng', desc: 'Charge 2: 1-' + dmg.ltng.max + ' Chain Lightning' });
2098
+ ret.push({ type: 'cold', desc: 'Charge 2: ' + dmg.cold.min + '-' + dmg.cold.max + ' Chaos Bolt' });
2099
+ }
2100
+
2101
+ break;
2102
+ default:
2103
+ renderStagedDamage();
2104
+
2105
+ {
2106
+ let effect = this.skillEffect(id, lvl);
2107
+
2108
+ if (Object.keys(effect).length) {
2109
+ ret.push({ type: 'phy', desc: 'Effect: ' + Object.values(effect).join('-') });
2110
+ }
2111
+ }
2112
+
2113
+ break;
2114
+ }
2115
+
2116
+ if (!(id === 32)) {
2117
+ if (this.d2.skills[id].ToHitCalc) {
2118
+ ret.push({ type: 'phy', desc: '+' + this.calculateFormulaKey(id, 'ToHitCalc') + '% Attack Rating' });
2119
+ } else if (isFinite(this.d2.skills[id].ToHit)) {
2120
+ ret.push({ type: 'phy', desc: '+' + this.calculateFormula(id, 'toht') + '% Attack Rating' });
2121
+ }
2122
+ }
2123
+
2124
+ if (isFinite(this.d2.skills[id].mana)) {
2125
+ let mana;
2126
+
2127
+ switch (id) {
2128
+ case 133:
2129
+ mana = (this.calculateFormula(id, 'mana') * 2) | 0;
2130
+ break;
2131
+ case 140:
2132
+ mana = 2;
2133
+ break;
2134
+ case 147:
2135
+ mana = 3;
2136
+ break;
2137
+ case 151:
2138
+ mana = (this.calculateFormula(id, 'mana') + 12.5) | 0;
2139
+ break;
2140
+ default:
2141
+ mana = this.calculateFormula(id, 'mana');
2142
+ break;
2143
+ }
2144
+
2145
+ mana = ((mana * 10) | 0) / 10;
2146
+
2147
+ ret.push({ type: 'phy', desc: 'Mana Cost: ' + mana });
2148
+ }
2149
+
2150
+ if (isFinite(this.d2.skills[id].delay)) {
2151
+ ret.push({ type: 'phy', desc: 'Delay: ' + (this.d2.skills[id].delay / 25) + ' Sec.' });
2152
+ }
2153
+ }
2154
+
2155
+ return ret;
2156
+ }
2157
+ },
2158
+ created: async function () {
2159
+ decode(window.location.hash.slice(1)).forEach(build => {
2160
+ this.addBuild(build);
2161
+ });
2162
+
2163
+ if (!this.builds.length) {
2164
+ this.addBuild();
2165
+ }
2166
+
2167
+ Object.keys(this.skills).forEach(id => {
2168
+ this.skillsLookup[this.d2.skills[id].skill] = id;
2169
+ this.skills[id].req = [];
2170
+ this.skills[id].dep = [];
2171
+ });
2172
+
2173
+ Object.keys(this.skills).forEach(id => {
2174
+ [this.d2.skills[id].reqskill1, this.d2.skills[id].reqskill2].forEach(skillName => {
2175
+ if (skillName) {
2176
+ this.skills[id].req.push(this.skillsLookup[skillName]);
2177
+ }
2178
+ });
2179
+
2180
+ this.skills[id].req.forEach(reqid => {
2181
+ this.skills[reqid].dep.push(id | 0);
2182
+ });
2183
+ });
2184
+
2185
+ // Skill data patches - These aren't correct somehow.
2186
+ this.d2.skills[51].EDmgSymPerCalc = this.d2.skills[51].EDmgSymPerCalc.slice(1);
2187
+ this.d2.skills[26].calc1 = 'min(par3 + lvl, par4)';
2188
+
2189
+ this.currentBuild = 0;
2190
+ },
2191
+ });
2192
+ })();