@d2runewizard/d2s 2.0.125 → 2.0.126

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 (40) hide show
  1. package/lib/binary/bitreader.d.ts +23 -23
  2. package/lib/binary/bitreader.js +107 -107
  3. package/lib/binary/bitwriter.d.ts +21 -21
  4. package/lib/binary/bitwriter.js +117 -117
  5. package/lib/binary/constants.d.ts +4 -4
  6. package/lib/binary/constants.js +8 -8
  7. package/lib/binary/seekToSequence.d.ts +2 -2
  8. package/lib/binary/seekToSequence.js +12 -12
  9. package/lib/d2/attribute_enhancer.d.ts +5 -5
  10. package/lib/d2/attribute_enhancer.js +595 -595
  11. package/lib/d2/attributes.d.ts +4 -4
  12. package/lib/d2/attributes.js +98 -98
  13. package/lib/d2/constants.d.ts +4 -4
  14. package/lib/d2/constants.js +15 -15
  15. package/lib/d2/d2s.d.ts +10 -10
  16. package/lib/d2/d2s.js +115 -115
  17. package/lib/d2/header.d.ts +8 -8
  18. package/lib/d2/header.js +94 -94
  19. package/lib/d2/items.d.ts +19 -19
  20. package/lib/d2/items.js +869 -831
  21. package/lib/d2/items.js.map +1 -1
  22. package/lib/d2/skills.d.ts +4 -4
  23. package/lib/d2/skills.js +45 -45
  24. package/lib/d2/stash.d.ts +3 -3
  25. package/lib/d2/stash.js +243 -243
  26. package/lib/d2/types.d.ts +438 -420
  27. package/lib/d2/types.js +14 -14
  28. package/lib/d2/versions/default_header.d.ts +5 -5
  29. package/lib/d2/versions/default_header.js +750 -750
  30. package/lib/data/parser.d.ts +3 -3
  31. package/lib/data/parser.js +626 -626
  32. package/lib/data/versions/105_constant_data.d.ts +16150 -16150
  33. package/lib/data/versions/105_constant_data.js +24316 -24316
  34. package/lib/data/versions/96_constant_data.d.ts +14427 -14427
  35. package/lib/data/versions/96_constant_data.js +4 -4
  36. package/lib/data/versions/99_constant_data.d.ts +15572 -15572
  37. package/lib/data/versions/99_constant_data.js +4 -4
  38. package/lib/index.d.ts +8 -8
  39. package/lib/index.js +46 -46
  40. package/package.json +46 -46
@@ -1,596 +1,596 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enhanceItem = exports.enhanceItems = exports.enhancePlayerAttributes = exports.enhanceAttributes = void 0;
4
- var ItemType;
5
- (function (ItemType) {
6
- ItemType[ItemType["Armor"] = 1] = "Armor";
7
- ItemType[ItemType["Shield"] = 2] = "Shield";
8
- ItemType[ItemType["Weapon"] = 3] = "Weapon";
9
- ItemType[ItemType["Other"] = 4] = "Other";
10
- })(ItemType || (ItemType = {}));
11
- //do nice stuff
12
- //combine group properties (all resists/all stats) and build friendly strings for a ui
13
- //enhanced def/durability/weapon damage.
14
- //lookup socketed compact items (runes/gems) properties for the slot they are in
15
- //compute attributes like str/resists/etc..
16
- async function enhanceAttributes(char, constants, config) {
17
- enhanceItems(char.items, constants, char.attributes.level, config);
18
- enhanceItems([char.golem_item], constants, char.attributes.level, config);
19
- enhanceItems(char.merc_items, constants, char.attributes.level, config);
20
- enhanceItems(char.corpse_items, constants, char.attributes.level, config);
21
- enhancePlayerAttributes(char, constants, config);
22
- }
23
- exports.enhanceAttributes = enhanceAttributes;
24
- async function enhancePlayerAttributes(char, constants, config) {
25
- const items = char.items.filter((item) => {
26
- return item.location_id === 1 && item.equipped_id !== 13 && item.equipped_id !== 14;
27
- });
28
- char.item_bonuses = [].concat
29
- .apply([], items.map((item) => _allAttributes(item, constants)))
30
- .filter((attribute) => attribute != null);
31
- char.item_bonuses = _groupAttributes(char.item_bonuses, constants);
32
- _enhanceAttributeDescription(char.item_bonuses, constants, char.attributes.level, config);
33
- }
34
- exports.enhancePlayerAttributes = enhancePlayerAttributes;
35
- async function enhanceItems(items, constants, level = 1, config, parent) {
36
- if (!items) {
37
- return;
38
- }
39
- for (const item of items) {
40
- if (!item) {
41
- continue;
42
- }
43
- if (item.socketed_items && item.socketed_items.length) {
44
- enhanceItems(item.socketed_items, constants, level, config, item);
45
- }
46
- enhanceItem(item, constants, level, config, parent);
47
- }
48
- }
49
- exports.enhanceItems = enhanceItems;
50
- function enhanceItem(item, constants, level = 1, config, parent) {
51
- var _a, _b, _c, _d;
52
- if (config === null || config === void 0 ? void 0 : config.disableItemEnhancements) {
53
- return;
54
- }
55
- if (parent) {
56
- //socket item.
57
- const pt = constants.armor_items[parent.type] || constants.weapon_items[parent.type] || constants.other_items[item.type];
58
- const t = constants.other_items[item.type];
59
- if (t.m) {
60
- item.magic_attributes = _compactAttributes(t.m[pt.gt], constants);
61
- }
62
- }
63
- let details = null;
64
- if (constants.armor_items[item.type]) {
65
- details = constants.armor_items[item.type];
66
- item.type_id = ItemType.Armor;
67
- if (details.maxac) {
68
- if (item.ethereal == 0) {
69
- item.defense_rating = details.maxac;
70
- }
71
- else if (item.ethereal == 1) {
72
- item.defense_rating = Math.floor(details.maxac * 1.5);
73
- }
74
- }
75
- }
76
- else if (constants.weapon_items[item.type]) {
77
- details = constants.weapon_items[item.type];
78
- item.type_id = ItemType.Weapon;
79
- const base_damage = {};
80
- if (item.ethereal == 0) {
81
- if (details.mind)
82
- base_damage.mindam = details.mind;
83
- if (details.maxd)
84
- base_damage.maxdam = details.maxd;
85
- if (details.min2d)
86
- base_damage.twohandmindam = details.min2d;
87
- if (details.max2d)
88
- base_damage.twohandmaxdam = details.max2d;
89
- }
90
- else if (item.ethereal == 1) {
91
- if (details.mind)
92
- base_damage.mindam = Math.floor(details.mind * 1.5);
93
- if (details.maxd)
94
- base_damage.maxdam = Math.floor(details.maxd * 1.5);
95
- if (details.min2d)
96
- base_damage.twohandmindam = Math.floor(details.min2d * 1.5);
97
- if (details.max2d)
98
- base_damage.twohandmaxdam = Math.floor(details.max2d * 1.5);
99
- }
100
- item.base_damage = base_damage;
101
- }
102
- else if (constants.other_items[item.type]) {
103
- item.type_id = ItemType.Other;
104
- details = constants.other_items[item.type];
105
- }
106
- if (details) {
107
- if (details.n)
108
- item.type_name = details.n;
109
- if (details.rs)
110
- item.reqstr = details.rs;
111
- if (details.rd)
112
- item.reqdex = details.rd;
113
- if (details.i)
114
- item.inv_file = details.i;
115
- if (details.ih)
116
- item.inv_height = details.ih;
117
- if (details.iw)
118
- item.inv_width = details.iw;
119
- if (details.it)
120
- item.inv_transform = details.it;
121
- if (details.iq)
122
- item.item_quality = details.iq;
123
- if (details.c)
124
- item.categories = details.c;
125
- if (details.durability) {
126
- if (item.ethereal == 0) {
127
- item.current_durability = details.durability;
128
- item.max_durability = details.durability;
129
- }
130
- else if (item.ethereal == 1) {
131
- item.current_durability = details.durability - Math.ceil(details.durability / 2) + 1;
132
- item.max_durability = details.durability - Math.ceil(details.durability / 2) + 1;
133
- }
134
- }
135
- if (item.multiple_pictures) {
136
- item.inv_file = details.ig[item.picture_id];
137
- }
138
- if (item.magic_prefix || item.magic_suffix) {
139
- if (item.magic_prefix && ((_a = constants.magic_prefixes[item.magic_prefix]) === null || _a === void 0 ? void 0 : _a.tc)) {
140
- item.transform_color = constants.magic_prefixes[item.magic_prefix].tc;
141
- }
142
- if (item.magic_suffix && ((_b = constants.magic_suffixes[item.magic_suffix]) === null || _b === void 0 ? void 0 : _b.tc)) {
143
- item.transform_color = constants.magic_suffixes[item.magic_suffix].tc;
144
- }
145
- }
146
- else if (item.magical_name_ids && item.magical_name_ids.length === 6) {
147
- for (let i = 0; i < 6; i++) {
148
- const id = item.magical_name_ids[i];
149
- if (id) {
150
- if (i % 2 == 0 && constants.magic_prefixes[id] && ((_c = constants.magic_prefixes[id]) === null || _c === void 0 ? void 0 : _c.tc)) {
151
- // even is prefixes
152
- item.transform_color = constants.magic_prefixes[id].tc;
153
- }
154
- else if (constants.magic_suffixes[id] && ((_d = constants.magic_suffixes[id]) === null || _d === void 0 ? void 0 : _d.tc)) {
155
- // odd is suffixes
156
- item.transform_color = constants.magic_suffixes[id].tc;
157
- }
158
- }
159
- }
160
- }
161
- else if (item.unique_id) {
162
- const unq = constants.unq_items[item.unique_id];
163
- if (details.ui)
164
- item.inv_file = details.ui;
165
- if (unq && unq.i)
166
- item.inv_file = unq.i;
167
- if (unq && unq.tc)
168
- item.transform_color = unq.tc;
169
- }
170
- else if (item.set_id) {
171
- const set = constants.set_items[item.set_id];
172
- if (details.ui)
173
- item.inv_file = details.ui;
174
- if (set && set.i)
175
- item.inv_file = set.i;
176
- if (set && set.tc)
177
- item.transform_color = set.tc;
178
- }
179
- }
180
- if (item.magic_attributes || item.runeword_attributes || item.socketed_items) {
181
- item.displayed_magic_attributes = _enhanceAttributeDescription(item.magic_attributes, constants, level, config);
182
- item.displayed_runeword_attributes = _enhanceAttributeDescription(item.runeword_attributes, constants, level, config);
183
- item.combined_magic_attributes = _groupAttributes(_allAttributes(item, constants), constants);
184
- item.displayed_combined_magic_attributes = _enhanceAttributeDescription(item.combined_magic_attributes, constants, level, config);
185
- }
186
- }
187
- exports.enhanceItem = enhanceItem;
188
- function _enhanceAttributeDescription(_magic_attributes, constants, level = 1, config) {
189
- if (!_magic_attributes)
190
- return [];
191
- const magic_attributes = [..._magic_attributes.map((attr) => (Object.assign({}, attr)))];
192
- const dgrps = [0, 0, 0];
193
- const dgrpsVal = [0, 0, 0];
194
- for (const property of magic_attributes) {
195
- const prop = constants.magical_properties[property.id];
196
- const v = property.values[property.values.length - 1];
197
- if (prop.dg) {
198
- if (dgrpsVal[prop.dg - 1] === 0) {
199
- dgrpsVal[prop.dg - 1] = v;
200
- }
201
- if (dgrpsVal[prop.dg - 1] - v === 0) {
202
- dgrps[prop.dg - 1]++;
203
- }
204
- }
205
- }
206
- for (const property of magic_attributes) {
207
- const prop = constants.magical_properties[property.id];
208
- if (prop == null) {
209
- throw new Error(`Cannot find Magical Property for id: ${property.id}`);
210
- }
211
- let v = property.values[property.values.length - 1];
212
- if (prop.ob === "level") {
213
- switch (prop.o) {
214
- case 1: {
215
- v = Math.floor((level * v) / 100);
216
- break;
217
- }
218
- case 2:
219
- case 3:
220
- case 4:
221
- case 5: {
222
- v = Math.floor((level * v) / 2 ** prop.op);
223
- break;
224
- }
225
- default: {
226
- break;
227
- }
228
- }
229
- property.op_stats = prop.os;
230
- property.op_value = v;
231
- }
232
- let descFunc = prop.dF;
233
- let descString = v >= 0 ? prop.dP : prop.dN;
234
- //hack for d2r...?
235
- if (property.id == 39 || property.id == 41 || property.id == 43 || property.id == 45) {
236
- descString = prop.dP;
237
- }
238
- let descVal = prop.dV;
239
- let desc2 = prop.d2;
240
- if (prop.dg && dgrps[prop.dg - 1] === 4) {
241
- v = dgrpsVal[prop.dg - 1];
242
- descString = v >= 0 ? prop.dgP : prop.dgN ? prop.dgN : prop.dgP;
243
- descVal = prop.dgV;
244
- descFunc = prop.dgF;
245
- desc2 = prop.dg2;
246
- }
247
- if (prop.np) {
248
- //damage range or enhanced damage.
249
- let count = 0;
250
- descString = prop.dR;
251
- if (prop.s === "poisonmindam") {
252
- //poisonmindam see https://user.xmission.com/~trevin/DiabloIIv1.09_Magic_Properties.shtml for reference
253
- const min = Math.floor((property.values[0] * property.values[2]) / 256);
254
- const max = Math.floor((property.values[1] * property.values[2]) / 256);
255
- const seconds = Math.floor(property.values[2] / 25);
256
- property.values = [min, max, seconds];
257
- }
258
- if (property.values[0] === property.values[1]) {
259
- count++;
260
- descString = prop.dE;
261
- //TODO. why???
262
- if (prop.s === "item_maxdamage_percent") {
263
- descString = `+%d% ${descString.replace(/}/gi, "").replace(/%\+?d%%/gi, "")}`;
264
- }
265
- }
266
- property.description = descString.replace(/%d/gi, () => {
267
- const v = property.values[count++];
268
- return v;
269
- });
270
- }
271
- else {
272
- _descFunc(property, constants, v, descFunc, descVal, descString, desc2);
273
- }
274
- }
275
- if (config === null || config === void 0 ? void 0 : config.sortProperties) {
276
- //sort using sort order from game.
277
- magic_attributes.sort((a, b) => constants.magical_properties[b.id].so - constants.magical_properties[a.id].so);
278
- }
279
- for (let i = magic_attributes.length - 1; i >= 1; i--) {
280
- for (let j = i - 1; j >= 0; j--) {
281
- if (magic_attributes[i].description === magic_attributes[j].description) {
282
- magic_attributes[j].visible = false;
283
- }
284
- }
285
- }
286
- return magic_attributes;
287
- }
288
- function _compactAttributes(mods, constants) {
289
- const magic_attributes = [];
290
- for (const mod of mods) {
291
- const properties = constants.properties[mod.m] || [];
292
- for (let i = 0; i < properties.length; i++) {
293
- const property = properties[i];
294
- let stat = property.s;
295
- switch (property.f) {
296
- case 5: {
297
- stat = "mindamage";
298
- break;
299
- }
300
- case 6: {
301
- stat = "maxdamage";
302
- break;
303
- }
304
- case 7: {
305
- stat = "item_maxdamage_percent";
306
- break;
307
- }
308
- case 20: {
309
- stat = "item_indesctructible";
310
- break;
311
- }
312
- default: {
313
- break;
314
- }
315
- }
316
- const id = _itemStatCostFromStat(stat, constants);
317
- const prop = constants.magical_properties[id];
318
- if (prop.np)
319
- i += prop.np;
320
- const v = [mod.min, mod.max];
321
- if (mod.p) {
322
- v.push(mod.p);
323
- }
324
- magic_attributes.push({
325
- id: id,
326
- values: v,
327
- name: prop.s,
328
- });
329
- }
330
- }
331
- return magic_attributes;
332
- }
333
- function _descFunc(property, constants, v, descFunc, descVal, descString, desc2) {
334
- if (!descFunc) {
335
- return;
336
- }
337
- const sign = v >= 0 ? "+" : "";
338
- let value = null;
339
- const desc2Present = descFunc >= 6 && descFunc <= 10;
340
- switch (descFunc) {
341
- case 1:
342
- case 6:
343
- case 12: {
344
- value = `${sign}${v}`;
345
- break;
346
- }
347
- case 2:
348
- case 7: {
349
- value = `${v}%`;
350
- break;
351
- }
352
- case 3:
353
- case 9: {
354
- value = `${v}`;
355
- break;
356
- }
357
- case 4:
358
- case 8: {
359
- value = `${sign}${v}%`;
360
- break;
361
- }
362
- case 5:
363
- case 10: {
364
- if (descString.indexOf("%%") < 0) {
365
- value = `${(v * 100) / 128}%`;
366
- }
367
- else {
368
- value = (v * 100) / 128;
369
- }
370
- break;
371
- }
372
- case 11: {
373
- property.description = descString.replace(/%d/, (v / 100).toString());
374
- break;
375
- }
376
- case 13: {
377
- const clazz = constants.classes[property.values[0]];
378
- property.description = `${sign}${v} ${clazz.as}`;
379
- break;
380
- }
381
- case 14: {
382
- const clazz = constants.classes[property.values[1]];
383
- const skillTabStr = clazz.ts[property.values[0]];
384
- descString = _sprintf(skillTabStr, v);
385
- property.description = `${descString} ${clazz.co}`;
386
- break;
387
- }
388
- case 15: {
389
- descString = _sprintf(descString, property.values[2], property.values[0], constants.skills[property.values[1]].s);
390
- property.description = `${descString}`;
391
- break;
392
- }
393
- case 16: {
394
- property.description = descString.replace(/%d/, v.toString());
395
- property.description = property.description.replace(/%s/, constants.skills[property.values[0]].s);
396
- break;
397
- }
398
- case 17: {
399
- //todo
400
- property.description = `${v} ${descString} (Increases near [time])`;
401
- break;
402
- }
403
- case 18: {
404
- //todo
405
- property.description = `${v}% ${descString} (Increases near [time])`;
406
- break;
407
- }
408
- case 19: {
409
- property.description = _sprintf(descString, v.toString());
410
- break;
411
- }
412
- case 20: {
413
- value = `${v * -1}%`;
414
- break;
415
- }
416
- case 21: {
417
- value = `${v * -1}`;
418
- break;
419
- }
420
- case 22: {
421
- //todo
422
- property.description = `${v}% ${descString} [montype]`;
423
- break;
424
- }
425
- case 23: {
426
- //todo
427
- property.description = `${v}% ${descString} [monster]]`;
428
- break;
429
- }
430
- case 24: {
431
- //charges
432
- //legacy desc string
433
- if (descString.indexOf("(") == 0) {
434
- let count = 0;
435
- descString = descString.replace(/%d/gi, () => {
436
- return property.values[2 + count++].toString();
437
- });
438
- property.description = `Level ${property.values[0]} ${constants.skills[property.values[1]].s} ${descString}`;
439
- }
440
- else {
441
- property.description = _sprintf(descString, property.values[0], constants.skills[property.values[1]].s, property.values[2], property.values[3]);
442
- }
443
- break;
444
- }
445
- case 27: {
446
- const skill = constants.skills[property.values[0]];
447
- const clazz = _classFromCode(skill.c, constants);
448
- if (descString) {
449
- property.description = _sprintf(descString, v, skill === null || skill === void 0 ? void 0 : skill.s, clazz === null || clazz === void 0 ? void 0 : clazz.co);
450
- }
451
- else {
452
- property.description = `${sign}${v} to ${skill === null || skill === void 0 ? void 0 : skill.s} ${clazz === null || clazz === void 0 ? void 0 : clazz.co}`;
453
- }
454
- break;
455
- }
456
- case 28: {
457
- const skill = constants.skills[property.values[0]];
458
- property.description = `${sign}${v} to ${skill === null || skill === void 0 ? void 0 : skill.s}`;
459
- break;
460
- }
461
- case 29: {
462
- property.description = _sprintf(descString, v.toString());
463
- break;
464
- }
465
- default: {
466
- throw new Error(`No handler for descFunc: ${descFunc}`);
467
- }
468
- }
469
- if (value) {
470
- descVal = descVal ? descVal : 0;
471
- switch (descVal) {
472
- case 0: {
473
- property.description = _sprintf(descString, value);
474
- break;
475
- }
476
- case 1: {
477
- property.description = `${value} ${descString}`;
478
- break;
479
- }
480
- case 2: {
481
- property.description = `${descString} ${value}`;
482
- break;
483
- }
484
- default: {
485
- throw new Error(`No handler for descVal: ${descVal}`);
486
- }
487
- }
488
- }
489
- if (desc2Present) {
490
- property.description += ` ${desc2}`;
491
- }
492
- }
493
- function _sprintf(str, ...args) {
494
- let i = 0;
495
- return str
496
- .replace(/%\+?d|%\+?s/gi, (m) => {
497
- let v = args[i++].toString();
498
- if (m.indexOf("+") >= 0) {
499
- v = "+" + v;
500
- }
501
- return v;
502
- })
503
- .replace("%%", "%");
504
- }
505
- function _itemStatCostFromStat(stat, constants) {
506
- return constants.magical_properties.findIndex((e) => e.s === stat);
507
- }
508
- function _classFromCode(code, constants) {
509
- return constants.classes.filter((e) => e.c === code)[0];
510
- }
511
- function _allAttributes(item, constants) {
512
- let socketed_attributes = [];
513
- if (item.socketed_items) {
514
- for (const i of item.socketed_items) {
515
- if (i.magic_attributes) {
516
- socketed_attributes = socketed_attributes.concat(...JSON.parse(JSON.stringify(i.magic_attributes)));
517
- }
518
- }
519
- }
520
- const magic_attributes = item.magic_attributes || [];
521
- const runeword_attributes = item.runeword_attributes || [];
522
- return [
523
- ...[],
524
- ...JSON.parse(JSON.stringify(magic_attributes)),
525
- ...JSON.parse(JSON.stringify(runeword_attributes)),
526
- ...JSON.parse(JSON.stringify(socketed_attributes)),
527
- ].filter((attribute) => attribute != null);
528
- }
529
- function _groupAttributes(all_attributes, constants) {
530
- const combined_magic_attributes = [];
531
- for (const magic_attribute of all_attributes) {
532
- const prop = constants.magical_properties[magic_attribute.id];
533
- const properties = combined_magic_attributes.filter((e) => {
534
- //encoded skills need to look at those params too.
535
- if (prop.e === 3) {
536
- return e.id === magic_attribute.id && e.values[0] === magic_attribute.values[0] && e.values[1] === magic_attribute.values[1];
537
- }
538
- if (prop.dF === 15) {
539
- return (e.id === magic_attribute.id &&
540
- e.values[0] === magic_attribute.values[0] &&
541
- e.values[1] === magic_attribute.values[1] &&
542
- e.values[2] === magic_attribute.values[2]);
543
- }
544
- if (prop.dF === 16 || prop.dF === 23) {
545
- return e.id === magic_attribute.id && e.values[0] === magic_attribute.values[0] && e.values[1] === magic_attribute.values[1];
546
- }
547
- if (prop.s === "state" || prop.s === "item_nonclassskill") {
548
- //state
549
- return e.id === magic_attribute.id && e.values[0] === magic_attribute.values[0] && e.values[1] === magic_attribute.values[1];
550
- }
551
- return e.id === magic_attribute.id;
552
- });
553
- if (properties && properties.length) {
554
- for (let i = 0; i < properties.length; i++) {
555
- const property = properties[i];
556
- if (prop.np) {
557
- //damage props
558
- property.values[0] += magic_attribute.values[0];
559
- property.values[1] += magic_attribute.values[1];
560
- break;
561
- }
562
- //only combine attributes if the params for the descFunc are the same.
563
- let sameParams = true;
564
- const numValues = prop.e === 3 ? 2 : 1;
565
- for (let j = 0; j < property.values.length - numValues; j++) {
566
- sameParams = property.values[j] === magic_attribute.values[j];
567
- if (!sameParams) {
568
- break;
569
- }
570
- }
571
- if (sameParams) {
572
- for (let j = 1; j <= numValues; j++) {
573
- const idx = property.values.length - j;
574
- property.values[idx] += magic_attribute.values[idx];
575
- }
576
- }
577
- else {
578
- combined_magic_attributes.push({
579
- id: magic_attribute.id,
580
- values: magic_attribute.values,
581
- name: magic_attribute.name,
582
- });
583
- }
584
- }
585
- }
586
- else {
587
- combined_magic_attributes.push({
588
- id: magic_attribute.id,
589
- values: magic_attribute.values,
590
- name: magic_attribute.name,
591
- });
592
- }
593
- }
594
- return combined_magic_attributes;
595
- }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enhanceItem = exports.enhanceItems = exports.enhancePlayerAttributes = exports.enhanceAttributes = void 0;
4
+ var ItemType;
5
+ (function (ItemType) {
6
+ ItemType[ItemType["Armor"] = 1] = "Armor";
7
+ ItemType[ItemType["Shield"] = 2] = "Shield";
8
+ ItemType[ItemType["Weapon"] = 3] = "Weapon";
9
+ ItemType[ItemType["Other"] = 4] = "Other";
10
+ })(ItemType || (ItemType = {}));
11
+ //do nice stuff
12
+ //combine group properties (all resists/all stats) and build friendly strings for a ui
13
+ //enhanced def/durability/weapon damage.
14
+ //lookup socketed compact items (runes/gems) properties for the slot they are in
15
+ //compute attributes like str/resists/etc..
16
+ async function enhanceAttributes(char, constants, config) {
17
+ enhanceItems(char.items, constants, char.attributes.level, config);
18
+ enhanceItems([char.golem_item], constants, char.attributes.level, config);
19
+ enhanceItems(char.merc_items, constants, char.attributes.level, config);
20
+ enhanceItems(char.corpse_items, constants, char.attributes.level, config);
21
+ enhancePlayerAttributes(char, constants, config);
22
+ }
23
+ exports.enhanceAttributes = enhanceAttributes;
24
+ async function enhancePlayerAttributes(char, constants, config) {
25
+ const items = char.items.filter((item) => {
26
+ return item.location_id === 1 && item.equipped_id !== 13 && item.equipped_id !== 14;
27
+ });
28
+ char.item_bonuses = [].concat
29
+ .apply([], items.map((item) => _allAttributes(item, constants)))
30
+ .filter((attribute) => attribute != null);
31
+ char.item_bonuses = _groupAttributes(char.item_bonuses, constants);
32
+ _enhanceAttributeDescription(char.item_bonuses, constants, char.attributes.level, config);
33
+ }
34
+ exports.enhancePlayerAttributes = enhancePlayerAttributes;
35
+ async function enhanceItems(items, constants, level = 1, config, parent) {
36
+ if (!items) {
37
+ return;
38
+ }
39
+ for (const item of items) {
40
+ if (!item) {
41
+ continue;
42
+ }
43
+ if (item.socketed_items && item.socketed_items.length) {
44
+ enhanceItems(item.socketed_items, constants, level, config, item);
45
+ }
46
+ enhanceItem(item, constants, level, config, parent);
47
+ }
48
+ }
49
+ exports.enhanceItems = enhanceItems;
50
+ function enhanceItem(item, constants, level = 1, config, parent) {
51
+ var _a, _b, _c, _d;
52
+ if (config === null || config === void 0 ? void 0 : config.disableItemEnhancements) {
53
+ return;
54
+ }
55
+ if (parent) {
56
+ //socket item.
57
+ const pt = constants.armor_items[parent.type] || constants.weapon_items[parent.type] || constants.other_items[item.type];
58
+ const t = constants.other_items[item.type];
59
+ if (t.m) {
60
+ item.magic_attributes = _compactAttributes(t.m[pt.gt], constants);
61
+ }
62
+ }
63
+ let details = null;
64
+ if (constants.armor_items[item.type]) {
65
+ details = constants.armor_items[item.type];
66
+ item.type_id = ItemType.Armor;
67
+ if (details.maxac) {
68
+ if (item.ethereal == 0) {
69
+ item.defense_rating = details.maxac;
70
+ }
71
+ else if (item.ethereal == 1) {
72
+ item.defense_rating = Math.floor(details.maxac * 1.5);
73
+ }
74
+ }
75
+ }
76
+ else if (constants.weapon_items[item.type]) {
77
+ details = constants.weapon_items[item.type];
78
+ item.type_id = ItemType.Weapon;
79
+ const base_damage = {};
80
+ if (item.ethereal == 0) {
81
+ if (details.mind)
82
+ base_damage.mindam = details.mind;
83
+ if (details.maxd)
84
+ base_damage.maxdam = details.maxd;
85
+ if (details.min2d)
86
+ base_damage.twohandmindam = details.min2d;
87
+ if (details.max2d)
88
+ base_damage.twohandmaxdam = details.max2d;
89
+ }
90
+ else if (item.ethereal == 1) {
91
+ if (details.mind)
92
+ base_damage.mindam = Math.floor(details.mind * 1.5);
93
+ if (details.maxd)
94
+ base_damage.maxdam = Math.floor(details.maxd * 1.5);
95
+ if (details.min2d)
96
+ base_damage.twohandmindam = Math.floor(details.min2d * 1.5);
97
+ if (details.max2d)
98
+ base_damage.twohandmaxdam = Math.floor(details.max2d * 1.5);
99
+ }
100
+ item.base_damage = base_damage;
101
+ }
102
+ else if (constants.other_items[item.type]) {
103
+ item.type_id = ItemType.Other;
104
+ details = constants.other_items[item.type];
105
+ }
106
+ if (details) {
107
+ if (details.n)
108
+ item.type_name = details.n;
109
+ if (details.rs)
110
+ item.reqstr = details.rs;
111
+ if (details.rd)
112
+ item.reqdex = details.rd;
113
+ if (details.i)
114
+ item.inv_file = details.i;
115
+ if (details.ih)
116
+ item.inv_height = details.ih;
117
+ if (details.iw)
118
+ item.inv_width = details.iw;
119
+ if (details.it)
120
+ item.inv_transform = details.it;
121
+ if (details.iq)
122
+ item.item_quality = details.iq;
123
+ if (details.c)
124
+ item.categories = details.c;
125
+ if (details.durability) {
126
+ if (item.ethereal == 0) {
127
+ item.current_durability = details.durability;
128
+ item.max_durability = details.durability;
129
+ }
130
+ else if (item.ethereal == 1) {
131
+ item.current_durability = details.durability - Math.ceil(details.durability / 2) + 1;
132
+ item.max_durability = details.durability - Math.ceil(details.durability / 2) + 1;
133
+ }
134
+ }
135
+ if (item.multiple_pictures) {
136
+ item.inv_file = details.ig[item.picture_id];
137
+ }
138
+ if (item.magic_prefix || item.magic_suffix) {
139
+ if (item.magic_prefix && ((_a = constants.magic_prefixes[item.magic_prefix]) === null || _a === void 0 ? void 0 : _a.tc)) {
140
+ item.transform_color = constants.magic_prefixes[item.magic_prefix].tc;
141
+ }
142
+ if (item.magic_suffix && ((_b = constants.magic_suffixes[item.magic_suffix]) === null || _b === void 0 ? void 0 : _b.tc)) {
143
+ item.transform_color = constants.magic_suffixes[item.magic_suffix].tc;
144
+ }
145
+ }
146
+ else if (item.magical_name_ids && item.magical_name_ids.length === 6) {
147
+ for (let i = 0; i < 6; i++) {
148
+ const id = item.magical_name_ids[i];
149
+ if (id) {
150
+ if (i % 2 == 0 && constants.magic_prefixes[id] && ((_c = constants.magic_prefixes[id]) === null || _c === void 0 ? void 0 : _c.tc)) {
151
+ // even is prefixes
152
+ item.transform_color = constants.magic_prefixes[id].tc;
153
+ }
154
+ else if (constants.magic_suffixes[id] && ((_d = constants.magic_suffixes[id]) === null || _d === void 0 ? void 0 : _d.tc)) {
155
+ // odd is suffixes
156
+ item.transform_color = constants.magic_suffixes[id].tc;
157
+ }
158
+ }
159
+ }
160
+ }
161
+ else if (item.unique_id) {
162
+ const unq = constants.unq_items[item.unique_id];
163
+ if (details.ui)
164
+ item.inv_file = details.ui;
165
+ if (unq && unq.i)
166
+ item.inv_file = unq.i;
167
+ if (unq && unq.tc)
168
+ item.transform_color = unq.tc;
169
+ }
170
+ else if (item.set_id) {
171
+ const set = constants.set_items[item.set_id];
172
+ if (details.ui)
173
+ item.inv_file = details.ui;
174
+ if (set && set.i)
175
+ item.inv_file = set.i;
176
+ if (set && set.tc)
177
+ item.transform_color = set.tc;
178
+ }
179
+ }
180
+ if (item.magic_attributes || item.runeword_attributes || item.socketed_items) {
181
+ item.displayed_magic_attributes = _enhanceAttributeDescription(item.magic_attributes, constants, level, config);
182
+ item.displayed_runeword_attributes = _enhanceAttributeDescription(item.runeword_attributes, constants, level, config);
183
+ item.combined_magic_attributes = _groupAttributes(_allAttributes(item, constants), constants);
184
+ item.displayed_combined_magic_attributes = _enhanceAttributeDescription(item.combined_magic_attributes, constants, level, config);
185
+ }
186
+ }
187
+ exports.enhanceItem = enhanceItem;
188
+ function _enhanceAttributeDescription(_magic_attributes, constants, level = 1, config) {
189
+ if (!_magic_attributes)
190
+ return [];
191
+ const magic_attributes = [..._magic_attributes.map((attr) => (Object.assign({}, attr)))];
192
+ const dgrps = [0, 0, 0];
193
+ const dgrpsVal = [0, 0, 0];
194
+ for (const property of magic_attributes) {
195
+ const prop = constants.magical_properties[property.id];
196
+ const v = property.values[property.values.length - 1];
197
+ if (prop.dg) {
198
+ if (dgrpsVal[prop.dg - 1] === 0) {
199
+ dgrpsVal[prop.dg - 1] = v;
200
+ }
201
+ if (dgrpsVal[prop.dg - 1] - v === 0) {
202
+ dgrps[prop.dg - 1]++;
203
+ }
204
+ }
205
+ }
206
+ for (const property of magic_attributes) {
207
+ const prop = constants.magical_properties[property.id];
208
+ if (prop == null) {
209
+ throw new Error(`Cannot find Magical Property for id: ${property.id}`);
210
+ }
211
+ let v = property.values[property.values.length - 1];
212
+ if (prop.ob === "level") {
213
+ switch (prop.o) {
214
+ case 1: {
215
+ v = Math.floor((level * v) / 100);
216
+ break;
217
+ }
218
+ case 2:
219
+ case 3:
220
+ case 4:
221
+ case 5: {
222
+ v = Math.floor((level * v) / 2 ** prop.op);
223
+ break;
224
+ }
225
+ default: {
226
+ break;
227
+ }
228
+ }
229
+ property.op_stats = prop.os;
230
+ property.op_value = v;
231
+ }
232
+ let descFunc = prop.dF;
233
+ let descString = v >= 0 ? prop.dP : prop.dN;
234
+ //hack for d2r...?
235
+ if (property.id == 39 || property.id == 41 || property.id == 43 || property.id == 45) {
236
+ descString = prop.dP;
237
+ }
238
+ let descVal = prop.dV;
239
+ let desc2 = prop.d2;
240
+ if (prop.dg && dgrps[prop.dg - 1] === 4) {
241
+ v = dgrpsVal[prop.dg - 1];
242
+ descString = v >= 0 ? prop.dgP : prop.dgN ? prop.dgN : prop.dgP;
243
+ descVal = prop.dgV;
244
+ descFunc = prop.dgF;
245
+ desc2 = prop.dg2;
246
+ }
247
+ if (prop.np) {
248
+ //damage range or enhanced damage.
249
+ let count = 0;
250
+ descString = prop.dR;
251
+ if (prop.s === "poisonmindam") {
252
+ //poisonmindam see https://user.xmission.com/~trevin/DiabloIIv1.09_Magic_Properties.shtml for reference
253
+ const min = Math.floor((property.values[0] * property.values[2]) / 256);
254
+ const max = Math.floor((property.values[1] * property.values[2]) / 256);
255
+ const seconds = Math.floor(property.values[2] / 25);
256
+ property.values = [min, max, seconds];
257
+ }
258
+ if (property.values[0] === property.values[1]) {
259
+ count++;
260
+ descString = prop.dE;
261
+ //TODO. why???
262
+ if (prop.s === "item_maxdamage_percent") {
263
+ descString = `+%d% ${descString.replace(/}/gi, "").replace(/%\+?d%%/gi, "")}`;
264
+ }
265
+ }
266
+ property.description = descString.replace(/%d/gi, () => {
267
+ const v = property.values[count++];
268
+ return v;
269
+ });
270
+ }
271
+ else {
272
+ _descFunc(property, constants, v, descFunc, descVal, descString, desc2);
273
+ }
274
+ }
275
+ if (config === null || config === void 0 ? void 0 : config.sortProperties) {
276
+ //sort using sort order from game.
277
+ magic_attributes.sort((a, b) => constants.magical_properties[b.id].so - constants.magical_properties[a.id].so);
278
+ }
279
+ for (let i = magic_attributes.length - 1; i >= 1; i--) {
280
+ for (let j = i - 1; j >= 0; j--) {
281
+ if (magic_attributes[i].description === magic_attributes[j].description) {
282
+ magic_attributes[j].visible = false;
283
+ }
284
+ }
285
+ }
286
+ return magic_attributes;
287
+ }
288
+ function _compactAttributes(mods, constants) {
289
+ const magic_attributes = [];
290
+ for (const mod of mods) {
291
+ const properties = constants.properties[mod.m] || [];
292
+ for (let i = 0; i < properties.length; i++) {
293
+ const property = properties[i];
294
+ let stat = property.s;
295
+ switch (property.f) {
296
+ case 5: {
297
+ stat = "mindamage";
298
+ break;
299
+ }
300
+ case 6: {
301
+ stat = "maxdamage";
302
+ break;
303
+ }
304
+ case 7: {
305
+ stat = "item_maxdamage_percent";
306
+ break;
307
+ }
308
+ case 20: {
309
+ stat = "item_indesctructible";
310
+ break;
311
+ }
312
+ default: {
313
+ break;
314
+ }
315
+ }
316
+ const id = _itemStatCostFromStat(stat, constants);
317
+ const prop = constants.magical_properties[id];
318
+ if (prop.np)
319
+ i += prop.np;
320
+ const v = [mod.min, mod.max];
321
+ if (mod.p) {
322
+ v.push(mod.p);
323
+ }
324
+ magic_attributes.push({
325
+ id: id,
326
+ values: v,
327
+ name: prop.s,
328
+ });
329
+ }
330
+ }
331
+ return magic_attributes;
332
+ }
333
+ function _descFunc(property, constants, v, descFunc, descVal, descString, desc2) {
334
+ if (!descFunc) {
335
+ return;
336
+ }
337
+ const sign = v >= 0 ? "+" : "";
338
+ let value = null;
339
+ const desc2Present = descFunc >= 6 && descFunc <= 10;
340
+ switch (descFunc) {
341
+ case 1:
342
+ case 6:
343
+ case 12: {
344
+ value = `${sign}${v}`;
345
+ break;
346
+ }
347
+ case 2:
348
+ case 7: {
349
+ value = `${v}%`;
350
+ break;
351
+ }
352
+ case 3:
353
+ case 9: {
354
+ value = `${v}`;
355
+ break;
356
+ }
357
+ case 4:
358
+ case 8: {
359
+ value = `${sign}${v}%`;
360
+ break;
361
+ }
362
+ case 5:
363
+ case 10: {
364
+ if (descString.indexOf("%%") < 0) {
365
+ value = `${(v * 100) / 128}%`;
366
+ }
367
+ else {
368
+ value = (v * 100) / 128;
369
+ }
370
+ break;
371
+ }
372
+ case 11: {
373
+ property.description = descString.replace(/%d/, (v / 100).toString());
374
+ break;
375
+ }
376
+ case 13: {
377
+ const clazz = constants.classes[property.values[0]];
378
+ property.description = `${sign}${v} ${clazz.as}`;
379
+ break;
380
+ }
381
+ case 14: {
382
+ const clazz = constants.classes[property.values[1]];
383
+ const skillTabStr = clazz.ts[property.values[0]];
384
+ descString = _sprintf(skillTabStr, v);
385
+ property.description = `${descString} ${clazz.co}`;
386
+ break;
387
+ }
388
+ case 15: {
389
+ descString = _sprintf(descString, property.values[2], property.values[0], constants.skills[property.values[1]].s);
390
+ property.description = `${descString}`;
391
+ break;
392
+ }
393
+ case 16: {
394
+ property.description = descString.replace(/%d/, v.toString());
395
+ property.description = property.description.replace(/%s/, constants.skills[property.values[0]].s);
396
+ break;
397
+ }
398
+ case 17: {
399
+ //todo
400
+ property.description = `${v} ${descString} (Increases near [time])`;
401
+ break;
402
+ }
403
+ case 18: {
404
+ //todo
405
+ property.description = `${v}% ${descString} (Increases near [time])`;
406
+ break;
407
+ }
408
+ case 19: {
409
+ property.description = _sprintf(descString, v.toString());
410
+ break;
411
+ }
412
+ case 20: {
413
+ value = `${v * -1}%`;
414
+ break;
415
+ }
416
+ case 21: {
417
+ value = `${v * -1}`;
418
+ break;
419
+ }
420
+ case 22: {
421
+ //todo
422
+ property.description = `${v}% ${descString} [montype]`;
423
+ break;
424
+ }
425
+ case 23: {
426
+ //todo
427
+ property.description = `${v}% ${descString} [monster]]`;
428
+ break;
429
+ }
430
+ case 24: {
431
+ //charges
432
+ //legacy desc string
433
+ if (descString.indexOf("(") == 0) {
434
+ let count = 0;
435
+ descString = descString.replace(/%d/gi, () => {
436
+ return property.values[2 + count++].toString();
437
+ });
438
+ property.description = `Level ${property.values[0]} ${constants.skills[property.values[1]].s} ${descString}`;
439
+ }
440
+ else {
441
+ property.description = _sprintf(descString, property.values[0], constants.skills[property.values[1]].s, property.values[2], property.values[3]);
442
+ }
443
+ break;
444
+ }
445
+ case 27: {
446
+ const skill = constants.skills[property.values[0]];
447
+ const clazz = _classFromCode(skill.c, constants);
448
+ if (descString) {
449
+ property.description = _sprintf(descString, v, skill === null || skill === void 0 ? void 0 : skill.s, clazz === null || clazz === void 0 ? void 0 : clazz.co);
450
+ }
451
+ else {
452
+ property.description = `${sign}${v} to ${skill === null || skill === void 0 ? void 0 : skill.s} ${clazz === null || clazz === void 0 ? void 0 : clazz.co}`;
453
+ }
454
+ break;
455
+ }
456
+ case 28: {
457
+ const skill = constants.skills[property.values[0]];
458
+ property.description = `${sign}${v} to ${skill === null || skill === void 0 ? void 0 : skill.s}`;
459
+ break;
460
+ }
461
+ case 29: {
462
+ property.description = _sprintf(descString, v.toString());
463
+ break;
464
+ }
465
+ default: {
466
+ throw new Error(`No handler for descFunc: ${descFunc}`);
467
+ }
468
+ }
469
+ if (value) {
470
+ descVal = descVal ? descVal : 0;
471
+ switch (descVal) {
472
+ case 0: {
473
+ property.description = _sprintf(descString, value);
474
+ break;
475
+ }
476
+ case 1: {
477
+ property.description = `${value} ${descString}`;
478
+ break;
479
+ }
480
+ case 2: {
481
+ property.description = `${descString} ${value}`;
482
+ break;
483
+ }
484
+ default: {
485
+ throw new Error(`No handler for descVal: ${descVal}`);
486
+ }
487
+ }
488
+ }
489
+ if (desc2Present) {
490
+ property.description += ` ${desc2}`;
491
+ }
492
+ }
493
+ function _sprintf(str, ...args) {
494
+ let i = 0;
495
+ return str
496
+ .replace(/%\+?d|%\+?s/gi, (m) => {
497
+ let v = args[i++].toString();
498
+ if (m.indexOf("+") >= 0) {
499
+ v = "+" + v;
500
+ }
501
+ return v;
502
+ })
503
+ .replace("%%", "%");
504
+ }
505
+ function _itemStatCostFromStat(stat, constants) {
506
+ return constants.magical_properties.findIndex((e) => e.s === stat);
507
+ }
508
+ function _classFromCode(code, constants) {
509
+ return constants.classes.filter((e) => e.c === code)[0];
510
+ }
511
+ function _allAttributes(item, constants) {
512
+ let socketed_attributes = [];
513
+ if (item.socketed_items) {
514
+ for (const i of item.socketed_items) {
515
+ if (i.magic_attributes) {
516
+ socketed_attributes = socketed_attributes.concat(...JSON.parse(JSON.stringify(i.magic_attributes)));
517
+ }
518
+ }
519
+ }
520
+ const magic_attributes = item.magic_attributes || [];
521
+ const runeword_attributes = item.runeword_attributes || [];
522
+ return [
523
+ ...[],
524
+ ...JSON.parse(JSON.stringify(magic_attributes)),
525
+ ...JSON.parse(JSON.stringify(runeword_attributes)),
526
+ ...JSON.parse(JSON.stringify(socketed_attributes)),
527
+ ].filter((attribute) => attribute != null);
528
+ }
529
+ function _groupAttributes(all_attributes, constants) {
530
+ const combined_magic_attributes = [];
531
+ for (const magic_attribute of all_attributes) {
532
+ const prop = constants.magical_properties[magic_attribute.id];
533
+ const properties = combined_magic_attributes.filter((e) => {
534
+ //encoded skills need to look at those params too.
535
+ if (prop.e === 3) {
536
+ return e.id === magic_attribute.id && e.values[0] === magic_attribute.values[0] && e.values[1] === magic_attribute.values[1];
537
+ }
538
+ if (prop.dF === 15) {
539
+ return (e.id === magic_attribute.id &&
540
+ e.values[0] === magic_attribute.values[0] &&
541
+ e.values[1] === magic_attribute.values[1] &&
542
+ e.values[2] === magic_attribute.values[2]);
543
+ }
544
+ if (prop.dF === 16 || prop.dF === 23) {
545
+ return e.id === magic_attribute.id && e.values[0] === magic_attribute.values[0] && e.values[1] === magic_attribute.values[1];
546
+ }
547
+ if (prop.s === "state" || prop.s === "item_nonclassskill") {
548
+ //state
549
+ return e.id === magic_attribute.id && e.values[0] === magic_attribute.values[0] && e.values[1] === magic_attribute.values[1];
550
+ }
551
+ return e.id === magic_attribute.id;
552
+ });
553
+ if (properties && properties.length) {
554
+ for (let i = 0; i < properties.length; i++) {
555
+ const property = properties[i];
556
+ if (prop.np) {
557
+ //damage props
558
+ property.values[0] += magic_attribute.values[0];
559
+ property.values[1] += magic_attribute.values[1];
560
+ break;
561
+ }
562
+ //only combine attributes if the params for the descFunc are the same.
563
+ let sameParams = true;
564
+ const numValues = prop.e === 3 ? 2 : 1;
565
+ for (let j = 0; j < property.values.length - numValues; j++) {
566
+ sameParams = property.values[j] === magic_attribute.values[j];
567
+ if (!sameParams) {
568
+ break;
569
+ }
570
+ }
571
+ if (sameParams) {
572
+ for (let j = 1; j <= numValues; j++) {
573
+ const idx = property.values.length - j;
574
+ property.values[idx] += magic_attribute.values[idx];
575
+ }
576
+ }
577
+ else {
578
+ combined_magic_attributes.push({
579
+ id: magic_attribute.id,
580
+ values: magic_attribute.values,
581
+ name: magic_attribute.name,
582
+ });
583
+ }
584
+ }
585
+ }
586
+ else {
587
+ combined_magic_attributes.push({
588
+ id: magic_attribute.id,
589
+ values: magic_attribute.values,
590
+ name: magic_attribute.name,
591
+ });
592
+ }
593
+ }
594
+ return combined_magic_attributes;
595
+ }
596
596
  //# sourceMappingURL=attribute_enhancer.js.map