Commit 00938948301ef2d87243d3a3e9be6ca4d5383ddf
1 parent
3409b841
Implemented all TODOs up to waypoints. Made API more consistent
Showing
9 changed files
with
1062 additions
and
70 deletions
d2char.c
@@ -28,39 +28,47 @@ int isHardcore(D2CharHeader* c) { | @@ -28,39 +28,47 @@ int isHardcore(D2CharHeader* c) { | ||
28 | return c->charStatus & D2S_CHARSTATUS_HARDCORE; | 28 | return c->charStatus & D2S_CHARSTATUS_HARDCORE; |
29 | } | 29 | } |
30 | 30 | ||
31 | -void setHardcore(D2CharHeader* c) { | ||
32 | - | 31 | +void setHardcore(D2CharHeader* c, int bool) { |
32 | + if(bool) { | ||
33 | + c->charProgress |= D2S_CHARSTATUS_HARDCORE; | ||
34 | + } else { | ||
35 | + c->charProgress &= ~D2S_CHARSTATUS_HARDCORE; | ||
36 | + } | ||
33 | } | 37 | } |
34 | 38 | ||
35 | int hasDied(D2CharHeader* c) { | 39 | int hasDied(D2CharHeader* c) { |
36 | return c->charStatus & D2S_CHARSTATUS_DIED; | 40 | return c->charStatus & D2S_CHARSTATUS_DIED; |
37 | } | 41 | } |
38 | 42 | ||
39 | -void setDied(D2CharHeader* c) { | ||
40 | - | 43 | +void setDied(D2CharHeader* c, int bool) { |
44 | + if(bool) { | ||
45 | + c->charProgress |= D2S_CHARSTATUS_DIED; | ||
46 | + } else { | ||
47 | + c->charProgress &= ~D2S_CHARSTATUS_DIED; | ||
48 | + } | ||
41 | } | 49 | } |
42 | 50 | ||
43 | int isExpansion(D2CharHeader* c) { | 51 | int isExpansion(D2CharHeader* c) { |
44 | return c->charStatus & D2S_CHARSTATUS_EXPANSION; | 52 | return c->charStatus & D2S_CHARSTATUS_EXPANSION; |
45 | } | 53 | } |
46 | 54 | ||
47 | -void setExpansion(D2CharHeader* c) { | ||
48 | - | 55 | +void setExpansion(D2CharHeader* c, int bool) { |
56 | + if(bool) { | ||
57 | + c->charProgress |= D2S_CHARSTATUS_EXPANSION; | ||
58 | + } else { | ||
59 | + c->charProgress &= ~D2S_CHARSTATUS_EXPANSION; | ||
60 | + } | ||
49 | } | 61 | } |
50 | 62 | ||
51 | int isLadder(D2CharHeader* c) { | 63 | int isLadder(D2CharHeader* c) { |
52 | return c->charStatus & D2S_CHARSTATUS_LADDER; | 64 | return c->charStatus & D2S_CHARSTATUS_LADDER; |
53 | } | 65 | } |
54 | 66 | ||
55 | -void setLadder(D2CharHeader* c) { | ||
56 | - | ||
57 | -} | ||
58 | - | ||
59 | -D2S_ACT getCurrentAct(D2CharHeader* c) { | ||
60 | - if(isExpansion(c)) { | ||
61 | - return c->charProgress % 5; | 67 | +void setLadder(D2CharHeader* c, int bool) { |
68 | + if(bool) { | ||
69 | + c->charProgress |= D2S_CHARSTATUS_LADDER; | ||
62 | } else { | 70 | } else { |
63 | - return c->charProgress % 4; | 71 | + c->charProgress &= ~D2S_CHARSTATUS_LADDER; |
64 | } | 72 | } |
65 | } | 73 | } |
66 | 74 | ||
@@ -71,33 +79,34 @@ int isFemale(D2CharHeader* c) { | @@ -71,33 +79,34 @@ int isFemale(D2CharHeader* c) { | ||
71 | } | 79 | } |
72 | 80 | ||
73 | const char* getCharacterTitle(D2CharHeader* c) { | 81 | const char* getCharacterTitle(D2CharHeader* c) { |
74 | - int tier; | 82 | + D2S_DIFFICULTY hardestCleared; |
83 | + D2S_ACT act; // We don't care, but need to provide it | ||
84 | + getProgress(c,&act,&hardestCleared); | ||
75 | if(isExpansion(c)) { | 85 | if(isExpansion(c)) { |
76 | // Expansion | 86 | // Expansion |
77 | - tier = c->charProgress / 5; | ||
78 | if(isHardcore(c)) { | 87 | if(isHardcore(c)) { |
79 | // Expansion Hardcore | 88 | // Expansion Hardcore |
80 | - switch(tier) { | ||
81 | - case 1: | 89 | + switch(hardestCleared) { |
90 | + case D2S_DIFFICULTY_NORMAL: | ||
82 | return D2S_CHARPROGRESS_EXPANSION_TIER1_NAME_HARDCORE; | 91 | return D2S_CHARPROGRESS_EXPANSION_TIER1_NAME_HARDCORE; |
83 | break; | 92 | break; |
84 | - case 2: | 93 | + case D2S_DIFFICULTY_NIGHTMARE: |
85 | return D2S_CHARPROGRESS_EXPANSION_TIER2_NAME_HARDCORE; | 94 | return D2S_CHARPROGRESS_EXPANSION_TIER2_NAME_HARDCORE; |
86 | break; | 95 | break; |
87 | - case 3: | 96 | + case D2S_DIFFICULTY_HELL: |
88 | return D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_HARDCORE; | 97 | return D2S_CHARPROGRESS_EXPANSION_TIER3_NAME_HARDCORE; |
89 | break; | 98 | break; |
90 | } | 99 | } |
91 | } else { | 100 | } else { |
92 | // Expansion Softcore | 101 | // Expansion Softcore |
93 | - switch(tier) { | ||
94 | - case 1: | 102 | + switch(hardestCleared) { |
103 | + case D2S_DIFFICULTY_NORMAL: | ||
95 | return D2S_CHARPROGRESS_EXPANSION_TIER1_NAME; | 104 | return D2S_CHARPROGRESS_EXPANSION_TIER1_NAME; |
96 | break; | 105 | break; |
97 | - case 2: | 106 | + case D2S_DIFFICULTY_NIGHTMARE: |
98 | return D2S_CHARPROGRESS_EXPANSION_TIER2_NAME; | 107 | return D2S_CHARPROGRESS_EXPANSION_TIER2_NAME; |
99 | break; | 108 | break; |
100 | - case 3: | 109 | + case D2S_DIFFICULTY_HELL: |
101 | 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; |
102 | break; | 111 | break; |
103 | } | 112 | } |
@@ -106,27 +115,27 @@ const char* getCharacterTitle(D2CharHeader* c) { | @@ -106,27 +115,27 @@ const char* getCharacterTitle(D2CharHeader* c) { | ||
106 | // Classic | 115 | // Classic |
107 | if(isHardcore(c)) { | 116 | if(isHardcore(c)) { |
108 | // Classic Hardcore | 117 | // Classic Hardcore |
109 | - switch(tier) { | ||
110 | - case 1: | 118 | + switch(hardestCleared) { |
119 | + case D2S_DIFFICULTY_NORMAL: | ||
111 | 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; |
112 | break; | 121 | break; |
113 | - case 2: | 122 | + case D2S_DIFFICULTY_NIGHTMARE: |
114 | 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; |
115 | break; | 124 | break; |
116 | - case 3: | 125 | + case D2S_DIFFICULTY_HELL: |
117 | 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; |
118 | break; | 127 | break; |
119 | } | 128 | } |
120 | } else { | 129 | } else { |
121 | // Classic Softcore | 130 | // Classic Softcore |
122 | - switch(tier) { | ||
123 | - case 1: | 131 | + switch(hardestCleared) { |
132 | + case D2S_DIFFICULTY_NORMAL: | ||
124 | 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; |
125 | break; | 134 | break; |
126 | - case 2: | 135 | + case D2S_DIFFICULTY_NIGHTMARE: |
127 | 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; |
128 | break; | 137 | break; |
129 | - case 3: | 138 | + case D2S_DIFFICULTY_HELL: |
130 | 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; |
131 | break; | 140 | break; |
132 | } | 141 | } |
@@ -160,18 +169,72 @@ D2S_DIFFICULTY getCurrentDifficulty(D2CharHeader* c) { | @@ -160,18 +169,72 @@ D2S_DIFFICULTY getCurrentDifficulty(D2CharHeader* c) { | ||
160 | return D2S_DIFFICULTY_UNKNOWN; | 169 | return D2S_DIFFICULTY_UNKNOWN; |
161 | } | 170 | } |
162 | 171 | ||
163 | -int setProgress(D2S_ACT act, D2S_DIFFICULTY difficulty) { | ||
164 | - // TODO | ||
165 | - // set c->difficulty and c->progress? | 172 | +D2S_ACT getCurrentAct(D2CharHeader* c) { |
173 | + for(int i = D2S_DIFFICULTY_NORMAL; i <= D2S_DIFFICULTY_HELL; ++i) { | ||
174 | + if(c->difficulty[i] & D2S_DIFFICULTY_ACTIVE) { | ||
175 | + return (D2S_ACT)(c->difficulty[i] & 0x07); | ||
176 | + } | ||
177 | + } | ||
178 | + return D2S_ACT_UNKNOWN; | ||
179 | +} | ||
180 | + | ||
181 | +void getProgress(D2CharHeader* c, D2S_ACT* act, D2S_DIFFICULTY* difficulty) { | ||
182 | + if(isExpansion(c)) { | ||
183 | + *difficulty = c->charProgress / 5; | ||
184 | + *act = c->charProgress % 5; | ||
185 | + // Unfortunately, this won't distinguish between act IV and act V, because | ||
186 | + // the game does not increment the charProgress when you kill Diablo, so | ||
187 | + // the only way to know is check whether or not you started the act on the | ||
188 | + // quest data | ||
189 | + // NB: This doesn't happen in Classic | ||
190 | + if(*act == D2S_ACT4) { | ||
191 | + if(c->questData.quests[*difficulty].expansionAct.actStarted) { | ||
192 | + ++*act; | ||
193 | + } | ||
194 | + } | ||
195 | + } else { | ||
196 | + *difficulty = c->charProgress / 4; | ||
197 | + *act = c->charProgress % 4; | ||
198 | + } | ||
199 | +} | ||
200 | + | ||
201 | +int setProgress(D2CharHeader* c, D2S_ACT act, D2S_DIFFICULTY difficulty) { | ||
202 | + if(difficulty != D2S_DIFFICULTY_NORMAL || | ||
203 | + difficulty != D2S_DIFFICULTY_NIGHTMARE || | ||
204 | + difficulty != D2S_DIFFICULTY_HELL) { | ||
205 | + fprintf(stderr,"libd2char error: Invalid difficulty specified: %d\n", difficulty); | ||
206 | + return -1; | ||
207 | + } | ||
208 | + if(act != D2S_ACT1 || | ||
209 | + act != D2S_ACT2 || | ||
210 | + act != D2S_ACT3 || | ||
211 | + act != D2S_ACT4 || | ||
212 | + act != D2S_ACT5) { | ||
213 | + fprintf(stderr,"libd2char error: Invalid act specified: %d\n", act); | ||
214 | + return -1; | ||
215 | + } | ||
216 | + uint8_t progress = 0; | ||
217 | + if(isExpansion(c)) { | ||
218 | + progress += difficulty * 5; | ||
219 | + progress += act; | ||
220 | + if(act == D2S_ACT5) { | ||
221 | + // See comment above | ||
222 | + --progress; | ||
223 | + c->questData.quests[difficulty].expansionAct.actStarted = 1; | ||
224 | + } | ||
225 | + } else { | ||
226 | + progress = (difficulty * 4) + act; | ||
227 | + } | ||
228 | + c->charProgress = progress; | ||
166 | return 0; | 229 | return 0; |
167 | } | 230 | } |
168 | 231 | ||
169 | int getAttribute(D2S_STAT attr) { | 232 | int getAttribute(D2S_STAT attr) { |
170 | - // TODO | 233 | + // TODO implement |
171 | return 0; | 234 | return 0; |
172 | } | 235 | } |
173 | 236 | ||
174 | int setAttribute(D2S_STAT attr, unsigned int value) { | 237 | int setAttribute(D2S_STAT attr, unsigned int value) { |
175 | - // TODO | 238 | + // TODO implement |
176 | return 0; | 239 | return 0; |
177 | } | 240 | } |
178 | \ No newline at end of file | 241 | \ No newline at end of file |
d2char.h
@@ -45,6 +45,7 @@ typedef enum D2S_VERSION { | @@ -45,6 +45,7 @@ typedef enum D2S_VERSION { | ||
45 | } D2S_VERSION; | 45 | } D2S_VERSION; |
46 | 46 | ||
47 | typedef enum D2S_CHARCLASS { | 47 | typedef enum D2S_CHARCLASS { |
48 | + D2S_CHARCLASS_UNKNOWN = -1, | ||
48 | D2S_CHARCLASS_AMAZON = 0, | 49 | D2S_CHARCLASS_AMAZON = 0, |
49 | D2S_CHARCLASS_SORCERESS = 1, | 50 | D2S_CHARCLASS_SORCERESS = 1, |
50 | D2S_CHARCLASS_NECROMANCER = 2, | 51 | D2S_CHARCLASS_NECROMANCER = 2, |
@@ -74,6 +75,7 @@ typedef enum D2S_STAT { | @@ -74,6 +75,7 @@ typedef enum D2S_STAT { | ||
74 | } D2S_STAT; | 75 | } D2S_STAT; |
75 | 76 | ||
76 | typedef enum D2S_ACT { | 77 | typedef enum D2S_ACT { |
78 | + D2S_ACT_UNKNOWN = -1, | ||
77 | D2S_ACT1 = 0, | 79 | D2S_ACT1 = 0, |
78 | D2S_ACT2, | 80 | D2S_ACT2, |
79 | D2S_ACT3, | 81 | D2S_ACT3, |
@@ -132,16 +134,13 @@ typedef struct __attribute__((packed)){ | @@ -132,16 +134,13 @@ typedef struct __attribute__((packed)){ | ||
132 | uint32_t calcChecksum(D2CharHeader* c, void* charData); | 134 | uint32_t calcChecksum(D2CharHeader* c, void* charData); |
133 | int checkChecksum(D2CharHeader* c, void* charData); | 135 | int checkChecksum(D2CharHeader* c, void* charData); |
134 | int isHardcore(D2CharHeader* c); | 136 | int isHardcore(D2CharHeader* c); |
135 | -void setHardcore(D2CharHeader* c); | 137 | +void setHardcore(D2CharHeader* c, int bool); |
136 | int hasDied(D2CharHeader* c); | 138 | int hasDied(D2CharHeader* c); |
137 | -void setDied(D2CharHeader* c); | 139 | +void setDied(D2CharHeader* c, int bool); |
138 | int isExpansion(D2CharHeader* c); | 140 | int isExpansion(D2CharHeader* c); |
139 | -void setExpansion(D2CharHeader* c); | 141 | +void setExpansion(D2CharHeader* c, int bool); |
140 | int isLadder(D2CharHeader* c); | 142 | int isLadder(D2CharHeader* c); |
141 | -void setLadder(D2CharHeader* c); | ||
142 | - | ||
143 | -// 0 = Act I, 4 = Act V (Expansion) | ||
144 | -D2S_ACT getCurrentAct(D2CharHeader* c); | 143 | +void setLadder(D2CharHeader* c, int bool); |
145 | 144 | ||
146 | int isFemale(D2CharHeader* c); | 145 | int isFemale(D2CharHeader* c); |
147 | 146 | ||
@@ -151,10 +150,16 @@ const char* getCharacterTitle(D2CharHeader* c); | @@ -151,10 +150,16 @@ const char* getCharacterTitle(D2CharHeader* c); | ||
151 | // Writes to user-allocated string. Format is default locale's time representation | 150 | // Writes to user-allocated string. Format is default locale's time representation |
152 | size_t getLastPlayed(D2CharHeader* c, char* buf, size_t bufLen); | 151 | size_t getLastPlayed(D2CharHeader* c, char* buf, size_t bufLen); |
153 | 152 | ||
153 | +// This is the last difficulty played, not the highest available. For that, use getProgress() | ||
154 | // 0 = Normal, 2 = Hell | 154 | // 0 = Normal, 2 = Hell |
155 | D2S_DIFFICULTY getCurrentDifficulty(D2CharHeader* c); | 155 | D2S_DIFFICULTY getCurrentDifficulty(D2CharHeader* c); |
156 | 156 | ||
157 | -int setProgress(D2S_ACT act, D2S_DIFFICULTY difficulty); | 157 | +// This is the last act played, not the highest available. For that, use getProgress() |
158 | +// 0 = Act I, 4 = Act V (Expansion) | ||
159 | +D2S_ACT getCurrentAct(D2CharHeader* c); | ||
160 | + | ||
161 | +void getProgress(D2CharHeader* c, D2S_ACT* act, D2S_DIFFICULTY* difficulty); | ||
162 | +int setProgress(D2CharHeader* c, D2S_ACT act, D2S_DIFFICULTY difficulty); | ||
158 | 163 | ||
159 | int getAttribute(D2S_STAT attr); | 164 | int getAttribute(D2S_STAT attr); |
160 | int setAttribute(D2S_STAT attr, unsigned int value); | 165 | int setAttribute(D2S_STAT attr, unsigned int value); |
d2mercs.c
@@ -27,13 +27,224 @@ D2S_MERCTYPE getMercType(uint16_t mercID) { | @@ -27,13 +27,224 @@ D2S_MERCTYPE getMercType(uint16_t mercID) { | ||
27 | } | 27 | } |
28 | 28 | ||
29 | D2S_MERCSUBTYPE getMercSubType(uint16_t mercID) { | 29 | D2S_MERCSUBTYPE getMercSubType(uint16_t mercID) { |
30 | - // TODO | 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 | + } | ||
38 | + 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 | + } | ||
47 | + 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 | + } | ||
56 | + break; | ||
57 | + case D2S_MERCTYPE_BARBARIAN: | ||
58 | + case D2S_MERCTYPE_UNKNOWN: | ||
59 | + subtype = D2S_MERCSUBTYPE_NONE; | ||
60 | + break; | ||
61 | + } | ||
62 | + return subtype; | ||
31 | } | 63 | } |
32 | 64 | ||
33 | D2S_DIFFICULTY getMercDifficulty(uint16_t mercID) { | 65 | D2S_DIFFICULTY getMercDifficulty(uint16_t mercID) { |
34 | - // TODO | 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; | ||
81 | + } | ||
82 | + return D2S_DIFFICULTY_UNKNOWN; | ||
35 | } | 83 | } |
36 | 84 | ||
37 | -int setMerc(D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIFFICULTY difficulty) { | ||
38 | - // TODO | 85 | +int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIFFICULTY difficulty) { |
86 | + switch(type) { | ||
87 | + case D2S_MERCTYPE_ROGUE: | ||
88 | + switch(subtype) { | ||
89 | + case D2S_MERCSUBTYPE_FIRE_ARROW: | ||
90 | + switch(difficulty) { | ||
91 | + case D2S_DIFFICULTY_NORMAL: | ||
92 | + c->mercenaryType = 0; | ||
93 | + return 0; | ||
94 | + break; | ||
95 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
96 | + c->mercenaryType = 2; | ||
97 | + return 0; | ||
98 | + break; | ||
99 | + case D2S_DIFFICULTY_HELL: | ||
100 | + c->mercenaryType = 4; | ||
101 | + return 0; | ||
102 | + break; | ||
103 | + } | ||
104 | + break; | ||
105 | + case D2S_MERCSUBTYPE_COLD_ARROW: | ||
106 | + switch(difficulty) { | ||
107 | + case D2S_DIFFICULTY_NORMAL: | ||
108 | + c->mercenaryType = 1; | ||
109 | + return 0; | ||
110 | + break; | ||
111 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
112 | + c->mercenaryType = 3; | ||
113 | + return 0; | ||
114 | + break; | ||
115 | + case D2S_DIFFICULTY_HELL: | ||
116 | + c->mercenaryType = 5; | ||
117 | + return 0; | ||
118 | + break; | ||
119 | + } | ||
120 | + break; | ||
121 | + } | ||
122 | + break; | ||
123 | + case D2S_MERCTYPE_DESERT: | ||
124 | + switch(subtype) { | ||
125 | + case D2S_MERCSUBTYPE_COMBAT: | ||
126 | + switch(difficulty) { | ||
127 | + case D2S_DIFFICULTY_NORMAL: | ||
128 | + c->mercenaryType = 6; | ||
129 | + return 0; | ||
130 | + break; | ||
131 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
132 | + c->mercenaryType = 9; | ||
133 | + return 0; | ||
134 | + break; | ||
135 | + case D2S_DIFFICULTY_HELL: | ||
136 | + c->mercenaryType = 12; | ||
137 | + return 0; | ||
138 | + break; | ||
139 | + } | ||
140 | + break; | ||
141 | + case D2S_MERCSUBTYPE_DEFENSIVE: | ||
142 | + switch(difficulty) { | ||
143 | + case D2S_DIFFICULTY_NORMAL: | ||
144 | + c->mercenaryType = 7; | ||
145 | + return 0; | ||
146 | + break; | ||
147 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
148 | + c->mercenaryType = 10; | ||
149 | + return 0; | ||
150 | + break; | ||
151 | + case D2S_DIFFICULTY_HELL: | ||
152 | + c->mercenaryType = 13; | ||
153 | + return 0; | ||
154 | + break; | ||
155 | + } | ||
156 | + break; | ||
157 | + case D2S_MERCSUBTYPE_OFFENSIVE: | ||
158 | + switch(difficulty) { | ||
159 | + case D2S_DIFFICULTY_NORMAL: | ||
160 | + c->mercenaryType = 8; | ||
161 | + return 0; | ||
162 | + break; | ||
163 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
164 | + c->mercenaryType = 11; | ||
165 | + return 0; | ||
166 | + break; | ||
167 | + case D2S_DIFFICULTY_HELL: | ||
168 | + c->mercenaryType = 14; | ||
169 | + return 0; | ||
170 | + break; | ||
171 | + } | ||
172 | + break; | ||
173 | + } | ||
174 | + break; | ||
175 | + case D2S_MERCTYPE_SORCEROR: | ||
176 | + switch(subtype) { | ||
177 | + case D2S_MERCSUBTYPE_FIRE: | ||
178 | + switch(difficulty) { | ||
179 | + case D2S_DIFFICULTY_NORMAL: | ||
180 | + c->mercenaryType = 15; | ||
181 | + return 0; | ||
182 | + break; | ||
183 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
184 | + c->mercenaryType = 18; | ||
185 | + return 0; | ||
186 | + break; | ||
187 | + case D2S_DIFFICULTY_HELL: | ||
188 | + c->mercenaryType = 21; | ||
189 | + return 0; | ||
190 | + break; | ||
191 | + } | ||
192 | + break; | ||
193 | + case D2S_MERCSUBTYPE_COLD: | ||
194 | + switch(difficulty) { | ||
195 | + case D2S_DIFFICULTY_NORMAL: | ||
196 | + c->mercenaryType = 16; | ||
197 | + return 0; | ||
198 | + break; | ||
199 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
200 | + c->mercenaryType = 19; | ||
201 | + return 0; | ||
202 | + break; | ||
203 | + case D2S_DIFFICULTY_HELL: | ||
204 | + c->mercenaryType = 22; | ||
205 | + return 0; | ||
206 | + break; | ||
207 | + } | ||
208 | + break; | ||
209 | + case D2S_MERCSUBTYPE_LIGHTNING: | ||
210 | + switch(difficulty) { | ||
211 | + case D2S_DIFFICULTY_NORMAL: | ||
212 | + c->mercenaryType = 17; | ||
213 | + return 0; | ||
214 | + break; | ||
215 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
216 | + c->mercenaryType = 20; | ||
217 | + return 0; | ||
218 | + break; | ||
219 | + case D2S_DIFFICULTY_HELL: | ||
220 | + c->mercenaryType = 23; | ||
221 | + return 0; | ||
222 | + break; | ||
223 | + } | ||
224 | + break; | ||
225 | + } | ||
226 | + break; | ||
227 | + case D2S_MERCTYPE_BARBARIAN: | ||
228 | + // There's actually 2 identifiers for barbarians in each difficulty, they don't seem to have | ||
229 | + // noticeable effect in game, so I'm considering only one of them. If you want to specifcially | ||
230 | + // change to the other type, you probably know already what the mercID is so change it directly | ||
231 | + // in the header instead of using this function | ||
232 | + switch(difficulty) { | ||
233 | + case D2S_DIFFICULTY_NORMAL: | ||
234 | + c->mercenaryType = 24; | ||
235 | + return 0; | ||
236 | + break; | ||
237 | + case D2S_DIFFICULTY_NIGHTMARE: | ||
238 | + c->mercenaryType = 26; | ||
239 | + return 0; | ||
240 | + break; | ||
241 | + case D2S_DIFFICULTY_HELL: | ||
242 | + c->mercenaryType = 28; | ||
243 | + return 0; | ||
244 | + break; | ||
245 | + } | ||
246 | + break; | ||
247 | + } | ||
248 | + fprintf(stderr,"libd2char error: invalid combination of parameters for setMerc()\n"); | ||
249 | + return -1; | ||
39 | } | 250 | } |
40 | \ No newline at end of file | 251 | \ No newline at end of file |
d2mercs.h
@@ -186,6 +186,6 @@ const char* getMercName(uint16_t mercID, uint16_t mercNameID); | @@ -186,6 +186,6 @@ const char* getMercName(uint16_t mercID, uint16_t mercNameID); | ||
186 | D2S_MERCTYPE getMercType(uint16_t mercID); | 186 | D2S_MERCTYPE getMercType(uint16_t mercID); |
187 | D2S_MERCSUBTYPE getMercSubType(uint16_t mercID); | 187 | D2S_MERCSUBTYPE getMercSubType(uint16_t mercID); |
188 | D2S_DIFFICULTY getMercDifficulty(uint16_t mercID); | 188 | D2S_DIFFICULTY getMercDifficulty(uint16_t mercID); |
189 | -int setMerc(D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIFFICULTY difficulty); | 189 | +int setMerc(D2CharHeader* c, D2S_MERCTYPE type, D2S_MERCSUBTYPE subtype, D2S_DIFFICULTY difficulty); |
190 | 190 | ||
191 | #endif | 191 | #endif |
192 | \ No newline at end of file | 192 | \ No newline at end of file |
d2quest.c
@@ -17,10 +17,16 @@ int getCheckpointDescriptions(D2S_QUEST quest, const char* *descriptions[16]) { | @@ -17,10 +17,16 @@ int getCheckpointDescriptions(D2S_QUEST quest, const char* *descriptions[16]) { | ||
17 | return -1; | 17 | return -1; |
18 | } | 18 | } |
19 | memcpy(descriptions,(&checkpointDescriptions) + (quest * 16 * sizeof(const char*)), 16 * sizeof(const char*)); | 19 | memcpy(descriptions,(&checkpointDescriptions) + (quest * 16 * sizeof(const char*)), 16 * sizeof(const char*)); |
20 | + return 0; | ||
20 | } | 21 | } |
21 | 22 | ||
22 | int getQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t* data) { | 23 | int getQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t* data) { |
23 | - // TODO sanity check diff and quest | 24 | + if(difficulty != D2S_DIFFICULTY_NORMAL || |
25 | + difficulty != D2S_DIFFICULTY_NIGHTMARE || | ||
26 | + difficulty != D2S_DIFFICULTY_HELL) { | ||
27 | + fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty); | ||
28 | + return -1; | ||
29 | + } | ||
24 | if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) { | 30 | if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) { |
25 | *data = d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest]; | 31 | *data = d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest]; |
26 | } else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) { | 32 | } else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) { |
@@ -39,7 +45,12 @@ int getQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, u | @@ -39,7 +45,12 @@ int getQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, u | ||
39 | } | 45 | } |
40 | 46 | ||
41 | int setQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t questData) { | 47 | int setQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t questData) { |
42 | - // TODO sanity check diff and quest | 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); | ||
52 | + return -1; | ||
53 | + } | ||
43 | if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) { | 54 | if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) { |
44 | d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest] = questData; | 55 | d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest] = questData; |
45 | } else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) { | 56 | } else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) { |
@@ -133,22 +144,34 @@ int setQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty | @@ -133,22 +144,34 @@ int setQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty | ||
133 | return setQuestStatus(d,quest,difficulty,questData); | 144 | return setQuestStatus(d,quest,difficulty,questData); |
134 | } | 145 | } |
135 | 146 | ||
136 | -int getSpecialQuestStatus(D2QuestData* d, unsigned int specialQuestState, D2S_DIFFICULTY difficulty) { | 147 | +int getSpecialQuestStatus(D2QuestData* d, D2S_SPECIALQUEST specialQuestState, D2S_DIFFICULTY difficulty) { |
148 | + if(difficulty != D2S_DIFFICULTY_NORMAL || | ||
149 | + difficulty != D2S_DIFFICULTY_NIGHTMARE || | ||
150 | + difficulty != D2S_DIFFICULTY_HELL) { | ||
151 | + fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty); | ||
152 | + return -1; | ||
153 | + } | ||
137 | int ret = 0; | 154 | int ret = 0; |
138 | switch(specialQuestState) { | 155 | switch(specialQuestState) { |
139 | case D2S_SPECIALQUEST_AKARA_RESPEC: | 156 | case D2S_SPECIALQUEST_AKARA_RESPEC: |
140 | ret = d->quests[difficulty].akaraRespecData & D2S_QUEST_STATUS_REWARD_AVAILABLE; | 157 | ret = d->quests[difficulty].akaraRespecData & D2S_QUEST_STATUS_REWARD_AVAILABLE; |
141 | break; | 158 | break; |
159 | + default: | ||
160 | + fprintf(stderr,"libd2char error: invalid special quest %d\n",specialQuestState); | ||
161 | + ret = -1; | ||
162 | + break; | ||
142 | } | 163 | } |
143 | return ret; | 164 | return ret; |
144 | } | 165 | } |
145 | 166 | ||
146 | -int setSpecialQuestStatus(D2QuestData* d, unsigned int specialQuestState, D2S_DIFFICULTY difficulty, int bool) { | 167 | +int setSpecialQuestStatus(D2QuestData* d, D2S_SPECIALQUEST specialQuestState, D2S_DIFFICULTY difficulty, int bool) { |
147 | if(difficulty != D2S_DIFFICULTY_NORMAL || | 168 | if(difficulty != D2S_DIFFICULTY_NORMAL || |
148 | difficulty != D2S_DIFFICULTY_NIGHTMARE || | 169 | difficulty != D2S_DIFFICULTY_NIGHTMARE || |
149 | difficulty != D2S_DIFFICULTY_HELL) { | 170 | difficulty != D2S_DIFFICULTY_HELL) { |
150 | fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty); | 171 | fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty); |
172 | + return -1; | ||
151 | } | 173 | } |
174 | + int ret = 0; | ||
152 | switch(specialQuestState) { | 175 | switch(specialQuestState) { |
153 | case D2S_SPECIALQUEST_AKARA_RESPEC: | 176 | case D2S_SPECIALQUEST_AKARA_RESPEC: |
154 | // This operation only makes sense if the quest is actually completed, otherwise ignore request | 177 | // This operation only makes sense if the quest is actually completed, otherwise ignore request |
@@ -160,5 +183,10 @@ int setSpecialQuestStatus(D2QuestData* d, unsigned int specialQuestState, D2S_DI | @@ -160,5 +183,10 @@ int setSpecialQuestStatus(D2QuestData* d, unsigned int specialQuestState, D2S_DI | ||
160 | } | 183 | } |
161 | } | 184 | } |
162 | break; | 185 | break; |
186 | + default: | ||
187 | + fprintf(stderr,"libd2char error: invalid special quest %d\n",specialQuestState); | ||
188 | + ret = -1; | ||
189 | + break; | ||
163 | } | 190 | } |
191 | + return ret; | ||
164 | } | 192 | } |
165 | \ No newline at end of file | 193 | \ No newline at end of file |
d2skills.c
1 | -#include "d2char.h" | ||
2 | #include "d2skills.h" | 1 | #include "d2skills.h" |
3 | 2 | ||
4 | #include <stdio.h> | 3 | #include <stdio.h> |
5 | #include <stdlib.h> | 4 | #include <stdlib.h> |
6 | 5 | ||
7 | -D2S_CHARCLASS getSkillClass(D2S_SKILL skillID) { | ||
8 | - // TODO | ||
9 | -} | ||
10 | - | ||
11 | const char* getSkillName(D2S_SKILL skillID) { | 6 | const char* getSkillName(D2S_SKILL skillID) { |
12 | - if(skillID > D2S_SKILL_NUMSKILLS) { | 7 | + if(skillID > D2S_SKILL_NUMSKILLS || skillID < 0) { |
13 | fprintf(stderr,"libd2char error: skillID %d doesn't exist\n",skillID); | 8 | fprintf(stderr,"libd2char error: skillID %d doesn't exist\n",skillID); |
14 | return NULL; | 9 | return NULL; |
15 | } | 10 | } |
16 | - return skills[skillID]; | 11 | + return skillNames[skillID]; |
12 | +} | ||
13 | + | ||
14 | +D2S_SKILL getSkillIDFromCharOffset(D2S_CHARCLASS class, unsigned int offset) { | ||
15 | + if(offset < 0 || offset > D2S_SKILL_MAXSKILLS_PER_CHAR) { | ||
16 | + fprintf(stderr,"libd2char error: Invalid character skill offset: %d\n",offset); | ||
17 | + return D2S_SKILL_UNKNOWN; | ||
18 | + } | ||
19 | + switch(class) { | ||
20 | + case D2S_CHARCLASS_AMAZON: | ||
21 | + return amazonSkills[offset]; | ||
22 | + break; | ||
23 | + case D2S_CHARCLASS_SORCERESS: | ||
24 | + return sorceressSkills[offset]; | ||
25 | + break; | ||
26 | + case D2S_CHARCLASS_NECROMANCER: | ||
27 | + return necromancerSkills[offset]; | ||
28 | + break; | ||
29 | + case D2S_CHARCLASS_PALADIN: | ||
30 | + return paladinSkills[offset]; | ||
31 | + break; | ||
32 | + case D2S_CHARCLASS_BARBARIAN: | ||
33 | + return barbarianSkills[offset]; | ||
34 | + break; | ||
35 | + case D2S_CHARCLASS_DRUID: | ||
36 | + return druidSkills[offset]; | ||
37 | + break; | ||
38 | + case D2S_CHARCLASS_ASSASSIN: | ||
39 | + return assassinSkills[offset]; | ||
40 | + break; | ||
41 | + case D2S_CHARCLASS_UNKNOWN: | ||
42 | + default: | ||
43 | + return D2S_SKILL_UNKNOWN; | ||
44 | + break; | ||
45 | + } | ||
17 | } | 46 | } |
18 | \ No newline at end of file | 47 | \ No newline at end of file |
d2skills.h
@@ -3,14 +3,605 @@ | @@ -3,14 +3,605 @@ | ||
3 | 3 | ||
4 | #include <stdint.h> | 4 | #include <stdint.h> |
5 | 5 | ||
6 | +#include "d2char.h" | ||
6 | #include "d2strings.h" | 7 | #include "d2strings.h" |
7 | 8 | ||
8 | #define D2S_SKILL_NUMSKILLS 357 | 9 | #define D2S_SKILL_NUMSKILLS 357 |
10 | +#define D2S_SKILL_MAXSKILLS_PER_CHAR 30 | ||
9 | 11 | ||
10 | -// TODO skill class trees | ||
11 | -typedef int D2S_SKILL; | 12 | +typedef enum D2S_SKILL { |
13 | + D2S_SKILL_UNKNOWN = -1, | ||
14 | + D2S_SKILL_ATTACK = 0, | ||
15 | + D2S_SKILL_KICK, | ||
16 | + D2S_SKILL_THROW_ITEM, | ||
17 | + D2S_SKILL_UNSUMMON, | ||
18 | + D2S_SKILL_LEFT_HAND_THROW, | ||
19 | + D2S_SKILL_LEFT_HAND_SWING, | ||
20 | + D2S_SKILL_MAGIC_ARROW, | ||
21 | + D2S_SKILL_FIRE_ARROW, | ||
22 | + D2S_SKILL_INNER_SIGHT, | ||
23 | + D2S_SKILL_CRITICAL_STRIKE, | ||
24 | + D2S_SKILL_JAB, | ||
25 | + D2S_SKILL_COLD_ARROW, | ||
26 | + D2S_SKILL_MULTIPLE_SHOT, | ||
27 | + D2S_SKILL_DODGE, | ||
28 | + D2S_SKILL_POWER_STRIKE, | ||
29 | + D2S_SKILL_POISON_JAVELIN, | ||
30 | + D2S_SKILL_EXPLODING_ARROW, | ||
31 | + D2S_SKILL_SLOW_MISSILES, | ||
32 | + D2S_SKILL_AVOID, | ||
33 | + D2S_SKILL_IMPALE, | ||
34 | + D2S_SKILL_LIGHTNING_BOLT, | ||
35 | + D2S_SKILL_ICE_ARROW, | ||
36 | + D2S_SKILL_GUIDED_ARROW, | ||
37 | + D2S_SKILL_PENETRATE, | ||
38 | + D2S_SKILL_CHARGED_STRIKE, | ||
39 | + D2S_SKILL_PLAGUE_JAVELIN, | ||
40 | + D2S_SKILL_STRAFE, | ||
41 | + D2S_SKILL_IMMOLATION_ARROW, | ||
42 | + D2S_SKILL_DOPPLEZON, | ||
43 | + D2S_SKILL_EVADE, | ||
44 | + D2S_SKILL_FEND, | ||
45 | + D2S_SKILL_FREEZING_ARROW, | ||
46 | + D2S_SKILL_VALKYRIE, | ||
47 | + D2S_SKILL_PIERCE, | ||
48 | + D2S_SKILL_LIGHTNING_STRIKE, | ||
49 | + D2S_SKILL_LIGHTNING_FURY, | ||
50 | + D2S_SKILL_FIRE_BOLT, | ||
51 | + D2S_SKILL_WARMTH, | ||
52 | + D2S_SKILL_CHARGED_BOLT, | ||
53 | + D2S_SKILL_ICE_BOLT, | ||
54 | + D2S_SKILL_FROZEN_ARMOR, | ||
55 | + D2S_SKILL_INFERNO, | ||
56 | + D2S_SKILL_STATIC_FIELD, | ||
57 | + D2S_SKILL_TELEKINESIS, | ||
58 | + D2S_SKILL_FROST_NOVA, | ||
59 | + D2S_SKILL_ICE_BLAST, | ||
60 | + D2S_SKILL_BLAZE, | ||
61 | + D2S_SKILL_FIRE_BALL, | ||
62 | + D2S_SKILL_NOVA, | ||
63 | + D2S_SKILL_LIGHTNING, | ||
64 | + D2S_SKILL_SHIVER_ARMOR, | ||
65 | + D2S_SKILL_FIRE_WALL, | ||
66 | + D2S_SKILL_ENCHANT, | ||
67 | + D2S_SKILL_CHAIN_LIGHTNING, | ||
68 | + D2S_SKILL_TELEPORT, | ||
69 | + D2S_SKILL_GLACIAL_SPIKE, | ||
70 | + D2S_SKILL_METEOR, | ||
71 | + D2S_SKILL_THUNDER_STORM, | ||
72 | + D2S_SKILL_ENERGY_SHIELD, | ||
73 | + D2S_SKILL_BLIZZARD, | ||
74 | + D2S_SKILL_CHILLING_ARMOR, | ||
75 | + D2S_SKILL_FIRE_MASTERY, | ||
76 | + D2S_SKILL_HYDRA, | ||
77 | + D2S_SKILL_LIGHTNING_MASTERY, | ||
78 | + D2S_SKILL_FROZEN_ORB, | ||
79 | + D2S_SKILL_COLD_MASTERY, | ||
80 | + D2S_SKILL_AMPLIFY_DAMAGE, | ||
81 | + D2S_SKILL_TEETH, | ||
82 | + D2S_SKILL_BONE_ARMOR, | ||
83 | + D2S_SKILL_SKELETON_MASTERY, | ||
84 | + D2S_SKILL_RAISE_SKELETON, | ||
85 | + D2S_SKILL_DIM_VISION, | ||
86 | + D2S_SKILL_WEAKEN, | ||
87 | + D2S_SKILL_POISON_DAGGER, | ||
88 | + D2S_SKILL_CORPSE_EXPLOSION, | ||
89 | + D2S_SKILL_CLAY_GOLEM, | ||
90 | + D2S_SKILL_IRON_MAIDEN, | ||
91 | + D2S_SKILL_TERROR, | ||
92 | + D2S_SKILL_BONE_WALL, | ||
93 | + D2S_SKILL_GOLEM_MASTERY, | ||
94 | + D2S_SKILL_RAISE_SKELETAL_MAGE, | ||
95 | + D2S_SKILL_CONFUSE, | ||
96 | + D2S_SKILL_LIFE_TAP, | ||
97 | + D2S_SKILL_POISON_EXPLOSION, | ||
98 | + D2S_SKILL_BONE_SPEAR, | ||
99 | + D2S_SKILL_BLOOD_GOLEM, | ||
100 | + D2S_SKILL_ATTRACT, | ||
101 | + D2S_SKILL_DECREPIFY, | ||
102 | + D2S_SKILL_BONE_PRISON, | ||
103 | + D2S_SKILL_SUMMON_RESIST, | ||
104 | + D2S_SKILL_IRON_GOLEM, | ||
105 | + D2S_SKILL_LOWER_RESIST, | ||
106 | + D2S_SKILL_POISON_NOVA, | ||
107 | + D2S_SKILL_BONE_SPIRIT, | ||
108 | + D2S_SKILL_FIRE_GOLEM, | ||
109 | + D2S_SKILL_REVIVE, | ||
110 | + D2S_SKILL_SACRIFICE, | ||
111 | + D2S_SKILL_SMITE, | ||
112 | + D2S_SKILL_MIGHT, | ||
113 | + D2S_SKILL_PRAYER, | ||
114 | + D2S_SKILL_RESIST_FIRE, | ||
115 | + D2S_SKILL_HOLY_BOLT, | ||
116 | + D2S_SKILL_HOLY_FIRE, | ||
117 | + D2S_SKILL_THORNS, | ||
118 | + D2S_SKILL_DEFIANCE, | ||
119 | + D2S_SKILL_RESIST_COLD, | ||
120 | + D2S_SKILL_ZEAL, | ||
121 | + D2S_SKILL_CHARGE, | ||
122 | + D2S_SKILL_BLESSED_AIM, | ||
123 | + D2S_SKILL_CLEANSING, | ||
124 | + D2S_SKILL_RESIST_LIGHTNING, | ||
125 | + D2S_SKILL_VENGEANCE, | ||
126 | + D2S_SKILL_BLESSED_HAMMER, | ||
127 | + D2S_SKILL_CONCENTRATION, | ||
128 | + D2S_SKILL_HOLY_FREEZE, | ||
129 | + D2S_SKILL_VIGOR, | ||
130 | + D2S_SKILL_CONVERSION, | ||
131 | + D2S_SKILL_HOLY_SHIELD, | ||
132 | + D2S_SKILL_HOLY_SHOCK, | ||
133 | + D2S_SKILL_SANCTUARY, | ||
134 | + D2S_SKILL_MEDITATION, | ||
135 | + D2S_SKILL_FIST_OF_THE_HEAVENS, | ||
136 | + D2S_SKILL_FANATICISM, | ||
137 | + D2S_SKILL_CONVICTION, | ||
138 | + D2S_SKILL_REDEMPTION, | ||
139 | + D2S_SKILL_SALVATION, | ||
140 | + D2S_SKILL_BASH, | ||
141 | + D2S_SKILL_SWORD_MASTERY, | ||
142 | + D2S_SKILL_AXE_MASTERY, | ||
143 | + D2S_SKILL_MACE_MASTERY, | ||
144 | + D2S_SKILL_HOWL, | ||
145 | + D2S_SKILL_FIND_POTION, | ||
146 | + D2S_SKILL_LEAP, | ||
147 | + D2S_SKILL_DOUBLE_SWING, | ||
148 | + D2S_SKILL_POLE_ARM_MASTERY, | ||
149 | + D2S_SKILL_THROWING_MASTERY, | ||
150 | + D2S_SKILL_SPEAR_MASTERY, | ||
151 | + D2S_SKILL_TAUNT, | ||
152 | + D2S_SKILL_SHOUT, | ||
153 | + D2S_SKILL_STUN, | ||
154 | + D2S_SKILL_DOUBLE_THROW, | ||
155 | + D2S_SKILL_INCREASED_STAMINA, | ||
156 | + D2S_SKILL_FIND_ITEM, | ||
157 | + D2S_SKILL_LEAP_ATTACK, | ||
158 | + D2S_SKILL_CONCENTRATE, | ||
159 | + D2S_SKILL_IRON_SKIN, | ||
160 | + D2S_SKILL_BATTLE_CRY, | ||
161 | + D2S_SKILL_FRENZY, | ||
162 | + D2S_SKILL_INCREASED_SPEED, | ||
163 | + D2S_SKILL_BATTLE_ORDERS, | ||
164 | + D2S_SKILL_GRIM_WARD, | ||
165 | + D2S_SKILL_WHIRLWIND, | ||
166 | + D2S_SKILL_BERSERK, | ||
167 | + D2S_SKILL_NATURAL_RESISTANCE, | ||
168 | + D2S_SKILL_WAR_CRY, | ||
169 | + D2S_SKILL_BATTLE_COMMAND, | ||
170 | + D2S_SKILL_FIRE_HIT, | ||
171 | + D2S_SKILL_UNHOLY_BOLT, | ||
172 | + D2S_SKILL_SKELETON_RAISE, | ||
173 | + D2S_SKILL_MAGGOT_EGG, | ||
174 | + D2S_SKILL_SHAMAN_FIRE, | ||
175 | + D2S_SKILL_MAGOTTUP, | ||
176 | + D2S_SKILL_MAGOTTDOWN, | ||
177 | + D2S_SKILL_MAGOTTLAY, | ||
178 | + D2S_SKILL_ANDRIAL_SPRAY, | ||
179 | + D2S_SKILL_JUMP, | ||
180 | + D2S_SKILL_SWARM_MOVE, | ||
181 | + D2S_SKILL_NEST, | ||
182 | + D2S_SKILL_QUICK_STRIKE, | ||
183 | + D2S_SKILL_VAMPIRE_FIREBALL, | ||
184 | + D2S_SKILL_VAMPIRE_FIREWALL, | ||
185 | + D2S_SKILL_VAMPIRE_METEOR, | ||
186 | + D2S_SKILL_GARGOYLE_TRAP, | ||
187 | + D2S_SKILL_SPIDER_LAY, | ||
188 | + D2S_SKILL_VAMPIRE_HEAL, | ||
189 | + D2S_SKILL_VAMPIRE_RAISE, | ||
190 | + D2S_SKILL_SUBMERGE, | ||
191 | + D2S_SKILL_FETISH_AURA, | ||
192 | + D2S_SKILL_FETISH_INFERNO, | ||
193 | + D2S_SKILL_ZAKARUM_HEAL, | ||
194 | + D2S_SKILL_EMERGE, | ||
195 | + D2S_SKILL_RESURRECT, | ||
196 | + D2S_SKILL_BESTOW, | ||
197 | + D2S_SKILL_MISSILE_SKILL1, | ||
198 | + D2S_SKILL_MON_TELEPORT, | ||
199 | + D2S_SKILL_PRIME_LIGHTNING, | ||
200 | + D2S_SKILL_PRIME_BOLT, | ||
201 | + D2S_SKILL_PRIME_BLAZE, | ||
202 | + D2S_SKILL_PRIME_FIREWALL, | ||
203 | + D2S_SKILL_PRIME_SPIKE, | ||
204 | + D2S_SKILL_PRIME_ICE_NOVA, | ||
205 | + D2S_SKILL_PRIME_POISON_BALL, | ||
206 | + D2S_SKILL_PRIME_POISON_NOVA, | ||
207 | + D2S_SKILL_DIABLIGHT, | ||
208 | + D2S_SKILL_DIABCOLD, | ||
209 | + D2S_SKILL_DIABFIRE, | ||
210 | + D2S_SKILL_FINGERMAGESPIDER, | ||
211 | + D2S_SKILL_DIABWALL, | ||
212 | + D2S_SKILL_DIABRUN, | ||
213 | + D2S_SKILL_DIABPRISON, | ||
214 | + D2S_SKILL_POISON_BALL_TRAP, | ||
215 | + D2S_SKILL_ANDY_POISON_BOLT, | ||
216 | + D2S_SKILL_HIREABLE_MISSILE, | ||
217 | + D2S_SKILL_DESERT_TURRET, | ||
218 | + D2S_SKILL_ARCANE_TOWER, | ||
219 | + D2S_SKILL_MONBLIZZARD, | ||
220 | + D2S_SKILL_MOSQUITO, | ||
221 | + D2S_SKILL_CURSED_BALL_TRAP_RIGHT, | ||
222 | + D2S_SKILL_CURSED_BALL_TRAP_LEFT, | ||
223 | + D2S_SKILL_MONFROZENARMOR, | ||
224 | + D2S_SKILL_MONBONEARMOR, | ||
225 | + D2S_SKILL_MONBONESPIRIT, | ||
226 | + D2S_SKILL_MONCURSECAST, | ||
227 | + D2S_SKILL_HELLMETEOR, | ||
228 | + D2S_SKILL_REGURGITATOREAT, | ||
229 | + D2S_SKILL_MONFRENZY, | ||
230 | + D2S_SKILL_QUEENDEATH, | ||
231 | + D2S_SKILL_SCROLL_OF_IDENTIFY, | ||
232 | + D2S_SKILL_BOOK_OF_IDENTIFY, | ||
233 | + D2S_SKILL_SCROLL_OF_TOWNPORTAL, | ||
234 | + D2S_SKILL_BOOK_OF_TOWNPORTAL, | ||
235 | + D2S_SKILL_RAVEN, | ||
236 | + D2S_SKILL_POISON_CREEPER, | ||
237 | + D2S_SKILL_WEARWOLF, | ||
238 | + D2S_SKILL_SHAPE_SHIFTING, | ||
239 | + D2S_SKILL_FIRESTORM, | ||
240 | + D2S_SKILL_OAK_SAGE, | ||
241 | + D2S_SKILL_SUMMON_SPIRIT_WOLF, | ||
242 | + D2S_SKILL_WEARBEAR, | ||
243 | + D2S_SKILL_MOLTEN_BOULDER, | ||
244 | + D2S_SKILL_ARCTIC_BLAST, | ||
245 | + D2S_SKILL_CYCLE_OF_LIFE, | ||
246 | + D2S_SKILL_FERAL_RAGE, | ||
247 | + D2S_SKILL_MAUL, | ||
248 | + D2S_SKILL_ERUPTION, | ||
249 | + D2S_SKILL_CYCLONE_ARMOR, | ||
250 | + D2S_SKILL_HEART_OF_WOLVERINE, | ||
251 | + D2S_SKILL_SUMMON_FENRIS, | ||
252 | + D2S_SKILL_RABIES, | ||
253 | + D2S_SKILL_FIRE_CLAWS, | ||
254 | + D2S_SKILL_TWISTER, | ||
255 | + D2S_SKILL_VINES, | ||
256 | + D2S_SKILL_HUNGER, | ||
257 | + D2S_SKILL_SHOCK_WAVE, | ||
258 | + D2S_SKILL_VOLCANO, | ||
259 | + D2S_SKILL_TORNADO, | ||
260 | + D2S_SKILL_SPIRIT_OF_BARBS, | ||
261 | + D2S_SKILL_SUMMON_GRIZZLY, | ||
262 | + D2S_SKILL_FURY, | ||
263 | + D2S_SKILL_ARMAGEDDON, | ||
264 | + D2S_SKILL_HURRICANE, | ||
265 | + D2S_SKILL_FIRE_BLAST, | ||
266 | + D2S_SKILL_CLAW_MASTERY, | ||
267 | + D2S_SKILL_PSYCHIC_HAMMER, | ||
268 | + D2S_SKILL_TIGER_STRIKE, | ||
269 | + D2S_SKILL_DRAGON_TALON, | ||
270 | + D2S_SKILL_SHOCK_FIELD, | ||
271 | + D2S_SKILL_BLADE_SENTINEL, | ||
272 | + D2S_SKILL_QUICKNESS, | ||
273 | + D2S_SKILL_FISTS_OF_FIRE, | ||
274 | + D2S_SKILL_DRAGON_CLAW, | ||
275 | + D2S_SKILL_CHARGED_BOLT_SENTRY, | ||
276 | + D2S_SKILL_WAKE_OF_FIRE_SENTRY, | ||
277 | + D2S_SKILL_WEAPON_BLOCK, | ||
278 | + D2S_SKILL_CLOAK_OF_SHADOWS, | ||
279 | + D2S_SKILL_COBRA_STRIKE, | ||
280 | + D2S_SKILL_BLADE_FURY, | ||
281 | + D2S_SKILL_FADE, | ||
282 | + D2S_SKILL_SHADOW_WARRIOR, | ||
283 | + D2S_SKILL_CLAWS_OF_THUNDER, | ||
284 | + D2S_SKILL_DRAGON_TAIL, | ||
285 | + D2S_SKILL_LIGHTNING_SENTRY, | ||
286 | + D2S_SKILL_INFERNO_SENTRY, | ||
287 | + D2S_SKILL_MIND_BLAST, | ||
288 | + D2S_SKILL_BLADES_OF_ICE, | ||
289 | + D2S_SKILL_DRAGON_FLIGHT, | ||
290 | + D2S_SKILL_DEATH_SENTRY, | ||
291 | + D2S_SKILL_BLADE_SHIELD, | ||
292 | + D2S_SKILL_VENOM, | ||
293 | + D2S_SKILL_SHADOW_MASTER, | ||
294 | + D2S_SKILL_ROYAL_STRIKE, | ||
295 | + D2S_SKILL_WAKE_OF_DESTRUCTION_SENTRY, | ||
296 | + D2S_SKILL_IMP_INFERNO, | ||
297 | + D2S_SKILL_IMP_FIREBALL, | ||
298 | + D2S_SKILL_BAAL_TAUNT, | ||
299 | + D2S_SKILL_BAAL_CORPSE_EXPLODE, | ||
300 | + D2S_SKILL_BAAL_MONSTER_SPAWN, | ||
301 | + D2S_SKILL_CATAPULT_CHARGED_BALL, | ||
302 | + D2S_SKILL_CATAPULT_SPIKE_BALL, | ||
303 | + D2S_SKILL_SUCK_BLOOD, | ||
304 | + D2S_SKILL_CRY_HELP, | ||
305 | + D2S_SKILL_HEALING_VORTEX, | ||
306 | + D2S_SKILL_TELEPORT_2, | ||
307 | + D2S_SKILL_SELF_RESURRECT, | ||
308 | + D2S_SKILL_VINE_ATTACK, | ||
309 | + D2S_SKILL_OVERSEER_WHIP, | ||
310 | + D2S_SKILL_BARBS_AURA, | ||
311 | + D2S_SKILL_WOLVERINE_AURA, | ||
312 | + D2S_SKILL_OAK_SAGE_AURA, | ||
313 | + D2S_SKILL_IMP_FIRE_MISSILE, | ||
314 | + D2S_SKILL_IMPREGNATE, | ||
315 | + D2S_SKILL_SIEGE_BEAST_STOMP, | ||
316 | + D2S_SKILL_MINIONSPAWNER, | ||
317 | + D2S_SKILL_CATAPULTBLIZZARD, | ||
318 | + D2S_SKILL_CATAPULTPLAGUE, | ||
319 | + D2S_SKILL_CATAPULTMETEOR, | ||
320 | + D2S_SKILL_BOLTSENTRY, | ||
321 | + D2S_SKILL_CORPSECYCLER, | ||
322 | + D2S_SKILL_DEATHMAUL, | ||
323 | + D2S_SKILL_DEFENSE_CURSE, | ||
324 | + D2S_SKILL_BLOOD_MANA, | ||
325 | + D2S_SKILL_MON_INFERNO_SENTRY, | ||
326 | + D2S_SKILL_MON_DEATH_SENTRY, | ||
327 | + D2S_SKILL_SENTRY_LIGHTNING, | ||
328 | + D2S_SKILL_FENRIS_RAGE, | ||
329 | + D2S_SKILL_BAAL_TENTACLE, | ||
330 | + D2S_SKILL_BAAL_NOVA, | ||
331 | + D2S_SKILL_BAAL_INFERNO, | ||
332 | + D2S_SKILL_BAAL_COLD_MISSILES, | ||
333 | + D2S_SKILL_MEGA_DEMON_INFERNO, | ||
334 | + D2S_SKILL_EVIL_HUT_SPAWNER, | ||
335 | + D2S_SKILL_COUNTESS_FIREWALL, | ||
336 | + D2S_SKILL_IMPBOLT, | ||
337 | + D2S_SKILL_HORROR_ARCTIC_BLAST, | ||
338 | + D2S_SKILL_DEATH_SENTRY_LTNG, | ||
339 | + D2S_SKILL_VINECYCLER, | ||
340 | + D2S_SKILL_BEARSMITE, | ||
341 | + D2S_SKILL_RESURRECT2, | ||
342 | + D2S_SKILL_BLOODLORD_FRENZY, | ||
343 | + D2S_SKILL_BAAL_TELEPORT, | ||
344 | + D2S_SKILL_IMP_TELEPORT, | ||
345 | + D2S_SKILL_BAAL_CLONE_TELEPORT, | ||
346 | + D2S_SKILL_ZAKARUM_LIGHTNING, | ||
347 | + D2S_SKILL_VAMPIRE_MISSILE, | ||
348 | + D2S_SKILL_MEPHISTO_MISSILE, | ||
349 | + D2S_SKILL_DOOM_KNIGHT_MISSILE, | ||
350 | + D2S_SKILL_ROGUE_MISSILE, | ||
351 | + D2S_SKILL_HYDRA_MISSILE, | ||
352 | + D2S_SKILL_NECRO_MAGE_MISSILE, | ||
353 | + D2S_SKILL_MONBOW, | ||
354 | + D2S_SKILL_MONFIREARROW, | ||
355 | + D2S_SKILL_MONCOLDARROW, | ||
356 | + D2S_SKILL_MONEXPLODINGARROW, | ||
357 | + D2S_SKILL_MONFREEZINGARROW, | ||
358 | + D2S_SKILL_MONPOWERSTRIKE, | ||
359 | + D2S_SKILL_SUCCUBUSBOLT, | ||
360 | + D2S_SKILL_MEPHFROSTNOVA, | ||
361 | + D2S_SKILL_MONICESPEAR, | ||
362 | + D2S_SKILL_SHAMAN_ICE, | ||
363 | + D2S_SKILL_DIABLOGEDDON, | ||
364 | + D2S_SKILL_DELERIUM_CHANGE, | ||
365 | + D2S_SKILL_NIHLATHAK_CORPSE_EXPLOSION, | ||
366 | + D2S_SKILL_SERPENT_CHARGE, | ||
367 | + D2S_SKILL_TRAP_NOVA, | ||
368 | + D2S_SKILL_UNHOLY_BOLTEX, | ||
369 | + D2S_SKILL_SHAMAN_FIREEX, | ||
370 | + D2S_SKILL_IMP_FIRE_MISSILE_EX, | ||
371 | +} D2S_SKILL; | ||
12 | 372 | ||
13 | -const char* const skills[] = { | 373 | +const D2S_SKILL amazonSkills[D2S_SKILL_MAXSKILLS_PER_CHAR] = { |
374 | + D2S_SKILL_MAGIC_ARROW, | ||
375 | + D2S_SKILL_FIRE_ARROW, | ||
376 | + D2S_SKILL_INNER_SIGHT, | ||
377 | + D2S_SKILL_CRITICAL_STRIKE, | ||
378 | + D2S_SKILL_JAB, | ||
379 | + D2S_SKILL_COLD_ARROW, | ||
380 | + D2S_SKILL_MULTIPLE_SHOT, | ||
381 | + D2S_SKILL_DODGE, | ||
382 | + D2S_SKILL_POWER_STRIKE, | ||
383 | + D2S_SKILL_POISON_JAVELIN, | ||
384 | + D2S_SKILL_EXPLODING_ARROW, | ||
385 | + D2S_SKILL_SLOW_MISSILES, | ||
386 | + D2S_SKILL_AVOID, | ||
387 | + D2S_SKILL_IMPALE, | ||
388 | + D2S_SKILL_LIGHTNING_BOLT, | ||
389 | + D2S_SKILL_ICE_ARROW, | ||
390 | + D2S_SKILL_GUIDED_ARROW, | ||
391 | + D2S_SKILL_PENETRATE, | ||
392 | + D2S_SKILL_CHARGED_STRIKE, | ||
393 | + D2S_SKILL_PLAGUE_JAVELIN, | ||
394 | + D2S_SKILL_STRAFE, | ||
395 | + D2S_SKILL_IMMOLATION_ARROW, | ||
396 | + D2S_SKILL_DOPPLEZON, | ||
397 | + D2S_SKILL_EVADE, | ||
398 | + D2S_SKILL_FEND, | ||
399 | + D2S_SKILL_FREEZING_ARROW, | ||
400 | + D2S_SKILL_VALKYRIE, | ||
401 | + D2S_SKILL_PIERCE, | ||
402 | + D2S_SKILL_LIGHTNING_STRIKE, | ||
403 | + D2S_SKILL_LIGHTNING_FURY | ||
404 | +}; | ||
405 | + | ||
406 | +const D2S_SKILL sorceressSkills[D2S_SKILL_MAXSKILLS_PER_CHAR] = { | ||
407 | + D2S_SKILL_FIRE_BOLT, | ||
408 | + D2S_SKILL_WARMTH, | ||
409 | + D2S_SKILL_CHARGED_BOLT, | ||
410 | + D2S_SKILL_ICE_BOLT, | ||
411 | + D2S_SKILL_FROZEN_ARMOR, | ||
412 | + D2S_SKILL_INFERNO, | ||
413 | + D2S_SKILL_STATIC_FIELD, | ||
414 | + D2S_SKILL_TELEKINESIS, | ||
415 | + D2S_SKILL_FROST_NOVA, | ||
416 | + D2S_SKILL_ICE_BLAST, | ||
417 | + D2S_SKILL_BLAZE, | ||
418 | + D2S_SKILL_FIRE_BALL, | ||
419 | + D2S_SKILL_NOVA, | ||
420 | + D2S_SKILL_LIGHTNING, | ||
421 | + D2S_SKILL_SHIVER_ARMOR, | ||
422 | + D2S_SKILL_FIRE_WALL, | ||
423 | + D2S_SKILL_ENCHANT, | ||
424 | + D2S_SKILL_CHAIN_LIGHTNING, | ||
425 | + D2S_SKILL_TELEPORT, | ||
426 | + D2S_SKILL_GLACIAL_SPIKE, | ||
427 | + D2S_SKILL_METEOR, | ||
428 | + D2S_SKILL_THUNDER_STORM, | ||
429 | + D2S_SKILL_ENERGY_SHIELD, | ||
430 | + D2S_SKILL_BLIZZARD, | ||
431 | + D2S_SKILL_CHILLING_ARMOR, | ||
432 | + D2S_SKILL_FIRE_MASTERY, | ||
433 | + D2S_SKILL_HYDRA, | ||
434 | + D2S_SKILL_LIGHTNING_MASTERY, | ||
435 | + D2S_SKILL_FROZEN_ORB, | ||
436 | + D2S_SKILL_COLD_MASTERY | ||
437 | +}; | ||
438 | + | ||
439 | +const D2S_SKILL necromancerSkills[D2S_SKILL_MAXSKILLS_PER_CHAR] = { | ||
440 | + D2S_SKILL_AMPLIFY_DAMAGE, | ||
441 | + D2S_SKILL_TEETH, | ||
442 | + D2S_SKILL_BONE_ARMOR, | ||
443 | + D2S_SKILL_SKELETON_MASTERY, | ||
444 | + D2S_SKILL_RAISE_SKELETON, | ||
445 | + D2S_SKILL_DIM_VISION, | ||
446 | + D2S_SKILL_WEAKEN, | ||
447 | + D2S_SKILL_POISON_DAGGER, | ||
448 | + D2S_SKILL_CORPSE_EXPLOSION, | ||
449 | + D2S_SKILL_CLAY_GOLEM, | ||
450 | + D2S_SKILL_IRON_MAIDEN, | ||
451 | + D2S_SKILL_TERROR, | ||
452 | + D2S_SKILL_BONE_WALL, | ||
453 | + D2S_SKILL_GOLEM_MASTERY, | ||
454 | + D2S_SKILL_RAISE_SKELETAL_MAGE, | ||
455 | + D2S_SKILL_CONFUSE, | ||
456 | + D2S_SKILL_LIFE_TAP, | ||
457 | + D2S_SKILL_POISON_EXPLOSION, | ||
458 | + D2S_SKILL_BONE_SPEAR, | ||
459 | + D2S_SKILL_BLOOD_GOLEM, | ||
460 | + D2S_SKILL_ATTRACT, | ||
461 | + D2S_SKILL_DECREPIFY, | ||
462 | + D2S_SKILL_BONE_PRISON, | ||
463 | + D2S_SKILL_SUMMON_RESIST, | ||
464 | + D2S_SKILL_IRON_GOLEM, | ||
465 | + D2S_SKILL_LOWER_RESIST, | ||
466 | + D2S_SKILL_POISON_NOVA, | ||
467 | + D2S_SKILL_BONE_SPIRIT, | ||
468 | + D2S_SKILL_FIRE_GOLEM, | ||
469 | + D2S_SKILL_REVIVE | ||
470 | +}; | ||
471 | + | ||
472 | +const D2S_SKILL paladinSkills[D2S_SKILL_MAXSKILLS_PER_CHAR] = { | ||
473 | + D2S_SKILL_SACRIFICE, | ||
474 | + D2S_SKILL_SMITE, | ||
475 | + D2S_SKILL_MIGHT, | ||
476 | + D2S_SKILL_PRAYER, | ||
477 | + D2S_SKILL_RESIST_FIRE, | ||
478 | + D2S_SKILL_HOLY_BOLT, | ||
479 | + D2S_SKILL_HOLY_FIRE, | ||
480 | + D2S_SKILL_THORNS, | ||
481 | + D2S_SKILL_DEFIANCE, | ||
482 | + D2S_SKILL_RESIST_COLD, | ||
483 | + D2S_SKILL_ZEAL, | ||
484 | + D2S_SKILL_CHARGE, | ||
485 | + D2S_SKILL_BLESSED_AIM, | ||
486 | + D2S_SKILL_CLEANSING, | ||
487 | + D2S_SKILL_RESIST_LIGHTNING, | ||
488 | + D2S_SKILL_VENGEANCE, | ||
489 | + D2S_SKILL_BLESSED_HAMMER, | ||
490 | + D2S_SKILL_CONCENTRATION, | ||
491 | + D2S_SKILL_HOLY_FREEZE, | ||
492 | + D2S_SKILL_VIGOR, | ||
493 | + D2S_SKILL_CONVERSION, | ||
494 | + D2S_SKILL_HOLY_SHIELD, | ||
495 | + D2S_SKILL_HOLY_SHOCK, | ||
496 | + D2S_SKILL_SANCTUARY, | ||
497 | + D2S_SKILL_MEDITATION, | ||
498 | + D2S_SKILL_FIST_OF_THE_HEAVENS, | ||
499 | + D2S_SKILL_FANATICISM, | ||
500 | + D2S_SKILL_CONVICTION, | ||
501 | + D2S_SKILL_REDEMPTION, | ||
502 | + D2S_SKILL_SALVATION | ||
503 | +}; | ||
504 | + | ||
505 | +const D2S_SKILL barbarianSkills[D2S_SKILL_MAXSKILLS_PER_CHAR] = { | ||
506 | + D2S_SKILL_BASH, | ||
507 | + D2S_SKILL_SWORD_MASTERY, | ||
508 | + D2S_SKILL_AXE_MASTERY, | ||
509 | + D2S_SKILL_MACE_MASTERY, | ||
510 | + D2S_SKILL_HOWL, | ||
511 | + D2S_SKILL_FIND_POTION, | ||
512 | + D2S_SKILL_LEAP, | ||
513 | + D2S_SKILL_DOUBLE_SWING, | ||
514 | + D2S_SKILL_POLE_ARM_MASTERY, | ||
515 | + D2S_SKILL_THROWING_MASTERY, | ||
516 | + D2S_SKILL_SPEAR_MASTERY, | ||
517 | + D2S_SKILL_TAUNT, | ||
518 | + D2S_SKILL_SHOUT, | ||
519 | + D2S_SKILL_STUN, | ||
520 | + D2S_SKILL_DOUBLE_THROW, | ||
521 | + D2S_SKILL_INCREASED_STAMINA, | ||
522 | + D2S_SKILL_FIND_ITEM, | ||
523 | + D2S_SKILL_LEAP_ATTACK, | ||
524 | + D2S_SKILL_CONCENTRATE, | ||
525 | + D2S_SKILL_IRON_SKIN, | ||
526 | + D2S_SKILL_BATTLE_CRY, | ||
527 | + D2S_SKILL_FRENZY, | ||
528 | + D2S_SKILL_INCREASED_SPEED, | ||
529 | + D2S_SKILL_BATTLE_ORDERS, | ||
530 | + D2S_SKILL_GRIM_WARD, | ||
531 | + D2S_SKILL_WHIRLWIND, | ||
532 | + D2S_SKILL_BERSERK, | ||
533 | + D2S_SKILL_NATURAL_RESISTANCE, | ||
534 | + D2S_SKILL_WAR_CRY, | ||
535 | + D2S_SKILL_BATTLE_COMMAND | ||
536 | +}; | ||
537 | + | ||
538 | +const D2S_SKILL druidSkills[D2S_SKILL_MAXSKILLS_PER_CHAR] = { | ||
539 | + D2S_SKILL_RAVEN, | ||
540 | + D2S_SKILL_POISON_CREEPER, | ||
541 | + D2S_SKILL_WEARWOLF, | ||
542 | + D2S_SKILL_SHAPE_SHIFTING, | ||
543 | + D2S_SKILL_FIRESTORM, | ||
544 | + D2S_SKILL_OAK_SAGE, | ||
545 | + D2S_SKILL_SUMMON_SPIRIT_WOLF, | ||
546 | + D2S_SKILL_WEARBEAR, | ||
547 | + D2S_SKILL_MOLTEN_BOULDER, | ||
548 | + D2S_SKILL_ARCTIC_BLAST, | ||
549 | + D2S_SKILL_CYCLE_OF_LIFE, | ||
550 | + D2S_SKILL_FERAL_RAGE, | ||
551 | + D2S_SKILL_MAUL, | ||
552 | + D2S_SKILL_ERUPTION, | ||
553 | + D2S_SKILL_CYCLONE_ARMOR, | ||
554 | + D2S_SKILL_HEART_OF_WOLVERINE, | ||
555 | + D2S_SKILL_SUMMON_FENRIS, | ||
556 | + D2S_SKILL_RABIES, | ||
557 | + D2S_SKILL_FIRE_CLAWS, | ||
558 | + D2S_SKILL_TWISTER, | ||
559 | + D2S_SKILL_VINES, | ||
560 | + D2S_SKILL_HUNGER, | ||
561 | + D2S_SKILL_SHOCK_WAVE, | ||
562 | + D2S_SKILL_VOLCANO, | ||
563 | + D2S_SKILL_TORNADO, | ||
564 | + D2S_SKILL_SPIRIT_OF_BARBS, | ||
565 | + D2S_SKILL_SUMMON_GRIZZLY, | ||
566 | + D2S_SKILL_FURY, | ||
567 | + D2S_SKILL_ARMAGEDDON, | ||
568 | + D2S_SKILL_HURRICANE | ||
569 | +}; | ||
570 | + | ||
571 | +const D2S_SKILL assassinSkills[D2S_SKILL_MAXSKILLS_PER_CHAR] = { | ||
572 | + D2S_SKILL_FIRE_BLAST, | ||
573 | + D2S_SKILL_CLAW_MASTERY, | ||
574 | + D2S_SKILL_PSYCHIC_HAMMER, | ||
575 | + D2S_SKILL_TIGER_STRIKE, | ||
576 | + D2S_SKILL_DRAGON_TALON, | ||
577 | + D2S_SKILL_SHOCK_FIELD, | ||
578 | + D2S_SKILL_BLADE_SENTINEL, | ||
579 | + D2S_SKILL_QUICKNESS, | ||
580 | + D2S_SKILL_FISTS_OF_FIRE, | ||
581 | + D2S_SKILL_DRAGON_CLAW, | ||
582 | + D2S_SKILL_CHARGED_BOLT_SENTRY, | ||
583 | + D2S_SKILL_WAKE_OF_FIRE_SENTRY, | ||
584 | + D2S_SKILL_WEAPON_BLOCK, | ||
585 | + D2S_SKILL_CLOAK_OF_SHADOWS, | ||
586 | + D2S_SKILL_COBRA_STRIKE, | ||
587 | + D2S_SKILL_BLADE_FURY, | ||
588 | + D2S_SKILL_FADE, | ||
589 | + D2S_SKILL_SHADOW_WARRIOR, | ||
590 | + D2S_SKILL_CLAWS_OF_THUNDER, | ||
591 | + D2S_SKILL_DRAGON_TAIL, | ||
592 | + D2S_SKILL_LIGHTNING_SENTRY, | ||
593 | + D2S_SKILL_INFERNO_SENTRY, | ||
594 | + D2S_SKILL_MIND_BLAST, | ||
595 | + D2S_SKILL_BLADES_OF_ICE, | ||
596 | + D2S_SKILL_DRAGON_FLIGHT, | ||
597 | + D2S_SKILL_DEATH_SENTRY, | ||
598 | + D2S_SKILL_BLADE_SHIELD, | ||
599 | + D2S_SKILL_VENOM, | ||
600 | + D2S_SKILL_SHADOW_MASTER, | ||
601 | + D2S_SKILL_ROYAL_STRIKE | ||
602 | +}; | ||
603 | + | ||
604 | +const char* const skillNames[] = { | ||
14 | D2S_SKILL_0, | 605 | D2S_SKILL_0, |
15 | D2S_SKILL_1, | 606 | D2S_SKILL_1, |
16 | D2S_SKILL_2, | 607 | D2S_SKILL_2, |
@@ -372,6 +963,6 @@ const char* const skills[] = { | @@ -372,6 +963,6 @@ const char* const skills[] = { | ||
372 | 963 | ||
373 | // Returns static string from library memory, no need to free | 964 | // Returns static string from library memory, no need to free |
374 | const char* getSkillName(D2S_SKILL skillID); | 965 | const char* getSkillName(D2S_SKILL skillID); |
375 | -D2S_CHARCLASS getSkillClass(D2S_SKILL skillID); | 966 | +D2S_SKILL getSkillIDFromCharOffset(D2S_CHARCLASS class, unsigned int offset); |
376 | 967 | ||
377 | #endif | 968 | #endif |
378 | \ No newline at end of file | 969 | \ No newline at end of file |
d2waypoints.c
1 | #include "d2waypoints.h" | 1 | #include "d2waypoints.h" |
2 | #include "d2char.h" | 2 | #include "d2char.h" |
3 | 3 | ||
4 | +#include <stdio.h> | ||
5 | + | ||
6 | +const char* getWaypointName(D2S_WAYPOINT waypoint) { | ||
7 | + if(waypoint > D2S_WAYPOINTSDATA_NUMWAYPOINTS) { | ||
8 | + fprintf(stderr,"libd2char error: waypoint %d doesn't exist\n",waypoint); | ||
9 | + return NULL; | ||
10 | + } | ||
11 | + return waypoints[waypoint]; | ||
12 | +} | ||
13 | + | ||
4 | int isWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULTY difficulty) { | 14 | int isWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULTY difficulty) { |
5 | if(waypoint > D2S_WAYPOINTSDATA_NUMWAYPOINTS) { | 15 | if(waypoint > D2S_WAYPOINTSDATA_NUMWAYPOINTS) { |
16 | + fprintf(stderr,"libd2char error: waypoint %d doesn't exist\n",waypoint); | ||
17 | + return -1; | ||
18 | + } | ||
19 | + if(difficulty != D2S_DIFFICULTY_NORMAL || | ||
20 | + difficulty != D2S_DIFFICULTY_NIGHTMARE || | ||
21 | + difficulty != D2S_DIFFICULTY_HELL) { | ||
22 | + fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty); | ||
6 | return -1; | 23 | return -1; |
7 | } | 24 | } |
8 | unsigned int byte = waypoint / 8; | 25 | unsigned int byte = waypoint / 8; |
@@ -10,12 +27,19 @@ int isWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULT | @@ -10,12 +27,19 @@ int isWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULT | ||
10 | return (d->waypoints[difficulty].waypointData[byte] & (1 << offset)) >> offset; | 27 | return (d->waypoints[difficulty].waypointData[byte] & (1 << offset)) >> offset; |
11 | } | 28 | } |
12 | 29 | ||
13 | -// TODO: Return success | ||
14 | -void setWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULTY difficulty, int activated) { | 30 | +int setWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULTY difficulty, int activated) { |
15 | if(waypoint > D2S_WAYPOINTSDATA_NUMWAYPOINTS) { | 31 | if(waypoint > D2S_WAYPOINTSDATA_NUMWAYPOINTS) { |
16 | - return; | 32 | + fprintf(stderr,"libd2char error: waypoint %d doesn't exist\n",waypoint); |
33 | + return -1; | ||
34 | + } | ||
35 | + if(difficulty != D2S_DIFFICULTY_NORMAL || | ||
36 | + difficulty != D2S_DIFFICULTY_NIGHTMARE || | ||
37 | + difficulty != D2S_DIFFICULTY_HELL) { | ||
38 | + fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty); | ||
39 | + return -1; | ||
17 | } | 40 | } |
18 | unsigned int byte = waypoint / 8; | 41 | unsigned int byte = waypoint / 8; |
19 | unsigned int offset = waypoint % 8; | 42 | unsigned int offset = waypoint % 8; |
20 | d->waypoints[difficulty].waypointData[byte] |= (1 << offset); | 43 | d->waypoints[difficulty].waypointData[byte] |= (1 << offset); |
44 | + return 0; | ||
21 | } | 45 | } |
22 | \ No newline at end of file | 46 | \ No newline at end of file |
d2waypoints.h
@@ -13,7 +13,46 @@ typedef enum D2S_DIFFICULTY D2S_DIFFICULTY; | @@ -13,7 +13,46 @@ typedef enum D2S_DIFFICULTY D2S_DIFFICULTY; | ||
13 | #define D2S_WAYPOINTSDATA_NUMWAYPOINTS 39 | 13 | #define D2S_WAYPOINTSDATA_NUMWAYPOINTS 39 |
14 | 14 | ||
15 | typedef enum D2S_WAYPOINT { | 15 | typedef enum D2S_WAYPOINT { |
16 | -asd | 16 | + D2S_WAYPOINT_UNKNOWN = -1, |
17 | + D2S_WAYPOINT_ROGUE_ENCAMPMENT = 0, | ||
18 | + D2S_WAYPOINT_COLD_PLAINS, | ||
19 | + D2S_WAYPOINT_STONY_FIELD, | ||
20 | + D2S_WAYPOINT_DARK_WOOD, | ||
21 | + D2S_WAYPOINT_BLACK_MARSH, | ||
22 | + D2S_WAYPOINT_OUTER_CLOISTER, | ||
23 | + D2S_WAYPOINT_JAIL, | ||
24 | + D2S_WAYPOINT_INNER_CLOISTER, | ||
25 | + D2S_WAYPOINT_CATACOMBS, | ||
26 | + D2S_WAYPOINT_LUT_GHOLEIN, | ||
27 | + D2S_WAYPOINT_SEWERS, | ||
28 | + D2S_WAYPOINT_DRY_HILLS, | ||
29 | + D2S_WAYPOINT_HALLS_OF_THE_DEAD, | ||
30 | + D2S_WAYPOINT_FAR_OASIS, | ||
31 | + D2S_WAYPOINT_LOST_CITY, | ||
32 | + D2S_WAYPOINT_PALACE_CELLAR, | ||
33 | + D2S_WAYPOINT_ARCANE_SANCTUARY, | ||
34 | + D2S_WAYPOINT_CANYON_OF_THE_MAGI, | ||
35 | + D2S_WAYPOINT_KURAST_DOCS, | ||
36 | + D2S_WAYPOINT_SPIDER_FOREST, | ||
37 | + D2S_WAYPOINT_GREAT_MARSH, | ||
38 | + D2S_WAYPOINT_FLAYER_JUNGLE, | ||
39 | + D2S_WAYPOINT_LOWER_KURAST, | ||
40 | + D2S_WAYPOINT_KURAST_BAZAAR, | ||
41 | + D2S_WAYPOINT_UPPER_KURAST, | ||
42 | + D2S_WAYPOINT_TRAVINCAL, | ||
43 | + D2S_WAYPOINT_DURANCE_OF_HATE, | ||
44 | + D2S_WAYPOINT_PANDEMONIUM_FORTRESS, | ||
45 | + D2S_WAYPOINT_CITY_OF_THE_DAMNED, | ||
46 | + D2S_WAYPOINT_RIVER_OF_FLAMES, | ||
47 | + D2S_WAYPOINT_HARROGATH, | ||
48 | + D2S_WAYPOINT_FRIGID_HIGHLANDS, | ||
49 | + D2S_WAYPOINT_ARREAT_PLATEAU, | ||
50 | + D2S_WAYPOINT_CRYSTALLINE_PASSAGE, | ||
51 | + D2S_WAYPOINT_HALLS_OF_PAIN, | ||
52 | + D2S_WAYPOINT_GLACIAL_TRAIL, | ||
53 | + D2S_WAYPOINT_FROZEN_TUNDRA, | ||
54 | + D2S_WAYPOINT_ANCIENTS_WAY, | ||
55 | + D2S_WAYPOINT_WORLDSTONE_KEEP | ||
17 | } D2S_WAYPOINT; | 56 | } D2S_WAYPOINT; |
18 | 57 | ||
19 | const char* const waypoints[] = { | 58 | const char* const waypoints[] = { |
@@ -71,7 +110,9 @@ typedef struct __attribute__((packed)) { | @@ -71,7 +110,9 @@ typedef struct __attribute__((packed)) { | ||
71 | D2Waypoints waypoints[3]; // 1 set for each difficulty | 110 | D2Waypoints waypoints[3]; // 1 set for each difficulty |
72 | } D2WaypointsData; | 111 | } D2WaypointsData; |
73 | 112 | ||
113 | +// Returns static string from library memory, no need to free | ||
114 | +const char* getWaypointName(D2S_WAYPOINT waypoint); | ||
74 | int isWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULTY difficulty); | 115 | int isWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULTY difficulty); |
75 | -void setWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULTY difficulty, int activated); | 116 | +int setWaypointActivated(D2WaypointsData* d, D2S_WAYPOINT waypoint, D2S_DIFFICULTY difficulty, int activated); |
76 | 117 | ||
77 | #endif | 118 | #endif |
78 | \ No newline at end of file | 119 | \ No newline at end of file |