Commit 0b3dc28ee3ef1ac06307c6ad5abbaabedaaae142

Authored by Imanol-Mikel Barba Sabariego
1 parent e60e5172

renamed isfemale. moved D2S_DIFFICULTY to new d2common.h to break cyclic depende…

…ncies. added d2item prototype functions. started work on d2item definitions. reworked D2Merc into struct with get/set methods. reworked D2Quest into struct with get/set methods. minor docs fixes
d2char.c
... ... @@ -72,7 +72,7 @@ void setLadder(D2CharHeader* c, int bool) {
72 72 }
73 73 }
74 74  
75   -int isFemale(D2CharHeader* c) {
  75 +int _isFemale(D2CharHeader* c) {
76 76 return (c->charClass == D2S_CHARCLASS_AMAZON ||
77 77 c->charClass == D2S_CHARCLASS_ASSASSIN ||
78 78 c->charClass == D2S_CHARCLASS_SORCERESS);
... ... @@ -107,7 +107,7 @@ const char* getCharacterTitle(D2CharHeader* c) {
107 107 return D2S_CHARPROGRESS_EXPANSION_TIER2_NAME;
108 108 break;
109 109 case D2S_DIFFICULTY_HELL:
110   - return isFemale(c) ? D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_F : D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_M;
  110 + return _isFemale(c) ? D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_F : D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_M;
111 111 break;
112 112 }
113 113 }
... ... @@ -117,26 +117,26 @@ const char* getCharacterTitle(D2CharHeader* c) {
117 117 // Classic Hardcore
118 118 switch(hardestCleared) {
119 119 case D2S_DIFFICULTY_NORMAL:
120   - return isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_HARDCORE_F : D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_HARDCORE_M;
  120 + return _isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_HARDCORE_F : D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_HARDCORE_M;
121 121 break;
122 122 case D2S_DIFFICULTY_NIGHTMARE:
123   - return isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_HARDCORE_F : D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_HARDCORE_M;
  123 + return _isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_HARDCORE_F : D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_HARDCORE_M;
124 124 break;
125 125 case D2S_DIFFICULTY_HELL:
126   - return isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_HARDCORE_F : D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_HARDCORE_M;
  126 + return _isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_HARDCORE_F : D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_HARDCORE_M;
127 127 break;
128 128 }
129 129 } else {
130 130 // Classic Softcore
131 131 switch(hardestCleared) {
132 132 case D2S_DIFFICULTY_NORMAL:
133   - return isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_F : D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_M;
  133 + return _isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_F : D2S_CHARPROGRESS_CLASSIC_TIER1_NAME_M;
134 134 break;
135 135 case D2S_DIFFICULTY_NIGHTMARE:
136   - return isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_F : D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_M;
  136 + return _isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_F : D2S_CHARPROGRESS_CLASSIC_TIER2_NAME_M;
137 137 break;
138 138 case D2S_DIFFICULTY_HELL:
139   - return isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_F : D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_M;
  139 + return _isFemale(c) ? D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_F : D2S_CHARPROGRESS_CLASSIC_TIER3_NAME_M;
140 140 break;
141 141 }
142 142 }
... ...
d2char.h
... ... @@ -6,6 +6,7 @@
6 6 #include <string.h>
7 7 #include <time.h>
8 8  
  9 +#include "d2common.h"
9 10 #include "d2quest.h"
10 11 #include "d2strings.h"
11 12 #include "d2waypoints.h"
... ... @@ -26,15 +27,6 @@
26 27 #define D2S_CHARSTATUS_EXPANSION 0x20
27 28 #define D2S_CHARSTATUS_LADDER 0x40
28 29  
29   -#define D2S_DIFFICULTY_ACTIVE 0x80
30   -
31   -typedef enum D2S_DIFFICULTY {
32   - D2S_DIFFICULTY_UNKNOWN = -1,
33   - D2S_DIFFICULTY_NORMAL = 0,
34   - D2S_DIFFICULTY_NIGHTMARE = 1,
35   - D2S_DIFFICULTY_HELL = 2
36   -} D2S_DIFFICULTY;
37   -
38 30 typedef enum D2S_VERSION {
39 31 VER_106 = 71,
40 32 VER_107 = 87,
... ... @@ -121,8 +113,6 @@ void setExpansion(D2CharHeader* c, int bool);
121 113 int isLadder(D2CharHeader* c);
122 114 void setLadder(D2CharHeader* c, int bool);
123 115  
124   -int isFemale(D2CharHeader* c);
125   -
126 116 // Returns static string from library memory, no need to free
127 117 const char* getCharacterTitle(D2CharHeader* c);
128 118  
... ... @@ -130,11 +120,9 @@ const char* getCharacterTitle(D2CharHeader* c);
130 120 size_t getLastPlayed(D2CharHeader* c, char* buf, size_t bufLen);
131 121  
132 122 // This is the last difficulty played, not the highest available. For that, use getProgress()
133   -// 0 = Normal, 2 = Hell
134 123 D2S_DIFFICULTY getCurrentDifficulty(D2CharHeader* c);
135 124  
136 125 // This is the last act played, not the highest available. For that, use getProgress()
137   -// 0 = Act I, 4 = Act V (Expansion)
138 126 D2S_ACT getCurrentAct(D2CharHeader* c);
139 127  
140 128 void getProgress(D2CharHeader* c, D2S_ACT* act, D2S_DIFFICULTY* difficulty);
... ...
d2common.h 0 → 100644
  1 +#ifndef D2COMMON_H
  2 +#define D2COMMON_H
  3 +
  4 +#define D2S_DIFFICULTY_ACTIVE 0x80
  5 +
  6 +typedef enum D2S_DIFFICULTY {
  7 + D2S_DIFFICULTY_UNKNOWN = -1,
  8 + D2S_DIFFICULTY_NORMAL = 0,
  9 + D2S_DIFFICULTY_NIGHTMARE = 1,
  10 + D2S_DIFFICULTY_HELL = 2
  11 +} D2S_DIFFICULTY;
  12 +
  13 +#endif
0 14 \ No newline at end of file
... ...
d2item.c
... ... @@ -2,6 +2,38 @@
2 2  
3 3 #define readBits(start,size) ((*((unsigned long *) &data[(start) / 8]) >> ((start) & 7)) & ((1 << (size)) - 1))
4 4  
5   -const char* getItemName(D2S_ITEMDATA_IDENTIFIER itemID) {
6   - // TODO (LONG!z)
  5 +// This function translates the item identifiers (the 4
  6 +// character item ID used by the game, to an internal,
  7 +// sequential ID used for more efficient lookups instead
  8 +// of looping to find a match)
  9 +unsigned int _getItemIndex(D2S_ITEMDATA_IDENTIFIER itemID) {
  10 + // TODO (LONG!)
  11 +}
  12 +
  13 +void* _exportItemData(D2Item* item) {
  14 + // TODO
  15 +}
  16 +
  17 +void* _findInventoryClassOffset(D2S_INVENTORYCLASS inv, void* charData, size_t dataLen) {
  18 + // TODO
  19 +}
  20 +
  21 +D2Item getItem(D2S_INVENTORYCLASS inv, unsigned int offset, void* charData, size_t dataLen) {
  22 + // TODO
  23 +}
  24 +
  25 +int setItem(D2S_INVENTORYCLASS inv, unsigned int offset, D2Item* item, void* charData, size_t dataLen) {
  26 + // TODO
  27 +}
  28 +
  29 +int exportItem(D2Item* item, const char* filename) {
  30 + // TODO
  31 +}
  32 +
  33 +int importItem(D2Item* item, const char* filename) {
  34 + // TODO
  35 +}
  36 +
  37 +void printItem(D2Item* item) {
  38 + // TODO
7 39 }
8 40 \ No newline at end of file
... ...
d2item.h
... ... @@ -6,17 +6,31 @@
6 6 #include <stdint.h>
7 7 #include <stdlib.h>
8 8  
9   -// TODO: Find out set identifiers
10   -// TODO: Find out Unique identifiers
11   -// TODO: Find out rune word identifiers
12   -// TODO: Get magic prefixes and suffixes
13   -// TODO: Get rare name1 and name2 sets
14   -// TODO: Find out magical attributes
15   -
16 9 #define D2S_ITEMDATA_HEADER_LENGTH 2
17 10 #define D2S_ITEMDATA_NUMIDENTIFIERS 638
18 11 #define D2S_ITEMDATA_IDENTIFIER_LENGTH 4
19 12  
  13 +typedef enum D2S_ITEMDATA_LOCATION {
  14 + D2S_ITEMDATA_LOCATION_UNKNOWN = -1,
  15 + D2S_ITEMDATA_LOCATION_STORED = 0,
  16 + D2S_ITEMDATA_LOCATION_EQUIPPED,
  17 + D2S_ITEMDATA_LOCATION_BELT,
  18 + D2S_ITEMDATA_LOCATION_CURSOR,
  19 + D2S_ITEMDATA_LOCATION_SOCKETED
  20 +} D2S_ITEMDATA_LOCATION;
  21 +
  22 +typedef enum D2S_ITEMDATA_RARITY {
  23 + D2S_ITEMDATA_RARITY_UNKNOWN = -1,
  24 + D2S_ITEMDATA_RARITY_LOWQUALITY = 0,
  25 + D2S_ITEMDATA_RARITY_NORMAL,
  26 + D2S_ITEMDATA_RARITY_HIGHQUALITY,
  27 + D2S_ITEMDATA_RARITY_MAGICAL,
  28 + D2S_ITEMDATA_RARITY_SET,
  29 + D2S_ITEMDATA_RARITY_RARE,
  30 + D2S_ITEMDATA_RARITY_UNIQUE,
  31 + D2S_ITEMDATA_RARITY_CRAFTED
  32 +} D2S_ITEMDATA_RARITY;
  33 +
20 34 typedef enum D2S_ITEMDATA_IDENTIFIER {
21 35 D2S_ITEMDATA_IDENTIFIER_CAP = 0x20706163,
22 36 D2S_ITEMDATA_IDENTIFIER_WAR_HAT = 0x20706178,
... ... @@ -659,17 +673,2073 @@ typedef enum D2S_ITEMDATA_IDENTIFIER {
659 673 } D2S_ITEMDATA_IDENTIFIER;
660 674  
661 675 typedef enum D2S_ITEMDATA_SET_IDENTIFIER {
662   - TODO = 0
  676 + D2S_ITEMDATA_SETITEM_UNKNOWN = -1,
  677 + D2S_ITEMDATA_SETITEM_CIVERBS_WARD = 0,
  678 + D2S_ITEMDATA_SETITEM_CIVERBS_ICON,
  679 + D2S_ITEMDATA_SETITEM_CIVERBS_CUDGEL,
  680 + D2S_ITEMDATA_SETITEM_HSARUS_IRON_HEEL,
  681 + D2S_ITEMDATA_SETITEM_HSARUS_IRON_FIST,
  682 + D2S_ITEMDATA_SETITEM_HSARUS_IRON_STAY,
  683 + D2S_ITEMDATA_SETITEM_CLEGLAWS_TOOTH,
  684 + D2S_ITEMDATA_SETITEM_CLEGLAWS_CLAW,
  685 + D2S_ITEMDATA_SETITEM_CLEGLAWS_PINCERS,
  686 + D2S_ITEMDATA_SETITEM_IRATHAS_COLLAR,
  687 + D2S_ITEMDATA_SETITEM_IRATHAS_CUFF,
  688 + D2S_ITEMDATA_SETITEM_IRATHAS_COIL,
  689 + D2S_ITEMDATA_SETITEM_IRATHAS_CORD,
  690 + D2S_ITEMDATA_SETITEM_ISENHARTS_LIGHTBRAND,
  691 + D2S_ITEMDATA_SETITEM_ISERNHARTS_PARRY,
  692 + D2S_ITEMDATA_SETITEM_ISENHARTS_CASE,
  693 + D2S_ITEMDATA_SETITEM_ISENHARTS_HORNS,
  694 + D2S_ITEMDATA_SETITEM_VIDALAS_BARB,
  695 + D2S_ITEMDATA_SETITEM_VIDALAS_FETLOCK,
  696 + D2S_ITEMDATA_SETITEM_VIDALAS_AMBUSH,
  697 + D2S_ITEMDATA_SETITEM_VIDALAS_SNARE,
  698 + D2S_ITEMDATA_SETITEM_MILABREGAS_ORB,
  699 + D2S_ITEMDATA_SETITEM_MILABREGAS_ROD,
  700 + D2S_ITEMDATA_SETITEM_MILABREGAS_DIADEM,
  701 + D2S_ITEMDATA_SETITEM_MILABREGAS_ROBE,
  702 + D2S_ITEMDATA_SETITEM_CATHANS_RULE,
  703 + D2S_ITEMDATA_SETITEM_CATHANS_MESH,
  704 + D2S_ITEMDATA_SETITEM_CATHANS_VISAGE,
  705 + D2S_ITEMDATA_SETITEM_CATHANS_SIGIL,
  706 + D2S_ITEMDATA_SETITEM_CATHANS_SEAL,
  707 + D2S_ITEMDATA_SETITEM_TANCREDS_CROWBILL,
  708 + D2S_ITEMDATA_SETITEM_TANCREDS_SPINE,
  709 + D2S_ITEMDATA_SETITEM_TANCREDS_HOBNAILS,
  710 + D2S_ITEMDATA_SETITEM_TANCREDS_WEIRD,
  711 + D2S_ITEMDATA_SETITEM_TANCREDS_SKULL,
  712 + D2S_ITEMDATA_SETITEM_SIGONS_GAGE,
  713 + D2S_ITEMDATA_SETITEM_SIGONS_VISOR,
  714 + D2S_ITEMDATA_SETITEM_SIGONS_SHELTER,
  715 + D2S_ITEMDATA_SETITEM_SIGONS_SABOT,
  716 + D2S_ITEMDATA_SETITEM_SIGONS_WRAP,
  717 + D2S_ITEMDATA_SETITEM_SIGONS_GUARD,
  718 + D2S_ITEMDATA_SETITEM_INFERNAL_CRANIUM,
  719 + D2S_ITEMDATA_SETITEM_INFERNAL_TORCH,
  720 + D2S_ITEMDATA_SETITEM_INFERNAL_SIGN,
  721 + D2S_ITEMDATA_SETITEM_BERSEKERS_HEADGEAR,
  722 + D2S_ITEMDATA_SETITEM_BERSEKERS_HAUBERK,
  723 + D2S_ITEMDATA_SETITEM_BERSEKERS_HATCHET,
  724 + D2S_ITEMDATA_SETITEM_DEATHS_HAND,
  725 + D2S_ITEMDATA_SETITEM_DEATHS_GUARD,
  726 + D2S_ITEMDATA_SETITEM_DEATHS_TOUCH,
  727 + D2S_ITEMDATA_SETITEM_ANGELIC_SICKLE,
  728 + D2S_ITEMDATA_SETITEM_ANGELIC_MANTLE,
  729 + D2S_ITEMDATA_SETITEM_ANGELIC_HALO,
  730 + D2S_ITEMDATA_SETITEM_ANGELIC_WINGS,
  731 + D2S_ITEMDATA_SETITEM_ARCTIC_HORNS,
  732 + D2S_ITEMDATA_SETITEM_ARCTIC_FURS,
  733 + D2S_ITEMDATA_SETITEM_ARCTIC_BINDING,
  734 + D2S_ITEMDATA_SETITEM_ARCTIC_MITTS,
  735 + D2S_ITEMDATA_SETITEM_ARCANNAS_SIGN,
  736 + D2S_ITEMDATA_SETITEM_ARCANNAS_DEATHWAND,
  737 + D2S_ITEMDATA_SETITEM_ARCANNAS_HEAD,
  738 + D2S_ITEMDATA_SETITEM_ARCANNAS_FLESH,
  739 + D2S_ITEMDATA_SETITEM_NATALYAS_TOTEM,
  740 + D2S_ITEMDATA_SETITEM_NATALYAS_MARK,
  741 + D2S_ITEMDATA_SETITEM_NATALYAS_SHADOW,
  742 + D2S_ITEMDATA_SETITEM_NATALYAS_SOUL,
  743 + D2S_ITEMDATA_SETITEM_ALDURS_STONY_GAZE,
  744 + D2S_ITEMDATA_SETITEM_ALDURS_DECEPTION,
  745 + D2S_ITEMDATA_SETITEM_ALDURS_RHYTHM,
  746 + D2S_ITEMDATA_SETITEM_ALDURS_ADVANCE,
  747 + D2S_ITEMDATA_SETITEM_IMMORTAL_KINGS_WILL,
  748 + D2S_ITEMDATA_SETITEM_IMMORTAL_KINGS_SOULCAGE,
  749 + D2S_ITEMDATA_SETITEM_IMMORTAL_KINGS_DETAIL,
  750 + D2S_ITEMDATA_SETITEM_IMMORTAL_KINGS_FORGE,
  751 + D2S_ITEMDATA_SETITEM_IMMORTAL_KINGS_PILLAR,
  752 + D2S_ITEMDATA_SETITEM_IMMORTAL_KINGS_STONE_CRUSHER,
  753 + D2S_ITEMDATA_SETITEM_TAL_RASHAS_FIRESPUN_CLOTH,
  754 + D2S_ITEMDATA_SETITEM_TAL_RASHAS_ADJUDICATION,
  755 + D2S_ITEMDATA_SETITEM_TAL_RASHAS_LIDLESS_EYE,
  756 + D2S_ITEMDATA_SETITEM_TAL_RASHAS_GUARDIANSHIP,
  757 + D2S_ITEMDATA_SETITEM_TAL_RASHAS_HORADRIC_CREST,
  758 + D2S_ITEMDATA_SETITEM_GRISWOLDS_VALOR,
  759 + D2S_ITEMDATA_SETITEM_GRISWOLDS_HEART,
  760 + D2S_ITEMDATA_SETITEM_GRISWOLDS_REDEMPTION,
  761 + D2S_ITEMDATA_SETITEM_GRISWOLDS_HONOR,
  762 + D2S_ITEMDATA_SETITEM_TRANGOULS_GUISE,
  763 + D2S_ITEMDATA_SETITEM_TRANGOULS_SCALES,
  764 + D2S_ITEMDATA_SETITEM_TRANGOULS_WING,
  765 + D2S_ITEMDATA_SETITEM_TRANGOULS_CLAWS,
  766 + D2S_ITEMDATA_SETITEM_TRANGOULS_GIRTH,
  767 + D2S_ITEMDATA_SETITEM_MAVINAS_TRUE_SIGHT,
  768 + D2S_ITEMDATA_SETITEM_MAVINAS_EMBRACE,
  769 + D2S_ITEMDATA_SETITEM_MAVINAS_ICY_CLUTCH,
  770 + D2S_ITEMDATA_SETITEM_MAVINAS_TENET,
  771 + D2S_ITEMDATA_SETITEM_MAVINAS_CASTER,
  772 + D2S_ITEMDATA_SETITEM_TELLING_OF_BEADS,
  773 + D2S_ITEMDATA_SETITEM_LAYING_OF_HANDS,
  774 + D2S_ITEMDATA_SETITEM_RITE_OF_PASSAGE,
  775 + D2S_ITEMDATA_SETITEM_DARK_ADHERENT,
  776 + D2S_ITEMDATA_SETITEM_CREDENDUM,
  777 + D2S_ITEMDATA_SETITEM_DRAGOONS_TEACHING,
  778 + D2S_ITEMDATA_SETITEM_TAEBEKS_GLORY,
  779 + D2S_ITEMDATA_SETITEM_HAEMOSUS_ADAMENT,
  780 + D2S_ITEMDATA_SETITEM_ONDALS_ALMIGHTY,
  781 + D2S_ITEMDATA_SETITEM_GUILLAUMES_FACE,
  782 + D2S_ITEMDATA_SETITEM_WILHELMS_PRIDE,
  783 + D2S_ITEMDATA_SETITEM_MAGNUSS_SKIN,
  784 + D2S_ITEMDATA_SETITEM_WIHTSTANS_GUARD,
  785 + D2S_ITEMDATA_SETITEM_HWANINS_SPLENDOR,
  786 + D2S_ITEMDATA_SETITEM_HWANINS_REFUGE,
  787 + D2S_ITEMDATA_SETITEM_HWANINS_BLESSING,
  788 + D2S_ITEMDATA_SETITEM_HWANINS_JUSTICE,
  789 + D2S_ITEMDATA_SETITEM_SAZABIS_COBALT_REDEEMER,
  790 + D2S_ITEMDATA_SETITEM_SAZABIS_GHOST_LIBERATOR,
  791 + D2S_ITEMDATA_SETITEM_SAZABIS_MENTAL_SHEATH,
  792 + D2S_ITEMDATA_SETITEM_BULKATHOSS_SACRED_CHARGE,
  793 + D2S_ITEMDATA_SETITEM_BULKATHOSS_TRIBAL_GUARDIAN,
  794 + D2S_ITEMDATA_SETITEM_COW_KING_HORNS,
  795 + D2S_ITEMDATA_SETITEM_COW_KING_HIDE,
  796 + D2S_ITEMDATA_SETITEM_COW_KING_HOOVES,
  797 + D2S_ITEMDATA_SETITEM_NAJS_PUZZLER,
  798 + D2S_ITEMDATA_SETITEM_NAJS_LIGHT_PLATE,
  799 + D2S_ITEMDATA_SETITEM_NAJS_CIRCLET,
  800 + D2S_ITEMDATA_SETITEM_SANDERS_PARAGON,
  801 + D2S_ITEMDATA_SETITEM_SANDERS_RIPRAP,
  802 + D2S_ITEMDATA_SETITEM_SANDERS_TABOO,
  803 + D2S_ITEMDATA_SETITEM_SANDERS_SUPERSTITION
663 804 } D2S_ITEMDATA_SET_IDENTIFIER;
664 805  
  806 +const char* const setNames[] = {
  807 + D2S_ITEMDATA_SETITEM_IDENTIFIER_0,
  808 + D2S_ITEMDATA_SETITEM_IDENTIFIER_1,
  809 + D2S_ITEMDATA_SETITEM_IDENTIFIER_2,
  810 + D2S_ITEMDATA_SETITEM_IDENTIFIER_3,
  811 + D2S_ITEMDATA_SETITEM_IDENTIFIER_4,
  812 + D2S_ITEMDATA_SETITEM_IDENTIFIER_5,
  813 + D2S_ITEMDATA_SETITEM_IDENTIFIER_6,
  814 + D2S_ITEMDATA_SETITEM_IDENTIFIER_7,
  815 + D2S_ITEMDATA_SETITEM_IDENTIFIER_8,
  816 + D2S_ITEMDATA_SETITEM_IDENTIFIER_9,
  817 + D2S_ITEMDATA_SETITEM_IDENTIFIER_10,
  818 + D2S_ITEMDATA_SETITEM_IDENTIFIER_11,
  819 + D2S_ITEMDATA_SETITEM_IDENTIFIER_12,
  820 + D2S_ITEMDATA_SETITEM_IDENTIFIER_13,
  821 + D2S_ITEMDATA_SETITEM_IDENTIFIER_14,
  822 + D2S_ITEMDATA_SETITEM_IDENTIFIER_15,
  823 + D2S_ITEMDATA_SETITEM_IDENTIFIER_16,
  824 + D2S_ITEMDATA_SETITEM_IDENTIFIER_17,
  825 + D2S_ITEMDATA_SETITEM_IDENTIFIER_18,
  826 + D2S_ITEMDATA_SETITEM_IDENTIFIER_19,
  827 + D2S_ITEMDATA_SETITEM_IDENTIFIER_20,
  828 + D2S_ITEMDATA_SETITEM_IDENTIFIER_21,
  829 + D2S_ITEMDATA_SETITEM_IDENTIFIER_22,
  830 + D2S_ITEMDATA_SETITEM_IDENTIFIER_23,
  831 + D2S_ITEMDATA_SETITEM_IDENTIFIER_24,
  832 + D2S_ITEMDATA_SETITEM_IDENTIFIER_25,
  833 + D2S_ITEMDATA_SETITEM_IDENTIFIER_26,
  834 + D2S_ITEMDATA_SETITEM_IDENTIFIER_27,
  835 + D2S_ITEMDATA_SETITEM_IDENTIFIER_28,
  836 + D2S_ITEMDATA_SETITEM_IDENTIFIER_29,
  837 + D2S_ITEMDATA_SETITEM_IDENTIFIER_30,
  838 + D2S_ITEMDATA_SETITEM_IDENTIFIER_31,
  839 + D2S_ITEMDATA_SETITEM_IDENTIFIER_32,
  840 + D2S_ITEMDATA_SETITEM_IDENTIFIER_33,
  841 + D2S_ITEMDATA_SETITEM_IDENTIFIER_34,
  842 + D2S_ITEMDATA_SETITEM_IDENTIFIER_35,
  843 + D2S_ITEMDATA_SETITEM_IDENTIFIER_36,
  844 + D2S_ITEMDATA_SETITEM_IDENTIFIER_37,
  845 + D2S_ITEMDATA_SETITEM_IDENTIFIER_38,
  846 + D2S_ITEMDATA_SETITEM_IDENTIFIER_39,
  847 + D2S_ITEMDATA_SETITEM_IDENTIFIER_40,
  848 + D2S_ITEMDATA_SETITEM_IDENTIFIER_41,
  849 + D2S_ITEMDATA_SETITEM_IDENTIFIER_42,
  850 + D2S_ITEMDATA_SETITEM_IDENTIFIER_43,
  851 + D2S_ITEMDATA_SETITEM_IDENTIFIER_44,
  852 + D2S_ITEMDATA_SETITEM_IDENTIFIER_45,
  853 + D2S_ITEMDATA_SETITEM_IDENTIFIER_46,
  854 + D2S_ITEMDATA_SETITEM_IDENTIFIER_47,
  855 + D2S_ITEMDATA_SETITEM_IDENTIFIER_48,
  856 + D2S_ITEMDATA_SETITEM_IDENTIFIER_49,
  857 + D2S_ITEMDATA_SETITEM_IDENTIFIER_50,
  858 + D2S_ITEMDATA_SETITEM_IDENTIFIER_51,
  859 + D2S_ITEMDATA_SETITEM_IDENTIFIER_52,
  860 + D2S_ITEMDATA_SETITEM_IDENTIFIER_53,
  861 + D2S_ITEMDATA_SETITEM_IDENTIFIER_54,
  862 + D2S_ITEMDATA_SETITEM_IDENTIFIER_55,
  863 + D2S_ITEMDATA_SETITEM_IDENTIFIER_56,
  864 + D2S_ITEMDATA_SETITEM_IDENTIFIER_57,
  865 + D2S_ITEMDATA_SETITEM_IDENTIFIER_58,
  866 + D2S_ITEMDATA_SETITEM_IDENTIFIER_59,
  867 + D2S_ITEMDATA_SETITEM_IDENTIFIER_60,
  868 + D2S_ITEMDATA_SETITEM_IDENTIFIER_61,
  869 + D2S_ITEMDATA_SETITEM_IDENTIFIER_62,
  870 + D2S_ITEMDATA_SETITEM_IDENTIFIER_63,
  871 + D2S_ITEMDATA_SETITEM_IDENTIFIER_64,
  872 + D2S_ITEMDATA_SETITEM_IDENTIFIER_65,
  873 + D2S_ITEMDATA_SETITEM_IDENTIFIER_66,
  874 + D2S_ITEMDATA_SETITEM_IDENTIFIER_67,
  875 + D2S_ITEMDATA_SETITEM_IDENTIFIER_68,
  876 + D2S_ITEMDATA_SETITEM_IDENTIFIER_69,
  877 + D2S_ITEMDATA_SETITEM_IDENTIFIER_70,
  878 + D2S_ITEMDATA_SETITEM_IDENTIFIER_71,
  879 + D2S_ITEMDATA_SETITEM_IDENTIFIER_72,
  880 + D2S_ITEMDATA_SETITEM_IDENTIFIER_73,
  881 + D2S_ITEMDATA_SETITEM_IDENTIFIER_74,
  882 + D2S_ITEMDATA_SETITEM_IDENTIFIER_75,
  883 + D2S_ITEMDATA_SETITEM_IDENTIFIER_76,
  884 + D2S_ITEMDATA_SETITEM_IDENTIFIER_77,
  885 + D2S_ITEMDATA_SETITEM_IDENTIFIER_78,
  886 + D2S_ITEMDATA_SETITEM_IDENTIFIER_79,
  887 + D2S_ITEMDATA_SETITEM_IDENTIFIER_80,
  888 + D2S_ITEMDATA_SETITEM_IDENTIFIER_81,
  889 + D2S_ITEMDATA_SETITEM_IDENTIFIER_82,
  890 + D2S_ITEMDATA_SETITEM_IDENTIFIER_83,
  891 + D2S_ITEMDATA_SETITEM_IDENTIFIER_84,
  892 + D2S_ITEMDATA_SETITEM_IDENTIFIER_85,
  893 + D2S_ITEMDATA_SETITEM_IDENTIFIER_86,
  894 + D2S_ITEMDATA_SETITEM_IDENTIFIER_87,
  895 + D2S_ITEMDATA_SETITEM_IDENTIFIER_88,
  896 + D2S_ITEMDATA_SETITEM_IDENTIFIER_89,
  897 + D2S_ITEMDATA_SETITEM_IDENTIFIER_90,
  898 + D2S_ITEMDATA_SETITEM_IDENTIFIER_91,
  899 + D2S_ITEMDATA_SETITEM_IDENTIFIER_92,
  900 + D2S_ITEMDATA_SETITEM_IDENTIFIER_93,
  901 + D2S_ITEMDATA_SETITEM_IDENTIFIER_94,
  902 + D2S_ITEMDATA_SETITEM_IDENTIFIER_95,
  903 + D2S_ITEMDATA_SETITEM_IDENTIFIER_96,
  904 + D2S_ITEMDATA_SETITEM_IDENTIFIER_97,
  905 + D2S_ITEMDATA_SETITEM_IDENTIFIER_98,
  906 + D2S_ITEMDATA_SETITEM_IDENTIFIER_99,
  907 + D2S_ITEMDATA_SETITEM_IDENTIFIER_100,
  908 + D2S_ITEMDATA_SETITEM_IDENTIFIER_101,
  909 + D2S_ITEMDATA_SETITEM_IDENTIFIER_102,
  910 + D2S_ITEMDATA_SETITEM_IDENTIFIER_103,
  911 + D2S_ITEMDATA_SETITEM_IDENTIFIER_104,
  912 + D2S_ITEMDATA_SETITEM_IDENTIFIER_105,
  913 + D2S_ITEMDATA_SETITEM_IDENTIFIER_106,
  914 + D2S_ITEMDATA_SETITEM_IDENTIFIER_107,
  915 + D2S_ITEMDATA_SETITEM_IDENTIFIER_108,
  916 + D2S_ITEMDATA_SETITEM_IDENTIFIER_109,
  917 + D2S_ITEMDATA_SETITEM_IDENTIFIER_110,
  918 + D2S_ITEMDATA_SETITEM_IDENTIFIER_111,
  919 + D2S_ITEMDATA_SETITEM_IDENTIFIER_112,
  920 + D2S_ITEMDATA_SETITEM_IDENTIFIER_113,
  921 + D2S_ITEMDATA_SETITEM_IDENTIFIER_114,
  922 + D2S_ITEMDATA_SETITEM_IDENTIFIER_115,
  923 + D2S_ITEMDATA_SETITEM_IDENTIFIER_116,
  924 + D2S_ITEMDATA_SETITEM_IDENTIFIER_117,
  925 + D2S_ITEMDATA_SETITEM_IDENTIFIER_118,
  926 + D2S_ITEMDATA_SETITEM_IDENTIFIER_119,
  927 + D2S_ITEMDATA_SETITEM_IDENTIFIER_120,
  928 + D2S_ITEMDATA_SETITEM_IDENTIFIER_121,
  929 + D2S_ITEMDATA_SETITEM_IDENTIFIER_122,
  930 + D2S_ITEMDATA_SETITEM_IDENTIFIER_123,
  931 + D2S_ITEMDATA_SETITEM_IDENTIFIER_124,
  932 + D2S_ITEMDATA_SETITEM_IDENTIFIER_125,
  933 + D2S_ITEMDATA_SETITEM_IDENTIFIER_126
  934 +};
  935 +
  936 +/*
  937 +var uniqueNames = map[uint64]string{
  938 + 0: "The Gnasher",
  939 + 1: "Deathspade",
  940 + 2: "Bladebone",
  941 + 3: "Skull splitter",
  942 + 4: "Rakescar",
  943 + 5: "Axe of Fechmar",
  944 + 6: "Goreshovel",
  945 + 7: "The Chiefthan",
  946 + 8: "Brainhew",
  947 + 9: "Humongous",
  948 + 10: "Torch of Iros",
  949 + 11: "Maelstorm",
  950 + 12: "Gravenspine",
  951 + 13: "Umes Lament",
  952 + 14: "Felloak",
  953 + 15: "Knell Striker",
  954 + 16: "Rusthandle",
  955 + 17: "Stormeye",
  956 + 18: "Stoutnail",
  957 + 19: "Crushflange",
  958 + 20: "Bloodrise",
  959 + 21: "The Generals Tan Do Li Ga",
  960 + 22: "Ironstone",
  961 + 23: "Bonesnap",
  962 + 24: "Steeldriver",
  963 + 25: "Rixot's Keen",
  964 + 26: "Blood Crescent",
  965 + 27: "Skewer of Krintiz",
  966 + 28: "Gleamscythe",
  967 + 29: "Azurewrath",
  968 + 30: "Griswold's Edge",
  969 + 31: "Hellplague",
  970 + 32: "Culwens Point",
  971 + 33: "Shadowfang",
  972 + 34: "Soulflay",
  973 + 35: "Kinemils Awl",
  974 + 36: "Blacktongue",
  975 + 37: "Ripsaw",
  976 + 38: "The Patriarch",
  977 + 39: "Gull",
  978 + 40: "The Diggler",
  979 + 41: "The Jade Tan Do",
  980 + 42: "Spectral Shard",
  981 + 43: "The Dragon Chang",
  982 + 44: "Razortine",
  983 + 45: "Bloodthief",
  984 + 46: "Lance of Yaggai",
  985 + 47: "The Tannr Gorerod",
  986 + 48: "Dimoaks Hew",
  987 + 49: "Steelgoad",
  988 + 50: "Soul Harvest",
  989 + 51: "The Battlebranch",
  990 + 52: "Woestave",
  991 + 53: "The Grim Reaper",
  992 + 54: "Bane Ash",
  993 + 55: "Serpent Lord",
  994 + 56: "Spire of Lazarus",
  995 + 57: "The Salamander",
  996 + 58: "The Iron Jang Bong",
  997 + 59: "Pluckeye",
  998 + 60: "Witherstring",
  999 + 61: "Raven Claw",
  1000 + 62: "Rogue's Bow",
  1001 + 63: "Stormstrike",
  1002 + 64: "Wizendraw",
  1003 + 65: "Hellclap",
  1004 + 66: "Blastbark",
  1005 + 67: "Leadcrow",
  1006 + 68: "Ichorsting",
  1007 + 69: "Hellcast",
  1008 + 70: "Doomslinger",
  1009 + 71: "Biggin's Bonnet",
  1010 + 72: "Tarnhelm",
  1011 + 73: "Coif of Glory",
  1012 + 74: "Duskdeep",
  1013 + 75: "Wormskull",
  1014 + 76: "Howltusk",
  1015 + 77: "Undead Crown",
  1016 + 78: "The Face of Horror",
  1017 + 79: "Greyform",
  1018 + 80: "Blinkbat's Form",
  1019 + 81: "The Centurion",
  1020 + 82: "Twitchthroe",
  1021 + 83: "Darkglow",
  1022 + 84: "Hawkmail",
  1023 + 85: "Sparking Mail",
  1024 + 86: "Venom Ward",
  1025 + 87: "Iceblink",
  1026 + 88: "Boneflesh",
  1027 + 89: "Rockfleece",
  1028 + 90: "Rattlecage",
  1029 + 91: "Goldskin",
  1030 + 92: "Victors Silk",
  1031 + 93: "Heavenly Garb",
  1032 + 94: "Pelta Lunata",
  1033 + 95: "Umbral Disk",
  1034 + 96: "Stormguild",
  1035 + 97: "Wall of the Eyeless",
  1036 + 98: "Swordback Hold",
  1037 + 99: "Steelclash",
  1038 + 100: "Bverrit Keep",
  1039 + 101: "The Ward",
  1040 + 102: "The Hand of Broc",
  1041 + 103: "Bloodfist",
  1042 + 104: "Chance Guards",
  1043 + 105: "Magefist",
  1044 + 106: "Frostburn",
  1045 + 107: "Hotspur",
  1046 + 108: "Gorefoot",
  1047 + 109: "Treads of Cthon",
  1048 + 110: "Goblin Toe",
  1049 + 111: "Tearhaunch",
  1050 + 112: "Lenymo",
  1051 + 113: "Snakecord",
  1052 + 114: "Nightsmoke",
  1053 + 115: "Goldwrap",
  1054 + 116: "Bladebuckle",
  1055 + 117: "Nokozan Relic",
  1056 + 118: "The Eye of Etlich",
  1057 + 119: "The Mahim-Oak Curio",
  1058 + 120: "Nagelring",
  1059 + 121: "Manald Heal",
  1060 + 122: "The Stone of Jordan",
  1061 + 123: "Amulet of the Viper",
  1062 + 124: "Staff of Kings",
  1063 + 125: "Horadric Staff",
  1064 + 126: "Hell Forge Hammer",
  1065 + 127: "Khalim's Flail",
  1066 + 128: "Super Khalim's Flail",
  1067 + 129: "Coldkill",
  1068 + 130: "Butcher's Pupil",
  1069 + 131: "Islestrike",
  1070 + 132: "Pompe's Wrath",
  1071 + 133: "Guardian Naga",
  1072 + 134: "Warlord's Trust",
  1073 + 135: "Spellsteel",
  1074 + 136: "Stormrider",
  1075 + 137: "Boneslayer Blade",
  1076 + 138: "The Minataur",
  1077 + 139: "Suicide Branch",
  1078 + 140: "Carin Shard",
  1079 + 141: "Arm of King Leoric",
  1080 + 142: "Blackhand Key",
  1081 + 143: "Dark Clan Crusher",
  1082 + 144: "Zakarum's Hand",
  1083 + 145: "The Fetid Sprinkler",
  1084 + 146: "Hand of Blessed Light",
  1085 + 147: "Fleshrender",
  1086 + 148: "Sureshrill Frost",
  1087 + 149: "Moonfall",
  1088 + 150: "Baezil's Vortex",
  1089 + 151: "Earthshaker",
  1090 + 152: "Bloodtree Stump",
  1091 + 153: "The Gavel of Pain",
  1092 + 154: "Bloodletter",
  1093 + 155: "Coldsteel Eye",
  1094 + 156: "Hexfire",
  1095 + 157: "Blade of Ali Baba",
  1096 + 158: "Ginther's Rift",
  1097 + 159: "Headstriker",
  1098 + 160: "Plague Bearer",
  1099 + 161: "The Atlantian",
  1100 + 162: "Crainte Vomir",
  1101 + 163: "Bing Sz Wang",
  1102 + 164: "The Vile Husk",
  1103 + 165: "Cloudcrack",
  1104 + 166: "Todesfaelle Flamme",
  1105 + 167: "Swordguard",
  1106 + 168: "Spineripper",
  1107 + 169: "Heart Carver",
  1108 + 170: "Blackbog's Sharp",
  1109 + 171: "Stormspike",
  1110 + 172: "The Impaler",
  1111 + 173: "Kelpie Snare",
  1112 + 174: "Soulfeast Tine",
  1113 + 175: "Hone Sundan",
  1114 + 176: "Spire of Honor",
  1115 + 177: "The Meat Scraper",
  1116 + 178: "Blackleach Blade",
  1117 + 179: "Athena's Wrath",
  1118 + 180: "Pierre Tombale Couant",
  1119 + 181: "Husoldal Evo",
  1120 + 182: "Grim's Burning Dead",
  1121 + 183: "Razorswitch",
  1122 + 184: "Ribcracker",
  1123 + 185: "Chromatic Ire",
  1124 + 186: "Warpspear",
  1125 + 187: "Skullcollector",
  1126 + 188: "Skystrike",
  1127 + 189: "Riphook",
  1128 + 190: "Kuko Shakaku",
  1129 + 191: "Endlesshail",
  1130 + 192: "Whichwild String",
  1131 + 193: "Cliffkiller",
  1132 + 194: "Magewrath",
  1133 + 195: "Godstrike Arch",
  1134 + 196: "Langer Briser",
  1135 + 197: "Pus Spiter",
  1136 + 198: "Buriza-Do Kyanon",
  1137 + 199: "Demon Machine",
  1138 + 200: "Armor (Unknown)",
  1139 + 201: "Peasent Crown",
  1140 + 202: "Rockstopper",
  1141 + 203: "Stealskull",
  1142 + 204: "Darksight Helm",
  1143 + 205: "Valkyrie Wing",
  1144 + 206: "Crown of Thieves",
  1145 + 207: "Blckhorn's Face",
  1146 + 208: "Vampire Gaze",
  1147 + 209: "The Spirit Shroud",
  1148 + 210: "Skin of the Vipermagi",
  1149 + 211: "Skin of the Flayed One",
  1150 + 212: "Ironpelt",
  1151 + 213: "Spiritforge",
  1152 + 214: "Crow Caw",
  1153 + 215: "Shaftstop",
  1154 + 216: "Duriel's Shell",
  1155 + 217: "Skullder's Ire",
  1156 + 218: "Guardian Angel",
  1157 + 219: "Toothrow",
  1158 + 220: "Atma's Wail",
  1159 + 221: "Black Hades",
  1160 + 222: "Corpsemourn",
  1161 + 223: "Que-Hegan's Wisdom",
  1162 + 224: "Visceratuant",
  1163 + 225: "Mosers Blessed Circle",
  1164 + 226: "Stormchaser",
  1165 + 227: "Tiamat's Rebuke",
  1166 + 228: "Gerke's Sanctuary",
  1167 + 229: "Radimant's Sphere",
  1168 + 230: "Lidless Wall",
  1169 + 231: "Lance Guard",
  1170 + 232: "Venom Grip",
  1171 + 233: "Gravepalm",
  1172 + 234: "Ghoulhide",
  1173 + 235: "Lavagout",
  1174 + 236: "Hellmouth",
  1175 + 237: "Infernostride",
  1176 + 238: "Waterwalk",
  1177 + 239: "Silkweave",
  1178 + 240: "Wartraveler",
  1179 + 241: "Gorerider",
  1180 + 242: "String of Ears",
  1181 + 243: "Razortail",
  1182 + 244: "Gloomstrap",
  1183 + 245: "Snowclash",
  1184 + 246: "Thundergod's Vigor",
  1185 + 247: "Elite unique",
  1186 + 248: "Harlequin Crest",
  1187 + 249: "Veil of Steel",
  1188 + 250: "The Gladiator's Bane",
  1189 + 251: "Arkaine's Valor",
  1190 + 252: "Blackoak Shield",
  1191 + 253: "Stormshield",
  1192 + 254: "Hellslayer",
  1193 + 255: "Messerschmidt's Reaver",
  1194 + 256: "Baranar's Star",
  1195 + 257: "Schaefer's Hammer",
  1196 + 258: "The Cranium Basher",
  1197 + 259: "Lightsabre",
  1198 + 260: "Doombringer",
  1199 + 261: "The Grandfather",
  1200 + 262: "Wizardspike",
  1201 + 263: "Constricting Ring",
  1202 + 264: "Stormspire",
  1203 + 265: "Eaglehorn",
  1204 + 266: "Windforce",
  1205 + 267: "Ring",
  1206 + 268: "Bul Katho's Wedding Band",
  1207 + 269: "The Cat's Eye",
  1208 + 270: "The Rising Sun",
  1209 + 271: "Crescent Moon",
  1210 + 272: "Mara's Kaleidoscope",
  1211 + 273: "Atma's Scarab",
  1212 + 274: "Dwarf Star",
  1213 + 275: "Raven Frost",
  1214 + 276: "Highlord's Wrath",
  1215 + 277: "Saracen's Chance",
  1216 + 278: "Class specific",
  1217 + 279: "Arreat's Face",
  1218 + 280: "Homunculus",
  1219 + 281: "Titan's Revenge",
  1220 + 282: "Lycander's Aim",
  1221 + 283: "Lycander's Flank",
  1222 + 284: "The Oculus",
  1223 + 285: "Herald of Zakarum",
  1224 + 286: "Bartuc's Cut-Throat",
  1225 + 287: "Jalal's Mane",
  1226 + 288: "The Scalper",
  1227 + 289: "Bloodmoon",
  1228 + 290: "Djinnslayer",
  1229 + 291: "Deathbit",
  1230 + 292: "Warshrike",
  1231 + 293: "Gutsiphon",
  1232 + 294: "Razoredge",
  1233 + 295: "Gore Ripper",
  1234 + 296: "Demon Limb",
  1235 + 297: "Steel Shade",
  1236 + 298: "Tomb Reaver",
  1237 + 299: "Death's Web",
  1238 + 300: "Nature's Peace",
  1239 + 301: "Azurewrath",
  1240 + 302: "Seraph's Hymn",
  1241 + 303: "Zakarum's Salvation",
  1242 + 304: "Fleshripper",
  1243 + 305: "Odium",
  1244 + 306: "Horizon's Tornado",
  1245 + 307: "Stone Crusher",
  1246 + 308: "Jade Talon",
  1247 + 309: "Shadow Dancer",
  1248 + 310: "Cerebus' Bite",
  1249 + 311: "Tyrael's Might",
  1250 + 312: "Soul Drainer",
  1251 + 313: "Rune Master",
  1252 + 314: "Death Cleaver",
  1253 + 315: "Executioner's Justice",
  1254 + 316: "Stoneraven",
  1255 + 317: "Leviathan",
  1256 + 318: "Larzuk's Champion",
  1257 + 319: "Wisp Projector",
  1258 + 320: "Gargoyle's Bite",
  1259 + 321: "Lacerator",
  1260 + 322: "Mang Song's Lesson",
  1261 + 323: "Viperfork",
  1262 + 324: "Ethereal Edge",
  1263 + 325: "Demonhorn's Edge",
  1264 + 326: "The Reaper's Toll",
  1265 + 327: "Spiritkeeper",
  1266 + 328: "Hellrack",
  1267 + 329: "Alma Negra",
  1268 + 330: "Darkforge Spawn",
  1269 + 331: "Widowmaker",
  1270 + 332: "Bloodraven's Charge",
  1271 + 333: "Ghostflame",
  1272 + 334: "Shadowkiller",
  1273 + 335: "Gimmershred",
  1274 + 336: "Griffon's Eye",
  1275 + 337: "Windhammer",
  1276 + 338: "Thunderstroke",
  1277 + 339: "Giant Maimer",
  1278 + 340: "Demon's Arch",
  1279 + 341: "Boneflame",
  1280 + 342: "Steelpillar",
  1281 + 343: "Nightwing's Veil",
  1282 + 344: "Crown of Ages",
  1283 + 345: "Andariel's Visage",
  1284 + 346: "Darkfear",
  1285 + 347: "Dragonscale",
  1286 + 348: "Steel Carapice",
  1287 + 349: "Medusa's Gaze",
  1288 + 350: "Ravenlore",
  1289 + 351: "Boneshade",
  1290 + 352: "Nethercrow",
  1291 + 353: "Flamebellow",
  1292 + 354: "Fathom",
  1293 + 355: "Wolfhowl",
  1294 + 356: "Spirit Ward",
  1295 + 357: "Kira's Guardian",
  1296 + 358: "Ormus Robes",
  1297 + 359: "Gheed's Fortune",
  1298 + 360: "Stormlash",
  1299 + 361: "Halaberd's Reign",
  1300 + 362: "Warriv's Warder",
  1301 + 363: "Spike Thorn",
  1302 + 364: "Dracul's Grasp",
  1303 + 365: "Frostwind",
  1304 + 366: "Templar's Might",
  1305 + 367: "Eschuta's Temper",
  1306 + 368: "Firelizard's Talons",
  1307 + 369: "Sandstorm Trek",
  1308 + 370: "Marrowwalk",
  1309 + 371: "Heaven's Light",
  1310 + 372: "Merman's Speed",
  1311 + 373: "Arachnid Mesh",
  1312 + 374: "Nosferatu's Coil",
  1313 + 375: "Metalgrid",
  1314 + 376: "Verdugo's Hearty Cord",
  1315 + 377: "Sigurd's Staunch",
  1316 + 378: "Carrion Wind",
  1317 + 379: "Giantskull",
  1318 + 380: "Ironward",
  1319 + 381: "Annihilus",
  1320 + 382: "Arioc's Needle",
  1321 + 383: "Cranebeak",
  1322 + 384: "Nord's Tenderizer",
  1323 + 385: "Earthshifter",
  1324 + 386: "Wraithflight",
  1325 + 387: "Bonehew",
  1326 + 388: "Ondal's Wisdom",
  1327 + 389: "The Reedeemer",
  1328 + 390: "Headhunter's Glory",
  1329 + 391: "Steelrend",
  1330 + 392: "Rainbow Facet",
  1331 + 393: "Rainbow Facet",
  1332 + 394: "Rainbow Facet",
  1333 + 395: "Rainbow Facet",
  1334 + 396: "Rainbow Facet",
  1335 + 397: "Rainbow Facet",
  1336 + 398: "Rainbow Facet",
  1337 + 399: "Rainbow Facet",
  1338 + 400: "Hellfire Torch",
  1339 +}
  1340 +*/
  1341 +
665 1342 typedef enum D2S_ITEMDATA_UNIQUE_IDENTIFIER {
666 1343 TODO = 0
667 1344 } D2S_ITEMDATA_UNIQUE_IDENTIFIER;
668 1345  
  1346 +// TODO: Find out rune word identifiers (same as HE)
  1347 +
669 1348 typedef enum D2S_ITEMDATA_RUNEWORD_IDENTIFIER {
670 1349 TODO = 0
671 1350 } D2S_ITEMDATA_RUNEWORD_IDENTIFIER;
672 1351  
  1352 +/*
  1353 +
  1354 +var magicalPrefixes = map[uint64]string{
  1355 + 2: "Sturdy",
  1356 + 3: "Strong",
  1357 + 4: "Glorious",
  1358 + 5: "Blessed",
  1359 + 6: "Saintly",
  1360 + 7: "Holy",
  1361 + 8: "Devious",
  1362 + 9: "Fortified",
  1363 + 13: "Jagged",
  1364 + 14: "Deadly",
  1365 + 15: "Vicious",
  1366 + 16: "Brutal",
  1367 + 17: "Massive",
  1368 + 18: "Savage",
  1369 + 19: "Merciless",
  1370 + 20: "Vulpine",
  1371 + 25: "Tireless",
  1372 + 26: "Rugged",
  1373 + 27: "Bronze",
  1374 + 28: "Iron",
  1375 + 29: "Steel",
  1376 + 30: "Silver",
  1377 + 32: "Gold",
  1378 + 33: "Platinum",
  1379 + 34: "Meteoric",
  1380 + 35: "Sharp",
  1381 + 36: "Fine",
  1382 + 37: "Warrior's",
  1383 + 38: "Soldier's",
  1384 + 39: "Knight's",
  1385 + 40: "Lord's",
  1386 + 41: "King's",
  1387 + 42: "Howling",
  1388 + 43: "Fortuitous",
  1389 + 49: "Glimmering",
  1390 + 50: "Glowing",
  1391 + 53: "Lizard's",
  1392 + 55: "Snake's",
  1393 + 56: "Serpent's",
  1394 + 57: "Serpent's",
  1395 + 58: "Drake's",
  1396 + 59: "Dragon's",
  1397 + 60: "Dragon's",
  1398 + 61: "Wyrm's",
  1399 + 64: "Prismatic",
  1400 + 65: "Prismatic",
  1401 + 66: "Azure",
  1402 + 67: "Lapis",
  1403 + 68: "Lapis",
  1404 + 69: "Cobalt",
  1405 + 70: "Cobalt",
  1406 + 72: "Sapphire",
  1407 + 75: "Crimson",
  1408 + 76: "Burgundy",
  1409 + 77: "Burgundy",
  1410 + 78: "Garnet",
  1411 + 79: "Garnet",
  1412 + 81: "Ruby",
  1413 + 84: "Ocher",
  1414 + 85: "Tangerine",
  1415 + 86: "Tangerine",
  1416 + 87: "Coral",
  1417 + 88: "Coral",
  1418 + 90: "Amber",
  1419 + 93: "Beryl",
  1420 + 94: "Jade",
  1421 + 95: "Jade",
  1422 + 96: "Viridian",
  1423 + 97: "Viridian",
  1424 + 99: "Emerald",
  1425 + 101: "Fletcher's",
  1426 + 102: "Archer's",
  1427 + 103: "Archer's",
  1428 + 104: "Monk's",
  1429 + 105: "Priest's",
  1430 + 106: "Priest's",
  1431 + 107: "Summoner's",
  1432 + 108: "Necromancer's",
  1433 + 109: "Necromancer's",
  1434 + 110: "Angel's",
  1435 + 111: "Arch-Angel's",
  1436 + 112: "Arch-Angel's",
  1437 + 113: "Slayer's",
  1438 + 114: "Berserker's",
  1439 + 115: "Berserker's",
  1440 + 118: "Triumphant",
  1441 + 119: "Stout",
  1442 + 120: "Stout",
  1443 + 121: "Stout",
  1444 + 122: "Burly",
  1445 + 123: "Burly",
  1446 + 124: "Burly",
  1447 + 125: "Stalwart",
  1448 + 126: "Stalwart",
  1449 + 127: "Stalwart",
  1450 + 128: "Stout",
  1451 + 129: "Stout",
  1452 + 130: "Stout",
  1453 + 131: "Burly",
  1454 + 132: "Burly",
  1455 + 133: "Stalwart",
  1456 + 134: "Stalwart",
  1457 + 135: "Stout",
  1458 + 136: "Stout",
  1459 + 137: "Burly",
  1460 + 138: "Stalwart",
  1461 + 139: "Blanched",
  1462 + 140: "Eburin",
  1463 + 141: "Bone",
  1464 + 142: "Ivory",
  1465 + 143: "Sturdy",
  1466 + 144: "Sturdy",
  1467 + 145: "Strong",
  1468 + 146: "Glorious",
  1469 + 147: "Blessed",
  1470 + 148: "Saintly",
  1471 + 149: "Holy",
  1472 + 150: "Godly",
  1473 + 151: "Devious",
  1474 + 152: "Blank",
  1475 + 153: "Null",
  1476 + 154: "Antimagic",
  1477 + 155: "Red",
  1478 + 156: "Red",
  1479 + 157: "Sanguinary",
  1480 + 158: "Sanguinary",
  1481 + 159: "Bloody",
  1482 + 160: "Red",
  1483 + 161: "Sanguinary",
  1484 + 162: "Bloody",
  1485 + 163: "Red",
  1486 + 164: "Sanguinary",
  1487 + 165: "Bloody",
  1488 + 166: "Scarlet",
  1489 + 167: "Crimson",
  1490 + 168: "Jagged",
  1491 + 169: "Jagged",
  1492 + 170: "Jagged",
  1493 + 171: "Forked",
  1494 + 172: "Forked",
  1495 + 173: "Serrated",
  1496 + 174: "Serrated",
  1497 + 175: "Jagged",
  1498 + 176: "Jagged",
  1499 + 177: "Forked",
  1500 + 178: "Forked",
  1501 + 179: "Serrated",
  1502 + 180: "Jagged",
  1503 + 181: "Forked",
  1504 + 182: "Serrated",
  1505 + 183: "Carbuncle",
  1506 + 184: "Carmine",
  1507 + 185: "Vermillion",
  1508 + 186: "Jagged",
  1509 + 187: "Deadly",
  1510 + 188: "Vicious",
  1511 + 189: "Brutal",
  1512 + 190: "Massive",
  1513 + 191: "Savage",
  1514 + 192: "Merciless",
  1515 + 193: "Ferocious",
  1516 + 194: "Cruel",
  1517 + 195: "Cinnabar",
  1518 + 196: "Rusty",
  1519 + 197: "Realgar",
  1520 + 198: "Ruby",
  1521 + 199: "Vulpine",
  1522 + 200: "Dun",
  1523 + 201: "Tireless",
  1524 + 202: "Tireless",
  1525 + 203: "Brown",
  1526 + 204: "Rugged",
  1527 + 205: "Rugged",
  1528 + 206: "Rugged",
  1529 + 207: "Rugged",
  1530 + 208: "Rugged",
  1531 + 209: "Rugged",
  1532 + 210: "Rugged",
  1533 + 211: "Rugged",
  1534 + 212: "Rugged",
  1535 + 213: "Rugged",
  1536 + 214: "Rugged",
  1537 + 215: "Vigorous",
  1538 + 216: "Chestnut",
  1539 + 217: "Maroon",
  1540 + 218: "Bronze",
  1541 + 219: "Bronze",
  1542 + 220: "Bronze",
  1543 + 221: "Iron",
  1544 + 222: "Iron",
  1545 + 223: "Iron",
  1546 + 224: "Steel",
  1547 + 225: "Steel",
  1548 + 226: "Steel",
  1549 + 227: "Bronze",
  1550 + 228: "Bronze",
  1551 + 229: "Bronze",
  1552 + 230: "Iron",
  1553 + 231: "Iron",
  1554 + 232: "Steel",
  1555 + 233: "Steel",
  1556 + 234: "Bronze",
  1557 + 235: "Bronze",
  1558 + 236: "Iron",
  1559 + 237: "Steel",
  1560 + 238: "Bronze",
  1561 + 239: "Iron",
  1562 + 240: "Steel",
  1563 + 241: "Silver",
  1564 + 242: "Gold",
  1565 + 243: "Platinum",
  1566 + 244: "Meteoric",
  1567 + 245: "Strange",
  1568 + 246: "Weird",
  1569 + 247: "Nickel",
  1570 + 248: "Tin",
  1571 + 249: "Silver",
  1572 + 250: "Argent",
  1573 + 251: "Fine",
  1574 + 252: "Fine",
  1575 + 253: "Sharp",
  1576 + 254: "Fine",
  1577 + 255: "Sharp",
  1578 + 256: "Fine",
  1579 + 257: "Sharp",
  1580 + 258: "Fine",
  1581 + 259: "Warrior's",
  1582 + 260: "Soldier's",
  1583 + 261: "Knight's",
  1584 + 262: "Lord's",
  1585 + 263: "King's",
  1586 + 264: "Master's",
  1587 + 265: "Grandmaster's",
  1588 + 266: "Glimmering",
  1589 + 267: "Glowing",
  1590 + 268: "Bright",
  1591 + 269: "Screaming",
  1592 + 270: "Howling",
  1593 + 271: "Wailing",
  1594 + 272: "Screaming",
  1595 + 273: "Howling",
  1596 + 274: "Wailing",
  1597 + 275: "Lucky",
  1598 + 276: "Lucky",
  1599 + 277: "Lucky",
  1600 + 278: "Lucky",
  1601 + 279: "Lucky",
  1602 + 280: "Lucky",
  1603 + 281: "Felicitous",
  1604 + 282: "Fortuitous",
  1605 + 283: "Emerald",
  1606 + 284: "Lizard's",
  1607 + 285: "Lizard's",
  1608 + 286: "Lizard's",
  1609 + 287: "Snake's",
  1610 + 288: "Snake's",
  1611 + 289: "Snake's",
  1612 + 290: "Serpent's",
  1613 + 291: "Serpent's",
  1614 + 292: "Serpent's",
  1615 + 293: "Lizard's",
  1616 + 294: "Lizard's",
  1617 + 295: "Lizard's",
  1618 + 296: "Snake's",
  1619 + 297: "Snake's",
  1620 + 298: "Serpent's",
  1621 + 299: "Serpent's",
  1622 + 300: "Lizard's",
  1623 + 301: "Lizard's",
  1624 + 302: "Snake's",
  1625 + 303: "Serpent's",
  1626 + 304: "Lizard's",
  1627 + 305: "Snake's",
  1628 + 306: "Serpent's",
  1629 + 307: "Serpent's",
  1630 + 308: "Drake's",
  1631 + 309: "Dragon's",
  1632 + 310: "Dragon's",
  1633 + 311: "Wyrm's",
  1634 + 312: "Great Wyrm's",
  1635 + 313: "Bahamut's",
  1636 + 314: "Zircon",
  1637 + 315: "Jacinth",
  1638 + 316: "Turquoise",
  1639 + 317: "Shimmering",
  1640 + 318: "Shimmering",
  1641 + 319: "Shimmering",
  1642 + 320: "Shimmering",
  1643 + 321: "Shimmering",
  1644 + 322: "Shimmering",
  1645 + 323: "Shimmering",
  1646 + 324: "Rainbow",
  1647 + 325: "Scintillating",
  1648 + 326: "Prismatic",
  1649 + 327: "Chromatic",
  1650 + 328: "Shimmering",
  1651 + 329: "Rainbow",
  1652 + 330: "Scintillating",
  1653 + 331: "Prismatic",
  1654 + 332: "Chromatic",
  1655 + 333: "Shimmering",
  1656 + 334: "Rainbow",
  1657 + 335: "Scintillating",
  1658 + 336: "Shimmering",
  1659 + 337: "Scintillating",
  1660 + 338: "Azure",
  1661 + 339: "Lapis",
  1662 + 340: "Cobalt",
  1663 + 341: "Sapphire",
  1664 + 342: "Azure",
  1665 + 343: "Lapis",
  1666 + 344: "Cobalt",
  1667 + 345: "Sapphire",
  1668 + 346: "Azure",
  1669 + 347: "Lapis",
  1670 + 348: "Cobalt",
  1671 + 349: "Sapphire",
  1672 + 350: "Azure",
  1673 + 351: "Lapis",
  1674 + 352: "Lapis",
  1675 + 353: "Cobalt",
  1676 + 354: "Cobalt",
  1677 + 355: "Sapphire",
  1678 + 356: "Lapis Lazuli",
  1679 + 357: "Sapphire",
  1680 + 358: "Crimson",
  1681 + 359: "Russet",
  1682 + 360: "Garnet",
  1683 + 361: "Ruby",
  1684 + 362: "Crimson",
  1685 + 363: "Russet",
  1686 + 364: "Garnet",
  1687 + 365: "Ruby",
  1688 + 366: "Crimson",
  1689 + 367: "Russet",
  1690 + 368: "Garnet",
  1691 + 369: "Ruby",
  1692 + 370: "Russet",
  1693 + 371: "Russet",
  1694 + 372: "Garnet",
  1695 + 373: "Garnet",
  1696 + 374: "Ruby",
  1697 + 375: "Garnet",
  1698 + 376: "Ruby",
  1699 + 377: "Tangerine",
  1700 + 378: "Ocher",
  1701 + 379: "Coral",
  1702 + 380: "Amber",
  1703 + 381: "Tangerine",
  1704 + 382: "Ocher",
  1705 + 383: "Coral",
  1706 + 384: "Amber",
  1707 + 385: "Tangerine",
  1708 + 386: "Ocher",
  1709 + 387: "Coral",
  1710 + 388: "Amber",
  1711 + 389: "Tangerine",
  1712 + 390: "Ocher",
  1713 + 391: "Ocher",
  1714 + 392: "Coral",
  1715 + 393: "Coral",
  1716 + 394: "Amber",
  1717 + 395: "Camphor",
  1718 + 396: " Ambergris",
  1719 + 397: "Beryl",
  1720 + 398: "Viridian",
  1721 + 399: "Jade",
  1722 + 400: "Emerald",
  1723 + 401: "Beryl",
  1724 + 402: "Viridian",
  1725 + 403: "Jade",
  1726 + 404: "Emerald",
  1727 + 405: "Beryl",
  1728 + 406: "Viridian",
  1729 + 407: "Jade",
  1730 + 408: "Emerald",
  1731 + 409: "Beryl",
  1732 + 410: "Viridian",
  1733 + 411: "Viridian",
  1734 + 412: "Jade",
  1735 + 413: "Jade",
  1736 + 414: "Emerald",
  1737 + 415: "Beryl",
  1738 + 416: "Jade",
  1739 + 417: "Triumphant",
  1740 + 418: "Victorious",
  1741 + 419: "Aureolin",
  1742 + 420: "Mechanist's",
  1743 + 421: "Artificer's",
  1744 + 422: "Jeweler's",
  1745 + 423: "Assamic",
  1746 + 424: "Arcadian",
  1747 + 425: "Unearthly",
  1748 + 426: "Astral",
  1749 + 427: "Elysian",
  1750 + 428: "Celestial",
  1751 + 429: "Diamond",
  1752 + 430: "Fletcher's",
  1753 + 431: "Acrobat's",
  1754 + 432: "Harpoonist's",
  1755 + 433: "Fletcher's",
  1756 + 434: "Bowyer's",
  1757 + 435: "Archer's",
  1758 + 436: "Acrobat's",
  1759 + 437: "Gymnast's",
  1760 + 438: "Athlete's",
  1761 + 439: "Harpoonist's",
  1762 + 440: "Spearmaiden's",
  1763 + 441: "Lancer's",
  1764 + 442: "Burning",
  1765 + 443: "Sparking",
  1766 + 444: "Chilling",
  1767 + 445: "Burning",
  1768 + 446: "Blazing",
  1769 + 447: "Volcanic",
  1770 + 448: "Sparking",
  1771 + 449: "Charged",
  1772 + 450: "Powered",
  1773 + 451: "Chilling",
  1774 + 452: "Freezing",
  1775 + 453: "Glacial",
  1776 + 454: "Hexing",
  1777 + 455: "Fungal",
  1778 + 456: "Graverobber's",
  1779 + 457: "Hexing",
  1780 + 458: "Blighting",
  1781 + 459: "Accursed",
  1782 + 460: "Fungal",
  1783 + 461: "Noxious",
  1784 + 462: "Venomous",
  1785 + 463: "Graverobber's",
  1786 + 464: "Vodoun",
  1787 + 465: "Golemlord's",
  1788 + 466: "Lion Branded",
  1789 + 467: "Captain's",
  1790 + 468: "Preserver's",
  1791 + 469: "Lion Branded",
  1792 + 470: "Hawk Branded",
  1793 + 471: "Rose Branded",
  1794 + 472: "Captain's",
  1795 + 473: "Commander's",
  1796 + 474: "Marshal's",
  1797 + 475: "Preserver's",
  1798 + 476: "Warder's",
  1799 + 477: "Guardian's",
  1800 + 478: "Expert's",
  1801 + 479: "Fanatic",
  1802 + 480: "Sounding",
  1803 + 481: "Expert's",
  1804 + 482: "Veteran's",
  1805 + 483: "Master's",
  1806 + 484: "Fanatic",
  1807 + 485: "Raging",
  1808 + 486: "Furious",
  1809 + 487: "Sounding",
  1810 + 488: "Resonant",
  1811 + 489: "Echoing",
  1812 + 490: "Trainer's",
  1813 + 491: "Spiritual",
  1814 + 492: "Nature's",
  1815 + 493: "Trainer's",
  1816 + 494: "Caretaker's",
  1817 + 495: "Keeper's",
  1818 + 496: "Spiritual",
  1819 + 497: "Feral",
  1820 + 498: "Communal",
  1821 + 499: "Nature's",
  1822 + 500: "Terra's",
  1823 + 501: "Gaea's",
  1824 + 502: "Entrapping",
  1825 + 503: "Mentalist's",
  1826 + 504: "Shogukusha's",
  1827 + 505: "Entrapping",
  1828 + 506: "Trickster's",
  1829 + 507: "Cunning",
  1830 + 508: "Mentalist's",
  1831 + 509: "Psychic",
  1832 + 510: "Shadow",
  1833 + 511: "Shogukusha's",
  1834 + 512: "Sensei's",
  1835 + 513: "Kenshi's",
  1836 + 514: "Miocene",
  1837 + 515: "Miocene",
  1838 + 516: "Oligocene",
  1839 + 517: "Oligocene",
  1840 + 518: "Eocene",
  1841 + 519: "Eocene",
  1842 + 520: "Paleocene",
  1843 + 521: "Paleocene",
  1844 + 522: "Knave's",
  1845 + 523: "Jack's",
  1846 + 524: "Jester's",
  1847 + 525: "Joker's",
  1848 + 526: "Trump",
  1849 + 527: "Loud",
  1850 + 528: "Calling",
  1851 + 529: "Yelling",
  1852 + 530: "Shouting",
  1853 + 531: "Screaming",
  1854 + 532: "Paradox",
  1855 + 533: "Paradox",
  1856 + 534: "Robineye",
  1857 + 535: "Sparroweye",
  1858 + 536: "Falconeye",
  1859 + 537: "Hawkeye",
  1860 + 538: "Eagleeye",
  1861 + 539: "Visionary",
  1862 + 540: "Mnemonic",
  1863 + 541: "Snowflake",
  1864 + 542: "Shivering",
  1865 + 543: "Boreal",
  1866 + 544: "Hibernal",
  1867 + 545: "Ember",
  1868 + 546: "Smoldering",
  1869 + 547: "Smoking",
  1870 + 548: "Flaming",
  1871 + 549: "Scorching",
  1872 + 550: "Static",
  1873 + 551: "Glowing",
  1874 + 552: "Buzzing",
  1875 + 553: "Arcing",
  1876 + 554: "Shocking",
  1877 + 555: "Septic",
  1878 + 556: "Envenomed",
  1879 + 557: "Corosive",
  1880 + 558: "Toxic",
  1881 + 559: "Pestilent",
  1882 + 560: "Maiden's",
  1883 + 561: "Valkyrie's",
  1884 + 562: "Maiden's",
  1885 + 563: "Valkyrie's",
  1886 + 564: "Monk's",
  1887 + 565: "Priest's",
  1888 + 566: "Monk's",
  1889 + 567: "Priest's",
  1890 + 568: "Monk's",
  1891 + 569: "Priest's",
  1892 + 570: "Summoner's",
  1893 + 571: "Necromancer's",
  1894 + 572: "Summoner's",
  1895 + 573: "Necromancer's",
  1896 + 574: "Angel's",
  1897 + 575: "Arch-Angel's",
  1898 + 576: "Angel's",
  1899 + 577: "Arch-Angel's",
  1900 + 578: "Slayer's",
  1901 + 579: "Berserker's",
  1902 + 580: "Slayer's",
  1903 + 581: "Berserker's",
  1904 + 582: "Slayer's",
  1905 + 583: "Berserker's",
  1906 + 584: "Shaman's",
  1907 + 585: "Hierophant's",
  1908 + 586: "Shaman's",
  1909 + 587: "Hierophant's",
  1910 + 588: "Magekiller's",
  1911 + 589: "Witch-hunter's",
  1912 + 590: "Magekiller's",
  1913 + 591: "Witch-hunter's",
  1914 + 592: "Compact",
  1915 + 593: "Thin",
  1916 + 594: "Dense",
  1917 + 595: "Consecrated",
  1918 + 596: "Pure",
  1919 + 597: "Sacred",
  1920 + 598: "Hallowed",
  1921 + 599: "Divine",
  1922 + 600: "Pearl",
  1923 + 601: "Crimson",
  1924 + 602: "Red",
  1925 + 603: "Sanguinary",
  1926 + 604: "Bloody",
  1927 + 605: "Red",
  1928 + 606: "Sanguinary",
  1929 + 607: "Red",
  1930 + 608: "Jagged",
  1931 + 609: "Forked",
  1932 + 610: "Serrated",
  1933 + 611: "Jagged",
  1934 + 612: "Forked",
  1935 + 613: "Jagged",
  1936 + 614: "Snowflake",
  1937 + 615: "Shivering",
  1938 + 616: "Boreal",
  1939 + 617: "Hibernal",
  1940 + 618: "Snowflake",
  1941 + 619: "Shivering",
  1942 + 620: "Boreal",
  1943 + 621: "Hibernal",
  1944 + 622: "Snowflake",
  1945 + 623: "Shivering",
  1946 + 624: "Boreal",
  1947 + 625: "Hibernal",
  1948 + 626: "Ember",
  1949 + 627: "Smoldering",
  1950 + 628: "Smoking",
  1951 + 629: "Flaming",
  1952 + 630: "Ember",
  1953 + 631: "Smoldering",
  1954 + 632: "Smoking",
  1955 + 633: "Flaming",
  1956 + 634: "Ember",
  1957 + 635: "Smoldering",
  1958 + 636: "Smoking",
  1959 + 637: "Flaming",
  1960 + 638: "Static",
  1961 + 639: "Glowing",
  1962 + 640: "Arcing",
  1963 + 641: "Shocking",
  1964 + 642: "Static",
  1965 + 643: "Glowing",
  1966 + 644: "Arcing",
  1967 + 645: "Shocking",
  1968 + 646: "Static",
  1969 + 647: "Glowing",
  1970 + 648: "Arcing",
  1971 + 649: "Shocking",
  1972 + 650: "Septic",
  1973 + 651: "Envenomed",
  1974 + 652: "Toxic",
  1975 + 653: "Pestilent",
  1976 + 654: "Septic",
  1977 + 655: "Envenomed",
  1978 + 656: "Toxic",
  1979 + 657: "Pestilent",
  1980 + 658: "Septic",
  1981 + 659: "Envenomed",
  1982 + 660: "Toxic",
  1983 + 661: "Pestilent",
  1984 + 662: "Tireless",
  1985 + 663: "Lizard's",
  1986 + 664: "Azure",
  1987 + 665: "Crimson",
  1988 + 666: "Tangerine",
  1989 + 667: "Beryl",
  1990 + 668: "Godly",
  1991 + 669: "Cruel",
  1992 +}
  1993 +
  1994 +var magicalSuffixes = map[uint64]string{
  1995 + 1: "Health",
  1996 + 2: "Protection",
  1997 + 3: "Absorption",
  1998 + 4: "Life",
  1999 + 5: "(nothing?)",
  2000 + 6: "Warding",
  2001 + 7: "the Sentinel",
  2002 + 8: "Guarding",
  2003 + 9: "Negation",
  2004 + 10: "(nothing?)",
  2005 + 11: "Piercing",
  2006 + 12: "Bashing",
  2007 + 13: "Puncturing",
  2008 + 14: "Thorns",
  2009 + 15: "Spikes",
  2010 + 16: "Fleadiness",
  2011 + 17: "Alacrity",
  2012 + 18: "Swiitness ",
  2013 + 19: "Quickness",
  2014 + 20: "Blocking",
  2015 + 21: "Deilecting",
  2016 + 22: "the Apprentice",
  2017 + 23: "the Magus",
  2018 + 24: "Frost",
  2019 + 25: "the Glacier",
  2020 + 26: "Frost",
  2021 + 27: "Warmth",
  2022 + 28: "Flame",
  2023 + 29: "Fire",
  2024 + 30: "Burning",
  2025 + 31: "Flame",
  2026 + 32: "Shook",
  2027 + 33: "Lightning",
  2028 + 34: "Thunder",
  2029 + 35: "Shock",
  2030 + 36: "Craftsmanship",
  2031 + 37: "Quality",
  2032 + 38: "Maiming",
  2033 + 39: "Slaying",
  2034 + 40: "Gore",
  2035 + 41: "Carnage",
  2036 + 42: "Slaughter",
  2037 + 43: "Maiming",
  2038 + 44: "Worth",
  2039 + 45: "Measure",
  2040 + 46: "Excellence",
  2041 + 47: "Petlctmance",
  2042 + 48: "Measure",
  2043 + 49: "Blight",
  2044 + 50: "Venom",
  2045 + 51: "Pestilence",
  2046 + 52: "Blight",
  2047 + 53: "Dextetity",
  2048 + 54: "Dextetity",
  2049 + 55: "Skill",
  2050 + 56: "Skill",
  2051 + 57: "Accuracy",
  2052 + 58: "Precision",
  2053 + 59: "Precision",
  2054 + 60: "Petlection",
  2055 + 61: "Balance",
  2056 + 62: "Stability",
  2057 + 63: "(nothing?)",
  2058 + 64: "Regenetation",
  2059 + 65: "Regenetation",
  2060 + 66: "Regenetation",
  2061 + 67: "Regrowth",
  2062 + 68: "Regrowth",
  2063 + 69: "Vileness",
  2064 + 70: "(nothing?)",
  2065 + 71: "Greed",
  2066 + 72: "Wealth",
  2067 + 73: "Chance",
  2068 + 74: "Fortune",
  2069 + 75: "Energy",
  2070 + 76: "Energy",
  2071 + 77: "the Mind",
  2072 + 78: "Brilliance",
  2073 + 79: "Sorcery",
  2074 + 80: "Wizardry",
  2075 + 81: "the Beat",
  2076 + 82: "Light",
  2077 + 83: "Radiance",
  2078 + 84: "the Sun",
  2079 + 85: "Life",
  2080 + 86: "the Jackal",
  2081 + 87: "the Fox",
  2082 + 88: "the Wolf",
  2083 + 89: "the Wolf",
  2084 + 90: "the Tiget",
  2085 + 91: "the Mammoth",
  2086 + 92: "the Mammoth",
  2087 + 93: "the Colosuss",
  2088 + 94: "the Leech",
  2089 + 95: "the Locust",
  2090 + 96: "the Bat",
  2091 + 97: "the Vampire",
  2092 + 98: "Defiance",
  2093 + 99: "Amelioration",
  2094 + 100: "Remedy",
  2095 + 101: "(nothing?)",
  2096 + 102: "Simplicity",
  2097 + 103: "Ease",
  2098 + 104: "(nothing?)",
  2099 + 105: "Strength",
  2100 + 106: "Might",
  2101 + 107: "the Ox",
  2102 + 108: "the Ox",
  2103 + 109: "the Giant",
  2104 + 110: "the Giant",
  2105 + 111: "the Titan",
  2106 + 112: "Pacing",
  2107 + 113: "Haste",
  2108 + 114: "Speed",
  2109 + 115: "Health",
  2110 + 116: "Protection",
  2111 + 117: "Absorption",
  2112 + 118: "Life",
  2113 + 119: "Life Everlasting",
  2114 + 120: "Protection",
  2115 + 121: "Absorption",
  2116 + 122: "Life",
  2117 + 123: "Anima",
  2118 + 124: "Warding",
  2119 + 125: "the Sentinel",
  2120 + 126: "Guarding",
  2121 + 127: "Negation",
  2122 + 128: "the Sentinel",
  2123 + 129: "Guarding",
  2124 + 130: "Negation",
  2125 + 131: "Coolness",
  2126 + 132: "Incombustibility",
  2127 + 133: "Amianthus",
  2128 + 134: "Fire Quenching",
  2129 + 135: "Coolness",
  2130 + 136: "Incombustibility",
  2131 + 137: "Amianthus",
  2132 + 138: "Fire Quenching",
  2133 + 139: "Faith",
  2134 + 140: "Resistance",
  2135 + 141: "Insulation",
  2136 + 142: "Grounding",
  2137 + 143: "the Dynamo",
  2138 + 144: "Resistance",
  2139 + 145: "Insulation",
  2140 + 146: "Grounding",
  2141 + 147: "the Dynamo",
  2142 + 148: "Stoicism",
  2143 + 149: "Warming",
  2144 + 150: "Thawing",
  2145 + 151: "the Dunes",
  2146 + 152: "the Sirocco",
  2147 + 153: "Warming",
  2148 + 154: "Thawing",
  2149 + 155: "the Dunes",
  2150 + 156: "the Sirocco",
  2151 + 157: "Desire",
  2152 + 158: "Piercing",
  2153 + 159: "Bashing",
  2154 + 160: "Puncturing",
  2155 + 161: "Thorns",
  2156 + 162: "Spikes",
  2157 + 163: "Razors",
  2158 + 164: "Swords",
  2159 + 165: "Malice",
  2160 + 166: "Readiness",
  2161 + 167: "Alacrity",
  2162 + 168: "Swiftness",
  2163 + 169: "Quickness",
  2164 + 170: "Alacrity",
  2165 + 171: "Fewer",
  2166 + 172: "Blocking",
  2167 + 173: "Deflecting",
  2168 + 174: "the Apprentice",
  2169 + 175: "the Magus",
  2170 + 176: "Frost",
  2171 + 177: "the Icicle",
  2172 + 178: "the Glacier",
  2173 + 179: "Winter",
  2174 + 180: "Frost",
  2175 + 181: "Frigidity",
  2176 + 182: "Warmth",
  2177 + 183: "Flame",
  2178 + 184: "Fire",
  2179 + 185: "Burning",
  2180 + 186: "Incineration",
  2181 + 187: "Flame",
  2182 + 188: "Passion",
  2183 + 189: "Shock",
  2184 + 190: "Lightning",
  2185 + 191: "Thunder",
  2186 + 192: "Storms",
  2187 + 193: "Shock",
  2188 + 194: "Ennui",
  2189 + 195: "Craftsmanship",
  2190 + 196: "Quality",
  2191 + 197: "Maiming",
  2192 + 198: "Slaying",
  2193 + 199: "Gore",
  2194 + 200: "Damage",
  2195 + 201: "Slaughter",
  2196 + 202: "Butchery",
  2197 + 203: "Evisceration",
  2198 + 204: "Maiming",
  2199 + 205: "Craftsmanship",
  2200 + 206: "Craftsmanship",
  2201 + 207: "Craftsmanship",
  2202 + 208: "Quality",
  2203 + 209: "Quality",
  2204 + 210: "Maiming",
  2205 + 211: "Maiming",
  2206 + 212: "Craftsmanship",
  2207 + 213: "Craftsmanship",
  2208 + 214: "Quality",
  2209 + 215: "Quality",
  2210 + 216: "Maiming",
  2211 + 217: "Craftsmanship",
  2212 + 218: "Quality",
  2213 + 219: "Maiming",
  2214 + 220: "Ire",
  2215 + 221: "Wrath",
  2216 + 222: "Damage",
  2217 + 223: "Worth",
  2218 + 224: "Measure",
  2219 + 225: "Excellence",
  2220 + 226: "Performance",
  2221 + 227: "Transcendence",
  2222 + 228: "Worth",
  2223 + 229: "Measure",
  2224 + 230: "Excellence",
  2225 + 231: "Performance",
  2226 + 232: "Joyfulness",
  2227 + 233: "Bliss",
  2228 + 234: "Blight",
  2229 + 235: "Venom",
  2230 + 236: "Pestilence",
  2231 + 237: "Anthrax",
  2232 + 238: "Blight",
  2233 + 239: "Envy",
  2234 + 240: "Dexterity",
  2235 + 241: "Skill",
  2236 + 242: "Accuracy",
  2237 + 243: "Precision",
  2238 + 244: "Perfection",
  2239 + 245: "Nirvana",
  2240 + 246: "Dexterity",
  2241 + 247: "Skill",
  2242 + 248: "Accuracy",
  2243 + 249: "Precision",
  2244 + 250: "Perfection",
  2245 + 251: "Dexterity",
  2246 + 252: "Skill",
  2247 + 253: "Accuracy",
  2248 + 254: "Precision",
  2249 + 255: "Dexterity",
  2250 + 256: "Dexterity",
  2251 + 257: "Dexterity",
  2252 + 258: "Dexterity",
  2253 + 259: "Dexterity",
  2254 + 260: "Dexterity",
  2255 + 261: "Daring",
  2256 + 262: "Balance",
  2257 + 263: "Equilibrium",
  2258 + 264: "Stability",
  2259 + 265: "Balance",
  2260 + 266: "Balance",
  2261 + 267: "Balance",
  2262 + 268: "Truth",
  2263 + 269: "Regeneration",
  2264 + 270: "Regeneration",
  2265 + 271: "Regeneration",
  2266 + 272: "Regrowth",
  2267 + 273: "Regrowth",
  2268 + 274: "Revivification",
  2269 + 275: "Honor",
  2270 + 276: "Vileness",
  2271 + 277: "Greed",
  2272 + 278: "Wealth",
  2273 + 279: "Greed",
  2274 + 280: "Greed",
  2275 + 281: "Greed",
  2276 + 282: "Greed",
  2277 + 283: "Greed",
  2278 + 284: "Greed",
  2279 + 285: "Avarice",
  2280 + 286: "Chance",
  2281 + 287: "Fortune",
  2282 + 288: "Fortune",
  2283 + 289: "Luck",
  2284 + 290: "Fortune",
  2285 + 291: "Good Luck",
  2286 + 292: "Prosperity",
  2287 + 293: "Energy",
  2288 + 294: "the Mind",
  2289 + 295: "Brilliance",
  2290 + 296: "Sorcery",
  2291 + 297: "Wizardry",
  2292 + 298: "Enlightenment",
  2293 + 299: "Energy",
  2294 + 300: "the Mind",
  2295 + 301: "Brilliance",
  2296 + 302: "Sorcery",
  2297 + 303: "Wizardry",
  2298 + 304: "Energy",
  2299 + 305: "the Mind",
  2300 + 306: "Brilliance",
  2301 + 307: "Sorcery",
  2302 + 308: "Knowledge",
  2303 + 309: "the Bear",
  2304 + 310: "Light",
  2305 + 311: "Radiance",
  2306 + 312: "the Sun",
  2307 + 313: "the Jackal",
  2308 + 314: "the Fox",
  2309 + 315: "the Wolf",
  2310 + 316: "the Tiger",
  2311 + 317: "the Mammoth",
  2312 + 318: "the Colosuss",
  2313 + 319: "the Squid",
  2314 + 320: "the Whale",
  2315 + 321: "the Jackal",
  2316 + 322: "the Fox",
  2317 + 323: "the Wolf",
  2318 + 324: "the Tiger",
  2319 + 325: "the Mammoth",
  2320 + 326: "the Colosuss",
  2321 + 327: "the Jackal",
  2322 + 328: "the Fox",
  2323 + 329: "the Wolf",
  2324 + 330: "the Tiger",
  2325 + 331: "the Mammoth",
  2326 + 332: "Life",
  2327 + 333: "Life",
  2328 + 334: "Life",
  2329 + 335: "Substinence",
  2330 + 336: "Substinence",
  2331 + 337: "Substinence",
  2332 + 338: "Vita",
  2333 + 339: "Vita",
  2334 + 340: "Vita",
  2335 + 341: "Life",
  2336 + 342: "Life",
  2337 + 343: "Substinence",
  2338 + 344: "Substinence",
  2339 + 345: "Vita",
  2340 + 346: "Vita",
  2341 + 347: "Life",
  2342 + 348: "Substinence",
  2343 + 349: "Vita",
  2344 + 350: "Spirit",
  2345 + 351: "Hope",
  2346 + 352: "the Leech",
  2347 + 353: "the Locust",
  2348 + 354: "the Lamprey",
  2349 + 355: "the Leech",
  2350 + 356: "the Locust",
  2351 + 357: "the Lamprey",
  2352 + 358: "the Leech",
  2353 + 359: "the Bat",
  2354 + 360: "the Wraith",
  2355 + 361: "the Vampire",
  2356 + 362: "the Bat",
  2357 + 363: "the Wraith",
  2358 + 364: "the Vampire",
  2359 + 365: "the Bat",
  2360 + 366: "Defiance",
  2361 + 367: "Amelioration",
  2362 + 368: "Remedy",
  2363 + 369: "Simplicity",
  2364 + 370: "Ease",
  2365 + 371: "Freedom",
  2366 + 372: "Strength",
  2367 + 373: "Might",
  2368 + 374: "the Ox",
  2369 + 375: "the Giant",
  2370 + 376: "the Titan",
  2371 + 377: "Atlus",
  2372 + 378: "Strength",
  2373 + 379: "Might",
  2374 + 380: "the Us",
  2375 + 381: "the Giant",
  2376 + 382: "the Titan",
  2377 + 383: "Strength",
  2378 + 384: "Might",
  2379 + 385: "the Us",
  2380 + 386: "the Giant",
  2381 + 387: "Strength",
  2382 + 388: "Strength",
  2383 + 389: "Strength",
  2384 + 390: "Strength",
  2385 + 391: "Strength",
  2386 + 392: "Strength",
  2387 + 393: "Virility",
  2388 + 394: "Pacing",
  2389 + 395: "Haste",
  2390 + 396: "Speed",
  2391 + 397: "Traveling",
  2392 + 398: "Acceleration",
  2393 + 399: "Inertia",
  2394 + 400: "Inertia",
  2395 + 401: "Inertia",
  2396 + 402: "Self-Repair",
  2397 + 403: "Fast Repair",
  2398 + 404: "Ages",
  2399 + 405: "Heplenishing",
  2400 + 406: "Propagation",
  2401 + 407: "the Kraken",
  2402 + 408: "Memory",
  2403 + 409: "the Elephant",
  2404 + 410: "Power",
  2405 + 411: "Grace",
  2406 + 412: "Grace and Power",
  2407 + 413: "the Yeti",
  2408 + 414: "the Phoenix",
  2409 + 415: "the Efreeti",
  2410 + 416: "the Cobra",
  2411 + 417: "the Elements",
  2412 + 418: "Firebolts",
  2413 + 419: "Firebolts",
  2414 + 420: "Firebolts",
  2415 + 421: "Charged Shield",
  2416 + 422: "Charged Shield",
  2417 + 423: "Charged Shield",
  2418 + 424: "Icebolt",
  2419 + 425: "Frozen Armor",
  2420 + 426: "Static Field",
  2421 + 427: "Telekinesis",
  2422 + 428: "Frost Shield",
  2423 + 429: "Ice Blast",
  2424 + 430: "Blaze",
  2425 + 431: "Fire Ball",
  2426 + 432: "Nova",
  2427 + 433: "Nova",
  2428 + 434: "Nova Shield",
  2429 + 435: "Nova Shield",
  2430 + 436: "Nova Shield",
  2431 + 437: "Lightning",
  2432 + 438: "Lightning",
  2433 + 439: "Shiver Armor",
  2434 + 440: "Fire Wall",
  2435 + 441: "Enchant",
  2436 + 442: "Chain Lightning",
  2437 + 443: "Chain Lightning",
  2438 + 444: "Chain Lightning",
  2439 + 445: "Teleport Shield",
  2440 + 446: "Teleport Shield",
  2441 + 447: "Teleport Shield",
  2442 + 448: "Glacial Spike",
  2443 + 449: "Meteor",
  2444 + 450: "Thunder Storm",
  2445 + 451: "Energy Shield",
  2446 + 452: "Blizzard",
  2447 + 453: "Chilling Armor",
  2448 + 454: "Hydra Shield",
  2449 + 455: "Frozen ler",
  2450 + 456: "Dawn",
  2451 + 457: "Sunlight",
  2452 + 458: "Magic Arrows",
  2453 + 459: "Magic Arrows",
  2454 + 460: "Fire Arrows",
  2455 + 461: "Fire Arrows",
  2456 + 462: "lnner Sight",
  2457 + 463: "Inner Sight",
  2458 + 464: "Jabbing",
  2459 + 465: "Jabbing",
  2460 + 466: "Cold Arrows",
  2461 + 467: "Cold Arrows",
  2462 + 468: "Multiple Shot",
  2463 + 469: "Multiple Shot",
  2464 + 470: "Power Strike",
  2465 + 471: "Power Strike",
  2466 + 472: "Poison Jab",
  2467 + 473: "Poison Jab",
  2468 + 474: "Exploding Arrows",
  2469 + 475: "Exploding Arrows",
  2470 + 476: "Slow Missiles",
  2471 + 477: "Slow Missiles",
  2472 + 478: "lmpaling Strike",
  2473 + 479: "lmpaling Strike",
  2474 + 480: "Lightning Javelin",
  2475 + 481: "Lightning Javelin",
  2476 + 482: "Ice Arrows",
  2477 + 483: "Ice Arrows",
  2478 + 484: "Guided Arrows",
  2479 + 485: "Guided Arrows",
  2480 + 486: "Charged Strike",
  2481 + 487: "Charged Strike",
  2482 + 488: "Plague Jab",
  2483 + 489: "Plague Jab",
  2484 + 490: "lmmolating Arrows",
  2485 + 491: "lmmolating Arrows",
  2486 + 492: "Fending",
  2487 + 493: "Fending",
  2488 + 494: "Freezing Arrows",
  2489 + 495: "Freezing Arrows",
  2490 + 496: "Lightning Strike",
  2491 + 497: "Lightning Strike",
  2492 + 498: "Lightning Fury",
  2493 + 499: "Lightning Fury",
  2494 + 500: "Fire Bolts",
  2495 + 501: "Fire Bolts",
  2496 + 502: "Charged Bolts",
  2497 + 503: "Charged Bolts",
  2498 + 504: "Ice Bolts",
  2499 + 505: "Ice Bolts",
  2500 + 506: "Frozen Armor",
  2501 + 507: "Frozen Armor",
  2502 + 508: "Static Field",
  2503 + 509: "Static Field",
  2504 + 510: "Telekinesis",
  2505 + 511: "Telekinesis",
  2506 + 512: "Frost Novas",
  2507 + 513: "Frost Novas",
  2508 + 514: "Ice Blasts",
  2509 + 515: "Ice Blasts",
  2510 + 516: "Blazing",
  2511 + 517: "Blazing",
  2512 + 518: "Fire Balls",
  2513 + 519: "Fire Balls",
  2514 + 520: "Novas",
  2515 + 521: "Novas",
  2516 + 522: "Lightning",
  2517 + 523: "Lightning",
  2518 + 524: "Shiver Armor",
  2519 + 525: "Shiver Armor",
  2520 + 526: "Fire Walls",
  2521 + 527: "Fire Walls",
  2522 + 528: "Enchantment",
  2523 + 529: "Enchantment",
  2524 + 530: "Chain Lightning",
  2525 + 531: "Chain Lightning",
  2526 + 532: "Teleportation",
  2527 + 533: "Teleportation",
  2528 + 534: "Glacial Spikes",
  2529 + 535: "Glacial Spikes",
  2530 + 536: "Meteors",
  2531 + 537: "Meteors",
  2532 + 538: "Thunder Storm",
  2533 + 539: "Thunder Storm",
  2534 + 540: "Energy Shield",
  2535 + 541: "Energy Shield",
  2536 + 542: "Blizzards",
  2537 + 543: "Blizzards",
  2538 + 544: "Chilling Armor",
  2539 + 545: "Chilling Armor",
  2540 + 546: "Hydras",
  2541 + 547: "Hydras",
  2542 + 548: "Frozen Orbs",
  2543 + 549: "Frozen Orbs",
  2544 + 550: "Amplify Damage",
  2545 + 551: "Amplify Damage",
  2546 + 552: "Teeth",
  2547 + 553: "Teeth",
  2548 + 554: "Bone Armor",
  2549 + 555: "Bone Armor",
  2550 + 556: "Raise Skeletons",
  2551 + 557: "Raise Skeletons",
  2552 + 558: "Dim Vision",
  2553 + 559: "Dim Vision",
  2554 + 560: "Weaken",
  2555 + 561: "Weaken",
  2556 + 562: "Poison Dagger",
  2557 + 563: "Poison Dagger",
  2558 + 564: "Corpse Explosions",
  2559 + 565: "Corpse Explosions",
  2560 + 566: "Clay Golem Summoning",
  2561 + 567: "Clay Golem Summoning",
  2562 + 568: "Iron Maiden",
  2563 + 569: "Iron Maiden",
  2564 + 570: "Terror",
  2565 + 571: "Terror",
  2566 + 572: "Bone Walls",
  2567 + 573: "Bone Walls",
  2568 + 574: "Raise Skeletal Mages",
  2569 + 575: "Raise Skeletal Mages",
  2570 + 576: "Confusion",
  2571 + 577: "Confusion",
  2572 + 578: "Life Tap",
  2573 + 579: "Life Tap",
  2574 + 580: "Poison Explosion",
  2575 + 581: "Poison Explosion",
  2576 + 582: "Bone Spears",
  2577 + 583: "Bone Spears",
  2578 + 584: "Blood Golem Summoning",
  2579 + 585: "Blood Golem Summoning",
  2580 + 586: "Attraction",
  2581 + 587: "Attraction",
  2582 + 588: "Decrepification",
  2583 + 589: "Decrepification",
  2584 + 590: "Bone Imprisonment",
  2585 + 591: "Bone Imprisonment",
  2586 + 592: "Iron Golem Creation",
  2587 + 593: "Iron Golem Creation",
  2588 + 594: "Lower Resistance",
  2589 + 595: "Lower Flesistance",
  2590 + 596: "Poison Novas",
  2591 + 597: "Poison Novas",
  2592 + 598: "Bone Spirits",
  2593 + 599: "Bone Spirits",
  2594 + 600: "Fire Golem Summoning",
  2595 + 601: "Fire Golem Summoning",
  2596 + 602: "Revivification",
  2597 + 603: "Revivification",
  2598 + 604: "Sacrifice",
  2599 + 605: "Sacrifice",
  2600 + 606: "Holy Bolts",
  2601 + 607: "Holy Bolts",
  2602 + 608: "Zeal",
  2603 + 609: "Zeal",
  2604 + 610: "Vengeance",
  2605 + 611: "Vengeance",
  2606 + 612: "Blessed Hammers",
  2607 + 613: "Blessed Hammers",
  2608 + 614: "Conversion",
  2609 + 615: "Conversion",
  2610 + 616: "Fist of the Heavens",
  2611 + 617: "Fist of the Heavens",
  2612 + 618: "Bashing",
  2613 + 619: "Bashing",
  2614 + 620: "Howling",
  2615 + 621: "Howling",
  2616 + 622: "Potion Finding",
  2617 + 623: "Potion Finding",
  2618 + 624: "Taunting",
  2619 + 625: "Taunting",
  2620 + 626: "Shouting",
  2621 + 627: "Shouting",
  2622 + 628: "Stunning",
  2623 + 629: "Stunning",
  2624 + 630: "Item Finding",
  2625 + 631: "Item Finding",
  2626 + 632: "Concentration",
  2627 + 633: "Concentration",
  2628 + 634: "Battle Cry",
  2629 + 635: "Battle Cry",
  2630 + 636: "Battle Orders",
  2631 + 637: "Battle Orders",
  2632 + 638: "Grim Ward",
  2633 + 639: "Grim Ward",
  2634 + 640: "War Cry",
  2635 + 641: "War Cry",
  2636 + 642: "Battle Command",
  2637 + 643: "Battle Command",
  2638 + 644: "Firestorms",
  2639 + 645: "Firestorms",
  2640 + 646: "Molten Boulders",
  2641 + 647: "Molten Boulders",
  2642 + 648: "Eruption",
  2643 + 649: "Eruption",
  2644 + 650: "Cyclone Armor",
  2645 + 651: "Cyclone Armor",
  2646 + 652: "Twister",
  2647 + 653: "Twister",
  2648 + 654: "Volcano",
  2649 + 655: "Volcano",
  2650 + 656: "Tornado",
  2651 + 657: "Tornado",
  2652 + 658: "Armageddon",
  2653 + 659: "Armageddon",
  2654 + 660: "Hurricane",
  2655 + 661: "Hurricane",
  2656 + 662: "Damage Amplification",
  2657 + 663: "the Icicle",
  2658 + 664: "the Glacier",
  2659 + 665: "Fire",
  2660 + 666: "Burning",
  2661 + 667: "Lightning",
  2662 + 668: "Thunder",
  2663 + 669: "Daring",
  2664 + 670: "Daring",
  2665 + 671: "Knowledge",
  2666 + 672: "Knowledge",
  2667 + 673: "Virility",
  2668 + 674: "Virility",
  2669 + 675: "Readiness",
  2670 + 676: "Craftsmanship",
  2671 + 677: "Quality",
  2672 + 678: "Maiming",
  2673 + 679: "Craftsmanship",
  2674 + 680: "Quality",
  2675 + 681: "Craftsmanship",
  2676 + 682: "Blight",
  2677 + 683: "Venom",
  2678 + 684: "Pestilence",
  2679 + 685: "Anthrax",
  2680 + 686: "Blight",
  2681 + 687: "Venom",
  2682 + 688: "Pestilence",
  2683 + 689: "Anthrax",
  2684 + 690: "Blight",
  2685 + 691: "Venom",
  2686 + 692: "Pestilence",
  2687 + 693: "Anthrax",
  2688 + 694: "Frost",
  2689 + 695: "the Icicle",
  2690 + 696: "the Glacier",
  2691 + 697: "Winter",
  2692 + 698: "Frost",
  2693 + 699: "the Icicle",
  2694 + 700: "the Glacier",
  2695 + 701: "Winter",
  2696 + 702: "Frost",
  2697 + 703: "the Icicle",
  2698 + 704: "the Glacier",
  2699 + 705: "Winter",
  2700 + 706: "Flame",
  2701 + 707: "Fire",
  2702 + 708: "Burning",
  2703 + 709: "Incineration",
  2704 + 710: "Flame",
  2705 + 711: "Fire",
  2706 + 712: "Burning",
  2707 + 713: "Incineration",
  2708 + 714: "Flame",
  2709 + 715: "Fire",
  2710 + 716: "Burning",
  2711 + 717: "Incineration",
  2712 + 718: "Shock",
  2713 + 719: "Lightning",
  2714 + 720: "Thunder",
  2715 + 721: "Storms",
  2716 + 722: "Shock",
  2717 + 723: "Lightning",
  2718 + 724: "Thunder",
  2719 + 725: "Storms",
  2720 + 726: "Shock",
  2721 + 727: "Lightning",
  2722 + 728: "Thunder",
  2723 + 729: "Storms",
  2724 + 730: "Dexterity",
  2725 + 731: "Dexterity",
  2726 + 732: "Strength",
  2727 + 733: "Strength",
  2728 + 734: "Thorns",
  2729 + 735: "Frost",
  2730 + 736: "Flame",
  2731 + 737: "Blight",
  2732 + 738: "Shock",
  2733 + 739: "Regeneration",
  2734 + 740: "Energy",
  2735 + 741: "Light",
  2736 + 742: "the Leech",
  2737 + 743: "the Locust",
  2738 + 744: "the Lamprey",
  2739 + 745: "the Bat",
  2740 + 746: "the Wraith",
  2741 + 747: "the Vampire",
  2742 +*/
673 2743 typedef enum D2S_ITEMDATA_PREFIX_IDENTIFIER {
674 2744 TODO = 0
675 2745 } D2S_ITEMDATA_PREFIX_IDENTIFIER;
... ... @@ -678,21 +2748,909 @@ typedef enum D2S_ITEMDATA_SUFFIX_IDENTIFIER {
678 2748 TODO = 0
679 2749 } D2S_ITEMDATA_SUFFIX_IDENTIFIER;
680 2750  
  2751 +/*
  2752 +var rareNames = map[uint64]string{
  2753 + 1: "Bite",
  2754 + 2: "Scratch",
  2755 + 3: "Scalpel",
  2756 + 4: "Fang",
  2757 + 5: "Gutter",
  2758 + 6: "Thirst",
  2759 + 7: "Razor",
  2760 + 8: "Scythe",
  2761 + 9: "Edge",
  2762 + 10: "Saw",
  2763 + 11: "Splitter",
  2764 + 12: "Cleaver",
  2765 + 13: "Sever",
  2766 + 14: "Sunder",
  2767 + 15: "Rend",
  2768 + 16: "Mangler",
  2769 + 17: "Slayer",
  2770 + 18: "Reaver",
  2771 + 19: "Spawn",
  2772 + 20: "Gnash",
  2773 + 21: "Star",
  2774 + 22: "Blow",
  2775 + 23: "Smasher",
  2776 + 24: "Bane",
  2777 + 25: "Crusher",
  2778 + 26: "Breaker",
  2779 + 27: "Grinder",
  2780 + 28: "Crack",
  2781 + 29: "Mallet",
  2782 + 30: "Knell",
  2783 + 31: "Lance",
  2784 + 32: "Spike",
  2785 + 33: "Impaler",
  2786 + 34: "Skewer",
  2787 + 35: "Prod",
  2788 + 36: "Scourge",
  2789 + 37: "Wand",
  2790 + 38: "Wrack",
  2791 + 39: "Barb",
  2792 + 40: "Needle",
  2793 + 41: "Dart",
  2794 + 42: "Bolt",
  2795 + 43: "Quarrel",
  2796 + 44: "Fletch",
  2797 + 45: "Flight",
  2798 + 46: "Nock",
  2799 + 47: "Horn",
  2800 + 48: "Stinger",
  2801 + 49: "Quill",
  2802 + 50: "Goad",
  2803 + 51: "Branch",
  2804 + 52: "Spire",
  2805 + 53: "Song",
  2806 + 54: "Call",
  2807 + 55: "Cry",
  2808 + 56: "Spell",
  2809 + 57: "Chant",
  2810 + 58: "Weaver",
  2811 + 59: "Gnarl",
  2812 + 60: "Visage",
  2813 + 61: "Crest",
  2814 + 62: "Circlet",
  2815 + 63: "Veil",
  2816 + 64: "Hood",
  2817 + 65: "Mask",
  2818 + 66: "Brow",
  2819 + 67: "Casque",
  2820 + 68: "Visor",
  2821 + 69: "Cowl",
  2822 + 70: "Hide",
  2823 + 71: "Pelt",
  2824 + 72: "Carapace",
  2825 + 73: "Coat",
  2826 + 74: "Wrap",
  2827 + 75: "Suit",
  2828 + 76: "Cloak",
  2829 + 77: "Shroud",
  2830 + 78: "Jack",
  2831 + 79: "Mantle",
  2832 + 80: "Guard",
  2833 + 81: "Badge",
  2834 + 82: "Rock",
  2835 + 83: "Aegis",
  2836 + 84: "Ward",
  2837 + 85: "Tower",
  2838 + 86: "Shield",
  2839 + 87: "Wing",
  2840 + 88: "Mark",
  2841 + 89: "Emblem",
  2842 + 90: "Hand",
  2843 + 91: "Fist",
  2844 + 92: "Claw",
  2845 + 93: "Clutches",
  2846 + 94: "Grip",
  2847 + 95: "Grasp",
  2848 + 96: "Hold",
  2849 + 97: "Torch",
  2850 + 98: "Finger",
  2851 + 99: "Knuckle",
  2852 + 100: "Shank",
  2853 + 101: "Spur",
  2854 + 102: "Tread",
  2855 + 103: "Stalker",
  2856 + 104: "Greave",
  2857 + 105: "Blazer",
  2858 + 106: "Nails",
  2859 + 107: "Trample",
  2860 + 108: "Brogues",
  2861 + 109: "Track",
  2862 + 110: "Slippers",
  2863 + 111: "Clasp",
  2864 + 112: "Buckle",
  2865 + 113: "Harness",
  2866 + 114: "Lock",
  2867 + 115: "Fringe",
  2868 + 116: "Winding",
  2869 + 117: "Chain",
  2870 + 118: "Strap",
  2871 + 119: "Lash",
  2872 + 120: "Cord",
  2873 + 121: "Knot",
  2874 + 122: "Circle",
  2875 + 123: "Loop",
  2876 + 124: "Eye",
  2877 + 125: "Turn",
  2878 + 126: "Spiral",
  2879 + 127: "Coil",
  2880 + 128: "Gyre",
  2881 + 129: "Band",
  2882 + 130: "Whorl",
  2883 + 131: "Talisman",
  2884 + 132: "Heart",
  2885 + 133: "Noose",
  2886 + 134: "Necklace",
  2887 + 135: "Collar",
  2888 + 136: "Beads",
  2889 + 137: "Torc",
  2890 + 138: "Gorget",
  2891 + 139: "Scarab",
  2892 + 140: "Wood",
  2893 + 141: "Brand",
  2894 + 142: "Bludgeon",
  2895 + 143: "Cudgel",
  2896 + 144: "Loom",
  2897 + 145: "Harp",
  2898 + 146: "Master",
  2899 + 147: "Barl",
  2900 + 148: "Hew",
  2901 + 149: "Crook",
  2902 + 150: "Mar",
  2903 + 151: "Shell",
  2904 + 152: "Stake",
  2905 + 153: "Picket",
  2906 + 154: "Pale",
  2907 + 155: "Flange",
  2908 + 156: "Beast",
  2909 + 157: "Eagle",
  2910 + 158: "Raven",
  2911 + 159: "Viper",
  2912 + 160: "Ghoul",
  2913 + 161: "Skull",
  2914 + 162: "Blood",
  2915 + 163: "Dread",
  2916 + 164: "Doom",
  2917 + 165: "Grim",
  2918 + 166: "Bone",
  2919 + 167: "Death",
  2920 + 168: "Shadow",
  2921 + 169: "Storm",
  2922 + 170: "Rune",
  2923 + 171: "Plague",
  2924 + 172: "Stone",
  2925 + 173: "Wraith",
  2926 + 174: "Spirit",
  2927 + 175: "Storm",
  2928 + 176: "Demon",
  2929 + 177: "Cruel",
  2930 + 178: "Empyrion",
  2931 + 179: "Bramble",
  2932 + 180: "Pain",
  2933 + 181: "Loath",
  2934 + 182: "Glyph",
  2935 + 183: "Imp",
  2936 + 184: "Fiendra",
  2937 + 185: "Hailstone",
  2938 + 186: "Gale",
  2939 + 187: "Dire",
  2940 + 188: "Soul",
  2941 + 189: "Brimstone",
  2942 + 190: "Corpse",
  2943 + 191: "Carrion",
  2944 + 192: "Armageddon",
  2945 + 193: "Havoc",
  2946 + 194: "Bitter",
  2947 + 195: "Entropy",
  2948 + 196: "Chaos",
  2949 + 197: "Order",
  2950 + 198: "Rule",
  2951 + 199: "Warp",
  2952 + 200: "Rift",
  2953 + 201: "Corruption",
  2954 +}
  2955 +*/
  2956 +
681 2957 typedef enum D2S_ITEMDATA_RARENAME_IDENTIFIER {
682 2958 TODO = 0
683 2959 } D2S_ITEMDATA_RARENAME_IDENTIFIER;
684 2960  
  2961 +typedef struct D2ItemMagicalProperty {
  2962 + unsigned int numBits;
  2963 + int bias;
  2964 + const char* nameFmt;
  2965 +} D2ItemMagicalProperty;
  2966 +
  2967 +/*
  2968 +var magicalProperties = map[uint64]magicalProperty{
  2969 + 0: {Bits: []uint{8}, Bias: 32, Name: "+{0} to Strength"},
  2970 + 1: {Bits: []uint{7}, Bias: 32, Name: "+{0} to Energy"},
  2971 + 2: {Bits: []uint{7}, Bias: 32, Name: "+{0} to Dexterity"},
  2972 + 3: {Bits: []uint{7}, Bias: 32, Name: "+{0} to Vitality"},
  2973 + 7: {Bits: []uint{9}, Bias: 32, Name: "+{0} to Life"},
  2974 + 9: {Bits: []uint{8}, Bias: 32, Name: "+{0} to Mana"},
  2975 + 11: {Bits: []uint{8}, Bias: 32, Name: "+{0} to Maximum Stamina"},
  2976 + 16: {Bits: []uint{9}, Name: "+{0}% Enhanced Defense"},
  2977 +
  2978 + // It's weird that there's two bit fields here, but it seems like
  2979 + // the first bit field enhanced min damage, and the second enchances
  2980 + // maxium damage.
  2981 + 17: {Bits: []uint{9, 9}, Name: "+{0}% Enhanced Damage"},
  2982 + 19: {Bits: []uint{10}, Name: "+{0} to Attack rating"},
  2983 + 20: {Bits: []uint{6}, Name: "+{0}% Increased chance of blocking"},
  2984 + 21: {Bits: []uint{6}, Name: "+{0} to Minimum 1-handed damage"},
  2985 + 22: {Bits: []uint{7}, Name: "+{0} to Maximum 1-handed damage"},
  2986 + 23: {Bits: []uint{6}, Name: "+{0} to Minimum 2-handed damage"},
  2987 + 24: {Bits: []uint{7}, Name: "+{0} to Maximum 2-handed damage"},
  2988 + 25: {Bits: []uint{8}, Name: "Unknown (Invisible)"}, // damagepercent
  2989 + 26: {Bits: []uint{8}, Name: "Unknown (Invisible)"}, // manarecovery
  2990 + 27: {Bits: []uint{8}, Name: "Regenerate Mana {0}%"},
  2991 + 28: {Bits: []uint{8}, Name: "Heal Stamina {0}%"},
  2992 + 31: {Bits: []uint{11}, Bias: 10, Name: "+{0} Defense"},
  2993 + 32: {Bits: []uint{9}, Name: "+{0} vs. Missile"},
  2994 + 33: {Bits: []uint{8}, Bias: 10, Name: "+{0} vs. Melee"},
  2995 + 34: {Bits: []uint{6}, Name: "Damage Reduced by {0}"},
  2996 + 35: {Bits: []uint{6}, Name: "Magic Damage Reduced by {0}"},
  2997 + 36: {Bits: []uint{8}, Name: "Damage Reduced by {0}%"},
  2998 + 37: {Bits: []uint{8}, Name: "Magic Resist +{0}%"},
  2999 + 38: {Bits: []uint{8}, Name: "+{0}% to Maximum Magic Resist"},
  3000 + 39: {Bits: []uint{8}, Bias: 50, Name: "Fire Resist +{0}%"},
  3001 + 40: {Bits: []uint{5}, Name: "+{0}% to Maximum Fire Resist"},
  3002 + 41: {Bits: []uint{8}, Bias: 50, Name: "Lightning Resist +{0}%"},
  3003 + 42: {Bits: []uint{5}, Name: "+{0}% to Maximum Lightning Resist"},
  3004 + 43: {Bits: []uint{8}, Bias: 50, Name: "Cold Resist +{0}%"},
  3005 + 44: {Bits: []uint{5}, Name: "+{0}% to Maximum Cold Resist"},
  3006 + 45: {Bits: []uint{8}, Bias: 50, Name: "Poison Resist +{0}%"},
  3007 + 46: {Bits: []uint{5}, Name: "+{0}% to Maximum Poison Resist"},
  3008 + 48: {Bits: []uint{8, 9}, Name: "Adds {0}-{1} Fire Damage"},
  3009 + 49: {Bits: []uint{9}, Name: "+{0} to Maximum Fire Damage"},
  3010 + 50: {Bits: []uint{6, 10}, Name: "Adds {0}-{1} Lightning Damage"},
  3011 + 52: {Bits: []uint{8, 9}, Name: "Adds {0}-{1} Magic Damage"},
  3012 + 54: {Bits: []uint{8, 9, 8}, Name: "Adds {0}-{1} Cold Damage"},
  3013 + 57: {Bits: []uint{10, 10, 9}, Name: "Adds {0}-{1} Poison Damage over {2} Seconds"},
  3014 + 60: {Bits: []uint{7}, Name: "{0}% Life Stolen Per Hit"},
  3015 + 62: {Bits: []uint{7}, Name: "{0}% Mana Stolen Per Hit"},
  3016 + 67: {Bits: []uint{7}, Bias: 30, Name: "Unknown (Invisible)"}, // velocitypercent
  3017 + 68: {Bits: []uint{7}, Bias: 30, Name: "Unknown (Invisible)"}, // attackrate
  3018 + 71: {Bits: []uint{8}, Bias: 100, Name: "Unknown (Invisible)"}, // value
  3019 + 72: {Bits: []uint{9}, Name: "Unknown (Invisible)"}, // durability
  3020 + 73: {Bits: []uint{8}, Name: "+{0} Maximum Durability"},
  3021 + 74: {Bits: []uint{6}, Bias: 30, Name: "Replenish Life +{0}"},
  3022 + 75: {Bits: []uint{7}, Bias: 20, Name: "Increase Maximum Durability {0}%"},
  3023 + 76: {Bits: []uint{6}, Bias: 10, Name: "Increase Maximum Life {0}%"},
  3024 + 77: {Bits: []uint{6}, Bias: 10, Name: "Increase Maximum Mana {0}%"},
  3025 + 78: {Bits: []uint{7}, Name: "Attacker Takes Damage of {0}"},
  3026 + 79: {Bits: []uint{9}, Bias: 100, Name: "{0}% Extra Gold from Monsters"},
  3027 + 80: {Bits: []uint{8}, Bias: 100, Name: "{0}% Better Chance of Getting Magic Items"},
  3028 + 81: {Bits: []uint{7}, Name: "Knockback"},
  3029 + 82: {Bits: []uint{9}, Bias: 20, Name: "Unknown (Invisible)"}, // item_timeduration
  3030 +
  3031 + // First value is class, second is skill level, but they're printed in reverse
  3032 + // e.g. "+3 To Sorceress Skill Levels"
  3033 + 83: {Bits: []uint{3, 3}, Name: "+{1} to {0} Skill Levels"},
  3034 + 84: {Bits: []uint{3, 3}, Name: "+{1} to {0} Skill Levels"},
  3035 +
  3036 + // TODO: Check if experience gained really have a bias of 50.
  3037 + 85: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Experience Gained"},
  3038 + 86: {Bits: []uint{7}, Name: "+{0} Life After Each Kill"},
  3039 + 87: {Bits: []uint{7}, Name: "Reduces Prices {0}%"},
  3040 + 88: {Bits: []uint{1}, Name: "Unknown (Invisible)"}, // item_doubleherbduration
  3041 + 89: {Bits: []uint{4}, Bias: 4, Name: "+{0} to Light Radius"},
  3042 + // This property is not displayed on the item, but its effect is to alter
  3043 + // the color of the ambient light.
  3044 + 90: {Bits: []uint{5}, Name: "Ambient light"},
  3045 + // After subtracting the bias, this is usually a negative number.
  3046 + 91: {Bits: []uint{8}, Bias: 100, Name: "Requirements {0}%"},
  3047 + 92: {Bits: []uint{7}, Name: "Level requirements +{0} (Invisible)"},
  3048 + 93: {Bits: []uint{7}, Bias: 20, Name: "{0}% Increased Attack Speed"},
  3049 + 94: {Bits: []uint{7}, Bias: 64, Name: "Unknown (Invisible)"}, // item_levelreqpct
  3050 + 96: {Bits: []uint{7}, Bias: 20, Name: "{0}% Faster Run/Walk"},
  3051 +
  3052 + // Number of levels to a certain skill, e.g. +1 To Teleport.
  3053 + 97: {Bits: []uint{9, 6}, Name: "+{1} To {0}"},
  3054 +
  3055 + // NVSTATE Charm attributes. ID 98 only occurs on charms of a special
  3056 + // type, called NV state charms, they're basically for visual effects.
  3057 + // They're imported charms and does not occur naturally in the game.
  3058 + 98: {Bits: []uint{8, 1}, Name: "{1}+ to {0} (Visual effect only)"},
  3059 +
  3060 + 99: {Bits: []uint{7}, Bias: 20, Name: "{0}% Faster Hit Recovery"},
  3061 + 102: {Bits: []uint{7}, Bias: 20, Name: "{0}% Faster Block Rate"},
  3062 + 105: {Bits: []uint{7}, Bias: 20, Name: "{0}% Faster Cast Rate"},
  3063 +
  3064 + // These properties usually applied to class specific items,
  3065 + // first value selects the skill, the second determines how many
  3066 + // additional skill points are given.
  3067 + 107: {Bits: []uint{9, 3}, Name: "+{1} To {0}"},
  3068 + 108: {Bits: []uint{1}, Name: "Rest In Peace"},
  3069 + 109: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
  3070 + 181: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
  3071 + 182: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
  3072 + 183: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
  3073 + 184: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
  3074 + 185: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
  3075 + 186: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
  3076 + 187: {Bits: []uint{9, 5}, Name: "+{1} to spell {0} (char_class Only)"},
  3077 +
  3078 + 110: {Bits: []uint{8}, Bias: 20, Name: "Poison Length Reduced by {0}%"},
  3079 + 111: {Bits: []uint{9}, Bias: 20, Name: "Damage +{0}"},
  3080 + 112: {Bits: []uint{7}, Name: "Hit Causes Monsters to Flee {0}%"},
  3081 + 113: {Bits: []uint{7}, Name: "Hit Blinds Target +{0}"},
  3082 + 114: {Bits: []uint{6}, Name: "{0}% Damage Taken Goes to Mana"},
  3083 + // The value of the data field is always 1.
  3084 + 115: {Bits: []uint{1}, Name: "Ignore Target Defense"},
  3085 + 116: {Bits: []uint{7}, Name: "{0}% Target Defense"},
  3086 + // The value of the data field is always 1.
  3087 + 117: {Bits: []uint{7}, Name: "Prevent Monster Heal"},
  3088 + // The value of the data field is always 1.
  3089 + 118: {Bits: []uint{1}, Name: "Half Freeze Duration"},
  3090 + 119: {Bits: []uint{9}, Bias: 20, Name: "{0}% Bonus to Attack Rating"},
  3091 + 120: {Bits: []uint{7}, Bias: 128, Name: "{0} to Monster Defense Per Hit"},
  3092 + 121: {Bits: []uint{9}, Bias: 20, Name: "+{0}% Damage to Demons"},
  3093 + 122: {Bits: []uint{9}, Bias: 20, Name: "+{0}% Damage to Undead"},
  3094 + 123: {Bits: []uint{10}, Bias: 128, Name: "+{0} to Attack Rating against Demons"},
  3095 + 124: {Bits: []uint{10}, Bias: 128, Name: "+{0} to Attack Rating against Undead"},
  3096 + 125: {Bits: []uint{1}, Name: "Throwable"},
  3097 + // First value is class id, the next one is skill tree
  3098 + 126: {Bits: []uint{3, 3}, Name: "+{0} to Fire Skills"},
  3099 + 127: {Bits: []uint{3}, Name: "+{0} to All Skill Levels"},
  3100 + 128: {Bits: []uint{5}, Name: "Attacker Takes Lightning Damage of {0}"},
  3101 + 134: {Bits: []uint{5}, Name: "Freezes Target +{0}"},
  3102 + 135: {Bits: []uint{7}, Name: "{0}% Chance of Open Wounds"},
  3103 + 136: {Bits: []uint{7}, Name: "{0}% Chance of Crushing Blow"},
  3104 + 137: {Bits: []uint{7}, Name: "+{0} Kick Damage"},
  3105 + 138: {Bits: []uint{7}, Name: "+{0} to Mana After Each Kill"},
  3106 + 139: {Bits: []uint{7}, Name: "+{0} Life after each Demon Kill"},
  3107 + // Unknown property, shows up on Swordback Hold Spiked Shield.
  3108 + 140: {Bits: []uint{7}, Name: "Extra Blood (Invisible)"}, // item_extrablood
  3109 + 141: {Bits: []uint{7}, Name: "{0}% Deadly Strike"},
  3110 + 142: {Bits: []uint{7}, Name: "Fire Absorb {0}%"},
  3111 + 143: {Bits: []uint{7}, Name: "+{0} Fire Absorb"},
  3112 + 144: {Bits: []uint{7}, Name: "Lightning Absorb {0}%"},
  3113 + 145: {Bits: []uint{7}, Name: "+{0} Lightning Absorb"},
  3114 + 146: {Bits: []uint{7}, Name: "Magic Absorb {0}%"},
  3115 + 147: {Bits: []uint{7}, Name: "+{0} Magic Absorb"},
  3116 + 148: {Bits: []uint{7}, Name: "Cold Absorb {0}%"},
  3117 + 149: {Bits: []uint{7}, Name: "+{0} Cold Absorb"},
  3118 + 150: {Bits: []uint{7}, Name: "Slows Target by {0}%"},
  3119 + 151: {Bits: []uint{9, 5}, Name: "Level +{1} {0} When Equipped"},
  3120 + 152: {Bits: []uint{1}, Name: "Indestructible"},
  3121 + 153: {Bits: []uint{1}, Name: "Cannot Be Frozen"},
  3122 + 154: {Bits: []uint{7}, Bias: 20, Name: "{0}% Slower Stamina Drain"},
  3123 + 155: {Bits: []uint{10, 7}, Name: "{0}% Chance to Reanimate Target"},
  3124 + 156: {Bits: []uint{7}, Name: "Piercing Attack"},
  3125 + 157: {Bits: []uint{7}, Name: "Fires Magic Arrows"},
  3126 + 158: {Bits: []uint{7}, Name: "Fires Explosive Arrows or Bolts"},
  3127 + 159: {Bits: []uint{6}, Name: "+{0} to Minimum Throw Damage"},
  3128 + 160: {Bits: []uint{7}, Name: "+{0} to Maximum Throw Damage"},
  3129 + 179: {Bits: []uint{3}, Name: "+{0} to Druid Skill Levels"},
  3130 + 180: {Bits: []uint{3}, Name: "+{0} to Assassin Skill Levels"},
  3131 +
  3132 + // Ok so get this, this is quite complicated, the id 188 is for items with
  3133 + // + x to a certain skill tree, e.g. 1 + to defensive auras (paladin).
  3134 + //
  3135 + // So here's how it works, the field is 19 bits long, here's the bits for
  3136 + // the defensive auras skiller.
  3137 + //
  3138 + // 001 0000000000 011 010
  3139 + // ^ ^ ^ ^
  3140 + // levels unknown padding class id skill tree offset
  3141 + //
  3142 + // So in the above example, the first 3 bits 001 are the + levels (1), we'll
  3143 + // ignore the padding, the second interesting set of 3 bits is the class id.
  3144 + // Refer to the class.go for class ids, but paladin is 011 (3), and the
  3145 + // last 3 bits 010 (2) is the offset from the start of the class skill tree.
  3146 + // Refer to skills.go to find the different tree offsets. Paladin offset is
  3147 + // 9. So remember the last 3 bits 010 (2), that means the skill tree is
  3148 + // 9 + 2 = 11, aka the defensive auras tree.
  3149 + //
  3150 + // When reading the values, remember the bits are read from the right,
  3151 + // so the values will be [2 3 1], offset 2, class id 3, 1 + to skills.
  3152 + 188: {Bits: []uint{3, 13, 3}, Name: "+{2} to {0} Skills ({1} only)"},
  3153 +
  3154 + 189: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
  3155 + 190: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
  3156 + 191: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
  3157 + 192: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
  3158 + 193: {Bits: []uint{10, 9}, Name: "+{0} to {1} Skills (char_class Only)"},
  3159 +
  3160 + 194: {Bits: []uint{4}, Name: "Adds {0} extra sockets to the item"},
  3161 +
  3162 + // Order is spell id, level, % chance.
  3163 + 195: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When you die"},
  3164 + 196: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When you die"},
  3165 + 197: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When you die"},
  3166 +
  3167 + // Order is spell id, level, % chance.
  3168 + 198: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} On Striking"},
  3169 + 199: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} On Striking"},
  3170 + 200: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} On Striking"},
  3171 +
  3172 + // Order is spell id, level, % chance.
  3173 + 201: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When Struck"},
  3174 + 202: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When Struck"},
  3175 + 203: {Bits: []uint{6, 10, 7}, Name: "{2}% Chance to Cast Level {0} {1} When Struck"},
  3176 +
  3177 + // First value selects the spell id, second value is level, third is remaining charges
  3178 + // and the last is the total number of charges.
  3179 + 204: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3180 + 205: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3181 + 206: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3182 + 207: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3183 + 208: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3184 + 209: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3185 + 210: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3186 + 211: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3187 + 212: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3188 + 213: {Bits: []uint{6, 10, 8, 8}, Name: "Level {0} {1} ({2}/{3} Charges)"},
  3189 +
  3190 + // All values based on character level are stored in eights, so take
  3191 + // the number divide by 8 and multiply by the character level and round down.
  3192 + // Or, just do (value * 0.125)% per level.
  3193 + 214: {Bits: []uint{6}, Name: "+{0} to Defense (Based on Character Level)"},
  3194 + 215: {Bits: []uint{6}, Name: "{0}% Enhanced Defense (Based on Character Level)"},
  3195 + 216: {Bits: []uint{6}, Name: "+{0} to Life (Based on Character Level)"},
  3196 + 217: {Bits: []uint{6}, Name: "+{0} to Mana (Based on Character Level)"},
  3197 + 218: {Bits: []uint{6}, Name: "+{0} to Maximum Damage (Based on Character Level)"},
  3198 + 219: {Bits: []uint{6}, Name: "{0}% Enhanced Maximum Damage (Based on Character Level)"},
  3199 + 220: {Bits: []uint{6}, Name: "+{0} to Strength (Based on Character Level)"},
  3200 + 221: {Bits: []uint{6}, Name: "+{0} to Dexterity (Based on Character Level)"},
  3201 + 222: {Bits: []uint{6}, Name: "+{0} to Energy (Based on Character Level)"},
  3202 + 223: {Bits: []uint{6}, Name: "+{0} to Vitality (Based on Character Level)"},
  3203 + 224: {Bits: []uint{6}, Name: "+{0} to Attack Rating (Based on Character Level)"},
  3204 + 225: {Bits: []uint{6}, Name: "{0}% Bonus to Attack Rating (Based on Character Level)"},
  3205 + 226: {Bits: []uint{6}, Name: "+{0} Cold Damage (Based on Character Level)"},
  3206 + 227: {Bits: []uint{6}, Name: "+{0} Fire Damage (Based on Character Level)"},
  3207 + 228: {Bits: []uint{6}, Name: "+{0} Lightning Damage (Based on Character Level)"},
  3208 + 229: {Bits: []uint{6}, Name: "+{0} Poison Damage (Based on Character Level)"},
  3209 + 230: {Bits: []uint{6}, Name: "Cold Resist +{0}% (Based on Character Level)"},
  3210 + 231: {Bits: []uint{6}, Name: "Fire Resist +{0}% (Based on Character Level)"},
  3211 + 232: {Bits: []uint{6}, Name: "Lightning Resist +{0}% (Based on Character Level)"},
  3212 + 233: {Bits: []uint{6}, Name: "Poison Resist +{0}% (Based on Character Level)"},
  3213 + 234: {Bits: []uint{6}, Name: "+{0} Cold Absorb (Based on Character Level)"},
  3214 + 235: {Bits: []uint{6}, Name: "+{0} Fire Absorb (Based on Character Level)"},
  3215 + 236: {Bits: []uint{6}, Name: "+{0} Lightning Absorb (Based on Character Level)"},
  3216 + 237: {Bits: []uint{6}, Name: "{0} Poison Absorb (Based on Character Level)"},
  3217 + 238: {Bits: []uint{5}, Name: "Attacker Takes Damage of {0} (Based on Character Level)"},
  3218 + 239: {Bits: []uint{6}, Name: "{0}% Extra Gold from Monsters (Based on Character Level)"},
  3219 + 240: {Bits: []uint{6}, Name: "{0}% Better Chance of Getting Magic Items (Based on Character Level)"},
  3220 + 241: {Bits: []uint{6}, Name: "Heal Stamina Plus {0}% (Based on Character Level)"},
  3221 + 242: {Bits: []uint{6}, Name: "+{0} Maxmium Stamina (Based on Character Level)"},
  3222 + 243: {Bits: []uint{6}, Name: "{0}% Damage to Demons (Based on Character Level)"},
  3223 + 244: {Bits: []uint{6}, Name: "{0}% Damage to Undead (Based on Character Level)"},
  3224 + 245: {Bits: []uint{6}, Name: "+{0} to Attack Rating against Demons (Based on Character Level)"},
  3225 + 246: {Bits: []uint{6}, Name: "+{0} to Attack Rating against Undead (Based on Character Level)"},
  3226 + 247: {Bits: []uint{6}, Name: "{0}% Chance of Crushing Blow (Based on Character Level)"},
  3227 + 248: {Bits: []uint{6}, Name: "{0}% Chance of Open Wounds (Based on Character Level)"},
  3228 + 249: {Bits: []uint{6}, Name: "+{0} Kick Damage (Based on Character Level)"},
  3229 + 250: {Bits: []uint{6}, Name: "{0}% to Deadly Strike (Based on Character Level)"},
  3230 +
  3231 + // The value of the data field is not actually a time period, but a frequency in terms
  3232 + // of the number of times durability is repaired over a period of 100 seconds.
  3233 + // For example, if the value is 5, then this property repairs 1 durability in 100 / 5 = 20 seconds.
  3234 + 252: {Bits: []uint{6}, Name: "Repairs 1 Durability in {0} Seconds"},
  3235 +
  3236 + // As in the previous property, the value of the data field is a frequency in terms of the number
  3237 + // replenished over a period of 100 seconds. For example if the value is 4, then this property
  3238 + // replenishes 1 item in 100 / 4 = 25 seconds.
  3239 + 253: {Bits: []uint{6}, Name: "Replenishes Quantity"},
  3240 +
  3241 + // Number of additional items beyond the base limit, for example if the base
  3242 + // is 50 and additional is 30, then the total is 50 + 30.
  3243 + 254: {Bits: []uint{8}, Name: "Increased Stack Size"},
  3244 +
  3245 + // IDs 268 - 303 are some weird values that were never used in the actual game.
  3246 + // These values change depending on the time of day in the game.
  3247 + // The format of the bit fields are the same in all cases, the first 2 bits
  3248 + // specifies the the of time when the value is at its maximum.
  3249 + //
  3250 + // The second and third are respectively the minimum and maximum values of the property.
  3251 + // The maximum value at the time specified and the minimum at the opposite.
  3252 +
  3253 + 305: {Bits: []uint{8}, Bias: 50, Name: "{0} Pierce Cold"},
  3254 + 306: {Bits: []uint{8}, Bias: 50, Name: "{0} Pierce Fire"},
  3255 + 307: {Bits: []uint{8}, Bias: 50, Name: "{0} Pierce Lightning"},
  3256 + 308: {Bits: []uint{8}, Bias: 50, Name: "{0} Pierce Poision"},
  3257 +
  3258 + 324: {Bits: []uint{6}, Name: "Unknown (Invisible)"}, // item_extra_charges
  3259 + 329: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Fire Skill Damage"},
  3260 + 330: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Lightning Skill Damage"},
  3261 + 331: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Cold Skill Damage"},
  3262 + 332: {Bits: []uint{9}, Bias: 50, Name: "{0}% To Poison Skill Damage"},
  3263 + 333: {Bits: []uint{8}, Name: "-{0}% To Enemy Fire Resistance"},
  3264 + 334: {Bits: []uint{8}, Name: "-{0}% To Enemy Lightning Resistance"},
  3265 + 335: {Bits: []uint{8}, Name: "-{0}% To Enemy Cold Resistance"},
  3266 + 336: {Bits: []uint{8}, Name: "-{0}% To Enemy Poison Resistance"},
  3267 + 356: {Bits: []uint{2}, Name: "Quest Item Difficulty +{0} (Invisible)"},
  3268 +*/
  3269 +
685 3270 typedef enum D2S_ITEMDATA_MAGIC_PROPERTY {
686 3271 TODO = 0
687 3272 } D2S_ITEMDATA_MAGIC_PROPERTY;
688 3273  
689   -typedef struct __attribute__((packed)) {
690   - const char* header[D2S_ITEMDATA_HEADER_LENGTH]; // JM
691   - uint32_t unknown1; // This is likely version data
692   - uint8_t identified;
  3274 +/*
  3275 +var weaponDamageMap = map[string]weaponDamage{
  3276 + //Axes
  3277 + "hax": {Min: 3, Max: 6},
  3278 + "axe": {Min: 4, Max: 11},
  3279 + "2ax": {Min: 5, Max: 13},
  3280 + "mpi": {Min: 7, Max: 11},
  3281 + "wax": {Min: 10, Max: 18},
  3282 + "lax": {Min: 6, Max: 13},
  3283 + "bax": {Min: 10, Max: 18},
  3284 + "btx": {Min: 12, Max: 32},
  3285 + "gax": {Min: 9, Max: 30},
  3286 + "gix": {Min: 22, Max: 45},
  3287 + "9ha": {Min: 10, Max: 21},
  3288 + "9ax": {Min: 10, Max: 33},
  3289 + "92a": {Min: 13, Max: 38},
  3290 + "9mp": {Min: 14, Max: 34},
  3291 + "9wa": {Min: 16, Max: 45},
  3292 + "9la": {Min: 14, Max: 34},
  3293 + "9ba": {Min: 21, Max: 49},
  3294 + "9bt": {Min: 24, Max: 77},
  3295 + "9ga": {Min: 18, Max: 70},
  3296 + "9gi": {Min: 43, Max: 85},
  3297 + "7ha": {Min: 33, Max: 58},
  3298 + "7ax": {Min: 38, Max: 60},
  3299 + "72a": {Min: 33, Max: 66},
  3300 + "7mp": {Min: 30, Max: 48},
  3301 + "7wa": {Min: 24, Max: 71},
  3302 + "7la": {Min: 25, Max: 123},
  3303 + "7ba": {Min: 62, Max: 110},
  3304 + "7bt": {Min: 49, Max: 137},
  3305 + "7ga": {Min: 59, Max: 94},
  3306 + "7gi": {Min: 60, Max: 124},
  3307 +
  3308 + //Maces
  3309 + "clb": {Min: 1, Max: 6},
  3310 + "spc": {Min: 5, Max: 8},
  3311 + "mac": {Min: 3, Max: 10},
  3312 + "mst": {Min: 7, Max: 16},
  3313 + "fla": {Min: 1, Max: 24},
  3314 + "whm": {Min: 19, Max: 29},
  3315 + "mau": {Min: 30, Max: 43},
  3316 + "gma": {Min: 38, Max: 58},
  3317 + "9cl": {Min: 6, Max: 21},
  3318 + "9sp": {Min: 13, Max: 25},
  3319 + "9ma": {Min: 15, Max: 23},
  3320 + "9mt": {Min: 20, Max: 31},
  3321 + "9fl": {Min: 13, Max: 35},
  3322 + "9wh": {Min: 35, Max: 58},
  3323 + "9m9": {Min: 53, Max: 78},
  3324 + "9gm": {Min: 61, Max: 99},
  3325 + "7cl": {Min: 35, Max: 43},
  3326 + "7sp": {Min: 32, Max: 58},
  3327 + "7ma": {Min: 41, Max: 49},
  3328 + "7mt": {Min: 42, Max: 53},
  3329 + "7fl": {Min: 3, Max: 80},
  3330 + "7wh": {Min: 50, Max: 61},
  3331 + "7m7": {Min: 77, Max: 106},
  3332 + "7gm": {Min: 33, Max: 180},
  3333 +
  3334 + //Polearms
  3335 + "bar": {TwoMin: 1, TwoMax: 27},
  3336 + "vou": {TwoMin: 6, TwoMax: 21},
  3337 + "scy": {TwoMin: 8, TwoMax: 20},
  3338 + "pax": {TwoMin: 18, TwoMax: 39},
  3339 + "hal": {TwoMin: 21, TwoMax: 45},
  3340 + "wsc": {TwoMin: 15, TwoMax: 36},
  3341 + "9b7": {TwoMin: 6, TwoMax: 58},
  3342 + "9vo": {TwoMin: 14, TwoMax: 53},
  3343 + "9s8": {TwoMin: 18, TwoMax: 45},
  3344 + "9pa": {TwoMin: 34, TwoMax: 75},
  3345 + "9h9": {TwoMin: 13, TwoMax: 85},
  3346 + "9wc": {TwoMin: 30, TwoMax: 70},
  3347 + "7o7": {TwoMin: 28, TwoMax: 145},
  3348 + "7vo": {TwoMin: 17, TwoMax: 165},
  3349 + "7s8": {TwoMin: 12, TwoMax: 141},
  3350 + "7pa": {TwoMin: 33, TwoMax: 150},
  3351 + "7h7": {TwoMin: 46, TwoMax: 127},
  3352 + "7wc": {TwoMin: 40, TwoMax: 127},
  3353 +
  3354 + //Swords
  3355 + "ssd": {Min: 2, Max: 7},
  3356 + "scm": {Min: 2, Max: 6},
  3357 + "sbr": {Min: 3, Max: 8},
  3358 + "flc": {Min: 9, Max: 17},
  3359 + "crs": {Min: 5, Max: 15},
  3360 + "bsd": {Min: 7, Max: 14},
  3361 + "lsd": {Min: 3, Max: 19},
  3362 + "wsd": {Min: 8, Max: 20},
  3363 + "9ss": {Min: 8, Max: 22},
  3364 + "9sm": {Min: 8, Max: 21},
  3365 + "9sb": {Min: 10, Max: 24},
  3366 + "9fc": {Min: 16, Max: 35},
  3367 + "9cr": {Min: 13, Max: 35},
  3368 + "9bs": {Min: 16, Max: 34},
  3369 + "9ls": {Min: 10, Max: 42},
  3370 + "9wd": {Min: 18, Max: 43},
  3371 + "7ss": {Min: 31, Max: 59},
  3372 + "7sm": {Min: 26, Max: 46},
  3373 + "7sb": {Min: 33, Max: 45},
  3374 + "7fc": {Min: 28, Max: 68},
  3375 + "7cr": {Min: 31, Max: 35},
  3376 + "7bs": {Min: 37, Max: 53},
  3377 + "7ls": {Min: 5, Max: 77},
  3378 + "7wd": {Min: 40, Max: 50},
  3379 +
  3380 + // Two handed swords
  3381 + "2hs": {Min: 2, Max: 9, TwoMin: 5, TwoMax: 17},
  3382 + "clm": {Min: 5, Max: 12, TwoMin: 13, TwoMax: 30},
  3383 + "gis": {Min: 3, Max: 16, TwoMin: 9, TwoMax: 28},
  3384 + "bsw": {Min: 7, Max: 19, TwoMin: 20, TwoMax: 28},
  3385 + "flb": {Min: 9, Max: 15, TwoMin: 13, TwoMax: 26},
  3386 + "gsd": {Min: 12, Max: 20, TwoMin: 25, TwoMax: 42},
  3387 + "92h": {Min: 8, Max: 26, TwoMin: 18, TwoMax: 40},
  3388 + "9cm": {Min: 13, Max: 30, TwoMin: 26, TwoMax: 61},
  3389 + "9gs": {Min: 10, Max: 37, TwoMin: 19, TwoMax: 58},
  3390 + "9b9": {Min: 14, Max: 40, TwoMin: 39, TwoMax: 60},
  3391 + "9fb": {Min: 19, Max: 35, TwoMin: 29, TwoMax: 54},
  3392 + "9gd": {Min: 24, Max: 40, TwoMin: 47, TwoMax: 80},
  3393 + "7sh": {Min: 22, Max: 56, TwoMin: 50, TwoMax: 94},
  3394 + "7cm": {Min: 22, Max: 62, TwoMin: 67, TwoMax: 96},
  3395 + "7gs": {Min: 15, Max: 75, TwoMin: 55, TwoMax: 118},
  3396 + "7b7": {Min: 24, Max: 54, TwoMin: 71, TwoMax: 83},
  3397 + "7fb": {Min: 26, Max: 70, TwoMin: 61, TwoMax: 121},
  3398 + "7gd": {Min: 25, Max: 65, TwoMin: 58, TwoMax: 115},
  3399 +
  3400 + //Bows
  3401 + "sbw": {TwoMin: 1, TwoMax: 4},
  3402 + "hbw": {TwoMin: 2, TwoMax: 6},
  3403 + "lbw": {TwoMin: 3, TwoMax: 10},
  3404 + "cbw": {TwoMin: 4, TwoMax: 8},
  3405 + "sbb": {TwoMin: 3, TwoMax: 18},
  3406 + "swb": {TwoMin: 6, TwoMax: 14},
  3407 + "lwb": {TwoMin: 3, TwoMax: 23},
  3408 + "8sb": {TwoMin: 6, TwoMax: 19},
  3409 + "8hb": {TwoMin: 8, TwoMax: 22},
  3410 + "8lb": {TwoMin: 10, TwoMax: 29},
  3411 + "8cb": {TwoMin: 11, TwoMax: 26},
  3412 + "8s8": {TwoMin: 13, TwoMax: 30},
  3413 + "8l8": {TwoMin: 10, TwoMax: 42},
  3414 + "8sw": {TwoMin: 14, TwoMax: 35},
  3415 + "8lw": {TwoMin: 10, TwoMax: 50},
  3416 + "6sb": {TwoMin: 23, TwoMax: 50},
  3417 + "6hb": {TwoMin: 21, TwoMax: 41},
  3418 + "6lb": {TwoMin: 15, TwoMax: 59},
  3419 + "6cb": {TwoMin: 12, TwoMax: 52},
  3420 + "6s7": {TwoMin: 33, TwoMax: 40},
  3421 + "6l7": {TwoMin: 15, TwoMax: 63},
  3422 + "6sw": {TwoMin: 20, TwoMax: 53},
  3423 + "6lw": {TwoMin: 10, TwoMax: 68},
  3424 +
  3425 + //Crossbows
  3426 + "lxb": {TwoMin: 6, TwoMax: 9},
  3427 + "mxb": {TwoMin: 9, TwoMax: 16},
  3428 + "hxb": {TwoMin: 14, TwoMax: 26},
  3429 + "rxb": {TwoMin: 6, TwoMax: 12},
  3430 + "8lx": {TwoMin: 14, TwoMax: 27},
  3431 + "8mx": {TwoMin: 20, TwoMax: 42},
  3432 + "8hx": {TwoMin: 33, TwoMax: 55},
  3433 + "8rx": {TwoMin: 14, TwoMax: 32},
  3434 + "6lx": {TwoMin: 28, TwoMax: 73},
  3435 + "6mx": {TwoMin: 25, TwoMax: 87},
  3436 + "6hx": {TwoMin: 32, TwoMax: 91},
  3437 + "6rx": {TwoMin: 26, TwoMax: 40},
  3438 +
  3439 + //Javelins (throw damage, should update fields)
  3440 + "jav": {Min: 6, Max: 14},
  3441 + "pil": {Min: 7, Max: 20},
  3442 + "ssp": {Min: 10, Max: 22},
  3443 + "glv": {Min: 16, Max: 22},
  3444 + "tsp": {Min: 12, Max: 30},
  3445 + "9ja": {Min: 14, Max: 32},
  3446 + "9pi": {Min: 16, Max: 42},
  3447 + "9s9": {Min: 27, Max: 50},
  3448 + "9gl": {Min: 32, Max: 60},
  3449 + "9ts": {Min: 18, Max: 54},
  3450 + "7ja": {Min: 28, Max: 55},
  3451 + "7pi": {Min: 21, Max: 75},
  3452 + "7s7": {Min: 40, Max: 62},
  3453 + "7gl": {Min: 30, Max: 85},
  3454 + "7ts": {Min: 11, Max: 77},
  3455 +
  3456 + // Amazon-only Weapons (throw damage, should update fields)
  3457 + "am1": {Min: 7, Max: 12},
  3458 + "am2": {Min: 9, Max: 19},
  3459 + "am3": {Min: 18, Max: 24},
  3460 + "am4": {Min: 23, Max: 55},
  3461 + "am5": {Min: 6, Max: 22},
  3462 + "am6": {Min: 16, Max: 29},
  3463 + "am7": {Min: 19, Max: 41},
  3464 + "am8": {Min: 34, Max: 51},
  3465 + "am9": {Min: 42, Max: 101},
  3466 + "ama": {Min: 18, Max: 54},
  3467 + "amb": {Min: 20, Max: 47},
  3468 + "amc": {Min: 14, Max: 72},
  3469 + "amd": {Min: 65, Max: 95},
  3470 + "ame": {Min: 37, Max: 153},
  3471 + "amf": {Min: 35, Max: 66},
  3472 +
  3473 + //Scepters
  3474 + "scp": {Min: 6, Max: 11},
  3475 + "gsc": {Min: 8, Max: 18},
  3476 + "wsp": {Min: 10, Max: 17},
  3477 + "9sc": {Min: 13, Max: 24},
  3478 + "9qs": {Min: 14, Max: 36},
  3479 + "9ws": {Min: 16, Max: 38},
  3480 + "7sc": {Min: 40, Max: 52},
  3481 + "7qs": {Min: 45, Max: 54},
  3482 + "7ws": {Min: 37, Max: 43},
  3483 +
  3484 + //Spears
  3485 + "spr": {TwoMin: 3, TwoMax: 15},
  3486 + "tri": {TwoMin: 9, TwoMax: 15},
  3487 + "brn": {TwoMin: 7, TwoMax: 17},
  3488 + "spt": {TwoMin: 15, TwoMax: 23},
  3489 + "pik": {TwoMin: 14, TwoMax: 63},
  3490 + "9sr": {TwoMin: 10, TwoMax: 37},
  3491 + "9tr": {TwoMin: 19, TwoMax: 37},
  3492 + "9br": {TwoMin: 16, TwoMax: 40},
  3493 + "9st": {TwoMin: 29, TwoMax: 59},
  3494 + "9p9": {TwoMin: 27, TwoMax: 114},
  3495 + "7sr": {TwoMin: 35, TwoMax: 119},
  3496 + "7tr": {TwoMin: 29, TwoMax: 144},
  3497 + "7br": {TwoMin: 42, TwoMax: 92},
  3498 + "7st": {TwoMin: 18, TwoMax: 155},
  3499 + "7p7": {TwoMin: 33, TwoMax: 178},
  3500 +
  3501 + //Throwing
  3502 + "tkf": {Min: 4, Max: 9},
  3503 + "tax": {Min: 6, Max: 11},
  3504 + "bkf": {Min: 8, Max: 12},
  3505 + "bal": {Min: 12, Max: 15},
  3506 + "9tk": {Min: 11, Max: 24},
  3507 + "9ta": {Min: 14, Max: 27},
  3508 + "9bk": {Min: 18, Max: 33},
  3509 + "9b8": {Min: 24, Max: 34},
  3510 + "7tk": {Min: 23, Max: 54},
  3511 + "7bk": {Min: 23, Max: 39},
  3512 + "7ta": {Min: 15, Max: 66},
  3513 + "7b8": {Min: 7, Max: 60},
  3514 +
  3515 + //Daggers
  3516 + "dgr": {Min: 1, Max: 4},
  3517 + "dir": {Min: 3, Max: 9},
  3518 + "kri": {Min: 2, Max: 11},
  3519 + "bld": {Min: 4, Max: 15},
  3520 + "9dg": {Min: 6, Max: 18},
  3521 + "9di": {Min: 10, Max: 26},
  3522 + "9kr": {Min: 15, Max: 31},
  3523 + "9bl": {Min: 19, Max: 36},
  3524 + "7dg": {Min: 23, Max: 49},
  3525 + "7di": {Min: 37, Max: 53},
  3526 + "7kr": {Min: 15, Max: 57},
  3527 + "7bl": {Min: 32, Max: 47},
  3528 +
  3529 + //Staves
  3530 + "sst": {TwoMin: 1, TwoMax: 5},
  3531 + "lst": {TwoMin: 2, TwoMax: 8},
  3532 + "cst": {TwoMin: 4, TwoMax: 12},
  3533 + "bst": {TwoMin: 6, TwoMax: 13},
  3534 + "wst": {TwoMin: 12, TwoMax: 28},
  3535 + "8ss": {TwoMin: 6, TwoMax: 21},
  3536 + "8ls": {TwoMin: 8, TwoMax: 26},
  3537 + "8cs": {TwoMin: 11, TwoMax: 32},
  3538 + "8bs": {TwoMin: 14, TwoMax: 34},
  3539 + "8ws": {TwoMin: 24, TwoMax: 58},
  3540 + "6ss": {TwoMin: 69, TwoMax: 85},
  3541 + "6ls": {TwoMin: 75, TwoMax: 107},
  3542 + "6cs": {TwoMin: 80, TwoMax: 93},
  3543 + "6bs": {TwoMin: 65, TwoMax: 108},
  3544 + "6ws": {TwoMin: 83, TwoMax: 99},
  3545 +
  3546 + //Wands
  3547 + "wnd": {Min: 2, Max: 4},
  3548 + "ywn": {Min: 2, Max: 8},
  3549 + "bwn": {Min: 3, Max: 7},
  3550 + "gwn": {Min: 5, Max: 11},
  3551 + "9wn": {Min: 8, Max: 18},
  3552 + "9yw": {Min: 8, Max: 24},
  3553 + "9bw": {Min: 10, Max: 22},
  3554 + "9gw": {Min: 13, Max: 29},
  3555 + "7wn": {Min: 18, Max: 33},
  3556 + "7yw": {Min: 20, Max: 40},
  3557 + "7bw": {Min: 10, Max: 31},
  3558 + "7gw": {Min: 22, Max: 28},
  3559 +
  3560 + //Orbs
  3561 + "ob1": {Min: 2, Max: 5},
  3562 + "ob2": {Min: 3, Max: 8},
  3563 + "ob3": {Min: 4, Max: 10},
  3564 + "ob4": {Min: 5, Max: 12},
  3565 + "ob5": {Min: 8, Max: 18},
  3566 + "ob6": {Min: 8, Max: 21},
  3567 + "ob7": {Min: 10, Max: 26},
  3568 + "ob8": {Min: 11, Max: 29},
  3569 + "ob9": {Min: 13, Max: 32},
  3570 + "oba": {Min: 18, Max: 42},
  3571 + "obb": {Min: 21, Max: 46},
  3572 + "obc": {Min: 18, Max: 50},
  3573 + "obd": {Min: 23, Max: 55},
  3574 + "obe": {Min: 12, Max: 66},
  3575 + "obf": {Min: 30, Max: 53},
  3576 +
  3577 + // Assassin Claws
  3578 + "ktr": {Min: 4, Max: 7},
  3579 + "wrb": {Min: 5, Max: 9},
  3580 + "axf": {Min: 2, Max: 15},
  3581 + "ces": {Min: 7, Max: 15},
  3582 + "clw": {Min: 8, Max: 15},
  3583 + "btl": {Min: 10, Max: 14},
  3584 + "skr": {Min: 9, Max: 17},
  3585 + "9ar": {Min: 11, Max: 24},
  3586 + "9wb": {Min: 13, Max: 27},
  3587 + "9xf": {Min: 8, Max: 37},
  3588 + "9cs": {Min: 16, Max: 37},
  3589 + "9lw": {Min: 18, Max: 37},
  3590 + "9tw": {Min: 21, Max: 35},
  3591 + "9qr": {Min: 19, Max: 40},
  3592 + "7ar": {Min: 39, Max: 52},
  3593 + "7wb": {Min: 34, Max: 45},
  3594 + "7xf": {Min: 44, Max: 53},
  3595 + "7cs": {Min: 36, Max: 42},
  3596 + "7lw": {Min: 22, Max: 53},
  3597 + "7tw": {Min: 24, Max: 44},
  3598 + "7qr": {Min: 40, Max: 51},
  3599 +}
  3600 +*/
  3601 +
  3602 +typedef struct D2ItemWeaponDamage {
  3603 + D2S_ITEMDATA_IDENTIFIER itemID;
  3604 + unsigned int min;
  3605 + unsigned int max;
  3606 +} D2ItemWeaponDamage;
  3607 +
  3608 +const D2ItemWeaponDamage weaponDamage[] = {
  3609 + {D2S_ITEMDATA_IDENTIFIER_AXE,3,6},
  3610 +};
  3611 +
  3612 +typedef enum D2S_INVENTORYCLASS {
  3613 + D2S_INVENTORYCLASS_UNKNOWN = -1,
  3614 + D2S_INVENTORYCLASS_INVENTORY = 0,
  3615 + D2S_INVENTORYCLASS_MERCENARY,
  3616 + D2S_INVENTORYCLASS_CORPSE,
  3617 + D2S_INVENTORYCLASS_GOLEM
  3618 +} D2S_INVENTORYCLASS;
  3619 +
  3620 +typedef enum D2S_ITEMCLASS {
  3621 + D2S_ITEMCLASS_UNKNOWN = 0xFF,
  3622 + D2S_ITEMCLASS_OTHER = 0x01,
  3623 + D2S_ITEMCLASS_ARMOR = 0x02,
  3624 + D2S_ITEMCLASS_SHIELD = 0x03,
  3625 + D2S_ITEMCLASS_WEAPON = 0x04,
  3626 + D2S_ITEMCLASS_EAR = 0x05,
  3627 + D2S_ITEMCLASS_TOME = 0x06,
  3628 + D2S_ITEMCLASS_STACKABLE = 0x10
  3629 +} D2S_ITEMCLASS;
693 3630  
694   -} D2ItemData;
  3631 +typedef struct D2Item {
  3632 +/*
  3633 + - add/remove sockets
  3634 + - add/remove personalisation
  3635 + - add/remove ethereal
  3636 + - add/remove indestructible
  3637 + - change durability
  3638 + - change item level
  3639 + - change quality
  3640 + - change magical attributes
  3641 + - change suffix/prefix
  3642 +*/
  3643 +/*
  3644 + Class uint64 `json:"class"`
  3645 + Level uint64 `json:"level"`
  3646 + Name string `json:"name"`
  3647 +*/
  3648 +} D2Item;
695 3649  
696   -const char* getItemName(D2S_ITEMDATA_IDENTIFIER itemID);
  3650 +D2Item getItem(D2S_INVENTORYCLASS inv, unsigned int offset, void* charData, size_t dataLen);
  3651 +int setItem(D2S_INVENTORYCLASS inv, unsigned int offset, D2Item* item, void* charData, size_t dataLen);
  3652 +int exportItem(D2Item* item, const char* filename);
  3653 +int importItem(D2Item* item, const char* filename);
  3654 +void printItem(D2Item* item);
697 3655  
698 3656 #endif
699 3657 \ No newline at end of file
... ...
d2mercs.c
... ... @@ -3,91 +3,174 @@
3 3 #include <stdio.h>
4 4 #include <stdlib.h>
5 5  
6   -const char* getMercName(uint16_t mercID, uint16_t mercNameID) {
7   - int offset = getMercType(mercID);
8   - if(offset == D2S_MERCTYPE_UNKNOWN) {
9   - fprintf(stderr,"libd2char error: Unable to retrieve name for mercID %d, mercNameID %d\n",mercID, mercNameID);
10   - return NULL;
11   - }
12   - return mercNames[mercNameID + offset];
13   -}
14   -
15   -D2S_MERCTYPE getMercType(uint16_t mercID) {
16   - if(mercID >= 0 && mercID <= 5) {
17   - return D2S_MERCTYPE_ROGUE;
18   - } else if(mercID >= 6 && mercID <= 14) {
19   - return D2S_MERCTYPE_DESERT;
20   - } else if(mercID >= 15 && mercID <= 23) {
21   - return D2S_MERCTYPE_SORCEROR;
22   - } else if(mercID >= 24 && mercID <= 29) {
23   - return D2S_MERCTYPE_BARBARIAN;
24   - } else {
25   - return D2S_MERCTYPE_UNKNOWN;
26   - }
27   -}
28   -
29   -D2S_MERCSUBTYPE getMercSubType(uint16_t mercID) {
30   - D2S_MERCSUBTYPE subtype;
31   - switch(getMercType(mercID)) {
32   - case D2S_MERCTYPE_ROGUE:
33   - if(mercID == 0 || mercID == 2 || mercID == 4) {
34   - subtype = D2S_MERCSUBTYPE_FIRE_ARROW;
35   - } else {
36   - subtype = D2S_MERCSUBTYPE_COLD_ARROW;
37   - }
  6 +D2Merc getMerc(D2CharHeader* c) {
  7 + D2Merc mercData;
  8 + switch(c->mercenaryType){
  9 + case 0:
  10 + mercData.type = D2S_MERCTYPE_ROGUE;
  11 + mercData.subtype = D2S_MERCSUBTYPE_FIRE_ARROW;
  12 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
38 13 break;
39   - case D2S_MERCTYPE_DESERT:
40   - if(mercID == 6 || mercID == 9 || mercID == 12) {
41   - subtype = D2S_MERCSUBTYPE_COMBAT;
42   - } if(mercID == 7 || mercID == 10 || mercID == 13) {
43   - subtype = D2S_MERCSUBTYPE_DEFENSIVE;
44   - } else {
45   - subtype = D2S_MERCSUBTYPE_OFFENSIVE;
46   - }
  14 + case 1:
  15 + mercData.type = D2S_MERCTYPE_ROGUE;
  16 + mercData.subtype = D2S_MERCSUBTYPE_COLD_ARROW;
  17 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
47 18 break;
48   - case D2S_MERCTYPE_SORCEROR:
49   - if(mercID == 15 || mercID == 18 || mercID == 21) {
50   - subtype = D2S_MERCSUBTYPE_FIRE;
51   - } if(mercID == 16 || mercID == 19 || mercID == 22) {
52   - subtype = D2S_MERCSUBTYPE_COLD;
53   - } else {
54   - subtype = D2S_MERCSUBTYPE_LIGHTNING;
55   - }
  19 + case 2:
  20 + mercData.type = D2S_MERCTYPE_ROGUE;
  21 + mercData.subtype = D2S_MERCSUBTYPE_FIRE_ARROW;
  22 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
56 23 break;
57   - case D2S_MERCTYPE_BARBARIAN:
58   - case D2S_MERCTYPE_UNKNOWN:
59   - subtype = D2S_MERCSUBTYPE_NONE;
  24 + case 3:
  25 + mercData.type = D2S_MERCTYPE_ROGUE;
  26 + mercData.subtype = D2S_MERCSUBTYPE_COLD_ARROW;
  27 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  28 + break;
  29 + case 4:
  30 + mercData.type = D2S_MERCTYPE_ROGUE;
  31 + mercData.subtype = D2S_MERCSUBTYPE_FIRE_ARROW;
  32 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  33 + break;
  34 + case 5:
  35 + mercData.type = D2S_MERCTYPE_ROGUE;
  36 + mercData.subtype = D2S_MERCSUBTYPE_COLD_ARROW;
  37 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  38 + break;
  39 + case 6:
  40 + mercData.type = D2S_MERCTYPE_DESERT;
  41 + mercData.subtype = D2S_MERCSUBTYPE_COMBAT;
  42 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
  43 + break;
  44 + case 7:
  45 + mercData.type = D2S_MERCTYPE_DESERT;
  46 + mercData.subtype = D2S_MERCSUBTYPE_DEFENSIVE;
  47 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
  48 + break;
  49 + case 8:
  50 + mercData.type = D2S_MERCTYPE_DESERT;
  51 + mercData.subtype = D2S_MERCSUBTYPE_OFFENSIVE;
  52 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
  53 + break;
  54 + case 9:
  55 + mercData.type = D2S_MERCTYPE_DESERT;
  56 + mercData.subtype = D2S_MERCSUBTYPE_COMBAT;
  57 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  58 + break;
  59 + case 10:
  60 + mercData.type = D2S_MERCTYPE_DESERT;
  61 + mercData.subtype = D2S_MERCSUBTYPE_DEFENSIVE;
  62 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  63 + break;
  64 + case 11:
  65 + mercData.type = D2S_MERCTYPE_DESERT;
  66 + mercData.subtype = D2S_MERCSUBTYPE_OFFENSIVE;
  67 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  68 + break;
  69 + case 12:
  70 + mercData.type = D2S_MERCTYPE_DESERT;
  71 + mercData.subtype = D2S_MERCSUBTYPE_COMBAT;
  72 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  73 + break;
  74 + case 13:
  75 + mercData.type = D2S_MERCTYPE_DESERT;
  76 + mercData.subtype = D2S_MERCSUBTYPE_DEFENSIVE;
  77 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  78 + break;
  79 + case 14:
  80 + mercData.type = D2S_MERCTYPE_DESERT;
  81 + mercData.subtype = D2S_MERCSUBTYPE_OFFENSIVE;
  82 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  83 + break;
  84 + case 15:
  85 + mercData.type = D2S_MERCTYPE_SORCEROR;
  86 + mercData.subtype = D2S_MERCSUBTYPE_FIRE;
  87 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
  88 + break;
  89 + case 16:
  90 + mercData.type = D2S_MERCTYPE_SORCEROR;
  91 + mercData.subtype = D2S_MERCSUBTYPE_COLD;
  92 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
  93 + break;
  94 + case 17:
  95 + mercData.type = D2S_MERCTYPE_SORCEROR;
  96 + mercData.subtype = D2S_MERCSUBTYPE_LIGHTNING;
  97 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
  98 + break;
  99 + case 18:
  100 + mercData.type = D2S_MERCTYPE_SORCEROR;
  101 + mercData.subtype = D2S_MERCSUBTYPE_FIRE;
  102 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  103 + break;
  104 + case 19:
  105 + mercData.type = D2S_MERCTYPE_SORCEROR;
  106 + mercData.subtype = D2S_MERCSUBTYPE_COLD;
  107 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  108 + break;
  109 + case 20:
  110 + mercData.type = D2S_MERCTYPE_SORCEROR;
  111 + mercData.subtype = D2S_MERCSUBTYPE_LIGHTNING;
  112 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  113 + break;
  114 + case 21:
  115 + mercData.type = D2S_MERCTYPE_SORCEROR;
  116 + mercData.subtype = D2S_MERCSUBTYPE_FIRE;
  117 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  118 + break;
  119 + case 22:
  120 + mercData.type = D2S_MERCTYPE_SORCEROR;
  121 + mercData.subtype = D2S_MERCSUBTYPE_COLD;
  122 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  123 + break;
  124 + case 23:
  125 + mercData.type = D2S_MERCTYPE_SORCEROR;
  126 + mercData.subtype = D2S_MERCSUBTYPE_LIGHTNING;
  127 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  128 + break;
  129 + case 24:
  130 + mercData.type = D2S_MERCTYPE_BARBARIAN;
  131 + mercData.subtype = D2S_MERCSUBTYPE_NONE;
  132 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
  133 + break;
  134 + case 25:
  135 + mercData.type = D2S_MERCTYPE_BARBARIAN;
  136 + mercData.subtype = D2S_MERCSUBTYPE_NONE;
  137 + mercData.difficulty = D2S_DIFFICULTY_NORMAL;
  138 + break;
  139 + case 26:
  140 + mercData.type = D2S_MERCTYPE_BARBARIAN;
  141 + mercData.subtype = D2S_MERCSUBTYPE_NONE;
  142 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  143 + break;
  144 + case 27:
  145 + mercData.type = D2S_MERCTYPE_BARBARIAN;
  146 + mercData.subtype = D2S_MERCSUBTYPE_NONE;
  147 + mercData.difficulty = D2S_DIFFICULTY_NIGHTMARE;
  148 + break;
  149 + case 28:
  150 + mercData.type = D2S_MERCTYPE_BARBARIAN;
  151 + mercData.subtype = D2S_MERCSUBTYPE_NONE;
  152 + mercData.difficulty = D2S_DIFFICULTY_HELL;
  153 + break;
  154 + default:
  155 + mercData.type = D2S_MERCTYPE_UNKNOWN;
  156 + mercData.subtype = D2S_MERCSUBTYPE_NONE;
  157 + mercData.difficulty = D2S_DIFFICULTY_UNKNOWN;
60 158 break;
61 159 }
62   - return subtype;
63   -}
64   -
65   -D2S_DIFFICULTY getMercDifficulty(uint16_t mercID) {
66   - if(mercID == 0 || mercID == 1 ||
67   - mercID == 6 || mercID == 7 || mercID == 8 ||
68   - mercID == 15 || mercID == 16 || mercID == 17 ||
69   - mercID == 24 || mercID == 25) {
70   - return D2S_DIFFICULTY_NORMAL;
71   - } else if (mercID == 2 || mercID == 3 ||
72   - mercID == 9 || mercID == 10 || mercID == 11 ||
73   - mercID == 18 || mercID == 19 || mercID == 20 ||
74   - mercID == 26 || mercID == 27) {
75   - return D2S_DIFFICULTY_NIGHTMARE;
76   - } else if (mercID == 4 || mercID == 5 ||
77   - mercID == 12 || mercID == 13 || mercID == 14 ||
78   - mercID == 21 || mercID == 22 || mercID == 23 ||
79   - mercID == 28 || mercID == 29) {
80   - return D2S_DIFFICULTY_HELL;
  160 + if(mercData.type == D2S_MERCTYPE_UNKNOWN) {
  161 + fprintf(stderr,"libd2char error: Unable to retrieve name for mercID %d, mercNameID %d\n",c->mercenaryType, c->mercenaryNameID);
  162 + return mercData;
81 163 }
82   - return D2S_DIFFICULTY_UNKNOWN;
  164 + mercData.name = mercNames[c->mercenaryNameID + mercData.type];
  165 + return mercData;
83 166 }
84 167  
85   -int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIFFICULTY difficulty) {
86   - switch(type) {
  168 +int setMerc(D2CharHeader* c, D2Merc* mercData) {
  169 + switch(mercData->type) {
87 170 case D2S_MERCTYPE_ROGUE:
88   - switch(subtype) {
  171 + switch(mercData->subtype) {
89 172 case D2S_MERCSUBTYPE_FIRE_ARROW:
90   - switch(difficulty) {
  173 + switch(mercData->difficulty) {
91 174 case D2S_DIFFICULTY_NORMAL:
92 175 c->mercenaryType = 0;
93 176 return 0;
... ... @@ -103,7 +186,7 @@ int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIF
103 186 }
104 187 break;
105 188 case D2S_MERCSUBTYPE_COLD_ARROW:
106   - switch(difficulty) {
  189 + switch(mercData->difficulty) {
107 190 case D2S_DIFFICULTY_NORMAL:
108 191 c->mercenaryType = 1;
109 192 return 0;
... ... @@ -121,9 +204,9 @@ int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIF
121 204 }
122 205 break;
123 206 case D2S_MERCTYPE_DESERT:
124   - switch(subtype) {
  207 + switch(mercData->subtype) {
125 208 case D2S_MERCSUBTYPE_COMBAT:
126   - switch(difficulty) {
  209 + switch(mercData->difficulty) {
127 210 case D2S_DIFFICULTY_NORMAL:
128 211 c->mercenaryType = 6;
129 212 return 0;
... ... @@ -139,7 +222,7 @@ int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIF
139 222 }
140 223 break;
141 224 case D2S_MERCSUBTYPE_DEFENSIVE:
142   - switch(difficulty) {
  225 + switch(mercData->difficulty) {
143 226 case D2S_DIFFICULTY_NORMAL:
144 227 c->mercenaryType = 7;
145 228 return 0;
... ... @@ -155,7 +238,7 @@ int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIF
155 238 }
156 239 break;
157 240 case D2S_MERCSUBTYPE_OFFENSIVE:
158   - switch(difficulty) {
  241 + switch(mercData->difficulty) {
159 242 case D2S_DIFFICULTY_NORMAL:
160 243 c->mercenaryType = 8;
161 244 return 0;
... ... @@ -173,9 +256,9 @@ int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIF
173 256 }
174 257 break;
175 258 case D2S_MERCTYPE_SORCEROR:
176   - switch(subtype) {
  259 + switch(mercData->subtype) {
177 260 case D2S_MERCSUBTYPE_FIRE:
178   - switch(difficulty) {
  261 + switch(mercData->difficulty) {
179 262 case D2S_DIFFICULTY_NORMAL:
180 263 c->mercenaryType = 15;
181 264 return 0;
... ... @@ -191,7 +274,7 @@ int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIF
191 274 }
192 275 break;
193 276 case D2S_MERCSUBTYPE_COLD:
194   - switch(difficulty) {
  277 + switch(mercData->difficulty) {
195 278 case D2S_DIFFICULTY_NORMAL:
196 279 c->mercenaryType = 16;
197 280 return 0;
... ... @@ -207,7 +290,7 @@ int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIF
207 290 }
208 291 break;
209 292 case D2S_MERCSUBTYPE_LIGHTNING:
210   - switch(difficulty) {
  293 + switch(mercData->difficulty) {
211 294 case D2S_DIFFICULTY_NORMAL:
212 295 c->mercenaryType = 17;
213 296 return 0;
... ... @@ -229,7 +312,7 @@ int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIF
229 312 // noticeable effect in game, so I'm considering only one of them. If you want to specifcially
230 313 // change to the other type, you probably know already what the mercID is so change it directly
231 314 // in the header instead of using this function
232   - switch(difficulty) {
  315 + switch(mercData->difficulty) {
233 316 case D2S_DIFFICULTY_NORMAL:
234 317 c->mercenaryType = 24;
235 318 return 0;
... ...
d2mercs.h
... ... @@ -180,12 +180,14 @@ const char* const mercNames[] = {
180 180 D2S_MERC_NAME_148
181 181 };
182 182  
183   -// Returns static string from library memory, no need to free
184   -const char* getMercName(uint16_t mercID, uint16_t mercNameID);
  183 +typedef struct D2Merc {
  184 + const char* name;
  185 + D2S_MERCTYPE type;
  186 + D2S_MERCSUBTYPE subtype;
  187 + D2S_DIFFICULTY difficulty;
  188 +} D2Merc;
185 189  
186   -D2S_MERCTYPE getMercType(uint16_t mercID);
187   -D2S_MERCSUBTYPE getMercSubType(uint16_t mercID);
188   -D2S_DIFFICULTY getMercDifficulty(uint16_t mercID);
189   -int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIFFICULTY difficulty);
  190 +D2Merc getMerc(D2CharHeader* c);
  191 +int setMerc(D2CharHeader* c, D2Merc* mercData);
190 192  
191 193 #endif
192 194 \ No newline at end of file
... ...
d2quest.c
... ... @@ -3,145 +3,101 @@
3 3  
4 4 #include <stdio.h>
5 5  
6   -const char* getQuestName(D2S_QUEST quest) {
7   - if(quest > D2S_QUESTDATA_NUMQUESTS) {
8   - fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
9   - return NULL;
10   - }
11   - return questName[quest];
12   -}
13   -
14   -int getCheckpointDescriptions(D2S_QUEST quest, const char* *descriptions[16]) {
15   - if(quest > D2S_QUESTDATA_NUMQUESTS) {
16   - fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
17   - return -1;
18   - }
19   - memcpy(descriptions,(&checkpointDescriptions) + (quest * 16 * sizeof(const char*)), 16 * sizeof(const char*));
20   - return 0;
21   -}
22   -
23   -int getQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t* data) {
  6 +int getQuestData(D2QuestData* d, D2S_QUEST_IDENTIFIER questID, D2Quest* quest, D2S_DIFFICULTY difficulty) {
24 7 if(difficulty != D2S_DIFFICULTY_NORMAL ||
25 8 difficulty != D2S_DIFFICULTY_NIGHTMARE ||
26 9 difficulty != D2S_DIFFICULTY_HELL) {
27 10 fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty);
28 11 return -1;
29 12 }
30   - if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) {
31   - *data = d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest];
32   - } else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) {
33   - *data = d->quests[difficulty].actData[D2S_ACT2].questCheckpoints[quest - D2S_QUEST_RADAMENT_LAIR];
34   - } else if(quest >= D2S_QUEST_GOLDEN_BIRD && quest <= D2S_QUEST_GUARDIAN) {
35   - *data = d->quests[difficulty].actData[D2S_ACT3].questCheckpoints[quest - D2S_QUEST_GOLDEN_BIRD];
36   - } else if(quest >= D2S_QUEST_FALLEN_ANGEL && quest <= D2S_QUEST_TERROR_END) {
37   - *data = d->quests[difficulty].actData[D2S_ACT4].questCheckpoints[quest - D2S_QUEST_FALLEN_ANGEL];
38   - } else if(quest >= D2S_QUEST_SIEGE_ON_HARROGATH && quest <= D2S_QUEST_EVE_OF_DESTRUCTION) {
39   - *data = d->quests[difficulty].expansionAct.questCheckpoints[quest - D2S_QUEST_SIEGE_ON_HARROGATH];
  13 + memcpy(quest,&quests[questID],sizeof(D2Quest));
  14 + quest->difficulty = difficulty;
  15 + if(questID >= D2S_QUEST_DEN_OF_EVIL && questID <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) {
  16 + quest->questData = d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[questID];
  17 + } else if(questID >= D2S_QUEST_RADAMENT_LAIR && questID <= D2S_QUEST_SEVEN_TOMBS) {
  18 + quest->questData = d->quests[difficulty].actData[D2S_ACT2].questCheckpoints[questID - D2S_QUEST_RADAMENT_LAIR];
  19 + } else if(questID >= D2S_QUEST_GOLDEN_BIRD && questID <= D2S_QUEST_GUARDIAN) {
  20 + quest->questData = d->quests[difficulty].actData[D2S_ACT3].questCheckpoints[questID - D2S_QUEST_GOLDEN_BIRD];
  21 + } else if(questID >= D2S_QUEST_FALLEN_ANGEL && questID <= D2S_QUEST_TERROR_END) {
  22 + quest->questData = d->quests[difficulty].actData[D2S_ACT4].questCheckpoints[questID - D2S_QUEST_FALLEN_ANGEL];
  23 + } else if(questID >= D2S_QUEST_SIEGE_ON_HARROGATH && questID <= D2S_QUEST_EVE_OF_DESTRUCTION) {
  24 + quest->questData = d->quests[difficulty].expansionAct.questCheckpoints[questID - D2S_QUEST_SIEGE_ON_HARROGATH];
40 25 } else {
41   - fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
  26 + fprintf(stderr,"libd2char error: quest %d doesn't exist\n",questID);
42 27 return -1;
43 28 }
44 29 return 0;
45 30 }
46 31  
47   -int setQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t questData) {
48   - if(difficulty != D2S_DIFFICULTY_NORMAL ||
49   - difficulty != D2S_DIFFICULTY_NIGHTMARE ||
50   - difficulty != D2S_DIFFICULTY_HELL) {
51   - fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty);
  32 +int setQuestData(D2QuestData* d, D2S_QUEST_IDENTIFIER questID, D2Quest* quest) {
  33 + if(quest->difficulty != D2S_DIFFICULTY_NORMAL ||
  34 + quest->difficulty != D2S_DIFFICULTY_NIGHTMARE ||
  35 + quest->difficulty != D2S_DIFFICULTY_HELL) {
  36 + fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",quest->difficulty);
52 37 return -1;
53 38 }
54   - if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) {
55   - d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest] = questData;
56   - } else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) {
57   - d->quests[difficulty].actData[D2S_ACT2].questCheckpoints[quest - D2S_QUEST_RADAMENT_LAIR] = questData;
58   - } else if(quest >= D2S_QUEST_GOLDEN_BIRD && quest <= D2S_QUEST_GUARDIAN) {
59   - d->quests[difficulty].actData[D2S_ACT3].questCheckpoints[quest - D2S_QUEST_GOLDEN_BIRD] = questData;
60   - } else if(quest >= D2S_QUEST_FALLEN_ANGEL && quest <= D2S_QUEST_TERROR_END) {
61   - d->quests[difficulty].actData[D2S_ACT4].questCheckpoints[quest - D2S_QUEST_FALLEN_ANGEL] = questData;
62   - } else if(quest >= D2S_QUEST_SIEGE_ON_HARROGATH && quest <= D2S_QUEST_EVE_OF_DESTRUCTION) {
63   - d->quests[difficulty].expansionAct.questCheckpoints[quest - D2S_QUEST_SIEGE_ON_HARROGATH] = questData;
  39 + if(questID >= D2S_QUEST_DEN_OF_EVIL && questID <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) {
  40 + d->quests[quest->difficulty].actData[D2S_ACT1].questCheckpoints[questID] = quest->questData;
  41 + } else if(questID >= D2S_QUEST_RADAMENT_LAIR && questID <= D2S_QUEST_SEVEN_TOMBS) {
  42 + d->quests[quest->difficulty].actData[D2S_ACT2].questCheckpoints[questID - D2S_QUEST_RADAMENT_LAIR] = quest->questData;
  43 + } else if(questID >= D2S_QUEST_GOLDEN_BIRD && questID <= D2S_QUEST_GUARDIAN) {
  44 + d->quests[quest->difficulty].actData[D2S_ACT3].questCheckpoints[questID - D2S_QUEST_GOLDEN_BIRD] = quest->questData;
  45 + } else if(questID >= D2S_QUEST_FALLEN_ANGEL && questID <= D2S_QUEST_TERROR_END) {
  46 + d->quests[quest->difficulty].actData[D2S_ACT4].questCheckpoints[questID - D2S_QUEST_FALLEN_ANGEL] = quest->questData;
  47 + } else if(questID >= D2S_QUEST_SIEGE_ON_HARROGATH && questID <= D2S_QUEST_EVE_OF_DESTRUCTION) {
  48 + d->quests[quest->difficulty].expansionAct.questCheckpoints[questID - D2S_QUEST_SIEGE_ON_HARROGATH] = quest->questData;
64 49 } else {
65   - fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
  50 + fprintf(stderr,"libd2char error: quest %d doesn't exist\n",questID);
66 51 return -1;
67 52 }
68 53 return 0;
69 54 }
70 55  
71   -int isQuestStarted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty) {
72   - uint16_t data = 0;
73   - if(getQuestStatus(d,quest,difficulty,&data) < 0) {
74   - return -1;
75   - }
76   - return data & D2S_QUEST_STATUS_STARTED;
  56 +int isQuestStarted(D2Quest* quest) {
  57 + return quest->questData & D2S_QUEST_STATUS_STARTED;
77 58 }
78 59  
79   -int isQuestRewardCollected(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty) {
80   - uint16_t data = 0;
81   - if(getQuestStatus(d,quest,difficulty,&data) < 0) {
82   - return -1;
83   - }
84   - return data & D2S_QUEST_STATUS_REWARD_AVAILABLE;
  60 +int isQuestRewardCollected(D2Quest* quest) {
  61 + return quest->questData & D2S_QUEST_STATUS_REWARD_AVAILABLE;
85 62 }
86 63  
87   -int isQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty) {
88   - uint16_t data = 0;
89   - if(getQuestStatus(d,quest,difficulty,&data) < 0) {
90   - return -1;
91   - }
92   - return data & D2S_QUEST_STATUS_COMPLETED;
  64 +int isQuestCompleted(D2Quest* quest) {
  65 + return quest->questData & D2S_QUEST_STATUS_COMPLETED;
93 66 }
94 67  
95   -int setQuestStarted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
  68 +void setQuestStarted(D2Quest* quest, int bool) {
96 69 // To reset the quest, just zero out the whole thing
97 70 // To set as started, just set bit 2 and clear the rest
98   - uint16_t questData = 0;
99   - if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
100   - return -1;
101   - }
102 71 if(bool) {
103   - questData = D2S_QUEST_STATUS_STARTED;
  72 + quest->questData = D2S_QUEST_STATUS_STARTED;
104 73 } else {
105   - questData = 0x0000;
  74 + quest->questData = 0x0000;
106 75 }
107   - return setQuestStatus(d,quest,difficulty,questData);
108 76 }
109 77  
110   -int setQuestRewardCollected(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
  78 +void setQuestRewardCollected(D2Quest* quest, int bool) {
111 79 // To reset, just clear bit 0 and set bit 1.
112 80 // Do the inverse to set reward as collected (but why whould you tho???)
113 81 if(bool) {
114   - return setQuestCompleted(d,quest,difficulty,1);
  82 + setQuestCompleted(quest,1);
115 83 } else {
116   - if(setQuestCompleted(d,quest,difficulty,0) < 0) {
117   - return -1;
118   - }
119   - uint16_t questData;
120   - if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
121   - return -1;
122   - }
123   - questData |= D2S_QUEST_STATUS_REWARD_AVAILABLE;
124   - return setQuestStatus(d,quest,difficulty,questData);
  84 + setQuestCompleted(quest,0);
  85 + quest->questData |= D2S_QUEST_STATUS_REWARD_AVAILABLE;
125 86 }
126 87 }
127 88  
128   -int setQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
  89 +void setQuestCompleted(D2Quest* quest, int bool) {
129 90 // To reset, clear bit 0, bit 12 and bit 13 (13 is kinda optional since it will be cleared by
130 91 // the game when loading the savegame).
131 92 // To set as completed, just set bit 0 and bit 12 and clear bit 1
132   - uint16_t questData;
133   - if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
134   - return -1;
135   - }
136 93 if(bool) {
137   - questData &= ~D2S_QUEST_STATUS_REWARD_AVAILABLE;
138   - questData |= D2S_QUEST_STATUS_COMPLETED;
139   - questData |= D2S_QUEST_STATUS_SEEN_FINISH_ANIMATION;
  94 + quest->questData &= ~D2S_QUEST_STATUS_REWARD_AVAILABLE;
  95 + quest->questData |= D2S_QUEST_STATUS_COMPLETED;
  96 + quest->questData |= D2S_QUEST_STATUS_SEEN_FINISH_ANIMATION;
140 97 } else {
141   - questData &= ~D2S_QUEST_STATUS_COMPLETED;
142   - questData &= ~D2S_QUEST_STATUS_SEEN_FINISH_ANIMATION;
  98 + quest->questData &= ~D2S_QUEST_STATUS_COMPLETED;
  99 + quest->questData &= ~D2S_QUEST_STATUS_SEEN_FINISH_ANIMATION;
143 100 }
144   - return setQuestStatus(d,quest,difficulty,questData);
145 101 }
146 102  
147 103 int getSpecialQuestStatus(D2QuestData* d, D2S_SPECIALQUEST specialQuestState, D2S_DIFFICULTY difficulty) {
... ... @@ -172,10 +128,12 @@ int setSpecialQuestStatus(D2QuestData* d, D2S_SPECIALQUEST specialQuestState, D2
172 128 return -1;
173 129 }
174 130 int ret = 0;
  131 + D2Quest quest;
175 132 switch(specialQuestState) {
176 133 case D2S_SPECIALQUEST_AKARA_RESPEC:
177 134 // This operation only makes sense if the quest is actually completed, otherwise ignore request
178   - if(isQuestCompleted(d,D2S_QUEST_DEN_OF_EVIL,difficulty)) {
  135 + getQuestData(d,D2S_QUEST_DEN_OF_EVIL,&quest,difficulty);
  136 + if(isQuestCompleted(&quest)) {
179 137 if(bool) {
180 138 d->quests[difficulty].akaraRespecData = 0x8001;
181 139 } else {
... ...
d2quest.h
1 1 #ifndef D2QUEST_H
2 2 #define D2QUEST_H
3 3  
4   -// Forward declaration
5   -typedef enum D2S_DIFFICULTY D2S_DIFFICULTY;
6   -
7 4 #include <stdint.h>
8 5  
9 6 #include "d2char.h"
  7 +#include "d2common.h"
10 8 #include "d2strings.h"
11 9  
12 10 #define D2S_QUESTDATA_HEADER_LENGTH 4
13 11 #define D2S_QUESTDATA_NUMQUESTS 27
14 12  
15   -typedef enum D2S_QUEST {
  13 +typedef enum D2S_QUEST_IDENTIFIER {
16 14 D2S_QUEST_UNKNOWN = -1,
17 15 D2S_QUEST_DEN_OF_EVIL = 0,
18 16 D2S_QUEST_SISTER_BURIAL_GROUNDS,
... ... @@ -41,10 +39,44 @@ typedef enum D2S_QUEST {
41 39 D2S_QUEST_BETRAYAL_OF_HARROGATH,
42 40 D2S_QUEST_RITE_OF_PASSAGE,
43 41 D2S_QUEST_EVE_OF_DESTRUCTION
44   -} D2S_QUEST;
45   -
46   -const char* const questName[] = {
47   -
  42 +} D2S_QUEST_IDENTIFIER;
  43 +
  44 +// TODO transform this into struct with name and checkpoints
  45 +typedef struct D2Quest {
  46 + const char* name;
  47 + const char* checkpointNames[16];
  48 + uint16_t questData;
  49 + D2S_DIFFICULTY difficulty;
  50 +} D2Quest;
  51 +
  52 +const D2Quest quests[] = {
  53 + {"Den of Evil", {D2S_QUEST_CHECKPOINT_0, D2S_QUEST_CHECKPOINT_1, D2S_QUEST_CHECKPOINT_2, D2S_QUEST_CHECKPOINT_3, D2S_QUEST_CHECKPOINT_4, D2S_QUEST_CHECKPOINT_5, D2S_QUEST_CHECKPOINT_6, D2S_QUEST_CHECKPOINT_7, D2S_QUEST_CHECKPOINT_8, D2S_QUEST_CHECKPOINT_9, D2S_QUEST_CHECKPOINT_10, D2S_QUEST_CHECKPOINT_11, D2S_QUEST_CHECKPOINT_12, D2S_QUEST_CHECKPOINT_13, D2S_QUEST_CHECKPOINT_14, D2S_QUEST_CHECKPOINT_15}, 0, D2S_DIFFICULTY_UNKNOWN},
  54 + {"Sister's Burial Grounds", {D2S_QUEST_CHECKPOINT_16, D2S_QUEST_CHECKPOINT_17, D2S_QUEST_CHECKPOINT_18, D2S_QUEST_CHECKPOINT_19, D2S_QUEST_CHECKPOINT_20, D2S_QUEST_CHECKPOINT_21, D2S_QUEST_CHECKPOINT_22, D2S_QUEST_CHECKPOINT_23, D2S_QUEST_CHECKPOINT_24, D2S_QUEST_CHECKPOINT_25, D2S_QUEST_CHECKPOINT_26, D2S_QUEST_CHECKPOINT_27, D2S_QUEST_CHECKPOINT_28, D2S_QUEST_CHECKPOINT_29, D2S_QUEST_CHECKPOINT_30, D2S_QUEST_CHECKPOINT_31}, 0, D2S_DIFFICULTY_UNKNOWN},
  55 + {"Search For Cain", {D2S_QUEST_CHECKPOINT_32, D2S_QUEST_CHECKPOINT_33, D2S_QUEST_CHECKPOINT_34, D2S_QUEST_CHECKPOINT_35, D2S_QUEST_CHECKPOINT_36, D2S_QUEST_CHECKPOINT_37, D2S_QUEST_CHECKPOINT_38, D2S_QUEST_CHECKPOINT_39, D2S_QUEST_CHECKPOINT_40, D2S_QUEST_CHECKPOINT_41, D2S_QUEST_CHECKPOINT_42, D2S_QUEST_CHECKPOINT_43, D2S_QUEST_CHECKPOINT_44, D2S_QUEST_CHECKPOINT_45, D2S_QUEST_CHECKPOINT_46, D2S_QUEST_CHECKPOINT_47}, 0, D2S_DIFFICULTY_UNKNOWN},
  56 + {"The Forgotten Tower", {D2S_QUEST_CHECKPOINT_48, D2S_QUEST_CHECKPOINT_49, D2S_QUEST_CHECKPOINT_50, D2S_QUEST_CHECKPOINT_51, D2S_QUEST_CHECKPOINT_52, D2S_QUEST_CHECKPOINT_53, D2S_QUEST_CHECKPOINT_54, D2S_QUEST_CHECKPOINT_55, D2S_QUEST_CHECKPOINT_56, D2S_QUEST_CHECKPOINT_57, D2S_QUEST_CHECKPOINT_58, D2S_QUEST_CHECKPOINT_59, D2S_QUEST_CHECKPOINT_60, D2S_QUEST_CHECKPOINT_61, D2S_QUEST_CHECKPOINT_62, D2S_QUEST_CHECKPOINT_63}, 0, D2S_DIFFICULTY_UNKNOWN},
  57 + {"Tools of the Trade", {D2S_QUEST_CHECKPOINT_64, D2S_QUEST_CHECKPOINT_65, D2S_QUEST_CHECKPOINT_66, D2S_QUEST_CHECKPOINT_67, D2S_QUEST_CHECKPOINT_68, D2S_QUEST_CHECKPOINT_69, D2S_QUEST_CHECKPOINT_70, D2S_QUEST_CHECKPOINT_71, D2S_QUEST_CHECKPOINT_72, D2S_QUEST_CHECKPOINT_73, D2S_QUEST_CHECKPOINT_74, D2S_QUEST_CHECKPOINT_75, D2S_QUEST_CHECKPOINT_76, D2S_QUEST_CHECKPOINT_77, D2S_QUEST_CHECKPOINT_78, D2S_QUEST_CHECKPOINT_79}, 0, D2S_DIFFICULTY_UNKNOWN},
  58 + {"Sisters To the Slaughter", {D2S_QUEST_CHECKPOINT_80, D2S_QUEST_CHECKPOINT_81, D2S_QUEST_CHECKPOINT_82, D2S_QUEST_CHECKPOINT_83, D2S_QUEST_CHECKPOINT_84, D2S_QUEST_CHECKPOINT_85, D2S_QUEST_CHECKPOINT_86, D2S_QUEST_CHECKPOINT_87, D2S_QUEST_CHECKPOINT_88, D2S_QUEST_CHECKPOINT_89, D2S_QUEST_CHECKPOINT_90, D2S_QUEST_CHECKPOINT_91, D2S_QUEST_CHECKPOINT_92, D2S_QUEST_CHECKPOINT_93, D2S_QUEST_CHECKPOINT_94, D2S_QUEST_CHECKPOINT_95}, 0, D2S_DIFFICULTY_UNKNOWN},
  59 + {"Radament's Lair", {D2S_QUEST_CHECKPOINT_96, D2S_QUEST_CHECKPOINT_97, D2S_QUEST_CHECKPOINT_98, D2S_QUEST_CHECKPOINT_99, D2S_QUEST_CHECKPOINT_100, D2S_QUEST_CHECKPOINT_101, D2S_QUEST_CHECKPOINT_102, D2S_QUEST_CHECKPOINT_103, D2S_QUEST_CHECKPOINT_104, D2S_QUEST_CHECKPOINT_105, D2S_QUEST_CHECKPOINT_106, D2S_QUEST_CHECKPOINT_107, D2S_QUEST_CHECKPOINT_108, D2S_QUEST_CHECKPOINT_109, D2S_QUEST_CHECKPOINT_110, D2S_QUEST_CHECKPOINT_111}, 0, D2S_DIFFICULTY_UNKNOWN},
  60 + {"The Horadric Staff", {D2S_QUEST_CHECKPOINT_112, D2S_QUEST_CHECKPOINT_113, D2S_QUEST_CHECKPOINT_114, D2S_QUEST_CHECKPOINT_115, D2S_QUEST_CHECKPOINT_116, D2S_QUEST_CHECKPOINT_117, D2S_QUEST_CHECKPOINT_118, D2S_QUEST_CHECKPOINT_119, D2S_QUEST_CHECKPOINT_120, D2S_QUEST_CHECKPOINT_121, D2S_QUEST_CHECKPOINT_122, D2S_QUEST_CHECKPOINT_123, D2S_QUEST_CHECKPOINT_124, D2S_QUEST_CHECKPOINT_125, D2S_QUEST_CHECKPOINT_126, D2S_QUEST_CHECKPOINT_127}, 0, D2S_DIFFICULTY_UNKNOWN},
  61 + {"Tainted Sun", {D2S_QUEST_CHECKPOINT_128, D2S_QUEST_CHECKPOINT_129, D2S_QUEST_CHECKPOINT_130, D2S_QUEST_CHECKPOINT_131, D2S_QUEST_CHECKPOINT_132, D2S_QUEST_CHECKPOINT_133, D2S_QUEST_CHECKPOINT_134, D2S_QUEST_CHECKPOINT_135, D2S_QUEST_CHECKPOINT_136, D2S_QUEST_CHECKPOINT_137, D2S_QUEST_CHECKPOINT_138, D2S_QUEST_CHECKPOINT_139, D2S_QUEST_CHECKPOINT_140, D2S_QUEST_CHECKPOINT_141, D2S_QUEST_CHECKPOINT_142, D2S_QUEST_CHECKPOINT_143}, 0, D2S_DIFFICULTY_UNKNOWN},
  62 + {"Arcane Sanctuary", {D2S_QUEST_CHECKPOINT_144, D2S_QUEST_CHECKPOINT_145, D2S_QUEST_CHECKPOINT_146, D2S_QUEST_CHECKPOINT_147, D2S_QUEST_CHECKPOINT_148, D2S_QUEST_CHECKPOINT_149, D2S_QUEST_CHECKPOINT_150, D2S_QUEST_CHECKPOINT_151, D2S_QUEST_CHECKPOINT_152, D2S_QUEST_CHECKPOINT_153, D2S_QUEST_CHECKPOINT_154, D2S_QUEST_CHECKPOINT_155, D2S_QUEST_CHECKPOINT_156, D2S_QUEST_CHECKPOINT_157, D2S_QUEST_CHECKPOINT_158, D2S_QUEST_CHECKPOINT_159}, 0, D2S_DIFFICULTY_UNKNOWN},
  63 + {"The Summoner", {D2S_QUEST_CHECKPOINT_160, D2S_QUEST_CHECKPOINT_161, D2S_QUEST_CHECKPOINT_162, D2S_QUEST_CHECKPOINT_163, D2S_QUEST_CHECKPOINT_164, D2S_QUEST_CHECKPOINT_165, D2S_QUEST_CHECKPOINT_166, D2S_QUEST_CHECKPOINT_167, D2S_QUEST_CHECKPOINT_168, D2S_QUEST_CHECKPOINT_169, D2S_QUEST_CHECKPOINT_170, D2S_QUEST_CHECKPOINT_171, D2S_QUEST_CHECKPOINT_172, D2S_QUEST_CHECKPOINT_173, D2S_QUEST_CHECKPOINT_174, D2S_QUEST_CHECKPOINT_175}, 0, D2S_DIFFICULTY_UNKNOWN},
  64 + {"The Seven Tombs", {D2S_QUEST_CHECKPOINT_176, D2S_QUEST_CHECKPOINT_177, D2S_QUEST_CHECKPOINT_178, D2S_QUEST_CHECKPOINT_179, D2S_QUEST_CHECKPOINT_180, D2S_QUEST_CHECKPOINT_181, D2S_QUEST_CHECKPOINT_182, D2S_QUEST_CHECKPOINT_183, D2S_QUEST_CHECKPOINT_184, D2S_QUEST_CHECKPOINT_185, D2S_QUEST_CHECKPOINT_186, D2S_QUEST_CHECKPOINT_187, D2S_QUEST_CHECKPOINT_188, D2S_QUEST_CHECKPOINT_189, D2S_QUEST_CHECKPOINT_190, D2S_QUEST_CHECKPOINT_191}, 0, D2S_DIFFICULTY_UNKNOWN},
  65 + {"The Golden Bird", {D2S_QUEST_CHECKPOINT_192, D2S_QUEST_CHECKPOINT_193, D2S_QUEST_CHECKPOINT_194, D2S_QUEST_CHECKPOINT_195, D2S_QUEST_CHECKPOINT_196, D2S_QUEST_CHECKPOINT_197, D2S_QUEST_CHECKPOINT_198, D2S_QUEST_CHECKPOINT_199, D2S_QUEST_CHECKPOINT_200, D2S_QUEST_CHECKPOINT_201, D2S_QUEST_CHECKPOINT_202, D2S_QUEST_CHECKPOINT_203, D2S_QUEST_CHECKPOINT_204, D2S_QUEST_CHECKPOINT_205, D2S_QUEST_CHECKPOINT_206, D2S_QUEST_CHECKPOINT_207}, 0, D2S_DIFFICULTY_UNKNOWN},
  66 + {"Blade of the Old Religion", {D2S_QUEST_CHECKPOINT_208, D2S_QUEST_CHECKPOINT_209, D2S_QUEST_CHECKPOINT_210, D2S_QUEST_CHECKPOINT_211, D2S_QUEST_CHECKPOINT_212, D2S_QUEST_CHECKPOINT_213, D2S_QUEST_CHECKPOINT_214, D2S_QUEST_CHECKPOINT_215, D2S_QUEST_CHECKPOINT_216, D2S_QUEST_CHECKPOINT_217, D2S_QUEST_CHECKPOINT_218, D2S_QUEST_CHECKPOINT_219, D2S_QUEST_CHECKPOINT_220, D2S_QUEST_CHECKPOINT_221, D2S_QUEST_CHECKPOINT_222, D2S_QUEST_CHECKPOINT_223}, 0, D2S_DIFFICULTY_UNKNOWN},
  67 + {"Khalim's Will", {D2S_QUEST_CHECKPOINT_224, D2S_QUEST_CHECKPOINT_225, D2S_QUEST_CHECKPOINT_226, D2S_QUEST_CHECKPOINT_227, D2S_QUEST_CHECKPOINT_228, D2S_QUEST_CHECKPOINT_229, D2S_QUEST_CHECKPOINT_230, D2S_QUEST_CHECKPOINT_231, D2S_QUEST_CHECKPOINT_232, D2S_QUEST_CHECKPOINT_233, D2S_QUEST_CHECKPOINT_234, D2S_QUEST_CHECKPOINT_235, D2S_QUEST_CHECKPOINT_236, D2S_QUEST_CHECKPOINT_237, D2S_QUEST_CHECKPOINT_238, D2S_QUEST_CHECKPOINT_239}, 0, D2S_DIFFICULTY_UNKNOWN},
  68 + {"Lam Esen's Tome", {D2S_QUEST_CHECKPOINT_240, D2S_QUEST_CHECKPOINT_241, D2S_QUEST_CHECKPOINT_242, D2S_QUEST_CHECKPOINT_243, D2S_QUEST_CHECKPOINT_244, D2S_QUEST_CHECKPOINT_245, D2S_QUEST_CHECKPOINT_246, D2S_QUEST_CHECKPOINT_247, D2S_QUEST_CHECKPOINT_248, D2S_QUEST_CHECKPOINT_249, D2S_QUEST_CHECKPOINT_250, D2S_QUEST_CHECKPOINT_251, D2S_QUEST_CHECKPOINT_252, D2S_QUEST_CHECKPOINT_253, D2S_QUEST_CHECKPOINT_254, D2S_QUEST_CHECKPOINT_255}, 0, D2S_DIFFICULTY_UNKNOWN},
  69 + {"The Blackened Temple", {D2S_QUEST_CHECKPOINT_256, D2S_QUEST_CHECKPOINT_257, D2S_QUEST_CHECKPOINT_258, D2S_QUEST_CHECKPOINT_259, D2S_QUEST_CHECKPOINT_260, D2S_QUEST_CHECKPOINT_261, D2S_QUEST_CHECKPOINT_262, D2S_QUEST_CHECKPOINT_263, D2S_QUEST_CHECKPOINT_264, D2S_QUEST_CHECKPOINT_265, D2S_QUEST_CHECKPOINT_266, D2S_QUEST_CHECKPOINT_267, D2S_QUEST_CHECKPOINT_268, D2S_QUEST_CHECKPOINT_269, D2S_QUEST_CHECKPOINT_270, D2S_QUEST_CHECKPOINT_271}, 0, D2S_DIFFICULTY_UNKNOWN},
  70 + {"The Guardian", {D2S_QUEST_CHECKPOINT_272, D2S_QUEST_CHECKPOINT_273, D2S_QUEST_CHECKPOINT_274, D2S_QUEST_CHECKPOINT_275, D2S_QUEST_CHECKPOINT_276, D2S_QUEST_CHECKPOINT_277, D2S_QUEST_CHECKPOINT_278, D2S_QUEST_CHECKPOINT_279, D2S_QUEST_CHECKPOINT_280, D2S_QUEST_CHECKPOINT_281, D2S_QUEST_CHECKPOINT_282, D2S_QUEST_CHECKPOINT_283, D2S_QUEST_CHECKPOINT_284, D2S_QUEST_CHECKPOINT_285, D2S_QUEST_CHECKPOINT_286, D2S_QUEST_CHECKPOINT_287}, 0, D2S_DIFFICULTY_UNKNOWN},
  71 + {"Fallen Angel", {D2S_QUEST_CHECKPOINT_288, D2S_QUEST_CHECKPOINT_289, D2S_QUEST_CHECKPOINT_290, D2S_QUEST_CHECKPOINT_291, D2S_QUEST_CHECKPOINT_292, D2S_QUEST_CHECKPOINT_293, D2S_QUEST_CHECKPOINT_294, D2S_QUEST_CHECKPOINT_295, D2S_QUEST_CHECKPOINT_296, D2S_QUEST_CHECKPOINT_297, D2S_QUEST_CHECKPOINT_298, D2S_QUEST_CHECKPOINT_299, D2S_QUEST_CHECKPOINT_300, D2S_QUEST_CHECKPOINT_301, D2S_QUEST_CHECKPOINT_302, D2S_QUEST_CHECKPOINT_303}, 0, D2S_DIFFICULTY_UNKNOWN},
  72 + {"Hell's Forge", {D2S_QUEST_CHECKPOINT_304, D2S_QUEST_CHECKPOINT_305, D2S_QUEST_CHECKPOINT_306, D2S_QUEST_CHECKPOINT_307, D2S_QUEST_CHECKPOINT_308, D2S_QUEST_CHECKPOINT_309, D2S_QUEST_CHECKPOINT_310, D2S_QUEST_CHECKPOINT_311, D2S_QUEST_CHECKPOINT_312, D2S_QUEST_CHECKPOINT_313, D2S_QUEST_CHECKPOINT_314, D2S_QUEST_CHECKPOINT_315, D2S_QUEST_CHECKPOINT_316, D2S_QUEST_CHECKPOINT_317, D2S_QUEST_CHECKPOINT_318, D2S_QUEST_CHECKPOINT_319}, 0, D2S_DIFFICULTY_UNKNOWN},
  73 + {"Terror's End", {D2S_QUEST_CHECKPOINT_320, D2S_QUEST_CHECKPOINT_321, D2S_QUEST_CHECKPOINT_322, D2S_QUEST_CHECKPOINT_323, D2S_QUEST_CHECKPOINT_324, D2S_QUEST_CHECKPOINT_325, D2S_QUEST_CHECKPOINT_326, D2S_QUEST_CHECKPOINT_327, D2S_QUEST_CHECKPOINT_328, D2S_QUEST_CHECKPOINT_329, D2S_QUEST_CHECKPOINT_330, D2S_QUEST_CHECKPOINT_331, D2S_QUEST_CHECKPOINT_332, D2S_QUEST_CHECKPOINT_333, D2S_QUEST_CHECKPOINT_334, D2S_QUEST_CHECKPOINT_335}, 0, D2S_DIFFICULTY_UNKNOWN},
  74 + {"Siege On Harrogath", {D2S_QUEST_CHECKPOINT_336, D2S_QUEST_CHECKPOINT_337, D2S_QUEST_CHECKPOINT_338, D2S_QUEST_CHECKPOINT_339, D2S_QUEST_CHECKPOINT_340, D2S_QUEST_CHECKPOINT_341, D2S_QUEST_CHECKPOINT_342, D2S_QUEST_CHECKPOINT_343, D2S_QUEST_CHECKPOINT_344, D2S_QUEST_CHECKPOINT_345, D2S_QUEST_CHECKPOINT_346, D2S_QUEST_CHECKPOINT_347, D2S_QUEST_CHECKPOINT_348, D2S_QUEST_CHECKPOINT_349, D2S_QUEST_CHECKPOINT_350, D2S_QUEST_CHECKPOINT_351}, 0, D2S_DIFFICULTY_UNKNOWN},
  75 + {"Rescue On Mount Arreat", {D2S_QUEST_CHECKPOINT_352, D2S_QUEST_CHECKPOINT_353, D2S_QUEST_CHECKPOINT_354, D2S_QUEST_CHECKPOINT_355, D2S_QUEST_CHECKPOINT_356, D2S_QUEST_CHECKPOINT_357, D2S_QUEST_CHECKPOINT_358, D2S_QUEST_CHECKPOINT_359, D2S_QUEST_CHECKPOINT_360, D2S_QUEST_CHECKPOINT_361, D2S_QUEST_CHECKPOINT_362, D2S_QUEST_CHECKPOINT_363, D2S_QUEST_CHECKPOINT_364, D2S_QUEST_CHECKPOINT_365, D2S_QUEST_CHECKPOINT_366, D2S_QUEST_CHECKPOINT_367}, 0, D2S_DIFFICULTY_UNKNOWN},
  76 + {"Prison of Ice", {D2S_QUEST_CHECKPOINT_368, D2S_QUEST_CHECKPOINT_369, D2S_QUEST_CHECKPOINT_370, D2S_QUEST_CHECKPOINT_371, D2S_QUEST_CHECKPOINT_372, D2S_QUEST_CHECKPOINT_373, D2S_QUEST_CHECKPOINT_374, D2S_QUEST_CHECKPOINT_375, D2S_QUEST_CHECKPOINT_376, D2S_QUEST_CHECKPOINT_377, D2S_QUEST_CHECKPOINT_378, D2S_QUEST_CHECKPOINT_379, D2S_QUEST_CHECKPOINT_380, D2S_QUEST_CHECKPOINT_381, D2S_QUEST_CHECKPOINT_382, D2S_QUEST_CHECKPOINT_383}, 0, D2S_DIFFICULTY_UNKNOWN},
  77 + {"Betrayal of Harrogath", {D2S_QUEST_CHECKPOINT_384, D2S_QUEST_CHECKPOINT_385, D2S_QUEST_CHECKPOINT_386, D2S_QUEST_CHECKPOINT_387, D2S_QUEST_CHECKPOINT_388, D2S_QUEST_CHECKPOINT_389, D2S_QUEST_CHECKPOINT_390, D2S_QUEST_CHECKPOINT_391, D2S_QUEST_CHECKPOINT_392, D2S_QUEST_CHECKPOINT_393, D2S_QUEST_CHECKPOINT_394, D2S_QUEST_CHECKPOINT_395, D2S_QUEST_CHECKPOINT_396, D2S_QUEST_CHECKPOINT_397, D2S_QUEST_CHECKPOINT_398, D2S_QUEST_CHECKPOINT_399}, 0, D2S_DIFFICULTY_UNKNOWN},
  78 + {"Rite of Passage", {D2S_QUEST_CHECKPOINT_400, D2S_QUEST_CHECKPOINT_401, D2S_QUEST_CHECKPOINT_402, D2S_QUEST_CHECKPOINT_403, D2S_QUEST_CHECKPOINT_404, D2S_QUEST_CHECKPOINT_405, D2S_QUEST_CHECKPOINT_406, D2S_QUEST_CHECKPOINT_407, D2S_QUEST_CHECKPOINT_408, D2S_QUEST_CHECKPOINT_409, D2S_QUEST_CHECKPOINT_410, D2S_QUEST_CHECKPOINT_411, D2S_QUEST_CHECKPOINT_412, D2S_QUEST_CHECKPOINT_413, D2S_QUEST_CHECKPOINT_414, D2S_QUEST_CHECKPOINT_415}, 0, D2S_DIFFICULTY_UNKNOWN},
  79 + {"Eve of Destruction", {D2S_QUEST_CHECKPOINT_416, D2S_QUEST_CHECKPOINT_417, D2S_QUEST_CHECKPOINT_418, D2S_QUEST_CHECKPOINT_419, D2S_QUEST_CHECKPOINT_420, D2S_QUEST_CHECKPOINT_421, D2S_QUEST_CHECKPOINT_422, D2S_QUEST_CHECKPOINT_423, D2S_QUEST_CHECKPOINT_424, D2S_QUEST_CHECKPOINT_425, D2S_QUEST_CHECKPOINT_426, D2S_QUEST_CHECKPOINT_427, D2S_QUEST_CHECKPOINT_428, D2S_QUEST_CHECKPOINT_429, D2S_QUEST_CHECKPOINT_430, D2S_QUEST_CHECKPOINT_431}, 0, D2S_DIFFICULTY_UNKNOWN}
48 80 };
49 81  
50 82 enum D2S_QUEST_STATUS {
... ... @@ -56,442 +88,10 @@ enum D2S_QUEST_STATUS {
56 88 };
57 89  
58 90 typedef enum D2S_SPECIALQUEST {
59   - D2S_SPECIALQUEST_AKARA_RESPEC
  91 + D2S_SPECIALQUEST_UNKNOWN = -1,
  92 + D2S_SPECIALQUEST_AKARA_RESPEC = 0
60 93 } D2S_SPECIALQUEST;
61 94  
62   -const char* const checkpointDescriptions[] = {
63   - D2S_QUEST_CHECKPOINT_0,
64   - D2S_QUEST_CHECKPOINT_1,
65   - D2S_QUEST_CHECKPOINT_2,
66   - D2S_QUEST_CHECKPOINT_3,
67   - D2S_QUEST_CHECKPOINT_4,
68   - D2S_QUEST_CHECKPOINT_5,
69   - D2S_QUEST_CHECKPOINT_6,
70   - D2S_QUEST_CHECKPOINT_7,
71   - D2S_QUEST_CHECKPOINT_8,
72   - D2S_QUEST_CHECKPOINT_9,
73   - D2S_QUEST_CHECKPOINT_10,
74   - D2S_QUEST_CHECKPOINT_11,
75   - D2S_QUEST_CHECKPOINT_12,
76   - D2S_QUEST_CHECKPOINT_13,
77   - D2S_QUEST_CHECKPOINT_14,
78   - D2S_QUEST_CHECKPOINT_15,
79   - D2S_QUEST_CHECKPOINT_16,
80   - D2S_QUEST_CHECKPOINT_17,
81   - D2S_QUEST_CHECKPOINT_18,
82   - D2S_QUEST_CHECKPOINT_19,
83   - D2S_QUEST_CHECKPOINT_20,
84   - D2S_QUEST_CHECKPOINT_21,
85   - D2S_QUEST_CHECKPOINT_22,
86   - D2S_QUEST_CHECKPOINT_23,
87   - D2S_QUEST_CHECKPOINT_24,
88   - D2S_QUEST_CHECKPOINT_25,
89   - D2S_QUEST_CHECKPOINT_26,
90   - D2S_QUEST_CHECKPOINT_27,
91   - D2S_QUEST_CHECKPOINT_28,
92   - D2S_QUEST_CHECKPOINT_29,
93   - D2S_QUEST_CHECKPOINT_30,
94   - D2S_QUEST_CHECKPOINT_31,
95   - D2S_QUEST_CHECKPOINT_32,
96   - D2S_QUEST_CHECKPOINT_33,
97   - D2S_QUEST_CHECKPOINT_34,
98   - D2S_QUEST_CHECKPOINT_35,
99   - D2S_QUEST_CHECKPOINT_36,
100   - D2S_QUEST_CHECKPOINT_37,
101   - D2S_QUEST_CHECKPOINT_38,
102   - D2S_QUEST_CHECKPOINT_39,
103   - D2S_QUEST_CHECKPOINT_40,
104   - D2S_QUEST_CHECKPOINT_41,
105   - D2S_QUEST_CHECKPOINT_42,
106   - D2S_QUEST_CHECKPOINT_43,
107   - D2S_QUEST_CHECKPOINT_44,
108   - D2S_QUEST_CHECKPOINT_45,
109   - D2S_QUEST_CHECKPOINT_46,
110   - D2S_QUEST_CHECKPOINT_47,
111   - D2S_QUEST_CHECKPOINT_48,
112   - D2S_QUEST_CHECKPOINT_49,
113   - D2S_QUEST_CHECKPOINT_50,
114   - D2S_QUEST_CHECKPOINT_51,
115   - D2S_QUEST_CHECKPOINT_52,
116   - D2S_QUEST_CHECKPOINT_53,
117   - D2S_QUEST_CHECKPOINT_54,
118   - D2S_QUEST_CHECKPOINT_55,
119   - D2S_QUEST_CHECKPOINT_56,
120   - D2S_QUEST_CHECKPOINT_57,
121   - D2S_QUEST_CHECKPOINT_58,
122   - D2S_QUEST_CHECKPOINT_59,
123   - D2S_QUEST_CHECKPOINT_60,
124   - D2S_QUEST_CHECKPOINT_61,
125   - D2S_QUEST_CHECKPOINT_62,
126   - D2S_QUEST_CHECKPOINT_63,
127   - D2S_QUEST_CHECKPOINT_64,
128   - D2S_QUEST_CHECKPOINT_65,
129   - D2S_QUEST_CHECKPOINT_66,
130   - D2S_QUEST_CHECKPOINT_67,
131   - D2S_QUEST_CHECKPOINT_68,
132   - D2S_QUEST_CHECKPOINT_69,
133   - D2S_QUEST_CHECKPOINT_70,
134   - D2S_QUEST_CHECKPOINT_71,
135   - D2S_QUEST_CHECKPOINT_72,
136   - D2S_QUEST_CHECKPOINT_73,
137   - D2S_QUEST_CHECKPOINT_74,
138   - D2S_QUEST_CHECKPOINT_75,
139   - D2S_QUEST_CHECKPOINT_76,
140   - D2S_QUEST_CHECKPOINT_77,
141   - D2S_QUEST_CHECKPOINT_78,
142   - D2S_QUEST_CHECKPOINT_79,
143   - D2S_QUEST_CHECKPOINT_80,
144   - D2S_QUEST_CHECKPOINT_81,
145   - D2S_QUEST_CHECKPOINT_82,
146   - D2S_QUEST_CHECKPOINT_83,
147   - D2S_QUEST_CHECKPOINT_84,
148   - D2S_QUEST_CHECKPOINT_85,
149   - D2S_QUEST_CHECKPOINT_86,
150   - D2S_QUEST_CHECKPOINT_87,
151   - D2S_QUEST_CHECKPOINT_88,
152   - D2S_QUEST_CHECKPOINT_89,
153   - D2S_QUEST_CHECKPOINT_90,
154   - D2S_QUEST_CHECKPOINT_91,
155   - D2S_QUEST_CHECKPOINT_92,
156   - D2S_QUEST_CHECKPOINT_93,
157   - D2S_QUEST_CHECKPOINT_94,
158   - D2S_QUEST_CHECKPOINT_95,
159   - D2S_QUEST_CHECKPOINT_96,
160   - D2S_QUEST_CHECKPOINT_97,
161   - D2S_QUEST_CHECKPOINT_98,
162   - D2S_QUEST_CHECKPOINT_99,
163   - D2S_QUEST_CHECKPOINT_100,
164   - D2S_QUEST_CHECKPOINT_101,
165   - D2S_QUEST_CHECKPOINT_102,
166   - D2S_QUEST_CHECKPOINT_103,
167   - D2S_QUEST_CHECKPOINT_104,
168   - D2S_QUEST_CHECKPOINT_105,
169   - D2S_QUEST_CHECKPOINT_106,
170   - D2S_QUEST_CHECKPOINT_107,
171   - D2S_QUEST_CHECKPOINT_108,
172   - D2S_QUEST_CHECKPOINT_109,
173   - D2S_QUEST_CHECKPOINT_110,
174   - D2S_QUEST_CHECKPOINT_111,
175   - D2S_QUEST_CHECKPOINT_112,
176   - D2S_QUEST_CHECKPOINT_113,
177   - D2S_QUEST_CHECKPOINT_114,
178   - D2S_QUEST_CHECKPOINT_115,
179   - D2S_QUEST_CHECKPOINT_116,
180   - D2S_QUEST_CHECKPOINT_117,
181   - D2S_QUEST_CHECKPOINT_118,
182   - D2S_QUEST_CHECKPOINT_119,
183   - D2S_QUEST_CHECKPOINT_120,
184   - D2S_QUEST_CHECKPOINT_121,
185   - D2S_QUEST_CHECKPOINT_122,
186   - D2S_QUEST_CHECKPOINT_123,
187   - D2S_QUEST_CHECKPOINT_124,
188   - D2S_QUEST_CHECKPOINT_125,
189   - D2S_QUEST_CHECKPOINT_126,
190   - D2S_QUEST_CHECKPOINT_127,
191   - D2S_QUEST_CHECKPOINT_128,
192   - D2S_QUEST_CHECKPOINT_129,
193   - D2S_QUEST_CHECKPOINT_130,
194   - D2S_QUEST_CHECKPOINT_131,
195   - D2S_QUEST_CHECKPOINT_132,
196   - D2S_QUEST_CHECKPOINT_133,
197   - D2S_QUEST_CHECKPOINT_134,
198   - D2S_QUEST_CHECKPOINT_135,
199   - D2S_QUEST_CHECKPOINT_136,
200   - D2S_QUEST_CHECKPOINT_137,
201   - D2S_QUEST_CHECKPOINT_138,
202   - D2S_QUEST_CHECKPOINT_139,
203   - D2S_QUEST_CHECKPOINT_140,
204   - D2S_QUEST_CHECKPOINT_141,
205   - D2S_QUEST_CHECKPOINT_142,
206   - D2S_QUEST_CHECKPOINT_143,
207   - D2S_QUEST_CHECKPOINT_144,
208   - D2S_QUEST_CHECKPOINT_145,
209   - D2S_QUEST_CHECKPOINT_146,
210   - D2S_QUEST_CHECKPOINT_147,
211   - D2S_QUEST_CHECKPOINT_148,
212   - D2S_QUEST_CHECKPOINT_149,
213   - D2S_QUEST_CHECKPOINT_150,
214   - D2S_QUEST_CHECKPOINT_151,
215   - D2S_QUEST_CHECKPOINT_152,
216   - D2S_QUEST_CHECKPOINT_153,
217   - D2S_QUEST_CHECKPOINT_154,
218   - D2S_QUEST_CHECKPOINT_155,
219   - D2S_QUEST_CHECKPOINT_156,
220   - D2S_QUEST_CHECKPOINT_157,
221   - D2S_QUEST_CHECKPOINT_158,
222   - D2S_QUEST_CHECKPOINT_159,
223   - D2S_QUEST_CHECKPOINT_160,
224   - D2S_QUEST_CHECKPOINT_161,
225   - D2S_QUEST_CHECKPOINT_162,
226   - D2S_QUEST_CHECKPOINT_163,
227   - D2S_QUEST_CHECKPOINT_164,
228   - D2S_QUEST_CHECKPOINT_165,
229   - D2S_QUEST_CHECKPOINT_166,
230   - D2S_QUEST_CHECKPOINT_167,
231   - D2S_QUEST_CHECKPOINT_168,
232   - D2S_QUEST_CHECKPOINT_169,
233   - D2S_QUEST_CHECKPOINT_170,
234   - D2S_QUEST_CHECKPOINT_171,
235   - D2S_QUEST_CHECKPOINT_172,
236   - D2S_QUEST_CHECKPOINT_173,
237   - D2S_QUEST_CHECKPOINT_174,
238   - D2S_QUEST_CHECKPOINT_175,
239   - D2S_QUEST_CHECKPOINT_176,
240   - D2S_QUEST_CHECKPOINT_177,
241   - D2S_QUEST_CHECKPOINT_178,
242   - D2S_QUEST_CHECKPOINT_179,
243   - D2S_QUEST_CHECKPOINT_180,
244   - D2S_QUEST_CHECKPOINT_181,
245   - D2S_QUEST_CHECKPOINT_182,
246   - D2S_QUEST_CHECKPOINT_183,
247   - D2S_QUEST_CHECKPOINT_184,
248   - D2S_QUEST_CHECKPOINT_185,
249   - D2S_QUEST_CHECKPOINT_186,
250   - D2S_QUEST_CHECKPOINT_187,
251   - D2S_QUEST_CHECKPOINT_188,
252   - D2S_QUEST_CHECKPOINT_189,
253   - D2S_QUEST_CHECKPOINT_190,
254   - D2S_QUEST_CHECKPOINT_191,
255   - D2S_QUEST_CHECKPOINT_192,
256   - D2S_QUEST_CHECKPOINT_193,
257   - D2S_QUEST_CHECKPOINT_194,
258   - D2S_QUEST_CHECKPOINT_195,
259   - D2S_QUEST_CHECKPOINT_196,
260   - D2S_QUEST_CHECKPOINT_197,
261   - D2S_QUEST_CHECKPOINT_198,
262   - D2S_QUEST_CHECKPOINT_199,
263   - D2S_QUEST_CHECKPOINT_200,
264   - D2S_QUEST_CHECKPOINT_201,
265   - D2S_QUEST_CHECKPOINT_202,
266   - D2S_QUEST_CHECKPOINT_203,
267   - D2S_QUEST_CHECKPOINT_204,
268   - D2S_QUEST_CHECKPOINT_205,
269   - D2S_QUEST_CHECKPOINT_206,
270   - D2S_QUEST_CHECKPOINT_207,
271   - D2S_QUEST_CHECKPOINT_208,
272   - D2S_QUEST_CHECKPOINT_209,
273   - D2S_QUEST_CHECKPOINT_210,
274   - D2S_QUEST_CHECKPOINT_211,
275   - D2S_QUEST_CHECKPOINT_212,
276   - D2S_QUEST_CHECKPOINT_213,
277   - D2S_QUEST_CHECKPOINT_214,
278   - D2S_QUEST_CHECKPOINT_215,
279   - D2S_QUEST_CHECKPOINT_216,
280   - D2S_QUEST_CHECKPOINT_217,
281   - D2S_QUEST_CHECKPOINT_218,
282   - D2S_QUEST_CHECKPOINT_219,
283   - D2S_QUEST_CHECKPOINT_220,
284   - D2S_QUEST_CHECKPOINT_221,
285   - D2S_QUEST_CHECKPOINT_222,
286   - D2S_QUEST_CHECKPOINT_223,
287   - D2S_QUEST_CHECKPOINT_224,
288   - D2S_QUEST_CHECKPOINT_225,
289   - D2S_QUEST_CHECKPOINT_226,
290   - D2S_QUEST_CHECKPOINT_227,
291   - D2S_QUEST_CHECKPOINT_228,
292   - D2S_QUEST_CHECKPOINT_229,
293   - D2S_QUEST_CHECKPOINT_230,
294   - D2S_QUEST_CHECKPOINT_231,
295   - D2S_QUEST_CHECKPOINT_232,
296   - D2S_QUEST_CHECKPOINT_233,
297   - D2S_QUEST_CHECKPOINT_234,
298   - D2S_QUEST_CHECKPOINT_235,
299   - D2S_QUEST_CHECKPOINT_236,
300   - D2S_QUEST_CHECKPOINT_237,
301   - D2S_QUEST_CHECKPOINT_238,
302   - D2S_QUEST_CHECKPOINT_239,
303   - D2S_QUEST_CHECKPOINT_240,
304   - D2S_QUEST_CHECKPOINT_241,
305   - D2S_QUEST_CHECKPOINT_242,
306   - D2S_QUEST_CHECKPOINT_243,
307   - D2S_QUEST_CHECKPOINT_244,
308   - D2S_QUEST_CHECKPOINT_245,
309   - D2S_QUEST_CHECKPOINT_246,
310   - D2S_QUEST_CHECKPOINT_247,
311   - D2S_QUEST_CHECKPOINT_248,
312   - D2S_QUEST_CHECKPOINT_249,
313   - D2S_QUEST_CHECKPOINT_250,
314   - D2S_QUEST_CHECKPOINT_251,
315   - D2S_QUEST_CHECKPOINT_252,
316   - D2S_QUEST_CHECKPOINT_253,
317   - D2S_QUEST_CHECKPOINT_256,
318   - D2S_QUEST_CHECKPOINT_257,
319   - D2S_QUEST_CHECKPOINT_258,
320   - D2S_QUEST_CHECKPOINT_259,
321   - D2S_QUEST_CHECKPOINT_260,
322   - D2S_QUEST_CHECKPOINT_261,
323   - D2S_QUEST_CHECKPOINT_262,
324   - D2S_QUEST_CHECKPOINT_263,
325   - D2S_QUEST_CHECKPOINT_264,
326   - D2S_QUEST_CHECKPOINT_265,
327   - D2S_QUEST_CHECKPOINT_266,
328   - D2S_QUEST_CHECKPOINT_267,
329   - D2S_QUEST_CHECKPOINT_268,
330   - D2S_QUEST_CHECKPOINT_269,
331   - D2S_QUEST_CHECKPOINT_270,
332   - D2S_QUEST_CHECKPOINT_271,
333   - D2S_QUEST_CHECKPOINT_272,
334   - D2S_QUEST_CHECKPOINT_273,
335   - D2S_QUEST_CHECKPOINT_274,
336   - D2S_QUEST_CHECKPOINT_275,
337   - D2S_QUEST_CHECKPOINT_276,
338   - D2S_QUEST_CHECKPOINT_277,
339   - D2S_QUEST_CHECKPOINT_278,
340   - D2S_QUEST_CHECKPOINT_279,
341   - D2S_QUEST_CHECKPOINT_280,
342   - D2S_QUEST_CHECKPOINT_281,
343   - D2S_QUEST_CHECKPOINT_282,
344   - D2S_QUEST_CHECKPOINT_283,
345   - D2S_QUEST_CHECKPOINT_284,
346   - D2S_QUEST_CHECKPOINT_285,
347   - D2S_QUEST_CHECKPOINT_286,
348   - D2S_QUEST_CHECKPOINT_287,
349   - D2S_QUEST_CHECKPOINT_288,
350   - D2S_QUEST_CHECKPOINT_289,
351   - D2S_QUEST_CHECKPOINT_290,
352   - D2S_QUEST_CHECKPOINT_291,
353   - D2S_QUEST_CHECKPOINT_292,
354   - D2S_QUEST_CHECKPOINT_293,
355   - D2S_QUEST_CHECKPOINT_294,
356   - D2S_QUEST_CHECKPOINT_295,
357   - D2S_QUEST_CHECKPOINT_296,
358   - D2S_QUEST_CHECKPOINT_297,
359   - D2S_QUEST_CHECKPOINT_298,
360   - D2S_QUEST_CHECKPOINT_299,
361   - D2S_QUEST_CHECKPOINT_300,
362   - D2S_QUEST_CHECKPOINT_301,
363   - D2S_QUEST_CHECKPOINT_302,
364   - D2S_QUEST_CHECKPOINT_303,
365   - D2S_QUEST_CHECKPOINT_304,
366   - D2S_QUEST_CHECKPOINT_305,
367   - D2S_QUEST_CHECKPOINT_306,
368   - D2S_QUEST_CHECKPOINT_307,
369   - D2S_QUEST_CHECKPOINT_308,
370   - D2S_QUEST_CHECKPOINT_309,
371   - D2S_QUEST_CHECKPOINT_310,
372   - D2S_QUEST_CHECKPOINT_311,
373   - D2S_QUEST_CHECKPOINT_312,
374   - D2S_QUEST_CHECKPOINT_313,
375   - D2S_QUEST_CHECKPOINT_314,
376   - D2S_QUEST_CHECKPOINT_315,
377   - D2S_QUEST_CHECKPOINT_316,
378   - D2S_QUEST_CHECKPOINT_317,
379   - D2S_QUEST_CHECKPOINT_318,
380   - D2S_QUEST_CHECKPOINT_319,
381   - D2S_QUEST_CHECKPOINT_320,
382   - D2S_QUEST_CHECKPOINT_321,
383   - D2S_QUEST_CHECKPOINT_322,
384   - D2S_QUEST_CHECKPOINT_323,
385   - D2S_QUEST_CHECKPOINT_324,
386   - D2S_QUEST_CHECKPOINT_325,
387   - D2S_QUEST_CHECKPOINT_326,
388   - D2S_QUEST_CHECKPOINT_327,
389   - D2S_QUEST_CHECKPOINT_328,
390   - D2S_QUEST_CHECKPOINT_329,
391   - D2S_QUEST_CHECKPOINT_330,
392   - D2S_QUEST_CHECKPOINT_331,
393   - D2S_QUEST_CHECKPOINT_332,
394   - D2S_QUEST_CHECKPOINT_333,
395   - D2S_QUEST_CHECKPOINT_334,
396   - D2S_QUEST_CHECKPOINT_335,
397   - D2S_QUEST_CHECKPOINT_336,
398   - D2S_QUEST_CHECKPOINT_337,
399   - D2S_QUEST_CHECKPOINT_338,
400   - D2S_QUEST_CHECKPOINT_339,
401   - D2S_QUEST_CHECKPOINT_340,
402   - D2S_QUEST_CHECKPOINT_341,
403   - D2S_QUEST_CHECKPOINT_342,
404   - D2S_QUEST_CHECKPOINT_343,
405   - D2S_QUEST_CHECKPOINT_344,
406   - D2S_QUEST_CHECKPOINT_345,
407   - D2S_QUEST_CHECKPOINT_346,
408   - D2S_QUEST_CHECKPOINT_347,
409   - D2S_QUEST_CHECKPOINT_348,
410   - D2S_QUEST_CHECKPOINT_349,
411   - D2S_QUEST_CHECKPOINT_350,
412   - D2S_QUEST_CHECKPOINT_351,
413   - D2S_QUEST_CHECKPOINT_352,
414   - D2S_QUEST_CHECKPOINT_353,
415   - D2S_QUEST_CHECKPOINT_354,
416   - D2S_QUEST_CHECKPOINT_355,
417   - D2S_QUEST_CHECKPOINT_356,
418   - D2S_QUEST_CHECKPOINT_357,
419   - D2S_QUEST_CHECKPOINT_358,
420   - D2S_QUEST_CHECKPOINT_359,
421   - D2S_QUEST_CHECKPOINT_360,
422   - D2S_QUEST_CHECKPOINT_361,
423   - D2S_QUEST_CHECKPOINT_362,
424   - D2S_QUEST_CHECKPOINT_363,
425   - D2S_QUEST_CHECKPOINT_364,
426   - D2S_QUEST_CHECKPOINT_365,
427   - D2S_QUEST_CHECKPOINT_366,
428   - D2S_QUEST_CHECKPOINT_367,
429   - D2S_QUEST_CHECKPOINT_368,
430   - D2S_QUEST_CHECKPOINT_369,
431   - D2S_QUEST_CHECKPOINT_370,
432   - D2S_QUEST_CHECKPOINT_371,
433   - D2S_QUEST_CHECKPOINT_372,
434   - D2S_QUEST_CHECKPOINT_373,
435   - D2S_QUEST_CHECKPOINT_374,
436   - D2S_QUEST_CHECKPOINT_375,
437   - D2S_QUEST_CHECKPOINT_376,
438   - D2S_QUEST_CHECKPOINT_377,
439   - D2S_QUEST_CHECKPOINT_378,
440   - D2S_QUEST_CHECKPOINT_379,
441   - D2S_QUEST_CHECKPOINT_380,
442   - D2S_QUEST_CHECKPOINT_381,
443   - D2S_QUEST_CHECKPOINT_382,
444   - D2S_QUEST_CHECKPOINT_383,
445   - D2S_QUEST_CHECKPOINT_384,
446   - D2S_QUEST_CHECKPOINT_385,
447   - D2S_QUEST_CHECKPOINT_386,
448   - D2S_QUEST_CHECKPOINT_387,
449   - D2S_QUEST_CHECKPOINT_388,
450   - D2S_QUEST_CHECKPOINT_389,
451   - D2S_QUEST_CHECKPOINT_390,
452   - D2S_QUEST_CHECKPOINT_391,
453   - D2S_QUEST_CHECKPOINT_392,
454   - D2S_QUEST_CHECKPOINT_393,
455   - D2S_QUEST_CHECKPOINT_394,
456   - D2S_QUEST_CHECKPOINT_395,
457   - D2S_QUEST_CHECKPOINT_396,
458   - D2S_QUEST_CHECKPOINT_397,
459   - D2S_QUEST_CHECKPOINT_398,
460   - D2S_QUEST_CHECKPOINT_399,
461   - D2S_QUEST_CHECKPOINT_400,
462   - D2S_QUEST_CHECKPOINT_401,
463   - D2S_QUEST_CHECKPOINT_402,
464   - D2S_QUEST_CHECKPOINT_403,
465   - D2S_QUEST_CHECKPOINT_404,
466   - D2S_QUEST_CHECKPOINT_405,
467   - D2S_QUEST_CHECKPOINT_406,
468   - D2S_QUEST_CHECKPOINT_407,
469   - D2S_QUEST_CHECKPOINT_408,
470   - D2S_QUEST_CHECKPOINT_409,
471   - D2S_QUEST_CHECKPOINT_410,
472   - D2S_QUEST_CHECKPOINT_411,
473   - D2S_QUEST_CHECKPOINT_412,
474   - D2S_QUEST_CHECKPOINT_413,
475   - D2S_QUEST_CHECKPOINT_414,
476   - D2S_QUEST_CHECKPOINT_415,
477   - D2S_QUEST_CHECKPOINT_416,
478   - D2S_QUEST_CHECKPOINT_417,
479   - D2S_QUEST_CHECKPOINT_418,
480   - D2S_QUEST_CHECKPOINT_419,
481   - D2S_QUEST_CHECKPOINT_420,
482   - D2S_QUEST_CHECKPOINT_421,
483   - D2S_QUEST_CHECKPOINT_422,
484   - D2S_QUEST_CHECKPOINT_423,
485   - D2S_QUEST_CHECKPOINT_424,
486   - D2S_QUEST_CHECKPOINT_425,
487   - D2S_QUEST_CHECKPOINT_426,
488   - D2S_QUEST_CHECKPOINT_427,
489   - D2S_QUEST_CHECKPOINT_428,
490   - D2S_QUEST_CHECKPOINT_429,
491   - D2S_QUEST_CHECKPOINT_430,
492   - D2S_QUEST_CHECKPOINT_431
493   -};
494   -
495 95 typedef struct __attribute__((packed)) {
496 96 uint16_t actStarted;
497 97 uint16_t questCheckpoints[6];
... ... @@ -521,31 +121,31 @@ typedef struct __attribute__((packed)) {
521 121 D2Quests quests[3]; // 1 set for each difficulty
522 122 } D2QuestData;
523 123  
524   -// Returns static string from library memory, no need to free
525   -const char* getQuestName(D2S_QUEST quest);
  124 +// Populates a D2Quest struct with the quest name and
  125 +// its checkpoint names, as well as quest data for the
  126 +// specified difficulty. Returned strings are static
  127 +// strings from library memory, no need to free
  128 +int getQuestData(D2QuestData* d, D2S_QUEST_IDENTIFIER questID, D2Quest* quest, D2S_DIFFICULTY difficulty);
526 129  
527   -// Populates `descriptions` with static strings from library memory, no need to free.
528   -// `descriptions` contains one string for each bit field of the quest's uint16_t data.
529   -// Empty entries (non-existant or unknown checkpoints) will have NULL value. Be careful!
530   -int getCheckpointDescriptions(D2S_QUEST quest, const char* *descriptions[16]);
  130 +// Sets quest status for the specified quest
  131 +int setQuestData(D2QuestData* d, D2S_QUEST_IDENTIFIER questID, D2Quest* quest);
531 132  
532   -// Returns quest status for the specified quest and act.
533   -int getQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t* data);
534   -int setQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t questData);
  133 +int isQuestStarted(D2Quest* quest);
  134 +int isQuestRewardCollected(D2Quest* quest);
  135 +int isQuestCompleted(D2Quest* quest);
535 136  
536   -int isQuestStarted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty);
537   -int isQuestRewardCollected(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty);
538   -int isQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty);
  137 +// The following functions don't directly modify the quest
  138 +// you must call setQuestData afterwards
539 139  
540 140 // Set bool to 1 to set the status or 0 to remove it
541   -int setQuestStarted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool);
542   -int setQuestRewardCollected(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool);
  141 +void setQuestStarted(D2Quest* quest, int bool);
  142 +void setQuestRewardCollected(D2Quest* quest, int bool);
543 143  
544 144 // When called to set the request to NOT completed (`bool` = 0), this will NOT set the reward collected status
545 145 // which *may* render the quest unobtainable, this is done in case we may want to further modify the quest state.
546 146 // If you want to mark the quest as not completed just to get the reward, please use `setQuestRewardCollected(,,0)`
547 147 // instead.
548   -int setQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool);
  148 +void setQuestCompleted(D2Quest* quest, int bool);
549 149  
550 150 // Some quests have extra fields outside their quest data that govern certain states of the quest
551 151 // So far, I only know of the respec that Akara offers when clearing Den of Evil
... ...
d2strings.h
... ... @@ -1684,4 +1684,132 @@
1684 1684 #define D2S_ITEMDATA_IDENTIFIER_636 "Elixir"
1685 1685 #define D2S_ITEMDATA_IDENTIFIER_637 "Scroll of Knowledge"
1686 1686  
  1687 +// Set items
  1688 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_0 "Civerb's Ward"
  1689 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_1 "Civerb's Icon"
  1690 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_2 "Civerb's Cudgel"
  1691 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_3 "Hsaru's Iron Heel"
  1692 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_4 "Hsaru's Iron Fist"
  1693 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_5 "Hsaru's Iron Stay"
  1694 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_6 "Cleglaw's Tooth"
  1695 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_7 "Cleglaw's Claw"
  1696 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_8 "Cleglaw's Pincers"
  1697 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_9 "Iratha's Collar"
  1698 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_10 "Iratha's Cuff"
  1699 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_11 "Iratha's Coil"
  1700 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_12 "Iratha's Cord"
  1701 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_13 "Isenhart's Lightbrand"
  1702 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_14 "Isernhart's Parry"
  1703 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_15 "Isenhart's Case"
  1704 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_16 "Isenhart's Horns"
  1705 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_17 "Vidala's Barb"
  1706 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_18 "Vidala's Fetlock"
  1707 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_19 "Vidala's Ambush"
  1708 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_20 "Vidala's Snare"
  1709 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_21 "Milabrega's Orb"
  1710 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_22 "Milabrega's Rod"
  1711 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_23 "Milabrega's Diadem"
  1712 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_24 "Milabrega's Robe"
  1713 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_25 "Cathan's Rule"
  1714 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_26 "Cathan's Mesh"
  1715 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_27 "Cathan's Visage"
  1716 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_28 "Cathan's Sigil"
  1717 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_29 "Cathan's Seal"
  1718 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_30 "Tancred's Crowbill"
  1719 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_31 "Tancred's Spine"
  1720 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_32 "Tancred's Hobnails"
  1721 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_33 "Tancred's Weird"
  1722 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_34 "Tancred's Skull"
  1723 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_35 "Sigon's Gage"
  1724 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_36 "Sigon's Visor"
  1725 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_37 "Sigon's Shelter"
  1726 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_38 "Sigon's Sabot"
  1727 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_39 "Sigon's Wrap"
  1728 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_40 "Sigon's Guard"
  1729 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_41 "Infernal Cranium"
  1730 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_42 "Infernal Torch"
  1731 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_43 "Infernal Sign"
  1732 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_44 "Berseker's Headgear"
  1733 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_45 "Berseker's Hauberk"
  1734 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_46 "Berseker's Hatchet"
  1735 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_47 "Death's Hand"
  1736 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_48 "Death's Guard"
  1737 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_49 "Death's Touch"
  1738 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_50 "Angelic Sickle"
  1739 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_51 "Angelic Mantle"
  1740 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_52 "Angelic Halo"
  1741 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_53 "Angelic Wings"
  1742 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_54 "Arctic Horns"
  1743 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_55 "Arctic Furs"
  1744 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_56 "Arctic Binding"
  1745 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_57 "Arctic Mitts"
  1746 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_58 "Arcanna's Sign"
  1747 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_59 "Arcanna's Deathwand"
  1748 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_60 "Arcanna's Head"
  1749 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_61 "Arcanna's Flesh"
  1750 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_62 "Natalya's Totem"
  1751 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_63 "Natalya's Mark"
  1752 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_64 "Natalya's Shadow"
  1753 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_65 "Natalya's Soul"
  1754 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_66 "Aldur's Stony Gaze"
  1755 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_67 "Aldur's Deception"
  1756 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_68 "Aldur's Rhythm"
  1757 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_69 "Aldur's Advance"
  1758 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_70 "Immortal King's Will"
  1759 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_71 "Immortal King's Soulcage"
  1760 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_72 "Immortal King's Detail"
  1761 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_73 "Immortal King's Forge"
  1762 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_74 "Immortal King's Pillar"
  1763 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_75 "Immortal King's Stone Crusher"
  1764 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_76 "Tal Rasha's Fire-spun Cloth"
  1765 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_77 "Tal Rasha's Adjudication"
  1766 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_78 "Tal Rasha's Lidless eye"
  1767 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_79 "Tal Rasha's Guardianship"
  1768 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_80 "Tal Rasha's Horadric Crest"
  1769 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_81 "Griswold's Valor"
  1770 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_82 "Griswold's Heart"
  1771 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_83 "Griswold's Redemption"
  1772 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_84 "Griswold's Honor"
  1773 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_85 "Trang-Oul's Guise"
  1774 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_86 "Trang-Oul's Scales"
  1775 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_87 "Trang-Oul's Wing"
  1776 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_88 "Trang-Oul's Claws"
  1777 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_89 "Trang-Oul's Girth"
  1778 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_90 "M'avina's True Sight"
  1779 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_91 "M'avina's Embrace"
  1780 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_92 "M'avina's Icy Clutch"
  1781 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_93 "M'avina's Tenet"
  1782 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_94 "M'avina's Caster"
  1783 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_95 "Telling of Beads"
  1784 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_96 "Laying of Hands"
  1785 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_97 "Rite of Passage"
  1786 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_98 "Dark Adherent"
  1787 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_99 "Credendum"
  1788 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_100 "Dragoon's Teaching"
  1789 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_101 "Taebek's Glory"
  1790 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_102 "Haemosu's Adament"
  1791 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_103 "Ondal's Almighty"
  1792 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_104 "Guillaume's Face"
  1793 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_105 "Wilhelm's Pride"
  1794 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_106 "Magnus's Skin"
  1795 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_107 "Wihtstan's Guard"
  1796 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_108 "Hwanin's Splendor"
  1797 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_109 "Hwanin's Refuge"
  1798 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_110 "Hwanin's Blessing"
  1799 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_111 "Hwanin's Justice"
  1800 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_112 "Sazabi's Cobalt Redeemer"
  1801 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_113 "Sazabi's Ghost Liberator"
  1802 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_114 "Sazabi's Mental Sheath"
  1803 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_115 "Bul-Kathos's Sacred Charge"
  1804 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_116 "Bul-Kathos's Tribal Guardian"
  1805 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_117 "Cow King Horns"
  1806 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_118 "Cow King Hide"
  1807 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_119 "Cow King Hooves"
  1808 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_120 "Naj's Puzzler"
  1809 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_121 "Naj's Light Plate"
  1810 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_122 "Naj's Circlet"
  1811 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_123 "Sander's Paragon"
  1812 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_124 "Sander's Riprap"
  1813 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_125 "Sander's Taboo"
  1814 +#define D2S_ITEMDATA_SETITEM_IDENTIFIER_126 "Sander's Superstition"
1687 1815 #endif
... ...
d2waypoints.h
1 1 #ifndef D2WAYPOINTS_H
2 2 #define D2WAYPOINTS_H
3 3  
4   -// Forward declaration
5   -typedef enum D2S_DIFFICULTY D2S_DIFFICULTY;
6   -
7 4 #include <stdint.h>
8 5  
  6 +#include "d2common.h"
9 7 #include "d2strings.h"
10 8  
11 9 #define D2S_WAYPOINTSDATA_HEADER_LENGTH 2
... ...
docs/d2s_save_item_format_1.13d.txt
... ... @@ -697,7 +697,7 @@ Armor: Defense Rating
697 697 ├───────────────┼─────────────────────────────────────────────────────────────┤
698 698 │ │Defense value +10. i.e., a defense rating of 23 would be │
699 699 │ │stored in this field as 33; thus the maximum defense value │
700   -│10 │you can store is 1013 (although I haven't tried it). Note │
  700 +│11 │you can store is 1013 (although I haven't tried it). Note │
701 701 │ │that this is the base defense rating, before applying any │
702 702 │ │magical enhancements (i.e., the number shown in white). │
703 703 └───────────────┴─────────────────────────────────────────────────────────────┘
... ... @@ -722,6 +722,8 @@ they mean.
722 722 │8 │durability if the item is magically enhanced. │
723 723 │ │Note: I've found an indestructable item, and it appears that │
724 724 │ │in such a case the current durability field is missing! │
  725 +├───────────────┼─────────────────────────────────────────────────────────────┤
  726 +│1 │One random bit (no one knows why apparently) │
725 727 └───────────────┴─────────────────────────────────────────────────────────────┘
726 728  
727 729 Armor and (non-stacked) Weapons: Sockets
... ...
docs/d2s_save_item_magic_properties_1.09.html 0 → 100644
  1 +<html>
  2 +<head>
  3 + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  4 + <meta name="Author" content="Trevin Beattie">
  5 + <meta name="Description" content="Items in your character's .d2s file decoded">
  6 + <meta name="Keywords" content="d2s, Diablo, v1.09, bit field, magic, item, format">
  7 + <meta name="Classification" content="binary file format">
  8 + <title>Diablo II v1.09 Magic Properties</title>
  9 +</head>
  10 +<body>
  11 +
  12 +<h1 align=center>Diablo II Item Magical Properties</h1>
  13 +
  14 +<h3 align=center>for Diablo II v1.09 and the Diablo II Expansion Set:
  15 +Lord of Destruction</h3>
  16 +
  17 +<p align=center>Updated July 25, 2003<br>
  18 +<i><accessed> visitors since <accessed since></i></p>
  19 +
  20 +<p>This page gives a detail of each magical property an item can
  21 +have.&nbsp; See the <a href="DiabloIIv1.09_Item_Format.shtml">Item
  22 +Format</a> page for a view of the complete item structure.</p>
  23 +
  24 +<p>Following the item-specific data are a variable number of variable
  25 +length bit fields describing any magical enhancements placed on the
  26 +item.&nbsp; Each property begins with a 9-bit identifier.&nbsp; An
  27 +identifier of 0x1ff (all 1's) indicates the end of the property list
  28 +... except in the event the item belongs to a set, in which case there
  29 +will be another one or two groups of magical properties
  30 +following.&nbsp; I have yet to determine how the length of the list is
  31 +determined for set items.</p>
  32 +
  33 +<p>To read a magical property, first look up its 9-bit ID in the first
  34 +column.&nbsp; The second column shows you how many bits to read to get
  35 +the value associated with that property (e.g., the amount of fire
  36 +resistance).&nbsp; The bias field, if present, tells you the amount to
  37 +subtract from that value to get the actual amount shown in the game;
  38 +for example, if the field for Extra Gold from Monsters has a value of
  39 +150, and the bias is 100, your property is 50% Extra Gold.&nbsp; A few
  40 +of the items require a little more math; these will be explained in
  41 +the Contents column.</p>
  42 +
  43 +<p>Several magical properties have two or more data fields.&nbsp; Read
  44 +these in the order listed in the table.&nbsp; Each magical property ID
  45 +is associated with a fixed number and size of data fields.</p>
  46 +
  47 +<table BORDER WIDTH="100%">
  48 +<tr>
  49 +<th WIDTH="10%">ID (9 bits)</th>
  50 +<th WIDTH="10%">Size of the Following Field</th>
  51 +<th WIDTH="5%">Bias</th>
  52 +<th>Contents</th>
  53 +</tr>
  54 +
  55 +<tr>
  56 +<td align=center>0</td><td align=center>7</td><td align=center>32</td>
  57 +<td>+<i>X</i> to Strength</td>
  58 +</tr>
  59 +
  60 +<tr>
  61 +<td align=center>1</td><td align=center>7</td><td align=center>32</td>
  62 +<td>+<i>X</i> to Energy</td>
  63 +</tr>
  64 +
  65 +<tr>
  66 +<td align=center>2</td><td align=center>7</td><td align=center>32</td>
  67 +<td>+<i>X</i> to Dexterity</td>
  68 +</tr>
  69 +
  70 +<tr>
  71 +<td align=center>3</td><td align=center>7</td><td align=center>32</td>
  72 +<td>+<i>X</i> to Vitality</td>
  73 +</tr>
  74 +
  75 +<tr>
  76 +<td align=center>7</td><td align=center>8</td><td align=center>32</td>
  77 +<td>+<i>X</i> to Life</td>
  78 +</tr>
  79 +
  80 +<tr>
  81 +<td align=center>9</td><td align=center>8</td><td align=center>32</td>
  82 +<td>+<i>X</i> to Mana</td>
  83 +</tr>
  84 +
  85 +<tr>
  86 +<td align=center>11</td><td align=center>8</td><td align=center>32</td>
  87 +<td>+<i>X</i> to Maximum Stamina</td>
  88 +</tr>
  89 +
  90 +<tr>
  91 +<td align=center>16</td><td align=center>9</td><td></td>
  92 +<td>+<i>X</i>% Enhanced Defense</td>
  93 +</tr>
  94 +
  95 +<tr>
  96 +<td ROWSPAN="2" align=center>17</td><td align=center>9</td><td></td>
  97 +<td ROWSPAN="2"><div>+<i>X</i>% Enhanced Damage</div>
  98 +<div><i>Note: In all of the items I've examined, the two data fields have
  99 +the same value.</i></div>
  100 +<div><i>"Jesus on Bass" suggests that one data field enhances minimum
  101 +damage while the other field enhances maximum damage.&nbsp; I have
  102 +experimented and confirmed that the first field enhances your maximum
  103 +damage, and the second field enhances the minimum damage.</i></div></td>
  104 +</tr>
  105 +<tr><td align=center>9</td></tr>
  106 +
  107 +<tr>
  108 +<td align=center>19</td><td align=center>10</td><td></td>
  109 +<td>+<i>X</i> to Attack Rating</td>
  110 +</tr>
  111 +
  112 +<tr>
  113 +<td align=center>20</td><td align=center>6</td><td></td>
  114 +<td><i>X</i>% Increased Chance of Blocking</td>
  115 +</tr>
  116 +
  117 +<tr>
  118 +<td align=center>21</td><td align=center>6</td><td></td>
  119 +<td>+<i>X</i> to Minimum Damage</td>
  120 +</tr>
  121 +
  122 +<tr>
  123 +<td align=center>22</td><td align=center>7</td><td></td>
  124 +<td>+<i>X</i> to Maximum Damage</td>
  125 +</tr>
  126 +
  127 +<tr>
  128 +<td align=center>23</td><td align=center>6</td><td></td>
  129 +<td>+<i>X</i> to Minimum Damage<br>
  130 +<i>Note: I've often, but not always, seen this property and 21
  131 +together, and only one copy shows up in the game.&nbsp; I'm not sure
  132 +what the difference is.</i></td>
  133 +</tr>
  134 +
  135 +<tr>
  136 +<td align=center>24</td><td align=center>7</td><td></td>
  137 +<td>+<i>X</i> to Maximum Damage<br>
  138 +<i>Note: I've often, but not always, seen this property and 22
  139 +together, and only one copy shows up in the game.&nbsp; I'm not sure
  140 +what the difference is.</i></td>
  141 +</tr>
  142 +
  143 +<tr>
  144 +<td align=center>27</td><td align=center>8</td><td></td>
  145 +<td>Regenerate Mana <i>X</i>%</td>
  146 +</tr>
  147 +
  148 +<tr>
  149 +<td align=center>28</td><td align=center>8</td><td></td>
  150 +<td>Heal Stamina <i>X</i>%</td>
  151 +</tr>
  152 +
  153 +<tr>
  154 +<td align=center>31</td><td align=center>10</td><td align=center>10</td>
  155 +<td>+<i>X</i> Defense</td>
  156 +</tr>
  157 +
  158 +<tr>
  159 +<td align=center>32</td><td align=center>10</td><td align=center>10</td>
  160 +<td>+<i>X</i> Defense vs. Missile</td>
  161 +</tr>
  162 +
  163 +<tr>
  164 +<td align=center>33</td><td align=center>10</td><td align=center>10</td>
  165 +<td>+<i>X</i> Defense vs. Melee</td>
  166 +</tr>
  167 +
  168 +<tr>
  169 +<td align=center>34</td><td align=center>6</td><td></td>
  170 +<td>Damage Reduced by <i>X</i></td>
  171 +</tr>
  172 +
  173 +<tr>
  174 +<td align=center>35</td><td align=center>6</td><td></td>
  175 +<td>Magic Damage Reduced by <i>X</i></td>
  176 +</tr>
  177 +
  178 +<tr>
  179 +<td align=center>36</td><td align=center>8</td><td></td>
  180 +<td>Damage Reduced by <i>X</i>%</td>
  181 +</tr>
  182 +
  183 +<tr>
  184 +<td align=center>37</td><td align=center>8</td><td></td>
  185 +<td>Magic Resist +<i>X</i>%</td>
  186 +</tr>
  187 +
  188 +<tr>
  189 +<td align=center>38</td><td align=center>8</td><td></td>
  190 +<td>+<i>X</i>% to Maximum Magic Resist<br>
  191 +<i>A huge thanks goes to Gollen of Hungary for providing a table that
  192 +revealed this and many other codes in this table.</i></td>
  193 +</tr>
  194 +
  195 +<tr>
  196 +<td align=center>39</td><td align=center>8</td><td></td>
  197 +<td>Fire Resist +<i>X</i>%</td>
  198 +</tr>
  199 +
  200 +<tr>
  201 +<td align=center>40</td><td align=center>5</td><td></td>
  202 +<td>+<i>X</i>% to Maximum Fire Resist</td>
  203 +</tr>
  204 +
  205 +<tr>
  206 +<td align=center>41</td><td align=center>8</td><td></td>
  207 +<td>Lightning Resist +<i>X</i>%</td>
  208 +</tr>
  209 +
  210 +<tr>
  211 +<td align=center>42</td><td align=center>5</td><td></td>
  212 +<td>+<i>X</i>% to Maximum Lightning Resist</td>
  213 +</tr>
  214 +
  215 +<tr>
  216 +<td align=center>43</td><td align=center>8</td><td></td>
  217 +<td>Cold Resist +<i>X</i>%</td>
  218 +</tr>
  219 +
  220 +<tr>
  221 +<td align=center>44</td><td align=center>5</td><td></td>
  222 +<td>+<i>X</i>% to Maximum Cold Resist</td>
  223 +</tr>
  224 +
  225 +<tr>
  226 +<td align=center>45</td><td align=center>8</td><td></td>
  227 +<td>Poison Resist +<i>X</i>%</td>
  228 +</tr>
  229 +
  230 +<tr>
  231 +<td align=center>46</td><td align=center>5</td><td></td>
  232 +<td>+<i>X</i>% to Maximum Poison Resist</td>
  233 +</tr>
  234 +
  235 +<tr>
  236 +<td ROWSPAN="2" align=center>48</td><td align=center>8</td><td></td>
  237 +<td ROWSPAN="2">Adds <i>X</i>-<i>Y</i> fire damage</td>
  238 +</tr>
  239 +<tr><td align=center>8</td></tr>
  240 +
  241 +<tr>
  242 +<td ROWSPAN="2" align=center>50</td><td align=center>6</td><td></td>
  243 +<td ROWSPAN="2">Adds <i>X</i>-<i>Y</i> lightning damage</td>
  244 +</tr>
  245 +<tr><td align=center>9</td></tr>
  246 +
  247 +<tr>
  248 +<td ROWSPAN="2" align=center>52</td><td align=center>6</td><td></td>
  249 +<td ROWSPAN="2">Adds <i>X</i>-<i>Y</i> magic damage<br>
  250 +<i>contributed by Clement Lau -- thanks!</i></td>
  251 +</tr>
  252 +<tr><td align=center>7</td></tr>
  253 +
  254 +<tr>
  255 +<td ROWSPAN="3" align=center>54</td><td align=center>6</td><td></td>
  256 +<td ROWSPAN="2">Adds <i>X</i>-<i>Y</i> cold damage</td>
  257 +</tr>
  258 +<tr><td align=center>8</td></tr>
  259 +<tr><td align=center>8</td><td></td>
  260 +<td><i>This seems to be the duration of the cold/freeze effect.&nbsp;
  261 +Divide the value by 25 to get the number of seconds.</i></td>
  262 +</tr>
  263 +
  264 +<tr>
  265 +<td ROWSPAN="3" align=center>57</td><td align=center>9</td><td></td>
  266 +<td ROWSPAN="3"><p>Adds <i>X</i>-<i>Y</i> poison damage over <i>Z</i>
  267 +seconds</p>
  268 +<p><i>This property is a tricky one to figure out.&nbsp; For the
  269 +mathematically inclined, the first two fields give the minimum and
  270 +maximum, respectively, of <sup>1</sup>/<sub>256</sub><sup>th</sup> of
  271 +a unit of damage every <sup>1</sup>/<sub>25</sub><sup>th</sup> of a
  272 +second.&nbsp; The third field gives the duration of the poison; you
  273 +divide by 25 to get the number of seconds.&nbsp; Therefore, to compute
  274 +the amount of damage shown in the game, multiply the first field by
  275 +the third and divide by 256.&nbsp; (Repeat with the second
  276 +field.)</p>
  277 +<p>For example, if the field values are 30, 60, and 75, you get
  278 +30*75/256=8, 60*75/256=17, and 75/25=3, so the displayed property is
  279 +"Adds 8-17 Poison Damage over 3 seconds".</i></p></td>
  280 +</tr>
  281 +<tr><td align=center>9</td></tr>
  282 +<tr><td align=center>8</td></tr>
  283 +
  284 +<tr>
  285 +<td align=center>60</td><td align=center>7</td><td></td>
  286 +<td><i>X</i>% Life stolen per hit</td>
  287 +</tr>
  288 +
  289 +<tr>
  290 +<td align=center>62</td><td align=center>7</td><td></td>
  291 +<td><i>X</i>% Mana stolen per hit</td>
  292 +</tr>
  293 +
  294 +<tr>
  295 +<td align=center>73</td><td align=center>8</td><td align=center>30</td>
  296 +<td>+<i>X</i> Maximum Durability</td>
  297 +</tr>
  298 +
  299 +<tr>
  300 +<td align=center>74</td><td align=center>6</td><td align=center>30</td>
  301 +<td>Replenish Life +<i>X</i></td>
  302 +</tr>
  303 +
  304 +<tr>
  305 +<td align=center>75</td><td align=center>7</td><td align=center>20</td>
  306 +<td>Increase Maximum Durability <i>X</i>%</td>
  307 +</tr>
  308 +
  309 +<tr>
  310 +<td align=center>76</td><td align=center>6</td><td align=center>10</td>
  311 +<td>Increase Maximum Life <i>X</i>%</td>
  312 +</tr>
  313 +
  314 +<tr>
  315 +<td align=center>77</td><td align=center>6</td><td align=center>10</td>
  316 +<td>Increase Maximum Mana <i>X</i>%</td>
  317 +</tr>
  318 +
  319 +<tr>
  320 +<td align=center>78</td><td align=center>7</td><td></td>
  321 +<td>Attacker Takes Damage of <i>X</i></td>
  322 +</tr>
  323 +
  324 +<tr>
  325 +<td align=center>79</td><td align=center>9</td><td align=center>100</td>
  326 +<td><i>X</i>% Extra Gold from Monsters</td>
  327 +</tr>
  328 +
  329 +<tr>
  330 +<td align=center>80</td><td align=center>8</td><td align=center>100</td>
  331 +<td><i>X</i>% Better Chance of Getting Magic Items</td>
  332 +</tr>
  333 +
  334 +<tr>
  335 +<td align=center>81</td><td align=center>7</td><td></td>
  336 +<td>Knockback<br>
  337 +<i>I have no idea what the data field is used for.</i></td>
  338 +</tr>
  339 +
  340 +<tr>
  341 +<td align=center>83</td><td align=center>3</td><td></td>
  342 +<td>+<i>X</i> to Amazon Skill Levels</td>
  343 +</tr>
  344 +
  345 +<tr>
  346 +<td align=center>84</td><td align=center>3</td><td></td>
  347 +<td>+<i>X</i> to Paladin Skill Levels</td>
  348 +</tr>
  349 +
  350 +<tr>
  351 +<td align=center>85</td><td align=center>3</td><td></td>
  352 +<td>+<i>X</i> to Necromancer Skill Levels</td>
  353 +</tr>
  354 +
  355 +<tr>
  356 +<td align=center>86</td><td align=center>3</td><td></td>
  357 +<td>+<i>X</i> to Sorceress Skill Levels</td>
  358 +</tr>
  359 +
  360 +<tr>
  361 +<td align=center>87</td><td align=center>3</td><td></td>
  362 +<td>+<i>X</i> to Barbarian Skill Levels</td>
  363 +</tr>
  364 +
  365 +<tr>
  366 +<td align=center>89</td><td align=center>4</td><td align=center>4</td>
  367 +<td>+<i>X</i> to Light Radius</td>
  368 +</tr>
  369 +
  370 +<tr>
  371 +<td align=center>90</td><td align=center>5</td><td></td>
  372 +<td><i>This property is not displayed on the item, but its effect is
  373 +to alter the color of the ambient light. The possible colors are:
  374 +<table border align=center cellspacing=0>
  375 +<tr><th>Code</th><th>Color</th><th>Code</th><th>Color</th>
  376 +<th>Code</th><th>Color</th><th>Code</th><th>Color</th></tr>
  377 +<tr><td align=center>0</td><td>White</td>
  378 +<td align=center>1</td><td>Light Grey</td>
  379 +<td align=center>2</td><td>Dark Grey</td>
  380 +<td align=center>3</td><td>Black</td>
  381 +<tr><td></td><td></td><td align=center>4</td><td>Light Blue</td>
  382 +<td align=center>5</td><td>Dark Blue</td>
  383 +<td align=center>6</td><td>Crystal Blue</td></tr>
  384 +<tr><td></td><td></td><td align=center>7</td><td>Light Red</td>
  385 +<td align=center>8</td><td>Dark Red</td>
  386 +<td align=center>9</td><td>Crystal Red</td></tr>
  387 +<tr><td></td><td></td><td align=center>10</td><td>Light Green</td>
  388 +<td align=center>11</td><td>Dark Green</td>
  389 +<td align=center>12</td><td>Crystal Green</td></tr>
  390 +<tr><td></td><td></td><td align=center>13</td><td>Light Yellow</td>
  391 +<td align=center>14</td><td>Dark Yellow</td></tr>
  392 +<tr><td></td><td></td><td align=center>15</td><td>Light Gold</td>
  393 +<td align=center>16</td><td>Dark Gold</td></tr>
  394 +<tr><td></td><td></td><td align=center>17</td><td>Light Purple</td>
  395 +<td align=center>18</td><td>Dark Purple</td></tr>
  396 +<tr><td></td><td><td></td><td><td align=center>19</td><td>Orange</td></tr>
  397 +<tr><td></td><td><td align=center>20</td><td>Bright White</td></tr>
  398 +</table>
  399 +</td>
  400 +</tr>
  401 +
  402 +<tr>
  403 +<td align=center>91</td><td align=center>8</td><td align=center>100</td>
  404 +<td>Requirements -<i>X</i>%<br>
  405 +<i>Note that after subtracting the bias, <i>X</i> is (usually) a
  406 +negative number.</i></td>
  407 +</tr>
  408 +
  409 +<tr>
  410 +<td align=center>93</td><td align=center>7</td><td align=center>20</td>
  411 +<td><i>X</i>% Increased Attack Speed</td>
  412 +</tr>
  413 +
  414 +<tr>
  415 +<td align=center>96</td><td align=center>7</td><td align=center>20</td>
  416 +<td><i>X</i>% Faster Run/Walk</td>
  417 +</tr>
  418 +
  419 +<tr>
  420 +<td align=center>99</td><td align=center>7</td><td align=center>20</td>
  421 +<td><i>X</i>% Faster Hit Recovery</td>
  422 +</tr>
  423 +
  424 +<tr>
  425 +<td align=center>102</td><td align=center>7</td><td align=center>20</td>
  426 +<td><i>X</i>% Faster Block Rate</td>
  427 +</tr>
  428 +
  429 +<tr>
  430 +<td align=center>105</td><td align=center>7</td><td align=center>20</td>
  431 +<td><i>X</i>% Faster Cast Rate</td>
  432 +</tr>
  433 +
  434 +
  435 +<tr>
  436 +<td ROWSPAN="2" align=center>107,<br>108,<br>109,<br>181,<br>182,
  437 +<br>183,<br>184,<br>185,<br>186,<br>187</td>
  438 +<td align=center>9</td><td></td>
  439 +<td ROWSPAN="2">+<i>Y</i> to <i>spell X</i> (<i>character class</i>
  440 +Only)<br>
  441 +This property is usually applied to class-specific items found in the
  442 +Expansion Set. The first value selects the skill; there are too many
  443 +to list here, but I may provide them on another table if people ask
  444 +nicely. The second value determines how many additional skill points
  445 +are given.<br>
  446 +<i>Note that these three properties are all the same.&nbsp; I presume
  447 +different ID's are used because you can have up to three of these (ten
  448 +in an Expansion Set game), but no two properties for an item may have
  449 +the same ID.</td>
  450 +</tr>
  451 +<tr><td align=center>5</td></tr>
  452 +
  453 +<tr>
  454 +<td align=center>110</td><td align=center>8</td><td align=center>20</td>
  455 +<td>Poison Length Reduced by <i>X</i>%</td>
  456 +</tr>
  457 +
  458 +<tr>
  459 +<td align=center>111</td><td align=center>7</td><td align=center>20</td>
  460 +<td>Damage +<i>X</i></td>
  461 +</tr>
  462 +
  463 +<tr>
  464 +<td align=center>112</td><td align=center>7</td><td></td>
  465 +<td>Hit Causes Monster to Flee <i>X</i>%</td>
  466 +</tr>
  467 +
  468 +<tr>
  469 +<td align=center>113</td><td align=center>7</td><td></td>
  470 +<td>Hit Blinds Target +<i>X</i></td>
  471 +</tr>
  472 +
  473 +<tr>
  474 +<td align=center>114</td><td align=center>6</td><td></td>
  475 +<td><i>X</i>% Damage Taken Goes to Mana</td>
  476 +</tr>
  477 +
  478 +<tr>
  479 +<td align=center>115</td><td align=center>1</td><td></td>
  480 +<td>Ignore Target Defense<br>
  481 +<i>The value of the data field is always 1.</i></td>
  482 +</tr>
  483 +
  484 +<tr>
  485 +<td align=center>116</td><td align=center>7</td><td></td>
  486 +<td><i>X</i>% Target Defense</td>
  487 +</tr>
  488 +
  489 +<tr>
  490 +<td align=center>117</td><td align=center>7</td><td></td>
  491 +<td>Prevent Monster Heal<br>
  492 +<i>The value of the data field is 1; I don't know if it means
  493 +anything.</i></td>
  494 +</tr>
  495 +
  496 +<tr>
  497 +<td align=center>118</td><td align=center>1</td><td></td>
  498 +<td>Half Freeze Duration<br>
  499 +<i>The value of the data field is always 1.</i></td>
  500 +</tr>
  501 +
  502 +<tr>
  503 +<td align=center>119</td><td align=center>9</td><td align=center>20</td>
  504 +<td><i>X</i>% Bonus to Attack Rating</td>
  505 +</tr>
  506 +
  507 +<tr>
  508 +<td align=center>120</td><td align=center>7</td><td align=center>128</td>
  509 +<td><i>X</i> to Monster Defense Per Hit</td>
  510 +</tr>
  511 +
  512 +<tr>
  513 +<td align=center>121</td><td align=center>9</td><td align=center>20</td>
  514 +<td>+<i>X</i>% Damage to Demons</td>
  515 +</tr>
  516 +
  517 +<tr>
  518 +<td align=center>122</td><td align=center>9</td><td align=center>20</td>
  519 +<td>+<i>X</i>% Damage to Undead<br>
  520 +<i>Note that many types of weapon have a certain amount of this
  521 +property inherent in the weapon class, usually with values of 50% or
  522 +150%.&nbsp; This property is added on top of the weapon's base Damage
  523 +to Undead. For example, a flail may have a base rating of 50% Damage
  524 +to Undead. If this magic property is added to it with a value of 121,
  525 +then the displayed value is 121-20+50=151%.</i></td>
  526 +</tr>
  527 +
  528 +<tr>
  529 +<td align=center>123</td><td align=center>10</td><td align=center>128</td>
  530 +<td>+<i>X</i> to Attack Rating against Demons</td>
  531 +</tr>
  532 +
  533 +<tr>
  534 +<td align=center>124</td><td align=center>10</td><td align=center>128</td>
  535 +<td>+<i>X</i> to Attack Rating against Undead</td>
  536 +</tr>
  537 +
  538 +<tr>
  539 +<td align=center>126</td><td align=center>4</td><td></td>
  540 +<td>+<i>X</i> to Fire Skills</td>
  541 +</tr>
  542 +
  543 +<tr>
  544 +<td align=center>127</td><td align=center>3</td><td></td>
  545 +<td>+<i>X</i> to All Skill Levels</td>
  546 +</tr>
  547 +
  548 +<tr>
  549 +<td align=center>128</td><td align=center>5</td><td></td>
  550 +<td>Attacker Takes Lightning Damage of <i>X</i></td>
  551 +</tr>
  552 +
  553 +<tr>
  554 +<td align=center>134</td><td align=center>5</td><td></td>
  555 +<td>Freezes Target</td>
  556 +</tr>
  557 +
  558 +<tr>
  559 +<td align=center>135</td><td align=center>7</td><td></td>
  560 +<td><i>X</i>% Chance of Open Wounds</td>
  561 +</tr>
  562 +
  563 +<tr>
  564 +<td align=center>136</td><td align=center>7</td><td></td>
  565 +<td><i>X</i>% Chance of Crushing Blow</td>
  566 +</tr>
  567 +
  568 +<tr>
  569 +<td align=center>137</td><td align=center>7</td><td></td>
  570 +<td>+<i>X</i> Kick Damage</td>
  571 +</tr>
  572 +
  573 +<tr>
  574 +<td align=center>138</td><td align=center>7</td><td></td>
  575 +<td>+<i>X</i> to Mana After Each Kill</td>
  576 +</tr>
  577 +
  578 +<tr>
  579 +<td align=center>139</td><td align=center>7</td><td></td>
  580 +<td>+<i>X</i> Life after each Demon Kill</td>
  581 +</tr>
  582 +
  583 +<tr>
  584 +<td align=center>140</td><td align=center>7</td><td></td>
  585 +<td><i>Unknown.&nbsp; This property actually doesn't show up in the
  586 +item's description.&nbsp; Found it on the Swordback Hold Spiked
  587 +Shield.</i></td>
  588 +</tr>
  589 +
  590 +<tr>
  591 +<td align=center>141</td><td align=center>7</td><td></td>
  592 +<td><i>X</i>% Deadly Strike</td>
  593 +</tr>
  594 +
  595 +<tr>
  596 +<td align=center>142</td><td align=center>7</td><td></td>
  597 +<td>Fire Absorb <i>X</i>%<br>
  598 +<i>A huge thanks goes to Gollen of Hungary for providing a table that
  599 +revealed this and many other codes in this table.</i></td>
  600 +</tr>
  601 +
  602 +<tr>
  603 +<td align=center>143</td><td align=center>7</td><td></td>
  604 +<td><i>X</i> Fire Absorb</td>
  605 +</tr>
  606 +
  607 +<tr>
  608 +<td align=center>144</td><td align=center>7</td><td></td>
  609 +<td>Lightning Absorb <i>X</i>%</td>
  610 +</tr>
  611 +
  612 +<tr>
  613 +<td align=center>145</td><td align=center>7</td><td></td>
  614 +<td><i>X</i> Lightning Absorb</td>
  615 +</tr>
  616 +
  617 +<tr>
  618 +<td align=center>146</td><td align=center>7</td><td></td>
  619 +<td>Magic Absorb <i>X</i>%</td>
  620 +</tr>
  621 +
  622 +<tr>
  623 +<td align=center>147</td><td align=center>7</td><td></td>
  624 +<td><i>X</i> Magic Absorb</td>
  625 +</tr>
  626 +
  627 +<tr>
  628 +<td align=center>148</td><td align=center>7</td><td></td>
  629 +<td>Cold Absorb <i>X</i>%</td>
  630 +</tr>
  631 +
  632 +<tr>
  633 +<td align=center>149</td><td align=center>7</td><td></td>
  634 +<td><i>X</i> Cold Absorb</td>
  635 +</tr>
  636 +
  637 +<tr>
  638 +<td align=center>150</td><td align=center>7</td><td></td>
  639 +<td>Slows Target by <i>X</i>%</td>
  640 +</tr>
  641 +
  642 +<tr>
  643 +<td align=center>151</td><td align=center>7</td><td></td>
  644 +<td>Blessed Aim</td>
  645 +</tr>
  646 +
  647 +<tr>
  648 +<td align=center>152</td><td align=center>7</td><td></td>
  649 +<td>Defiance</td>
  650 +</tr>
  651 +
  652 +<tr>
  653 +<td align=center>153</td><td align=center>1</td><td></td>
  654 +<td>Cannot Be Frozen</td>
  655 +</tr>
  656 +
  657 +<tr>
  658 +<td align=center>154</td><td align=center>7</td><td></td>
  659 +<td><i>X</i>% Slower Stamina Drain</td>
  660 +</tr>
  661 +
  662 +<tr>
  663 +<td align=center>155</td><td align=center>7</td><td></td>
  664 +<td><i>X</i>% Chance to Reanimate Target</td>
  665 +</tr>
  666 +
  667 +<tr>
  668 +<td align=center>156</td><td align=center>7</td><td></td>
  669 +<td>Piercing Attack</td>
  670 +</tr>
  671 +
  672 +<tr>
  673 +<td align=center>157</td><td align=center>7</td><td></td>
  674 +<td>Fires Magic Arrows<br>
  675 +<i>contributed by Chris Moore -- thanks!</i></td>
  676 +</tr>
  677 +
  678 +<tr>
  679 +<td align=center>158</td><td align=center>7</td><td></td>
  680 +<td>Fires Explosive Arrows or Bolts</td>
  681 +</tr>
  682 +
  683 +<tr>
  684 +<td align=center>159</td><td align=center>6</td><td></td>
  685 +<td>+<i>X</i> to Minimum Damage<br>
  686 +<i>I've never seen this by itself; it's always been accompanied by
  687 +properties 21 and 23.</i></td>
  688 +</tr>
  689 +
  690 +<tr>
  691 +<td align=center>160</td><td align=center>7</td><td></td>
  692 +<td>+<i>X</i> to Maximum Damage<br>
  693 +<i>I've never seen this by itself; it's always been accompanied by
  694 +properties 22 and 24.</i></td>
  695 +</tr>
  696 +
  697 +<tr>
  698 +<td align=center>179</td><td align=center>3</td><td></td>
  699 +<td>+<i>X</i> to Druid Skill Levels</td>
  700 +</tr>
  701 +
  702 +<tr>
  703 +<td align=center>180</td><td align=center>3</td><td></td>
  704 +<td>+<i>X</i> to Assassin Skill Levels</td>
  705 +</tr>
  706 +
  707 +<tr>
  708 +<td ROWSPAN="2" align=center>188,<br>189,<br>190,<br>191,<br>192,<br>193</td>
  709 +<td align=center>5</td><td></td>
  710 +<td ROWSPAN="2">+<i>Y</i> to <i>skill set X</i> Skills
  711 +(<i>character class</i> Only)<br>
  712 +Skill sets are as follows:
  713 +<table border align=center cellspacing=0>
  714 +<tr><th>Class</th><th>Code</th><th>Skill Set</th>
  715 +<th>Code</th><th>Skill Set</th><th>Code</th><th>Skill Set</th></tr>
  716 +<tr><td align=center>Amazon</td><td align=center>0</td><td>Bow and Crossbow Skills</td>
  717 +<td align=center>1</td><td>Passive and Magic Skills</td>
  718 +<td align=center>2</td><td>Javelin and Spear Skills</td></tr>
  719 +<tr><td align=center>Sorceress</td><td align=center>3</td><td>Fire Spells</td>
  720 +<td align=center>4</td><td>Lightning Spells</td>
  721 +<td align=center>5</td><td>Cold Spells</td></tr>
  722 +<tr><td align=center>Necromancer</td><td align=center>6</td><td>Poison and Bone Spells</td>
  723 +<td align=center>7</td><td>Summoning Spells</td>
  724 +<td align=center>8</td><td>Curses</td></tr>
  725 +<tr><td align=center>Paladin</td><td align=center>9</td><td>Combat Skills</td>
  726 +<td align=center>10</td><td>Offensive Auras</td>
  727 +<td align=center>11</td><td>Defensive Auras</td></tr>
  728 +<tr><td align=center>Barbarian</td><td align=center>12</td><td>Combat Skills</td>
  729 +<td align=center>13</td><td>Combat Masteries</td>
  730 +<td align=center>14</td><td>Warcries</td></tr>
  731 +<tr><td align=center>Druid</td><td align=center>15</td><td>Summoning</td>
  732 +<td align=center>16</td><td>Shape Shifting</td>
  733 +<td align=center>17</td><td>Elemental</td></tr>
  734 +<tr><td align=center>Assassin</td><td align=center>18</td><td>Traps</td>
  735 +<td align=center>19</td><td>Shadow Disciplines</td>
  736 +<td align=center>20</td><td>Martial Arts</td></tr>
  737 +</table>
  738 +</td>
  739 +</tr>
  740 +<tr><td align=center>5</td></tr>
  741 +
  742 +<tr>
  743 +<td align=center>194</td><td align=center>4</td><td></td>
  744 +<td><i>Adds </i>X<i> extra sockets to the item.<br>This is simply
  745 +added to the item's <a
  746 +href="DiabloIIv1.09_Item_Format.shtml#sockets">natural number of
  747 +sockets</a>. It has no effect if the item is not already socketed.
  748 +This property may allow an item to have more sockets than the maximum
  749 +normally permitted on the item.</i><br>
  750 +<b>Warning:</b> <i>If you give an item too many sockets, you run the
  751 +risk of being unable to load the character with strange
  752 +errors! And even if the game does load successfully, it could crash
  753 +when you add too many gems to the item!</i></td>
  754 +</tr>
  755 +
  756 +<tr>
  757 +<td ROWSPAN="3" align=center>195,<br>196,<br>197</td>
  758 +<td align=center>9</td><td></td>
  759 +<td ROWSPAN="3"><i>Z</i>% Chance to cast level <i>Y</i> <i>spell X</i>
  760 +on attack<br>
  761 +The first value selects the spell, which coincidentally matches the
  762 +class skills as used in property #107 above.</td>
  763 +</tr>
  764 +<tr><td align=center>5</td></tr>
  765 +<tr><td align=center>7</td></tr>
  766 +
  767 +<tr>
  768 +<td ROWSPAN="3" align=center>198,<br>199,<br>200</td>
  769 +<td align=center>9</td><td></td>
  770 +<td ROWSPAN="3"><i>Z</i>% Chance to cast level <i>Y</i> <i>spell X</i>
  771 +on striking<br>
  772 +The first value selects the spell, which coincidentally matches the
  773 +class skills as used in property #107 above.</td>
  774 +</tr>
  775 +<tr><td align=center>5</td></tr>
  776 +<tr><td align=center>7</td></tr>
  777 +
  778 +<tr>
  779 +<td ROWSPAN="3" align=center>201,<br>202,<br>203</td>
  780 +<td align=center>9</td><td></td>
  781 +<td ROWSPAN="3"><i>Z</i>% Chance to cast level <i>Y</i> <i>spell X</i>
  782 +when struck<br>
  783 +The first value selects the spell, which coincidentally matches the
  784 +class skills as used in property #107 above.</td>
  785 +</tr>
  786 +<tr><td align=center>5</td></tr>
  787 +<tr><td align=center>7</td></tr>
  788 +
  789 +<tr>
  790 +<td ROWSPAN="4" align=center>204,<br>205,<br>206,<br>207,<br>208,
  791 +<br>209,<br>210,<br>211,<br>212,<br>213</td>
  792 +<td align=center>9</td><td></td>
  793 +<td ROWSPAN="4">level <i>X</i> <i>spell W</i> (<i>Y</i>/<i>Z</i>
  794 +Charges)<br>
  795 +The first value selects the spell, which coincidentally matches the
  796 +class skills as used in property #107 above.&nbsp; The second value
  797 +selects the level, the third gives the number of charges remaining in
  798 +the item, and the last is the total number of charges the item started
  799 +with. This property is usually applied to rings or amulets.</td>
  800 +</tr>
  801 +<tr><td align=center>5</td></tr>
  802 +<tr><td align=center>8</td></tr>
  803 +<tr><td align=center>8</td></tr>
  804 +
  805 +<tr><td></td><td colspan=2 align=right><b><i>Note:</i></b></td>
  806 +<td>Unless otherwise noted, all values Based on Character Level
  807 +are stored in eighths, so take the number, divide by 8, multiply by
  808 +the character level, and round down to get the result.</td>
  809 +</tr>
  810 +
  811 +<tr>
  812 +<td align=center>214</td><td align=center>6</td><td></td>
  813 +<td>+<i>X</i> to Defense (Based on Character Level)</td>
  814 +</tr>
  815 +
  816 +<tr>
  817 +<td align=center>215</td><td align=center>6</td><td></td>
  818 +<td><i>X</i>% Enhanced Defense (Based on Character Level)</td>
  819 +</tr>
  820 +
  821 +<tr>
  822 +<td align=center>216</td><td align=center>6</td><td></td>
  823 +<td>+<i>X</i> to Life (Based on Character Level)</td>
  824 +</tr>
  825 +
  826 +<tr>
  827 +<td align=center>217</td><td align=center>6</td><td></td>
  828 +<td>+<i>X</i> to Mana (Based on Character Level)</td>
  829 +</tr>
  830 +
  831 +<tr>
  832 +<td align=center>218</td><td align=center>6</td><td></td>
  833 +<td>+<i>X</i> to Maximum Damage (Based on Character Level)</td>
  834 +</tr>
  835 +
  836 +<tr>
  837 +<td align=center>219</td><td align=center>6</td><td></td>
  838 +<td><i>X</i>% Enhanced Maximum Damage (Based on Character Level)<br>
  839 +<i>A huge thanks goes to Gollen of Hungary for providing a table that
  840 +revealed this and many other codes in this table.</i></td>
  841 +</tr>
  842 +
  843 +<tr>
  844 +<td align=center>220</td><td align=center>6</td><td></td>
  845 +<td>+<i>X</i> to Strength (Based on Character Level)</td>
  846 +</tr>
  847 +
  848 +<tr>
  849 +<td align=center>221</td><td align=center>6</td><td></td>
  850 +<td>+<i>X</i> to Dexterity (Based on Character Level)</td>
  851 +</tr>
  852 +
  853 +<tr>
  854 +<td align=center>222</td><td align=center>6</td><td></td>
  855 +<td>+<i>X</i> to Energy (Based on Character Level)</td>
  856 +</tr>
  857 +
  858 +<tr>
  859 +<td align=center>223</td><td align=center>6</td><td></td>
  860 +<td>+<i>X</i> to Vitality (Based on Character Level)</td>
  861 +</tr>
  862 +
  863 +<tr>
  864 +<td align=center>224</td><td align=center>6</td><td></td>
  865 +<td>+<i>X</i> to Attack Rating (Based on Character Level)<br>
  866 +This value is in halves, so take the number, divide by 2, multiply by
  867 +the character level, and round down to get the attack rating.</td>
  868 +</tr>
  869 +
  870 +<tr>
  871 +<td align=center>225</td><td align=center>6</td><td></td>
  872 +<td><i>X</i>% Bonus to Attack Rating (Based on Character Level)<br>
  873 +This value is in halves, so take the number, divide by 2, multiply by
  874 +the character level, and round down to get the attack rating bonus.</td>
  875 +</tr>
  876 +
  877 +<tr>
  878 +<td align=center>226</td><td align=center>6</td><td></td>
  879 +<td>+<i>X</i> Cold Damage (Based on Character Level)</td>
  880 +</tr>
  881 +
  882 +<tr>
  883 +<td align=center>227</td><td align=center>6</td><td></td>
  884 +<td>+<i>X</i> Fire Damage (Based on Character Level)</td>
  885 +</tr>
  886 +
  887 +<tr>
  888 +<td align=center>228</td><td align=center>6</td><td></td>
  889 +<td>+<i>X</i> Lightning Damage (Based on Character Level)</td>
  890 +</tr>
  891 +
  892 +<tr>
  893 +<td align=center>229</td><td align=center>6</td><td></td>
  894 +<td>+<i>X</i> Poison Damage (Based on Character Level)</td>
  895 +</tr>
  896 +
  897 +<tr>
  898 +<td align=center>230</td><td align=center>6</td><td></td>
  899 +<td>Cold Resist +<i>X</i>% (Based on Character Level)</td>
  900 +</tr>
  901 +
  902 +<tr>
  903 +<td align=center>231</td><td align=center>6</td><td></td>
  904 +<td>Fire Resist +<i>X</i>% (Based on Character Level)</td>
  905 +</tr>
  906 +
  907 +<tr>
  908 +<td align=center>232</td><td align=center>6</td><td></td>
  909 +<td>Lightning Resist +<i>X</i>% (Based on Character Level)</td>
  910 +</tr>
  911 +
  912 +<tr>
  913 +<td align=center>233</td><td align=center>6</td><td></td>
  914 +<td>Poison Resist +<i>X</i>% (Based on Character Level)</td>
  915 +</tr>
  916 +
  917 +<tr> <td align=center>234</td><td align=center>6</td><td></td>
  918 +<td>+<i>X</i> Cold Absorb (Based on Character Level)</td>
  919 +</tr>
  920 +
  921 +<tr>
  922 +<td align=center>235</td><td align=center>6</td><td></td>
  923 +<td>+<i>X</i> Fire Absorb (Based on Character Level)</td>
  924 +</tr>
  925 +
  926 +<tr>
  927 +<td align=center>236</td><td align=center>6</td><td></td>
  928 +<td>+<i>X</i> Lightning Absorb (Based on Character Level)</td>
  929 +</tr>
  930 +
  931 +<tr>
  932 +<td align=center>237</td><td align=center>6</td><td></td>
  933 +<td><i>X</i> Poison Absorb (Based on Character Level)</td>
  934 +</tr>
  935 +
  936 +<tr><td></td><td colspan=2 align=right><b><i>Note:</i></b></td>
  937 +<td>Unless otherwise noted, all values Based on Character Level
  938 +are stored in eighths, so take the number, divide by 8, multiply by
  939 +the character level, and round down to get the result.</td>
  940 +</tr>
  941 +
  942 +<tr>
  943 +<td align=center>238</td><td align=center>6</td><td></td>
  944 +<td>Attacker Takes Damage of <i>X</i> (Based on Character Level)</td>
  945 +</tr>
  946 +
  947 +<tr>
  948 +<td align=center>239</td><td align=center>6</td><td></td>
  949 +<td><i>X</i>% Extra Gold from Monsters (Based on Character Level)</td>
  950 +</tr>
  951 +
  952 +<tr>
  953 +<td align=center>240</td><td align=center>6</td><td></td>
  954 +<td><i>X</i>% Better Chance of Getting Magic Items (Based on Character
  955 +Level)</td>
  956 +</tr>
  957 +
  958 +<tr>
  959 +<td align=center>241</td><td align=center>6</td><td></td>
  960 +<td>Heal Stamina Plus <i>X</i>% (Based on Character Level)</td>
  961 +</tr>
  962 +
  963 +<tr>
  964 +<td align=center>243</td><td align=center>6</td><td></td>
  965 +<td><i>X</i>% Damage to Demons (Based on Character Level)</td>
  966 +</tr>
  967 +
  968 +<tr>
  969 +<td align=center>244</td><td align=center>6</td><td></td>
  970 +<td><i>X</i>% Damage to Undead (Based on Character Level)</td>
  971 +</tr>
  972 +
  973 +<tr>
  974 +<td align=center>245</td><td align=center>6</td><td></td>
  975 +<td>+<i>X</i> to Attack Rating against Demons (Based on Character
  976 +Level)</td>
  977 +</tr>
  978 +
  979 +<tr>
  980 +<td align=center>246</td><td align=center>6</td><td></td>
  981 +<td>+<i>X</i> to Attack Rating against Undead (Based on Character
  982 +Level)</td>
  983 +</tr>
  984 +
  985 +<tr>
  986 +<td align=center>247</td><td align=center>6</td><td></td>
  987 +<td><i>X</i>% Chance of Crushing Blow (Based on Character Level)</td>
  988 +</tr>
  989 +
  990 +<tr>
  991 +<td align=center>248</td><td align=center>6</td><td></td>
  992 +<td><i>X</i>% Chance of Open Wounds (Based on Character Level)</td>
  993 +</tr>
  994 +
  995 +<tr>
  996 +<td align=center>249</td><td align=center>6</td><td></td>
  997 +<td>+<i>X</i> Kick Damage (Based on Character Level)</td>
  998 +</tr>
  999 +
  1000 +<tr>
  1001 +<td align=center>250</td><td align=center>6</td><td></td>
  1002 +<td><i>X</i>% to Deadly Strike (Based on Character Level)<br>
  1003 +<i>contributed by Chris Moore</i></td>
  1004 +</tr>
  1005 +
  1006 +<tr>
  1007 +<td align=center>252</td><td align=center>5</td><td></td>
  1008 +<td>Repairs 1 durability in <i>X</i> seconds<br>
  1009 +The value of the data field is not actually a time period, but a
  1010 +frequency in terms of the number of times durability is repaired over
  1011 +a period of 100 seconds. For example, if the value is 5, then this
  1012 +property repairs 1 durability in 100/5=20 seconds.</td>
  1013 +</tr>
  1014 +
  1015 +<tr>
  1016 +<td align=center>253</td><td align=center>5</td><td></td>
  1017 +<td>Replenishes Quantity<br>
  1018 +As in the previous property, the value of the data field is a
  1019 +frequency in terms of the number of items replenished over a period of
  1020 +100 seconds. For example, if the value is 4, then this property
  1021 +replenishes 1 item in 100/4=25 seconds.</td>
  1022 +</tr>
  1023 +
  1024 +<tr>
  1025 +<td align=center>254</td><td align=center>8</td><td></td>
  1026 +<td>Increased Stack Size<br>
  1027 +The value is the number of additional items that can be placed on the
  1028 +stack (beyond the base limit).</td>
  1029 +</tr>
  1030 +
  1031 +<tr>
  1032 +<td rowspan=3 align=center>268<br>through<br>303</td>
  1033 +<td align=center>2</td><td rowspan=3><b><i>Note:</i></b></td>
  1034 +<td rowspan=3>This range of magic properties change value depending on
  1035 +the time of day in the game. The format of the bit fields is the same
  1036 +in all cases. The first 2-bit field specifies the time of day when
  1037 +the value is at its maximum:<br>
  1038 +<table align=center cellspacing=0>
  1039 +<tr><td width="5%">0</td><td width="40%">During Daytime</td><td width="10%"></td>
  1040 +<td width="5%">1</td><td width="40%">Near Dusk</td></tr>
  1041 +<tr><td>2</td><td>During Nighttime</td><td></td>
  1042 +<td>3</td><td>Near Dawn</td></tr>
  1043 +</table>
  1044 +The second and third fields are, respectively, the minimum and maximum
  1045 +values of the property. It has the maximum value at the time
  1046 +specified, the minimum value at the opposite time, and a value halfway
  1047 +between minimum and maximum during the in-between times.<br>
  1048 +<i>A huge thanks goes to Gollen of Hungary for providing a table that
  1049 +revealed these and many other codes in this table.</i></tr>
  1050 +<tr><td align=center>10</td></tr>
  1051 +<tr><td align=center>10</td></tr>
  1052 +
  1053 +<tr>
  1054 +<td align=center>268</td><td align=center>2, 10, 10</td><td></td>
  1055 +<td>+<i>X</i> Defense (Increases <i>by time</i>)</td>
  1056 +</tr>
  1057 +
  1058 +<tr>
  1059 +<td align=center>269</td><td align=center>2, 10, 10</td><td></td>
  1060 +<td><i>X</i>% Enhanced Defense (Increases <i>by time</i>)</td>
  1061 +</tr>
  1062 +
  1063 +<tr>
  1064 +<td align=center>270</td><td align=center>2, 10, 10</td><td></td>
  1065 +<td>+<i>X</i> to Life (Increases <i>by time</i>)</td>
  1066 +</tr>
  1067 +
  1068 +<tr>
  1069 +<td align=center>271</td><td align=center>2, 10, 10</td><td></td>
  1070 +<td>+<i>X</i> to Mana (Increases <i>by time</i>)</td>
  1071 +</tr>
  1072 +
  1073 +<tr>
  1074 +<td align=center>272</td><td align=center>2, 10, 10</td><td></td>
  1075 +<td>+<i>X</i> to Damage (Increases <i>by time</i>)</td>
  1076 +</tr>
  1077 +
  1078 +<tr>
  1079 +<td align=center>273</td><td align=center>2, 10, 10</td><td></td>
  1080 +<td><i>X</i>% Enhanced Damage (Increases <i>by time</i>)</td>
  1081 +</tr>
  1082 +
  1083 +<tr>
  1084 +<td align=center>274</td><td align=center>2, 10, 10</td><td></td>
  1085 +<td>+<i>X</i> to Strength (Increases <i>by time</i>)</td>
  1086 +</tr>
  1087 +
  1088 +<tr>
  1089 +<td align=center>275</td><td align=center>2, 10, 10</td><td></td>
  1090 +<td>+<i>X</i> to Dexterity (Increases <i>by time</i>)</td>
  1091 +</tr>
  1092 +
  1093 +<tr>
  1094 +<td align=center>276</td><td align=center>2, 10, 10</td><td></td>
  1095 +<td>+<i>X</i> to Energy (Increases <i>by time</i>)</td>
  1096 +</tr>
  1097 +
  1098 +<tr>
  1099 +<td align=center>277</td><td align=center>2, 10, 10</td><td></td>
  1100 +<td>+<i>X</i> to Vitality (Increases <i>by time</i>)</td>
  1101 +</tr>
  1102 +
  1103 +<tr>
  1104 +<td align=center>278</td><td align=center>2, 10, 10</td><td></td>
  1105 +<td><i>X</i>% Enhanced Attack Rating (Increases <i>by time</i>)</td>
  1106 +</tr>
  1107 +
  1108 +<tr>
  1109 +<td align=center>279</td><td align=center>2, 10, 10</td><td></td>
  1110 +<td>+<i>X</i> to Attack Rating (Increases <i>by time</i>)</td>
  1111 +</tr>
  1112 +
  1113 +<tr>
  1114 +<td align=center>280</td><td align=center>2, 10, 10</td><td></td>
  1115 +<td>+<i>X</i> Cold Damage (Increases <i>by time</i>)</td>
  1116 +</tr>
  1117 +
  1118 +<tr>
  1119 +<td align=center>281</td><td align=center>2, 10, 10</td><td></td>
  1120 +<td>+<i>X</i> Fire Damage (Increases <i>by time</i>)</td>
  1121 +</tr>
  1122 +
  1123 +<tr>
  1124 +<td align=center>282</td><td align=center>2, 10, 10</td><td></td>
  1125 +<td>+<i>X</i> Lightning Damage (Increases <i>by time</i>)</td>
  1126 +</tr>
  1127 +
  1128 +<tr>
  1129 +<td align=center>283</td><td align=center>2, 10, 10</td><td></td>
  1130 +<td>+<i>X</i> Poison Damage (Increases <i>by time</i>)</td>
  1131 +</tr>
  1132 +
  1133 +<tr>
  1134 +<td align=center>284</td><td align=center>2, 10, 10</td><td></td>
  1135 +<td><i>X</i>% Cold Resist (Increases <i>by time</i>)</td>
  1136 +</tr>
  1137 +
  1138 +<tr>
  1139 +<td align=center>285</td><td align=center>2, 10, 10</td><td></td>
  1140 +<td><i>X</i>% Fire Resist (Increases <i>by time</i>)</td>
  1141 +</tr>
  1142 +
  1143 +<tr>
  1144 +<td align=center>286</td><td align=center>2, 10, 10</td><td></td>
  1145 +<td><i>X</i>% Lightning Resist (Increases <i>by time</i>)</td>
  1146 +</tr>
  1147 +
  1148 +<tr>
  1149 +<td align=center>287</td><td align=center>2, 10, 10</td><td></td>
  1150 +<td><i>X</i>% Poison Resist (Increases <i>by time</i>)</td>
  1151 +</tr>
  1152 +
  1153 +<tr>
  1154 +<td align=center>288</td><td align=center>2, 10, 10</td><td></td>
  1155 +<td>+<i>X</i> Cold Absorb (Increases <i>by time</i>)</td>
  1156 +</tr>
  1157 +
  1158 +<tr>
  1159 +<td align=center>289</td><td align=center>2, 10, 10</td><td></td>
  1160 +<td>+<i>X</i> Fire Absorb (Increases <i>by time</i>)</td>
  1161 +</tr>
  1162 +
  1163 +<tr>
  1164 +<td align=center>290</td><td align=center>2, 10, 10</td><td></td>
  1165 +<td>+<i>X</i> Lightning Absorb (Increases <i>by time</i>)</td>
  1166 +</tr>
  1167 +
  1168 +<tr>
  1169 +<td align=center>291</td><td align=center>2, 10, 10</td><td></td>
  1170 +<td>+<i>X</i> Poison Absorb (Increases <i>by time</i>)</td>
  1171 +</tr>
  1172 +
  1173 +<tr>
  1174 +<td></td><td align=center>2</td>
  1175 +<td rowspan=3 align=right><b><i>Note:</i></b></td>
  1176 +<td rowspan=3>All <i>by Time</i> magic properties change value depending on
  1177 +the time of day in the game. The format of the bit fields is the same
  1178 +in all cases. The first 2-bit field specifies the time of day when
  1179 +the value is at its maximum:<br>
  1180 +<table align=center cellspacing=0>
  1181 +<tr><td width="5%">0</td><td width="40%">During Daytime</td><td width="10%"></td>
  1182 +<td width="5%">1</td><td width="40%">Near Dusk</td></tr>
  1183 +<tr><td>2</td><td>During Nighttime</td><td></td>
  1184 +<td>3</td><td>Near Dawn</td></tr>
  1185 +</table>
  1186 +The second and third fields are, respectively, the minimum and maximum
  1187 +values of the property. It has the maximum value at the time
  1188 +specified, the minimum value at the opposite time, and a value halfway
  1189 +between minimum and maximum during the in-between times.</tr>
  1190 +<tr><td></td><td align=center>10</td></tr>
  1191 +<tr><td></td><td align=center>10</td></tr>
  1192 +
  1193 +<tr>
  1194 +<td align=center>292</td><td align=center>2, 10, 10</td><td></td>
  1195 +<td><i>X</i>% Extra Gold from Monsters (Increases <i>by time</i>)</td>
  1196 +</tr>
  1197 +
  1198 +<tr>
  1199 +<td align=center>293</td><td align=center>2, 10, 10</td><td></td>
  1200 +<td><i>X</i>% Better Chance of Getting Magic Items (Increases <i>by time</i>)</td>
  1201 +</tr>
  1202 +
  1203 +<tr>
  1204 +<td align=center>294</td><td align=center>2, 10, 10</td><td></td>
  1205 +<td>Heal Stamina Plus <i>X</i>% (Increases <i>by time</i>)</td>
  1206 +</tr>
  1207 +
  1208 +<tr>
  1209 +<td align=center>295</td><td align=center>2, 10, 10</td><td></td>
  1210 +<td>+<i>X</i> to Stamina (Increases <i>by time</i>)</td>
  1211 +</tr>
  1212 +
  1213 +<tr>
  1214 +<td align=center>296</td><td align=center>2, 10, 10</td><td></td>
  1215 +<td><i>X</i>% Damage to Demons (Increases <i>by time</i>)</td>
  1216 +</tr>
  1217 +
  1218 +<tr>
  1219 +<td align=center>297</td><td align=center>2, 10, 10</td><td></td>
  1220 +<td><i>X</i>% Damage to Undead (Increases <i>by time</i>)</td>
  1221 +</tr>
  1222 +
  1223 +<tr>
  1224 +<td align=center>298</td><td align=center>2, 10, 10</td><td></td>
  1225 +<td>+<i>X</i> to Attack Rating against Demons (Increases <i>by
  1226 +time</i>)</td>
  1227 +</tr>
  1228 +
  1229 +<tr>
  1230 +<td align=center>299</td><td align=center>2, 10, 10</td><td></td>
  1231 +<td>+<i>X</i> to Attack Rating against Undead (Increases <i>by
  1232 +time</i>)</td>
  1233 +</tr>
  1234 +
  1235 +<tr>
  1236 +<td align=center>300</td><td align=center>2, 10, 10</td><td></td>
  1237 +<td><i>X</i>% Chance of Crushing Blow (Increases <i>by time</i>)</td>
  1238 +</tr>
  1239 +
  1240 +<tr>
  1241 +<td align=center>301</td><td align=center>2, 10, 10</td><td></td>
  1242 +<td><i>X</i>% Chance of Open Wounds (Increases <i>by time</i>)</td>
  1243 +</tr>
  1244 +
  1245 +<tr>
  1246 +<td align=center>302</td><td align=center>2, 10, 10</td><td></td>
  1247 +<td>+<i>X</i> Kick Damage (Increases <i>by time</i>)</td>
  1248 +</tr>
  1249 +
  1250 +<tr>
  1251 +<td align=center>303</td><td align=center>2, 10, 10</td><td></td>
  1252 +<td><i>X</i>% Deadly Strike (Increases <i>by time</i>)</td>
  1253 +</tr>
  1254 +
  1255 +<tr>
  1256 +<td align=center>511<br>(0x1ff)</td><td align=center>0</td><td></td>
  1257 +<td>End of the (current) property list. If this is a set item, more
  1258 +property lists may follow; otherwise the last byte of item data is
  1259 +zero-padded.</td>
  1260 +</tr>
  1261 +
  1262 +</table>
  1263 +
  1264 +<hr>
  1265 +
  1266 +<p><i>Please send any additions or corrections to me using my
  1267 +<a href="mail.html">web-based mail form</a>.</i></p>
  1268 +
  1269 +</body>
  1270 +</html>
  1271 +
... ...
docs/design
... ... @@ -37,7 +37,6 @@ User should be able to:
37 37 - change item level
38 38 - import/export
39 39 - print object data (separate utility)
40   ------- FUTURE ------
41 40 - change quality
42 41 - change magical attributes
43 42 - change suffix/prefix
... ...
utils/bitscat.c 0 → 100644
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <unistd.h>
  4 +#include <fcntl.h>
  5 +
  6 +#define readBits(start,size,data) ((*((uint64_t *) &data[(start) / 8]) >> ((start) & 7)) & ((1 << (size)) - 1))
  7 +
  8 +uint64_t readData(const char* filename, unsigned int offset, unsigned int size) {
  9 + uint64_t data = 0;
  10 + int fd = open(filename, O_RDONLY);
  11 + if(fd == -1) {
  12 + return data;
  13 + }
  14 + if(lseek(fd, offset/8, SEEK_SET) == -1) {
  15 + close(fd);
  16 + return data;
  17 + }
  18 + ssize_t numBytes = read(fd, &data, sizeof(data));
  19 + if(numBytes != sizeof(data)) {
  20 + close(fd);
  21 + return data;
  22 + }
  23 + uint64_t* dataPtr = &data;
  24 + uint64_t aux = readBits(offset % 8, size, dataPtr);
  25 + data = aux;
  26 + close(fd);
  27 + return data;
  28 +}
  29 +
  30 +int main(int argc, char** argv) {
  31 + char c;
  32 + const char* filename = NULL;
  33 + unsigned int offset = 0;
  34 + unsigned int size = 0;
  35 + while ((c = getopt (argc, argv, "f:o:s:")) != -1) {
  36 + switch(c) {
  37 + case 'f':
  38 + filename = optarg;
  39 + break;
  40 + case 'o':
  41 + offset = atoi(optarg);
  42 + break;
  43 + case 's':
  44 + size = atoi(optarg);
  45 + break;
  46 + case '?':
  47 + return 1;
  48 + }
  49 + }
  50 +
  51 + if(!filename || !offset || !size) {
  52 + fprintf(stderr, "Need to specify filename (-f), offset (-o) and size (-s)\n");
  53 + return 1;
  54 + }
  55 + uint64_t data = readData(filename, offset, size);
  56 + printf("Read: 0x%016llX (%llu)\n", data, data);
  57 + return 0;
  58 +}
... ...