|
1
2
3
|
#include "d2char.h"
#include "d2quest.h"
|
|
4
5
|
#include <stdio.h>
|
|
6
|
const char* getQuestName(D2S_QUEST quest) {
|
|
7
8
|
if(quest > D2S_QUESTDATA_NUMQUESTS) {
fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
|
|
9
10
11
12
13
14
15
16
17
|
return NULL;
}
return questName[quest];
}
int getCheckpointDescriptions(D2S_QUEST quest, const char* *descriptions[16]) {
if(quest > D2S_QUESTDATA_NUMQUESTS) {
fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
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) {
|
|
24
25
26
27
28
29
|
if(difficulty != D2S_DIFFICULTY_NORMAL ||
difficulty != D2S_DIFFICULTY_NIGHTMARE ||
difficulty != D2S_DIFFICULTY_HELL) {
fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty);
return -1;
}
|
|
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
40
41
42
|
*data = d->quests[difficulty].expansionAct.questCheckpoints[quest - D2S_QUEST_SIEGE_ON_HARROGATH];
} else {
fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
return -1;
|
|
43
|
}
|
|
44
|
return 0;
|
|
45
46
|
}
|
|
47
|
int setQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t questData) {
|
|
48
49
50
51
52
53
|
if(difficulty != D2S_DIFFICULTY_NORMAL ||
difficulty != D2S_DIFFICULTY_NIGHTMARE ||
difficulty != D2S_DIFFICULTY_HELL) {
fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty);
return -1;
}
|
|
54
55
56
57
58
59
60
61
62
63
|
if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) {
d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest] = questData;
} else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) {
d->quests[difficulty].actData[D2S_ACT2].questCheckpoints[quest - D2S_QUEST_RADAMENT_LAIR] = questData;
} else if(quest >= D2S_QUEST_GOLDEN_BIRD && quest <= D2S_QUEST_GUARDIAN) {
d->quests[difficulty].actData[D2S_ACT3].questCheckpoints[quest - D2S_QUEST_GOLDEN_BIRD] = questData;
} else if(quest >= D2S_QUEST_FALLEN_ANGEL && quest <= D2S_QUEST_TERROR_END) {
d->quests[difficulty].actData[D2S_ACT4].questCheckpoints[quest - D2S_QUEST_FALLEN_ANGEL] = questData;
} else if(quest >= D2S_QUEST_SIEGE_ON_HARROGATH && quest <= D2S_QUEST_EVE_OF_DESTRUCTION) {
d->quests[difficulty].expansionAct.questCheckpoints[quest - D2S_QUEST_SIEGE_ON_HARROGATH] = questData;
|
|
64
65
|
} else {
fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
|
|
66
|
return -1;
|
|
67
|
}
|
|
68
|
return 0;
|
|
69
70
|
}
|
|
71
72
73
74
75
76
|
int isQuestStarted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty) {
uint16_t data = 0;
if(getQuestStatus(d,quest,difficulty,&data) < 0) {
return -1;
}
return data & D2S_QUEST_STATUS_STARTED;
|
|
77
78
|
}
|
|
79
80
81
82
83
84
|
int isQuestRewardCollected(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty) {
uint16_t data = 0;
if(getQuestStatus(d,quest,difficulty,&data) < 0) {
return -1;
}
return data & D2S_QUEST_STATUS_REWARD_AVAILABLE;
|
|
85
86
|
}
|
|
87
88
89
90
91
92
|
int isQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty) {
uint16_t data = 0;
if(getQuestStatus(d,quest,difficulty,&data) < 0) {
return -1;
}
return data & D2S_QUEST_STATUS_COMPLETED;
|
|
93
94
|
}
|
|
95
|
int setQuestStarted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
|
|
96
|
// To reset the quest, just zero out the whole thing
|
|
97
|
// To set as started, just set bit 2 and clear the rest
|
|
98
99
100
101
|
uint16_t questData = 0;
if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
return -1;
}
|
|
102
103
104
105
106
|
if(bool) {
questData = D2S_QUEST_STATUS_STARTED;
} else {
questData = 0x0000;
}
|
|
107
|
return setQuestStatus(d,quest,difficulty,questData);
|
|
108
109
|
}
|
|
110
|
int setQuestRewardCollected(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
|
|
111
112
|
// To reset, just clear bit 0 and set bit 1.
// Do the inverse to set reward as collected (but why whould you tho???)
|
|
113
|
if(bool) {
|
|
114
|
return setQuestCompleted(d,quest,difficulty,1);
|
|
115
|
} else {
|
|
116
117
118
119
120
121
122
|
if(setQuestCompleted(d,quest,difficulty,0) < 0) {
return -1;
}
uint16_t questData;
if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
return -1;
}
|
|
123
|
questData |= D2S_QUEST_STATUS_REWARD_AVAILABLE;
|
|
124
|
return setQuestStatus(d,quest,difficulty,questData);
|
|
125
|
}
|
|
126
127
|
}
|
|
128
|
int setQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
|
|
129
130
131
|
// To reset, clear bit 0, bit 12 and bit 13 (13 is kinda optional since it will be cleared by
// the game when loading the savegame).
// To set as completed, just set bit 0 and bit 12 and clear bit 1
|
|
132
133
134
135
|
uint16_t questData;
if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
return -1;
}
|
|
136
137
138
139
140
141
142
143
|
if(bool) {
questData &= ~D2S_QUEST_STATUS_REWARD_AVAILABLE;
questData |= D2S_QUEST_STATUS_COMPLETED;
questData |= D2S_QUEST_STATUS_SEEN_FINISH_ANIMATION;
} else {
questData &= ~D2S_QUEST_STATUS_COMPLETED;
questData &= ~D2S_QUEST_STATUS_SEEN_FINISH_ANIMATION;
}
|
|
144
|
return setQuestStatus(d,quest,difficulty,questData);
|
|
145
146
|
}
|
|
147
148
149
150
151
152
153
|
int getSpecialQuestStatus(D2QuestData* d, D2S_SPECIALQUEST specialQuestState, D2S_DIFFICULTY difficulty) {
if(difficulty != D2S_DIFFICULTY_NORMAL ||
difficulty != D2S_DIFFICULTY_NIGHTMARE ||
difficulty != D2S_DIFFICULTY_HELL) {
fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty);
return -1;
}
|
|
154
155
156
157
158
|
int ret = 0;
switch(specialQuestState) {
case D2S_SPECIALQUEST_AKARA_RESPEC:
ret = d->quests[difficulty].akaraRespecData & D2S_QUEST_STATUS_REWARD_AVAILABLE;
break;
|
|
159
160
161
162
|
default:
fprintf(stderr,"libd2char error: invalid special quest %d\n",specialQuestState);
ret = -1;
break;
|
|
163
164
165
166
|
}
return ret;
}
|
|
167
|
int setSpecialQuestStatus(D2QuestData* d, D2S_SPECIALQUEST specialQuestState, D2S_DIFFICULTY difficulty, int bool) {
|
|
168
169
170
171
|
if(difficulty != D2S_DIFFICULTY_NORMAL ||
difficulty != D2S_DIFFICULTY_NIGHTMARE ||
difficulty != D2S_DIFFICULTY_HELL) {
fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty);
|
|
172
|
return -1;
|
|
173
|
}
|
|
174
|
int ret = 0;
|
|
175
176
|
switch(specialQuestState) {
case D2S_SPECIALQUEST_AKARA_RESPEC:
|
|
177
178
179
|
// This operation only makes sense if the quest is actually completed, otherwise ignore request
if(isQuestCompleted(d,D2S_QUEST_DEN_OF_EVIL,difficulty)) {
if(bool) {
|
|
180
|
d->quests[difficulty].akaraRespecData = 0x8001;
|
|
181
|
} else {
|
|
182
183
184
185
|
d->quests[difficulty].akaraRespecData = 0x2002;
}
}
break;
|
|
186
187
188
189
|
default:
fprintf(stderr,"libd2char error: invalid special quest %d\n",specialQuestState);
ret = -1;
break;
|
|
190
|
}
|
|
191
|
return ret;
|
|
192
|
}
|