-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathitem.go
3718 lines (3649 loc) · 90.2 KB
/
item.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package d2s
type item struct {
Identified uint64 `json:"identified"`
Socketed uint64 `json:"socketed"`
New uint64 `json:"new"`
IsEar uint64 `json:"is_ear"`
StarterItem uint64 `json:"starter_item"`
SimpleItem uint64 `json:"simple_item"`
Ethereal uint64 `json:"ethereal"`
Personalized uint64 `json:"personalized"`
PersonalizedName string `json:"personalized_name,omitempty"`
GivenRuneword uint64 `json:"given_runeword"`
LocationID uint64 `json:"location_id"`
EquippedID uint64 `json:"equipped_id,omitempty"`
PositionX uint64 `json:"position_x"`
PositionY uint64 `json:"position_y"`
AltPositionID uint64 `json:"alt_position_id"`
Type string `json:"type"`
TypeID uint64 `json:"type_id"`
TypeName string `json:"type_name"`
NrOfItemsInSockets uint64 `json:"nr_of_items_in_sockets"`
ID uint64 `json:"id"`
Level uint64 `json:"level"`
Quality uint64 `json:"quality"`
MultiplePictures uint64 `json:"multiple_pictures"`
PictureID uint64 `json:"picture_id"`
ClassSpecific uint64 `json:"class_specific"`
LowQualityID uint64 `json:"low_quality_id"`
Timestamp uint64 `json:"timestamp"`
EarAttributes earAttributes `json:"ear_attributes"`
DefenseRating int64 `json:"defense_rating,omitempty"`
MaxDurability uint64 `json:"max_durability,omitempty"`
CurrentDurability uint64 `json:"current_durability,omitempty"`
TotalNrOfSockets uint64 `json:"total_nr_of_sockets"`
Quantity uint64 `json:"quantity,omitempty"`
MagicPrefix uint64 `json:"magic_prefix,omitempty"`
MagicPrefixName string `json:"magic_prefix_name,omitempty"`
MagicSuffix uint64 `json:"magic_suffix,omitempty"`
MagicSuffixName string `json:"magic_suffix_name,omitempty"`
RunewordID uint64 `json:"runeword_id,omitempty"`
RunewordName string `json:"runeword_name,omitempty"`
RunewordAttributes []magicAttribute `json:"runeword_attributes"`
SetID uint64 `json:"set_id,omitempty"`
SetName string `json:"set_name,omitempty"`
SetListCount uint64 `json:"set_list_count"`
SetAttributes [][]magicAttribute `json:"set_attributes"`
SetAttributesNumReq []uint `json:"set_attributes_num_req,omitempty"`
SetAttributesIDsReq []uint64 `json:"set_attributes_ids_req,omitempty"`
RareName string `json:"rare_name,omitempty"`
RareName2 string `json:"rare_name2,omitempty"`
MagicalNameIDs []uint64 `json:"magical_name_ids,omitempty"`
UniqueID uint64 `json:"unique_id,omitempty"`
UniqueName string `json:"unique_name,omitempty"`
MagicAttributes []magicAttribute `json:"magic_attributes"`
SocketedItems []item `json:"socketed_items"`
BaseDamage *weaponDamage `json:"base_damage,omitempty"`
}
func (i *item) getTypeID() uint64 {
if _, ok := armorCodes[i.Type]; ok {
return armor
}
if _, ok := shieldCodes[i.Type]; ok {
return shield
}
if _, ok := weaponCodes[i.Type]; ok {
return weapon
}
return other
}
// Attributes that only exists on a player ear.
type earAttributes struct {
Class uint64 `json:"class"`
Level uint64 `json:"level"`
Name string `json:"name"`
}
// Note the values array is of the type int64, this is because some properties
// contain negative values, such as - % requirements.
type magicAttribute struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Values []int64 `json:"values"`
}
type magicalProperty struct {
Bits []uint
Bias uint64
Name string
}
type weaponDamage struct {
Min int `json:"min,omitempty"`
Max int `json:"max,omitempty"`
TwoMin int `json:"twohand_min,omitempty"`
TwoMax int `json:"twohand_max,omitempty"`
}
var weaponDamageMap = map[string]weaponDamage{
//Axes
"hax": {Min: 3, Max: 6},
"axe": {Min: 4, Max: 11},
"2ax": {Min: 5, Max: 13},
"mpi": {Min: 7, Max: 11},
"wax": {Min: 10, Max: 18},
"lax": {Min: 6, Max: 13},
"bax": {Min: 10, Max: 18},
"btx": {Min: 12, Max: 32},
"gax": {Min: 9, Max: 30},
"gix": {Min: 22, Max: 45},
"9ha": {Min: 10, Max: 21},
"9ax": {Min: 10, Max: 33},
"92a": {Min: 13, Max: 38},
"9mp": {Min: 14, Max: 34},
"9wa": {Min: 16, Max: 45},
"9la": {Min: 14, Max: 34},
"9ba": {Min: 21, Max: 49},
"9bt": {Min: 24, Max: 77},
"9ga": {Min: 18, Max: 70},
"9gi": {Min: 43, Max: 85},
"7ha": {Min: 33, Max: 58},
"7ax": {Min: 38, Max: 60},
"72a": {Min: 33, Max: 66},
"7mp": {Min: 30, Max: 48},
"7wa": {Min: 24, Max: 71},
"7la": {Min: 25, Max: 123},
"7ba": {Min: 62, Max: 110},
"7bt": {Min: 49, Max: 137},
"7ga": {Min: 59, Max: 94},
"7gi": {Min: 60, Max: 124},
//Maces
"clb": {Min: 1, Max: 6},
"spc": {Min: 5, Max: 8},
"mac": {Min: 3, Max: 10},
"mst": {Min: 7, Max: 16},
"fla": {Min: 1, Max: 24},
"whm": {Min: 19, Max: 29},
"mau": {Min: 30, Max: 43},
"gma": {Min: 38, Max: 58},
"9cl": {Min: 6, Max: 21},
"9sp": {Min: 13, Max: 25},
"9ma": {Min: 15, Max: 23},
"9mt": {Min: 20, Max: 31},
"9fl": {Min: 13, Max: 35},
"9wh": {Min: 35, Max: 58},
"9m9": {Min: 53, Max: 78},
"9gm": {Min: 61, Max: 99},
"7cl": {Min: 35, Max: 43},
"7sp": {Min: 32, Max: 58},
"7ma": {Min: 41, Max: 49},
"7mt": {Min: 42, Max: 53},
"7fl": {Min: 3, Max: 80},
"7wh": {Min: 50, Max: 61},
"7m7": {Min: 77, Max: 106},
"7gm": {Min: 33, Max: 180},
//Polearms
"bar": {TwoMin: 1, TwoMax: 27},
"vou": {TwoMin: 6, TwoMax: 21},
"scy": {TwoMin: 8, TwoMax: 20},
"pax": {TwoMin: 18, TwoMax: 39},
"hal": {TwoMin: 21, TwoMax: 45},
"wsc": {TwoMin: 15, TwoMax: 36},
"9b7": {TwoMin: 6, TwoMax: 58},
"9vo": {TwoMin: 14, TwoMax: 53},
"9s8": {TwoMin: 18, TwoMax: 45},
"9pa": {TwoMin: 34, TwoMax: 75},
"9h9": {TwoMin: 13, TwoMax: 85},
"9wc": {TwoMin: 30, TwoMax: 70},
"7o7": {TwoMin: 28, TwoMax: 145},
"7vo": {TwoMin: 17, TwoMax: 165},
"7s8": {TwoMin: 12, TwoMax: 141},
"7pa": {TwoMin: 33, TwoMax: 150},
"7h7": {TwoMin: 46, TwoMax: 127},
"7wc": {TwoMin: 40, TwoMax: 127},
//Swords
"ssd": {Min: 2, Max: 7},
"scm": {Min: 2, Max: 6},
"sbr": {Min: 3, Max: 8},
"flc": {Min: 9, Max: 17},
"crs": {Min: 5, Max: 15},
"bsd": {Min: 7, Max: 14},
"lsd": {Min: 3, Max: 19},
"wsd": {Min: 8, Max: 20},
"9ss": {Min: 8, Max: 22},
"9sm": {Min: 8, Max: 21},
"9sb": {Min: 10, Max: 24},
"9fc": {Min: 16, Max: 35},
"9cr": {Min: 13, Max: 35},
"9bs": {Min: 16, Max: 34},
"9ls": {Min: 10, Max: 42},
"9wd": {Min: 18, Max: 43},
"7ss": {Min: 31, Max: 59},
"7sm": {Min: 26, Max: 46},
"7sb": {Min: 33, Max: 45},
"7fc": {Min: 28, Max: 68},
"7cr": {Min: 31, Max: 35},
"7bs": {Min: 37, Max: 53},
"7ls": {Min: 5, Max: 77},
"7wd": {Min: 40, Max: 50},
// Two handed swords
"2hs": {Min: 2, Max: 9, TwoMin: 5, TwoMax: 17},
"clm": {Min: 5, Max: 12, TwoMin: 13, TwoMax: 30},
"gis": {Min: 3, Max: 16, TwoMin: 9, TwoMax: 28},
"bsw": {Min: 7, Max: 19, TwoMin: 20, TwoMax: 28},
"flb": {Min: 9, Max: 15, TwoMin: 13, TwoMax: 26},
"gsd": {Min: 12, Max: 20, TwoMin: 25, TwoMax: 42},
"92h": {Min: 8, Max: 26, TwoMin: 18, TwoMax: 40},
"9cm": {Min: 13, Max: 30, TwoMin: 26, TwoMax: 61},
"9gs": {Min: 10, Max: 37, TwoMin: 19, TwoMax: 58},
"9b9": {Min: 14, Max: 40, TwoMin: 39, TwoMax: 60},
"9fb": {Min: 19, Max: 35, TwoMin: 29, TwoMax: 54},
"9gd": {Min: 24, Max: 40, TwoMin: 47, TwoMax: 80},
"7sh": {Min: 22, Max: 56, TwoMin: 50, TwoMax: 94},
"7cm": {Min: 22, Max: 62, TwoMin: 67, TwoMax: 96},
"7gs": {Min: 15, Max: 75, TwoMin: 55, TwoMax: 118},
"7b7": {Min: 24, Max: 54, TwoMin: 71, TwoMax: 83},
"7fb": {Min: 26, Max: 70, TwoMin: 61, TwoMax: 121},
"7gd": {Min: 25, Max: 65, TwoMin: 58, TwoMax: 115},
//Bows
"sbw": {TwoMin: 1, TwoMax: 4},
"hbw": {TwoMin: 2, TwoMax: 6},
"lbw": {TwoMin: 3, TwoMax: 10},
"cbw": {TwoMin: 4, TwoMax: 8},
"sbb": {TwoMin: 3, TwoMax: 18},
"swb": {TwoMin: 6, TwoMax: 14},
"lwb": {TwoMin: 3, TwoMax: 23},
"8sb": {TwoMin: 6, TwoMax: 19},
"8hb": {TwoMin: 8, TwoMax: 22},
"8lb": {TwoMin: 10, TwoMax: 29},
"8cb": {TwoMin: 11, TwoMax: 26},
"8s8": {TwoMin: 13, TwoMax: 30},
"8l8": {TwoMin: 10, TwoMax: 42},
"8sw": {TwoMin: 14, TwoMax: 35},
"8lw": {TwoMin: 10, TwoMax: 50},
"6sb": {TwoMin: 23, TwoMax: 50},
"6hb": {TwoMin: 21, TwoMax: 41},
"6lb": {TwoMin: 15, TwoMax: 59},
"6cb": {TwoMin: 12, TwoMax: 52},
"6s7": {TwoMin: 33, TwoMax: 40},
"6l7": {TwoMin: 15, TwoMax: 63},
"6sw": {TwoMin: 20, TwoMax: 53},
"6lw": {TwoMin: 10, TwoMax: 68},
//Crossbows
"lxb": {TwoMin: 6, TwoMax: 9},
"mxb": {TwoMin: 9, TwoMax: 16},
"hxb": {TwoMin: 14, TwoMax: 26},
"rxb": {TwoMin: 6, TwoMax: 12},
"8lx": {TwoMin: 14, TwoMax: 27},
"8mx": {TwoMin: 20, TwoMax: 42},
"8hx": {TwoMin: 33, TwoMax: 55},
"8rx": {TwoMin: 14, TwoMax: 32},
"6lx": {TwoMin: 28, TwoMax: 73},
"6mx": {TwoMin: 25, TwoMax: 87},
"6hx": {TwoMin: 32, TwoMax: 91},
"6rx": {TwoMin: 26, TwoMax: 40},
//Javelins (throw damage, should update fields)
"jav": {Min: 6, Max: 14},
"pil": {Min: 7, Max: 20},
"ssp": {Min: 10, Max: 22},
"glv": {Min: 16, Max: 22},
"tsp": {Min: 12, Max: 30},
"9ja": {Min: 14, Max: 32},
"9pi": {Min: 16, Max: 42},
"9s9": {Min: 27, Max: 50},
"9gl": {Min: 32, Max: 60},
"9ts": {Min: 18, Max: 54},
"7ja": {Min: 28, Max: 55},
"7pi": {Min: 21, Max: 75},
"7s7": {Min: 40, Max: 62},
"7gl": {Min: 30, Max: 85},
"7ts": {Min: 11, Max: 77},
// Amazon-only Weapons (throw damage, should update fields)
"am1": {Min: 7, Max: 12},
"am2": {Min: 9, Max: 19},
"am3": {Min: 18, Max: 24},
"am4": {Min: 23, Max: 55},
"am5": {Min: 6, Max: 22},
"am6": {Min: 16, Max: 29},
"am7": {Min: 19, Max: 41},
"am8": {Min: 34, Max: 51},
"am9": {Min: 42, Max: 101},
"ama": {Min: 18, Max: 54},
"amb": {Min: 20, Max: 47},
"amc": {Min: 14, Max: 72},
"amd": {Min: 65, Max: 95},
"ame": {Min: 37, Max: 153},
"amf": {Min: 35, Max: 66},
//Scepters
"scp": {Min: 6, Max: 11},
"gsc": {Min: 8, Max: 18},
"wsp": {Min: 10, Max: 17},
"9sc": {Min: 13, Max: 24},
"9qs": {Min: 14, Max: 36},
"9ws": {Min: 16, Max: 38},
"7sc": {Min: 40, Max: 52},
"7qs": {Min: 45, Max: 54},
"7ws": {Min: 37, Max: 43},
//Spears
"spr": {TwoMin: 3, TwoMax: 15},
"tri": {TwoMin: 9, TwoMax: 15},
"brn": {TwoMin: 7, TwoMax: 17},
"spt": {TwoMin: 15, TwoMax: 23},
"pik": {TwoMin: 14, TwoMax: 63},
"9sr": {TwoMin: 10, TwoMax: 37},
"9tr": {TwoMin: 19, TwoMax: 37},
"9br": {TwoMin: 16, TwoMax: 40},
"9st": {TwoMin: 29, TwoMax: 59},
"9p9": {TwoMin: 27, TwoMax: 114},
"7sr": {TwoMin: 35, TwoMax: 119},
"7tr": {TwoMin: 29, TwoMax: 144},
"7br": {TwoMin: 42, TwoMax: 92},
"7st": {TwoMin: 18, TwoMax: 155},
"7p7": {TwoMin: 33, TwoMax: 178},
//Throwing
"tkf": {Min: 4, Max: 9},
"tax": {Min: 6, Max: 11},
"bkf": {Min: 8, Max: 12},
"bal": {Min: 12, Max: 15},
"9tk": {Min: 11, Max: 24},
"9ta": {Min: 14, Max: 27},
"9bk": {Min: 18, Max: 33},
"9b8": {Min: 24, Max: 34},
"7tk": {Min: 23, Max: 54},
"7bk": {Min: 23, Max: 39},
"7ta": {Min: 15, Max: 66},
"7b8": {Min: 7, Max: 60},
//Daggers
"dgr": {Min: 1, Max: 4},
"dir": {Min: 3, Max: 9},
"kri": {Min: 2, Max: 11},
"bld": {Min: 4, Max: 15},
"9dg": {Min: 6, Max: 18},
"9di": {Min: 10, Max: 26},
"9kr": {Min: 15, Max: 31},
"9bl": {Min: 19, Max: 36},
"7dg": {Min: 23, Max: 49},
"7di": {Min: 37, Max: 53},
"7kr": {Min: 15, Max: 57},
"7bl": {Min: 32, Max: 47},
//Staves
"sst": {TwoMin: 1, TwoMax: 5},
"lst": {TwoMin: 2, TwoMax: 8},
"cst": {TwoMin: 4, TwoMax: 12},
"bst": {TwoMin: 6, TwoMax: 13},
"wst": {TwoMin: 12, TwoMax: 28},
"8ss": {TwoMin: 6, TwoMax: 21},
"8ls": {TwoMin: 8, TwoMax: 26},
"8cs": {TwoMin: 11, TwoMax: 32},
"8bs": {TwoMin: 14, TwoMax: 34},
"8ws": {TwoMin: 24, TwoMax: 58},
"6ss": {TwoMin: 69, TwoMax: 85},
"6ls": {TwoMin: 75, TwoMax: 107},
"6cs": {TwoMin: 80, TwoMax: 93},
"6bs": {TwoMin: 65, TwoMax: 108},
"6ws": {TwoMin: 83, TwoMax: 99},
//Wands
"wnd": {Min: 2, Max: 4},
"ywn": {Min: 2, Max: 8},
"bwn": {Min: 3, Max: 7},
"gwn": {Min: 5, Max: 11},
"9wn": {Min: 8, Max: 18},
"9yw": {Min: 8, Max: 24},
"9bw": {Min: 10, Max: 22},
"9gw": {Min: 13, Max: 29},
"7wn": {Min: 18, Max: 33},
"7yw": {Min: 20, Max: 40},
"7bw": {Min: 10, Max: 31},
"7gw": {Min: 22, Max: 28},
//Orbs
"ob1": {Min: 2, Max: 5},
"ob2": {Min: 3, Max: 8},
"ob3": {Min: 4, Max: 10},
"ob4": {Min: 5, Max: 12},
"ob5": {Min: 8, Max: 18},
"ob6": {Min: 8, Max: 21},
"ob7": {Min: 10, Max: 26},
"ob8": {Min: 11, Max: 29},
"ob9": {Min: 13, Max: 32},
"oba": {Min: 18, Max: 42},
"obb": {Min: 21, Max: 46},
"obc": {Min: 18, Max: 50},
"obd": {Min: 23, Max: 55},
"obe": {Min: 12, Max: 66},
"obf": {Min: 30, Max: 53},
// Assassin Claws
"ktr": {Min: 4, Max: 7},
"wrb": {Min: 5, Max: 9},
"axf": {Min: 2, Max: 15},
"ces": {Min: 7, Max: 15},
"clw": {Min: 8, Max: 15},
"btl": {Min: 10, Max: 14},
"skr": {Min: 9, Max: 17},
"9ar": {Min: 11, Max: 24},
"9wb": {Min: 13, Max: 27},
"9xf": {Min: 8, Max: 37},
"9cs": {Min: 16, Max: 37},
"9lw": {Min: 18, Max: 37},
"9tw": {Min: 21, Max: 35},
"9qr": {Min: 19, Max: 40},
"7ar": {Min: 39, Max: 52},
"7wb": {Min: 34, Max: 45},
"7xf": {Min: 44, Max: 53},
"7cs": {Min: 36, Max: 42},
"7lw": {Min: 22, Max: 53},
"7tw": {Min: 24, Max: 44},
"7qr": {Min: 40, Max: 51},
}
// Item types, used to decide what attribute to give an item socketed with
// gems or runes mostly.
const (
armor = 0x01
shield = 0x02
weapon = 0x03
other = 0x04
)
// Item location IDs.
const (
stored = 0x00
equipped = 0x01
belt = 0x02
cursor = 0x04
socketed = 0x06
)
// Rarity IDs.
const (
lowQuality = 0x01
normal = 0x02
highQuality = 0x03
magicallyEnhanced = 0x04
partOfSet = 0x05
rare = 0x06
unique = 0x07
crafted = 0x08
)
// Each set item has 5 bits of data containing the number of set lists follow
// the magical attributes list, this map tells us how many lists to read
// depending on the value given from the 5 bits. A number of 0-5 set lists.
var setListMap = map[uint64]uint64{
0: 0,
1: 1,
2: 1,
3: 2,
4: 1,
6: 2,
7: 3,
10: 2,
12: 2,
15: 4,
31: 5,
}
// Certain set items (only Civerb's Ward in unmodded D2) have bonuses
// that require certain other set items in order to be activated
// (instead of the normal requirements of just 'wearing > x of any
// items in the set'); determined by add_func=1 in SetItems.txt
var setReqIDsMap = map[uint64][]uint64{
// Civerb's Ward: [Civerb's Icon, Civerb's Cudgel]
0: []uint64{1, 2},
}
// All item types that contain the quantity bits will exist in here,
// we'll use this when reading items to make sure we only read quantity bits
// when they exist, or we'll ruin the rest of the bit offsets for the item.
var quantityMap = map[string]bool{
//Misc
"tbk": true,
"ibk": true,
"key": true,
"gps": true,
"ops": true,
"gpm": true,
"opm": true,
"gpl": true,
"opl": true,
"aqv": true,
"cqv": true,
//Throwables
"tkf": true,
"tax": true,
"bkf": true,
"bal": true,
"9tk": true,
"9ta": true,
"9bk": true,
"9b8": true,
"7tk": true,
"7ta": true,
"7bk": true,
"7b8": true,
//Javelins
"jav": true,
"pil": true,
"ssp": true,
"glv": true,
"tsp": true,
"9ja": true,
"9pi": true,
"9s9": true,
"9gl": true,
"9ts": true,
"7ja": true,
"7pi": true,
"7s7": true,
"7gl": true,
"7ts": true,
"am5": true,
"ama": true,
"amf": true,
}
// Items that are tomes contain 5 extra bits, so we need to keep track of what
// items are tomes, and read the bits accordingly.
var tomeMap = map[string]bool{
"tbk": true,
"ibk": true,
}
var magicalProperties = map[uint64]magicalProperty{
0: {Bits: []uint{8}, Bias: 32, Name: "+{0} to Strength"},
1: {Bits: []uint{7}, Bias: 32, Name: "+{0} to Energy"},
2: {Bits: []uint{7}, Bias: 32, Name: "+{0} to Dexterity"},
3: {Bits: []uint{7}, Bias: 32, Name: "+{0} to Vitality"},
7: {Bits: []uint{9}, Bias: 32, Name: "+{0} to Life"},
9: {Bits: []uint{8}, Bias: 32, Name: "+{0} to Mana"},
11: {Bits: []uint{8}, Bias: 32, Name: "+{0} to Maximum Stamina"},
16: {Bits: []uint{9}, Name: "+{0}% Enhanced Defense"},
// It's weird that there's two bit fields here, but it seems like
// the first bit field enhanced min damage, and the second enchances
// maxium damage.
17: {Bits: []uint{9, 9}, Name: "+{0}% Enhanced Damage"},
19: {Bits: []uint{10}, Name: "+{0} to Attack rating"},
20: {Bits: []uint{6}, Name: "+{0}% Increased chance of blocking"},
21: {Bits: []uint{6}, Name: "+{0} to Minimum 1-handed damage"},
22: {Bits: []uint{7}, Name: "+{0} to Maximum 1-handed damage"},
23: {Bits: []uint{6}, Name: "+{0} to Minimum 2-handed damage"},
24: {Bits: []uint{7}, Name: "+{0} to Maximum 2-handed damage"},
25: {Bits: []uint{8}, Name: "Unknown (Invisible)"}, // damagepercent
26: {Bits: []uint{8}, Name: "Unknown (Invisible)"}, // manarecovery
27: {Bits: []uint{8}, Name: "Regenerate Mana {0}%"},
28: {Bits: []uint{8}, Name: "Heal Stamina {0}%"},
31: {Bits: []uint{11}, Bias: 10, Name: "+{0} Defense"},
32: {Bits: []uint{9}, Name: "+{0} vs. Missile"},
33: {Bits: []uint{8}, Bias: 10, Name: "+{0} vs. Melee"},
34: {Bits: []uint{6}, Name: "Damage Reduced by {0}"},
35: {Bits: []uint{6}, Name: "Magic Damage Reduced by {0}"},
36: {Bits: []uint{8}, Name: "Damage Reduced by {0}%"},
37: {Bits: []uint{8}, Name: "Magic Resist +{0}%"},
38: {Bits: []uint{8}, Name: "+{0}% to Maximum Magic Resist"},
39: {Bits: []uint{8}, Bias: 50, Name: "Fire Resist +{0}%"},
40: {Bits: []uint{5}, Name: "+{0}% to Maximum Fire Resist"},
41: {Bits: []uint{8}, Bias: 50, Name: "Lightning Resist +{0}%"},
42: {Bits: []uint{5}, Name: "+{0}% to Maximum Lightning Resist"},
43: {Bits: []uint{8}, Bias: 50, Name: "Cold Resist +{0}%"},
44: {Bits: []uint{5}, Name: "+{0}% to Maximum Cold Resist"},
45: {Bits: []uint{8}, Bias: 50, Name: "Poison Resist +{0}%"},
46: {Bits: []uint{5}, Name: "+{0}% to Maximum Poison Resist"},
48: {Bits: []uint{8, 9}, Name: "Adds {0}-{1} Fire Damage"},
49: {Bits: []uint{9}, Name: "+{0} to Maximum Fire Damage"},
50: {Bits: []uint{6, 10}, Name: "Adds {0}-{1} Lightning Damage"},
52: {Bits: []uint{8, 9}, Name: "Adds {0}-{1} Magic Damage"},
54: {Bits: []uint{8, 9, 8}, Name: "Adds {0}-{1} Cold Damage"},
57: {Bits: []uint{10, 10, 9}, Name: "Adds {0}-{1} Poison Damage over {2} Seconds"},
60: {Bits: []uint{7}, Name: "{0}% Life Stolen Per Hit"},
62: {Bits: []uint{7}, Name: "{0}% Mana Stolen Per Hit"},
67: {Bits: []uint{7}, Bias: 30, Name: "Unknown (Invisible)"}, // velocitypercent
68: {Bits: []uint{7}, Bias: 30, Name: "Unknown (Invisible)"}, // attackrate
71: {Bits: []uint{8}, Bias: 100, Name: "Unknown (Invisible)"}, // value
72: {Bits: []uint{9}, Name: "Unknown (Invisible)"}, // durability
73: {Bits: []uint{8}, Name: "+{0} Maximum Durability"},
74: {Bits: []uint{6}, Bias: 30, Name: "Replenish Life +{0}"},
75: {Bits: []uint{7}, Bias: 20, Name: "Increase Maximum Durability {0}%"},
76: {Bits: []uint{6}, Bias: 10, Name: "Increase Maximum Life {0}%"},
77: {Bits: []uint{6}, Bias: 10, Name: "Increase Maximum Mana {0}%"},
78: {Bits: []uint{7}, Name: "Attacker Takes Damage of {0}"},
79: {Bits: []uint{9}, Bias: 100, Name: "{0}% Extra Gold from Monsters"},
80: {Bits: []uint{8}, Bias: 100, Name: "{0}% Better Chance of Getting Magic Items"},
81: {Bits: []uint{7}, Name: "Knockback"},
82: {Bits: []uint{9}, Bias: 20, Name: "Unknown (Invisible)"}, // item_timeduration
// First value is class, second is skill level, but they're printed in reverse
// e.g. "+3 To Sorceress Skill Levels"
83: {Bits: []uint{3, 3}, Name: "+{1} to {0} Skill Levels"},
84: {Bits: []uint{3, 3}, Name: "+{1} to {0} Skill Levels"},
// TODO: Check if experience gained really have a bias of 50.
85: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Experience Gained"},
86: {Bits: []uint{7}, Name: "+{0} Life After Each Kill"},
87: {Bits: []uint{7}, Name: "Reduces Prices {0}%"},
88: {Bits: []uint{1}, Name: "Unknown (Invisible)"}, // item_doubleherbduration
89: {Bits: []uint{4}, Bias: 4, Name: "+{0} to Light Radius"},
// This property is not displayed on the item, but its effect is to alter
// the color of the ambient light.
90: {Bits: []uint{5}, Name: "Ambient light"},
// After subtracting the bias, this is usually a negative number.
91: {Bits: []uint{8}, Bias: 100, Name: "Requirements {0}%"},
92: {Bits: []uint{7}, Name: "Level requirements +{0} (Invisible)"},
93: {Bits: []uint{7}, Bias: 20, Name: "{0}% Increased Attack Speed"},
94: {Bits: []uint{7}, Bias: 64, Name: "Unknown (Invisible)"}, // item_levelreqpct
96: {Bits: []uint{7}, Bias: 20, Name: "{0}% Faster Run/Walk"},
// Number of levels to a certain skill, e.g. +1 To Teleport.
97: {Bits: []uint{9, 6}, Name: "+{1} To {0}"},
// NVSTATE Charm attributes. ID 98 only occurs on charms of a special
// type, called NV state charms, they're basically for visual effects.
// They're imported charms and does not occur naturally in the game.
98: {Bits: []uint{8, 1}, Name: "{1}+ to {0} (Visual effect only)"},
99: {Bits: []uint{7}, Bias: 20, Name: "{0}% Faster Hit Recovery"},
102: {Bits: []uint{7}, Bias: 20, Name: "{0}% Faster Block Rate"},
105: {Bits: []uint{7}, Bias: 20, Name: "{0}% Faster Cast Rate"},
// These properties usually applied to class specific items,
// first value selects the skill, the second determines how many
// additional skill points are given.
107: {Bits: []uint{9, 3}, Name: "+{1} To {0}"},
108: {Bits: []uint{1}, Name: "Rest In Peace"},
109: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
181: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
182: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
183: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
184: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
185: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
186: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
187: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
110: {Bits: []uint{8}, Bias: 20, Name: "Poison Length Reduced by {0}%"},
111: {Bits: []uint{9}, Bias: 20, Name: "Damage +{0}"},
112: {Bits: []uint{7}, Name: "Hit Causes Monsters to Flee {0}%"},
113: {Bits: []uint{7}, Name: "Hit Blinds Target +{0}"},
114: {Bits: []uint{6}, Name: "{0}% Damage Taken Goes to Mana"},
// The value of the data field is always 1.
115: {Bits: []uint{1}, Name: "Ignore Target Defense"},
116: {Bits: []uint{7}, Name: "{0}% Target Defense"},
// The value of the data field is always 1.
117: {Bits: []uint{7}, Name: "Prevent Monster Heal"},
// The value of the data field is always 1.
118: {Bits: []uint{1}, Name: "Half Freeze Duration"},
119: {Bits: []uint{9}, Bias: 20, Name: "{0}% Bonus to Attack Rating"},
120: {Bits: []uint{7}, Bias: 128, Name: "{0} to Monster Defense Per Hit"},
121: {Bits: []uint{9}, Bias: 20, Name: "+{0}% Damage to Demons"},
122: {Bits: []uint{9}, Bias: 20, Name: "+{0}% Damage to Undead"},
123: {Bits: []uint{10}, Bias: 128, Name: "+{0} to Attack Rating against Demons"},
124: {Bits: []uint{10}, Bias: 128, Name: "+{0} to Attack Rating against Undead"},
125: {Bits: []uint{1}, Name: "Throwable"},
// First value is class id, the next one is skill tree
126: {Bits: []uint{3, 3}, Name: "+{0} to Fire Skills"},
127: {Bits: []uint{3}, Name: "+{0} to All Skill Levels"},
128: {Bits: []uint{5}, Name: "Attacker Takes Lightning Damage of {0}"},
134: {Bits: []uint{5}, Name: "Freezes Target +{0}"},
135: {Bits: []uint{7}, Name: "{0}% Chance of Open Wounds"},
136: {Bits: []uint{7}, Name: "{0}% Chance of Crushing Blow"},
137: {Bits: []uint{7}, Name: "+{0} Kick Damage"},
138: {Bits: []uint{7}, Name: "+{0} to Mana After Each Kill"},
139: {Bits: []uint{7}, Name: "+{0} Life after each Demon Kill"},
// Unknown property, shows up on Swordback Hold Spiked Shield.
140: {Bits: []uint{7}, Name: "Extra Blood (Invisible)"}, // item_extrablood
141: {Bits: []uint{7}, Name: "{0}% Deadly Strike"},
142: {Bits: []uint{7}, Name: "Fire Absorb {0}%"},
143: {Bits: []uint{7}, Name: "+{0} Fire Absorb"},
144: {Bits: []uint{7}, Name: "Lightning Absorb {0}%"},
145: {Bits: []uint{7}, Name: "+{0} Lightning Absorb"},
146: {Bits: []uint{7}, Name: "Magic Absorb {0}%"},
147: {Bits: []uint{7}, Name: "+{0} Magic Absorb"},
148: {Bits: []uint{7}, Name: "Cold Absorb {0}%"},
149: {Bits: []uint{7}, Name: "+{0} Cold Absorb"},
150: {Bits: []uint{7}, Name: "Slows Target by {0}%"},
151: {Bits: []uint{9, 5}, Name: "Level +{1} {0} When Equipped"},
152: {Bits: []uint{1}, Name: "Indestructible"},
153: {Bits: []uint{1}, Name: "Cannot Be Frozen"},
154: {Bits: []uint{7}, Bias: 20, Name: "{0}% Slower Stamina Drain"},
155: {Bits: []uint{10, 7}, Name: "{0}% Chance to Reanimate Target"},
156: {Bits: []uint{7}, Name: "Piercing Attack"},
157: {Bits: []uint{7}, Name: "Fires Magic Arrows"},
158: {Bits: []uint{7}, Name: "Fires Explosive Arrows or Bolts"},
159: {Bits: []uint{6}, Name: "+{0} to Minimum Throw Damage"},
160: {Bits: []uint{7}, Name: "+{0} to Maximum Throw Damage"},
179: {Bits: []uint{3}, Name: "+{0} to Druid Skill Levels"},
180: {Bits: []uint{3}, Name: "+{0} to Assassin Skill Levels"},
// Ok so get this, this is quite complicated, the id 188 is for items with
// + x to a certain skill tree, e.g. 1 + to defensive auras (paladin).
//
// So here's how it works, the field is 19 bits long, here's the bits for
// the defensive auras skiller.
//
// 001 0000000000 011 010
// ^ ^ ^ ^
// levels unknown padding class id skill tree offset
//
// So in the above example, the first 3 bits 001 are the + levels (1), we'll
// ignore the padding, the second interesting set of 3 bits is the class id.
// Refer to the class.go for class ids, but paladin is 011 (3), and the
// last 3 bits 010 (2) is the offset from the start of the class skill tree.
// Refer to skills.go to find the different tree offsets. Paladin offset is
// 9. So remember the last 3 bits 010 (2), that means the skill tree is
// 9 + 2 = 11, aka the defensive auras tree.
//
// When reading the values, remember the bits are read from the right,
// so the values will be [2 3 1], offset 2, class id 3, 1 + to skills.
188: {Bits: []uint{3, 13, 3}, Name: "+{2} to {0} Skills ({1} only)"},
189: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
190: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
191: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
192: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
193: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
194: {Bits: []uint{4}, Name: "Adds {0} extra sockets to the item"},
// Order is spell id, level, % chance.
195: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When you die"},
196: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When you die"},
197: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When you die"},
// Order is spell id, level, % chance.
198: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} On Striking"},
199: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} On Striking"},
200: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} On Striking"},
// Order is spell id, level, % chance.
201: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When Struck"},
202: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When Struck"},
203: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When Struck"},
// First value selects the spell id, second value is level, third is remaining charges
// and the last is the total number of charges.
204: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
205: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
206: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
207: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
208: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
209: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
210: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
211: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
212: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
213: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
// All values based on character level are stored in eights, so take
// the number divide by 8 and multiply by the character level and round down.
// Or, just do (value * 0.125)% per level.
214: {Bits: []uint{6}, Name: "+{0} to Defense (Based on Character Level)"},
215: {Bits: []uint{6}, Name: "{0}% Enhanced Defense (Based on Character Level)"},
216: {Bits: []uint{6}, Name: "+{0} to Life (Based on Character Level)"},
217: {Bits: []uint{6}, Name: "+{0} to Mana (Based on Character Level)"},
218: {Bits: []uint{6}, Name: "+{0} to Maximum Damage (Based on Character Level)"},
219: {Bits: []uint{6}, Name: "{0}% Enhanced Maximum Damage (Based on Character Level)"},
220: {Bits: []uint{6}, Name: "+{0} to Strength (Based on Character Level)"},
221: {Bits: []uint{6}, Name: "+{0} to Dexterity (Based on Character Level)"},
222: {Bits: []uint{6}, Name: "+{0} to Energy (Based on Character Level)"},
223: {Bits: []uint{6}, Name: "+{0} to Vitality (Based on Character Level)"},
224: {Bits: []uint{6}, Name: "+{0} to Attack Rating (Based on Character Level)"},
225: {Bits: []uint{6}, Name: "{0}% Bonus to Attack Rating (Based on Character Level)"},
226: {Bits: []uint{6}, Name: "+{0} Cold Damage (Based on Character Level)"},
227: {Bits: []uint{6}, Name: "+{0} Fire Damage (Based on Character Level)"},
228: {Bits: []uint{6}, Name: "+{0} Lightning Damage (Based on Character Level)"},
229: {Bits: []uint{6}, Name: "+{0} Poison Damage (Based on Character Level)"},
230: {Bits: []uint{6}, Name: "Cold Resist +{0}% (Based on Character Level)"},
231: {Bits: []uint{6}, Name: "Fire Resist +{0}% (Based on Character Level)"},
232: {Bits: []uint{6}, Name: "Lightning Resist +{0}% (Based on Character Level)"},
233: {Bits: []uint{6}, Name: "Poison Resist +{0}% (Based on Character Level)"},
234: {Bits: []uint{6}, Name: "+{0} Cold Absorb (Based on Character Level)"},
235: {Bits: []uint{6}, Name: "+{0} Fire Absorb (Based on Character Level)"},
236: {Bits: []uint{6}, Name: "+{0} Lightning Absorb (Based on Character Level)"},
237: {Bits: []uint{6}, Name: "{0} Poison Absorb (Based on Character Level)"},
238: {Bits: []uint{5}, Name: "Attacker Takes Damage of {0} (Based on Character Level)"},
239: {Bits: []uint{6}, Name: "{0}% Extra Gold from Monsters (Based on Character Level)"},
240: {Bits: []uint{6}, Name: "{0}% Better Chance of Getting Magic Items (Based on Character Level)"},
241: {Bits: []uint{6}, Name: "Heal Stamina Plus {0}% (Based on Character Level)"},
242: {Bits: []uint{6}, Name: "+{0} Maxmium Stamina (Based on Character Level)"},
243: {Bits: []uint{6}, Name: "{0}% Damage to Demons (Based on Character Level)"},
244: {Bits: []uint{6}, Name: "{0}% Damage to Undead (Based on Character Level)"},
245: {Bits: []uint{6}, Name: "+{0} to Attack Rating against Demons (Based on Character Level)"},
246: {Bits: []uint{6}, Name: "+{0} to Attack Rating against Undead (Based on Character Level)"},
247: {Bits: []uint{6}, Name: "{0}% Chance of Crushing Blow (Based on Character Level)"},
248: {Bits: []uint{6}, Name: "{0}% Chance of Open Wounds (Based on Character Level)"},
249: {Bits: []uint{6}, Name: "+{0} Kick Damage (Based on Character Level)"},
250: {Bits: []uint{6}, Name: "{0}% to Deadly Strike (Based on Character Level)"},
// The value of the data field is not actually a time period, but a frequency in terms
// of the number of times durability is repaired over a period of 100 seconds.
// For example, if the value is 5, then this property repairs 1 durability in 100 / 5 = 20 seconds.
252: {Bits: []uint{6}, Name: "Repairs 1 Durability in {0} Seconds"},
// As in the previous property, the value of the data field is a frequency in terms of the number
// replenished over a period of 100 seconds. For example if the value is 4, then this property
// replenishes 1 item in 100 / 4 = 25 seconds.
253: {Bits: []uint{6}, Name: "Replenishes Quantity"},
// Number of additional items beyond the base limit, for example if the base
// is 50 and additional is 30, then the total is 50 + 30.
254: {Bits: []uint{8}, Name: "Increased Stack Size"},
// IDs 268 - 303 are some weird values that were never used in the actual game.
// These values change depending on the time of day in the game.
// The format of the bit fields are the same in all cases, the first 2 bits
// specifies the the of time when the value is at its maximum.
//
// The second and third are respectively the minimum and maximum values of the property.
// The maximum value at the time specified and the minimum at the opposite.
305: {Bits: []uint{8}, Bias: 50, Name: "{0} Pierce Cold"},
306: {Bits: []uint{8}, Bias: 50, Name: "{0} Pierce Fire"},
307: {Bits: []uint{8}, Bias: 50, Name: "{0} Pierce Lightning"},
308: {Bits: []uint{8}, Bias: 50, Name: "{0} Pierce Poision"},
324: {Bits: []uint{6}, Name: "Unknown (Invisible)"}, // item_extra_charges
329: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Fire Skill Damage"},
330: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Lightning Skill Damage"},
331: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Cold Skill Damage"},
332: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Poison Skill Damage"},
333: {Bits: []uint{8}, Name: "-{0}% To Enemy Fire Resistance"},
334: {Bits: []uint{8}, Name: "-{0}% To Enemy Lightning Resistance"},
335: {Bits: []uint{8}, Name: "-{0}% To Enemy Cold Resistance"},
336: {Bits: []uint{8}, Name: "-{0}% To Enemy Poison Resistance"},
356: {Bits: []uint{2}, Name: "Quest Item Difficulty +{0} (Invisible)"},
}
// Shield codes
var shieldCodes = map[string]string{
"uow": "Aegis",
"pa4": "Aerin Shield",
"pa7": "Akaran Rondache",
"pa6": "Akaran Targe",
"pad": "Kurast Shield",
"xts": "Ancient Shield",
"xpk": "Barbed Shield",
"upk": "Blade Barrier",
"nef": "Bloodlord Skull",
"bsh": "Bone Shield",
"buc": "Buckler",
"ne9": "Cantor Trophy",
"pa5": "Crown Shield",
"xuc": "Defender",
"ne5": "Demon Head",
"xit": "Dragon Shield",
"ne7": "Fetish Trophy",
"ne4": "Gargoyle Head",
"gts": "Gothic Shield",
"xsh": "Grim Shield",
"pa9": "Gilded Shield",
"nea": "Heirophant Trophy",
"uuc": "Heater",
"neg": "Hellspawn Skull",
"pa3": "Heraldic Shield",
"kit": "Kite Shield",
"lrg": "Large Shield",
"uml": "Luna",
"neb": "Minion Skull",
"uit": "Monarch",
"ne6": "Mummified Trophy",
"ned": "Overseer Skull",
"xow": "Pavise",
"ne1": "Preserved Head",
"pa8": "Protector Shield",
"pa2": "Rondache",
"xml": "Round Shield",
"paa": "Royal Shield",
"pac": "Sacred Rondache",
"pab": "Sacred Targe",
"xrg": "Scutum",
"ne8": "Sexton Trophy",
"sml": "Small Shield",
"spk": "Spiked Shield",
"nee": "Succubus Skull",
"pa1": "Targe",
"tow": "Tower Shield",
"ush": "Troll Nest",
"ne3": "Unraveller Head",
"paf": "Vortex Shield",
"uts": "Ward",
"pae": "Zakarum Shield",
"ne2": "Zombie Head",
}
// Armor codes.
var armorCodes = map[string]string{
"dr6": "Alpha Helm",
"aar": "Ancient Armor",
"dr3": "Antlers",
"utp": "Archon Plate",
"ulm": "Armet",
"ba4": "Assault Helmet",
"ba5": "Avenger Guard",
"upl": "Balrog Skin",
"xhl": "Basinet",
"ztb": "Battle Belt",
"xtb": "Battle Boots",
"xtg": "Battle Gauntlets",
"mbl": "Belt",
"drb": "Blood Spirit",
"bhm": "Bone Helm",
"uh9": "Bone Visage",
"uhn": "Boneweave",
"umb": "Boneweave Boots",
"mgl": "Bracers",
"ulg": "Bramble Mitts",
"brs": "Breast Plate",
"cap": "Cap",
"bab": "Carnage Helm",
"xlm": "Casque",
"mbt": "Chain Boots",
"chn": "Chain Mail",
"xul": "Chaos Armor",
"ci0": "Circlet",
"uhc": "Colossus Girdle",
"bae": "Conqueror Crown",
"urn": "Corona",
"ci1": "Coronet",
"crn": "Crown",
"utg": "Crusader Gauntlets",
"xrs": "Cuirass",
"xsk": "Death Mask",
"usk": "Demonhead",
"xla": "Demonhide Armor",
"xlb": "Demonhide Boots",
"xlg": "Demonhide Gloves",
"zlb": "Demonhide Sash",
"bad": "Destroyer Helm",
"ci3": "Diadem",
"ung": "Diamond Mail",
"drf": "Dream Spirit",
"uui": "Dusk Shroud",
"drd": "Earth Spirit",
"xth": "Embossed Plate",
"dr4": "Falcon Mask",
"ba2": "Fanged Helm",
"fld": "Field Plate",
"fhl": "Full Helm",
"plt": "Plate Mail",
"ful": "Full Plate Mail",
"bac": "Fury Visor",
"hgl": "Gauntlets",
"xui": "Ghost Armor",
"uhl": "Giant Conch",
"hbl": "Girdle",
"lgl": "Gloves",
"gth": "Gothic Plate",
"xrn": "Grand Crown",
"urs": "Great Hauberk",
"ghm": "Great Helm",
"dr7": "Griffon Headress",
"xh9": "Grim Helm",
"baf": "Guardian Crown",
"hla": "Hard Leather Armor",
"dr2": "Hawk Helm",
"tbl": "Heavy Belt",
"vbt": "Heavy Boots",
"xmg": "Heavy Bracers",
"vgl": "Heavy Gloves",
"ult": "Hellforged Plate",
"hlm": "Helm",
"ba3": "Horned Helm",
"dr8": "Hunter's Guise",
"ukp": "Hydraskull",
"urg": "Hyperion",
"ba1": "Jawbone Cap",
"ba6": "Jawbone Visor",
"uld": "Kraken Shell",
"uth": "Lacquered Plate",
"lea": "Leather Armor",
"lbt": "Leather Boots",
"vbl": "Light Belt",
"tgl": "Light Gauntlets",
"ltp": "Light Plate",
"tbt": "Light Plated Boots",
"xng": "Linked Mail",
"ba7": "Lion Helm",
"ucl": "Loricated Mail",
"xtp": "Mage Plate",
"msk": "Mask",