@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
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "leveling",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "scripts": {
6
+ "dev": "vite",
7
+ "build": "vite build",
8
+ "preview": "vite preview"
9
+ },
10
+ "dependencies": {
11
+ "vue": "^3.2.25"
12
+ },
13
+ "devDependencies": {
14
+ "@vitejs/plugin-vue": "^2.3.1",
15
+ "vite": "^2.9.5"
16
+ }
17
+ }
@@ -0,0 +1,526 @@
1
+ <script setup>
2
+ import { reactive, computed } from "vue";
3
+
4
+ import "../../../objext.js";
5
+ import monlvl from "../../../json/monlvl.json";
6
+ import levels from "../../../json/levels.json";
7
+ import monstats from "../../../json/monstats.json";
8
+ import monpopulationest from "../../../json/monpopulationest.json";
9
+ import moncountest from "../../../json/moncountest.json";
10
+ import superuniques from "../../../json/superuniques.json";
11
+
12
+ levels[47]['*StringName'] = 'Act 2 ' + levels[47]['*StringName'];
13
+ levels[48]['*StringName'] = 'Act 2 ' + levels[48]['*StringName'];
14
+ levels[49]['*StringName'] = 'Act 2 ' + levels[49]['*StringName'];
15
+ levels[92]['*StringName'] = 'Act 3 ' + levels[92]['*StringName'];
16
+ levels[93]['*StringName'] = 'Act 3 ' + levels[93]['*StringName'];
17
+
18
+ // 57e2f6
19
+ const expCurve = [13, 16, 110, 159, 207, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 225, 174, 92, 38, 5];
20
+ const expPenalty = [1024, 976, 928, 880, 832, 784, 736, 688, 640, 592, 544, 496, 448, 400, 352, 304, 256, 192, 144, 108, 81, 61, 46, 35, 26, 20, 15, 11, 8, 6, 5];
21
+
22
+ const data = reactive({
23
+ level: 1,
24
+ mindmg: 1,
25
+ maxdmg: 1,
26
+ damageType: '',
27
+ areaRestrict: 'combat',
28
+ areaSizeNormalize: 1,
29
+ minGrade: 60,
30
+ clearMode: 'all',
31
+ });
32
+
33
+ function clamp (min, value, max) {
34
+ if (value < min) {
35
+ return min;
36
+ }
37
+
38
+ if (value > max) {
39
+ return max;
40
+ }
41
+
42
+ return value;
43
+ }
44
+
45
+ function expModifier (mlvl) {
46
+ let diff = data.level < 25 ? clamp(-10, mlvl - data.level, 10) : clamp(-10, mlvl - data.level, 0);
47
+ let diffmod = expCurve[diff + 10];
48
+ let lvlmod = expPenalty[clamp(69, data.level, 99) - 69];
49
+
50
+ return lvlmod * diffmod / 1024 / 255;
51
+ }
52
+
53
+ function monEffort (monId, mlvl, diff, type, superId) {
54
+ let exp = expModifier(mlvl) * (monlvl[mlvl][s('L-XP', diff)] || 0),
55
+ hp = (monlvl[mlvl][s('L-HP', diff)] || 0) * (
56
+ (monstats[monId][['minHP', 'MinHP(N)', 'MinHP(H)'][diff]] || 0) +
57
+ (monstats[monId][['maxHP', 'MaxHP(N)', 'MaxHP(H)'][diff]] || 0)
58
+ ) / 200,
59
+ dmg = 1;
60
+
61
+ let minion = type === -1;
62
+
63
+ if (minion) {
64
+ type = 0;
65
+ exp *= 5;
66
+ }
67
+ else {
68
+ exp *= [1, 3, 5, 5, 5][type];
69
+ }
70
+
71
+ hp *= minion ? [2, 1.75, 1.5][diff] : [
72
+ 1,
73
+ [3, 2.5, 2][diff],
74
+ [4, 3, 2][diff],
75
+ [4, 3, 2][diff],
76
+ 1,
77
+ ][type];
78
+
79
+ if (data.damageType) {
80
+ let res = monstats[monId][s('Res' + data.damageType, diff)] || 0;
81
+
82
+ dmg = (data.mindmg + data.maxdmg) / 2;
83
+
84
+ if (superId) {
85
+ let mods = {};
86
+
87
+ for (let c = 1; c < 5; c++) {
88
+ if (superuniques[superId]['Mod' + c]) {
89
+ mods[superuniques[superId]['Mod' + c]] = superuniques[superId]['Mod' + c];
90
+ }
91
+ }
92
+
93
+ switch (data.damageType) {
94
+ case 'Dm':
95
+ if (mods[28]) {
96
+ res += 50;
97
+ }
98
+
99
+ break;
100
+ case 'Fi':
101
+ if (mods[9]) {
102
+ res += diff === 2 ? 100 : 75;
103
+ }
104
+
105
+ if (mods[8]) {
106
+ res += 40;
107
+ }
108
+
109
+ break;
110
+ case 'Li':
111
+ if (mods[17]) {
112
+ res += diff === 2 ? 100 : 75;
113
+ }
114
+
115
+ if (mods[8]) {
116
+ res += 40;
117
+ }
118
+
119
+ break;
120
+ case 'Co':
121
+ if (mods[18]) {
122
+ res += diff === 2 ? 100 : 75;
123
+ }
124
+
125
+ if (mods[8]) {
126
+ res += 40;
127
+ }
128
+
129
+ break;
130
+ case 'Po':
131
+ if (mods[9]) {
132
+ res += diff === 2 ? 100 : 75;
133
+ }
134
+
135
+ if (mods[8]) {
136
+ res += 40;
137
+ }
138
+
139
+ break;
140
+ }
141
+ }
142
+
143
+ hp /= clamp(0, 1 - res / 100, 2);
144
+ }
145
+
146
+ exp *= (monstats[monId][s('Exp')] || 0) / 100;
147
+
148
+ let hitstokill = isFinite(hp) ? Math.max(1, Math.ceil(hp / dmg)) : Infinity;
149
+
150
+ return exp / hitstokill;
151
+ }
152
+
153
+ function s(key, diff) {
154
+ return '' + key + ['', '(N)', '(H)'][diff || 0];
155
+ }
156
+
157
+ function t(key, diff) {
158
+ return '' + key + [' (norm)', ' (nm)', ' (hell)'][diff || 0];
159
+ }
160
+
161
+ const grades = [
162
+ [97, 'A+'],
163
+ [93, 'A'],
164
+ [90, 'A-'],
165
+ [87, 'B+'],
166
+ [83, 'B'],
167
+ [80, 'B-'],
168
+ [77, 'C+'],
169
+ [73, 'C'],
170
+ [70, 'C-'],
171
+ [67, 'D+'],
172
+ [63, 'D'],
173
+ [60, 'D-'],
174
+ [0, 'F'],
175
+ ];
176
+
177
+ function grade (score) {
178
+ for (let i = 0; i < grades.length; i++) {
179
+ if (score >= grades[i][0]) {
180
+ return grades[i][1];
181
+ }
182
+ }
183
+
184
+ return 'F';
185
+ }
186
+
187
+ const results = computed(() => {
188
+ let ret = {};
189
+
190
+ [0, 1, 2].forEach(diff => {
191
+ let makelvlkey = lvlId => t(levels[lvlId]['*StringName'] + ' [ID ' + lvlId + ']', diff);
192
+
193
+ monpopulationest.forEach((leveldata, lvlId) => {
194
+ if (data.level < 20 && (data.areaRestrict !== 'any' && diff > 0 || diff >= 0 && lvlId >= 128)) {
195
+ return;
196
+ }
197
+
198
+ if (data.level < 40 && (data.areaRestrict !== 'any' && diff > 1 || diff >= 1 && lvlId >= 128)) {
199
+ return;
200
+ }
201
+
202
+ if (data.level < 60 && (data.areaRestrict !== 'any' && diff > 2 || diff >= 2 && lvlId >= 128)) {
203
+ return;
204
+ }
205
+
206
+ if ([32, 133, 134, 135, 136].includes(lvlId | 0)) {
207
+ return;
208
+ }
209
+
210
+ if (!moncountest[lvlId]) {
211
+ return;
212
+ }
213
+
214
+ let totalest = (moncountest[lvlId][diff] || 0)**data.areaSizeNormalize;
215
+
216
+ if (totalest <= 0) {
217
+ return;
218
+ }
219
+
220
+ if (['all', 'norm'].includes(data.clearMode)) {
221
+ leveldata.normal.forEach((monData, monId) => {
222
+ let mlvl = monData[s('mlvl', diff)] || 0,
223
+ packCount = monData[s('packCount', diff)] || 0,
224
+ lvlkey = makelvlkey(lvlId),
225
+ group = ((monstats[monId]['MinGrp'] || 0) + (monstats[monId]['MaxGrp'] || 0)) / 2,
226
+ party = ((monstats[monId]['PartyMin'] || 0) + (monstats[monId]['PartyMax'] || 0)) / 2,
227
+ minions = [
228
+ monstats[monId]['minion1'] || null,
229
+ monstats[monId]['minion2'] || null,
230
+ ].filter(Boolean);
231
+
232
+ if (data.areaRestrict === 'combat' && mlvl > data.level + 5) {
233
+ return;
234
+ }
235
+
236
+ if (mlvl > 0 && packCount > 0) {
237
+ ret[lvlkey] = ret[lvlkey] || 0;
238
+ ret[lvlkey] += monEffort(monId, mlvl, diff) * packCount * group / totalest;
239
+
240
+ if (minions.length && party > 0) {
241
+ minions.forEach(minionId => {
242
+ ret[lvlkey] += monEffort(minionId, mlvl, diff) * packCount * party / minions.length / totalest;
243
+ });
244
+ }
245
+ }
246
+ });
247
+ }
248
+
249
+ leveldata.champion.forEach((monData, monId) => {
250
+ let mlvl = (monData[s('mlvl', diff)] || 0) + 2,
251
+ packCount = monData[s('packCount', diff)] || 0,
252
+ lvlkey = makelvlkey(lvlId),
253
+ group = 3,
254
+ party = ((monstats[monId]['PartyMin'] || 0) + (monstats[monId]['PartyMax'] || 0)) / 2,
255
+ minions = [
256
+ monstats[monId]['minion1'] || null,
257
+ monstats[monId]['minion2'] || null,
258
+ ].filter(Boolean);
259
+
260
+ if (data.areaRestrict === 'combat' && mlvl > data.level + 5) {
261
+ return;
262
+ }
263
+
264
+ if (mlvl > 0 && packCount > 0) {
265
+ ret[lvlkey] = ret[lvlkey] || 0;
266
+
267
+ if (['all', 'champs'].includes(data.clearMode)) {
268
+ ret[lvlkey] += monEffort(monId, mlvl, diff, 1) * packCount * group / totalest;
269
+ }
270
+
271
+ if (minions.length && party > 0) {
272
+ minions.forEach(minionId => {
273
+ ret[lvlkey] += monEffort(minionId, mlvl, diff, -1) * packCount * party / minions.length / totalest;
274
+ });
275
+ }
276
+ }
277
+ });
278
+
279
+ leveldata.unique.forEach((monData, monId) => {
280
+ let mlvl = (monData[s('mlvl', diff)] || 0) + 3,
281
+ packCount = monData[s('packCount', diff)] || 0,
282
+ lvlkey = makelvlkey(lvlId),
283
+ group = 1,
284
+ party = ((monstats[monId]['PartyMin'] || 0) + (monstats[monId]['PartyMax'] || 0)) / 2,
285
+ minions = [
286
+ monstats[monId]['minion1'] || null,
287
+ monstats[monId]['minion2'] || null,
288
+ ].filter(Boolean);
289
+
290
+ if (data.areaRestrict === 'combat' && mlvl > data.level + 5) {
291
+ return;
292
+ }
293
+
294
+ if (party) {
295
+ party += diff;
296
+ }
297
+
298
+ if (mlvl > 0 && packCount > 0) {
299
+ ret[lvlkey] = ret[lvlkey] || 0;
300
+
301
+ if (['all', 'champs'].includes(data.clearMode)) {
302
+ ret[lvlkey] += monEffort(monId, mlvl, diff, 2) * packCount * group / totalest;
303
+ }
304
+
305
+ if (minions.length && party > 0) {
306
+ minions.forEach(minionId => {
307
+ ret[lvlkey] += monEffort(minionId, mlvl, diff, -1) * packCount * party / minions.length / totalest;
308
+ });
309
+ }
310
+ }
311
+ });
312
+
313
+ leveldata.superunique.forEach((monData, superId) => {
314
+ let mlvl = (monData[s('mlvl', diff)] || 0) + 3,
315
+ monId = superuniques[superId].Class,
316
+ packCount = monData[s('packCount', diff)] || 0,
317
+ lvlkey = makelvlkey(lvlId),
318
+ lvlkeybaal = makelvlkey(132),
319
+ group = 1,
320
+ party = ((superuniques[superId]['MinGrp'] || 0) + (superuniques[superId]['MaxGrp'] || 0)) / 2,
321
+ minions = [
322
+ monstats[monId]['minion1'] || null,
323
+ monstats[monId]['minion2'] || null,
324
+ ].filter(Boolean);
325
+
326
+ if (data.areaRestrict === 'combat' && mlvl > data.level + 5) {
327
+ return;
328
+ }
329
+
330
+ if (party) {
331
+ party += diff;
332
+ }
333
+
334
+ if (mlvl > 0 && packCount > 0) {
335
+ ret[lvlkey] = ret[lvlkey] || 0;
336
+
337
+ if (['all', 'champs'].includes(data.clearMode)) {
338
+ let effort = monEffort(monId, mlvl, diff, 3, superId) * packCount * group / totalest;
339
+ ret[lvlkey] += effort;
340
+
341
+ if (lvlId == 131) {
342
+ ret[lvlkeybaal] += effort;
343
+ }
344
+ }
345
+
346
+ if (minions.length && party > 0) {
347
+ minions.forEach(minionId => {
348
+ let meffort = monEffort(minionId, mlvl, diff, -1) * packCount * party / minions.length / totalest;
349
+ ret[lvlkey] += meffort;
350
+
351
+ if (lvlId == 131) {
352
+ ret[lvlkeybaal] += meffort;
353
+ }
354
+ });
355
+ }
356
+ }
357
+ });
358
+
359
+ leveldata.boss.forEach((monData, monId) => {
360
+ let mlvl = monData[s('mlvl', diff)] || 0,
361
+ packCount = monData[s('packCount', diff)] || 0,
362
+ lvlkey = t(levels[lvlId]['*StringName'] + ' [ID ' + lvlId + ']', diff);
363
+
364
+ if (data.areaRestrict === 'combat' && mlvl > data.level + 5) {
365
+ return;
366
+ }
367
+
368
+ if (mlvl > 0 && packCount > 0) {
369
+ ret[lvlkey] = ret[lvlkey] || 0;
370
+
371
+ if (['all'].includes(data.clearMode)) {
372
+ ret[lvlkey] += monEffort(monId, mlvl, diff, 4) * packCount / totalest;
373
+ }
374
+ }
375
+ });
376
+ });
377
+
378
+ let newret = ret;
379
+
380
+ ({
381
+ 22: [21],
382
+ 23: [21, 22],
383
+ 24: [21, 22, 23],
384
+ 25: [21, 22, 23, 24],
385
+ 36: [35],
386
+ 37: [35, 36],
387
+ 73: [72],
388
+ 89: [88],
389
+ 91: [88, 89],
390
+ 93: [92],
391
+ 94: [80],
392
+ 95: [80],
393
+ 96: [81],
394
+ 97: [81],
395
+ 98: [82],
396
+ 99: [82],
397
+ 102: [101],
398
+ 132: [131],
399
+ }).forEach((sourcelvlIds, lvlId) => {
400
+ let n = ret[makelvlkey(lvlId)] * moncountest[lvlId][diff], d = moncountest[lvlId][diff];
401
+
402
+ sourcelvlIds.forEach(sourcelvlId => {
403
+ n += ret[makelvlkey(sourcelvlId)] * moncountest[sourcelvlId][diff] / 2;
404
+ d += moncountest[sourcelvlId][diff] / 2;
405
+ });
406
+
407
+ newret[makelvlkey(lvlId)] = n / d;
408
+ });
409
+
410
+ ret = newret;
411
+ });
412
+
413
+ let max = 0;
414
+
415
+ ret = ret.map(v => {
416
+ v = v || 0;
417
+ max = Math.max(v, max);
418
+ return v;
419
+ });
420
+
421
+ ret = ret.map(v => v * 100 / max).filter(v => v >= data.minGrade).toArray().sort((a, b) => b[1] - a[1]);
422
+ ret[0][1] = 100;
423
+
424
+ return ret.filter(Boolean);
425
+ });
426
+
427
+ </script>
428
+
429
+ <template>
430
+ <div>
431
+ <div class="row">
432
+ <div class="col-auto" style="width:5.5rem">
433
+ <label class="form-label">Level</label>
434
+ <input
435
+ class="form-control"
436
+ type="number"
437
+ min="1"
438
+ max="98"
439
+ step="1"
440
+ v-model.number="data.level"
441
+ />
442
+ </div>
443
+ <div class="col-auto">
444
+ <label class="form-label">Element</label>
445
+ <select class="form-select" v-model="data.damageType">
446
+ <option value="">Unknown</option>
447
+ <option value="Dm">Physical</option>
448
+ <option value="Ma">Magic</option>
449
+ <option value="Fi">Fire</option>
450
+ <option value="Li">Lightning</option>
451
+ <option value="Co">Cold</option>
452
+ <option value="Po">Poison</option>
453
+ </select>
454
+ </div>
455
+ <div class="col-auto">
456
+ <label class="form-label">Area Restrictions</label>
457
+ <select class="form-select" v-model="data.areaRestrict">
458
+ <option value="any">Any Area</option>
459
+ <option value="no grush">Quest Gated (No Glitch Rush)</option>
460
+ <option value="combat">Reasonable Combat (+5 over level)</option>
461
+ </select>
462
+ </div>
463
+ <div class="col-auto">
464
+ <label class="form-label">Clear Mode</label>
465
+ <select class="form-select" v-model="data.clearMode">
466
+ <option value="all">All</option>
467
+ <option value="champs">Champions / Uniques / Minions</option>
468
+ <option value="norm">Normal Mobs Only</option>
469
+ </select>
470
+ </div>
471
+ <div class="col-auto">
472
+ <label class="form-label">Minimum Grade</label>
473
+ <select class="form-select" v-model="data.minGrade">
474
+ <option v-for="grade in grades" :key="grade[0]" :value="grade[0]">{{ grade[1] }}</option>
475
+ </select>
476
+ </div>
477
+ <div class="col-auto" style="width:15rem">
478
+ <label class="form-label">Area Size Normalization: {{ data.areaSizeNormalize.toFixed(2) }}</label>
479
+ <input
480
+ class="form-range"
481
+ type="range"
482
+ min="0"
483
+ max="2"
484
+ :step="1/6"
485
+ v-model.number="data.areaSizeNormalize"
486
+ />
487
+ </div>
488
+ <div v-if="data.damageType" class="col-auto" style="width:8rem">
489
+ <label class="form-label">Min Damage</label>
490
+ <input
491
+ class="form-control"
492
+ type="number"
493
+ min="1"
494
+ step="1"
495
+ v-model.number="data.mindmg"
496
+ />
497
+ </div>
498
+ <div v-if="data.damageType" class="col-auto" style="width:8rem">
499
+ <label class="form-label">Max Damage</label>
500
+ <input
501
+ class="form-control"
502
+ type="number"
503
+ min="1"
504
+ step="1"
505
+ v-model.number="data.maxdmg"
506
+ />
507
+ </div>
508
+ </div>
509
+ <table class="table">
510
+ <thead>
511
+ <tr><th>Area</th><th>Rating</th><th>Grade</th></tr>
512
+ </thead>
513
+ <tbody>
514
+ <tr v-for="(level, index) in results" :key="index">
515
+ <td>{{ level[0] }}</td>
516
+ <td>{{ Math.floor(level[1]) }}%</td>
517
+ <td>{{ grade(level[1]) }}</td>
518
+ </tr>
519
+ </tbody>
520
+ </table>
521
+ </div>
522
+ </template>
523
+
524
+ <style>
525
+
526
+ </style>
@@ -0,0 +1,4 @@
1
+ import { createApp } from 'vue';
2
+ import App from './App.vue';
3
+
4
+ createApp(App).mount('#app');
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ // https://vitejs.dev/config/
5
+ export default defineConfig({
6
+ base: '',
7
+ plugins: [vue()]
8
+ })
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["johnsoncodehk.volar"]
3
+ }
@@ -0,0 +1,7 @@
1
+ # Vue 3 + Vite
2
+
3
+ This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
4
+
5
+ ## Recommended IDE Setup
6
+
7
+ - [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)