|
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
20
21
|
memcpy(descriptions,(&checkpointDescriptions) + (quest * 16 * sizeof(const char*)), 16 * sizeof(const char*));
}
|
|
22
23
|
int getQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t* data) {
// TODO sanity check diff and quest
|
|
24
|
if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) {
|
|
25
|
*data = d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest];
|
|
26
|
} else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) {
|
|
27
|
*data = d->quests[difficulty].actData[D2S_ACT2].questCheckpoints[quest - D2S_QUEST_RADAMENT_LAIR];
|
|
28
|
} else if(quest >= D2S_QUEST_GOLDEN_BIRD && quest <= D2S_QUEST_GUARDIAN) {
|
|
29
|
*data = d->quests[difficulty].actData[D2S_ACT3].questCheckpoints[quest - D2S_QUEST_GOLDEN_BIRD];
|
|
30
|
} else if(quest >= D2S_QUEST_FALLEN_ANGEL && quest <= D2S_QUEST_TERROR_END) {
|
|
31
|
*data = d->quests[difficulty].actData[D2S_ACT4].questCheckpoints[quest - D2S_QUEST_FALLEN_ANGEL];
|
|
32
|
} else if(quest >= D2S_QUEST_SIEGE_ON_HARROGATH && quest <= D2S_QUEST_EVE_OF_DESTRUCTION) {
|
|
33
34
35
36
|
*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;
|
|
37
|
}
|
|
38
|
return 0;
|
|
39
40
|
}
|
|
41
42
|
int setQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t questData) {
// TODO sanity check diff and quest
|
|
43
44
45
46
47
48
49
50
51
52
|
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;
|
|
53
54
|
} else {
fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest);
|
|
55
|
return -1;
|
|
56
|
}
|
|
57
|
return 0;
|
|
58
59
|
}
|
|
60
61
62
63
64
65
|
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;
|
|
66
67
|
}
|
|
68
69
70
71
72
73
|
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;
|
|
74
75
|
}
|
|
76
77
78
79
80
81
|
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;
|
|
82
83
|
}
|
|
84
|
int setQuestStarted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
|
|
85
|
// To reset the quest, just zero out the whole thing
|
|
86
|
// To set as started, just set bit 2 and clear the rest
|
|
87
88
89
90
|
uint16_t questData = 0;
if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
return -1;
}
|
|
91
92
93
94
95
|
if(bool) {
questData = D2S_QUEST_STATUS_STARTED;
} else {
questData = 0x0000;
}
|
|
96
|
return setQuestStatus(d,quest,difficulty,questData);
|
|
97
98
|
}
|
|
99
|
int setQuestRewardCollected(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
|
|
100
101
|
// To reset, just clear bit 0 and set bit 1.
// Do the inverse to set reward as collected (but why whould you tho???)
|
|
102
|
if(bool) {
|
|
103
|
return setQuestCompleted(d,quest,difficulty,1);
|
|
104
|
} else {
|
|
105
106
107
108
109
110
111
|
if(setQuestCompleted(d,quest,difficulty,0) < 0) {
return -1;
}
uint16_t questData;
if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
return -1;
}
|
|
112
|
questData |= D2S_QUEST_STATUS_REWARD_AVAILABLE;
|
|
113
|
return setQuestStatus(d,quest,difficulty,questData);
|
|
114
|
}
|
|
115
116
|
}
|
|
117
|
int setQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
|
|
118
119
120
|
// 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
|
|
121
122
123
124
|
uint16_t questData;
if(getQuestStatus(d,quest,difficulty,&questData) < 0) {
return -1;
}
|
|
125
126
127
128
129
130
131
132
|
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;
}
|
|
133
|
return setQuestStatus(d,quest,difficulty,questData);
|
|
134
135
|
}
|
|
136
|
int getSpecialQuestStatus(D2QuestData* d, unsigned int specialQuestState, D2S_DIFFICULTY difficulty) {
|
|
137
138
139
140
141
142
143
144
145
|
int ret = 0;
switch(specialQuestState) {
case D2S_SPECIALQUEST_AKARA_RESPEC:
ret = d->quests[difficulty].akaraRespecData & D2S_QUEST_STATUS_REWARD_AVAILABLE;
break;
}
return ret;
}
|
|
146
|
int setSpecialQuestStatus(D2QuestData* d, unsigned int specialQuestState, D2S_DIFFICULTY difficulty, int bool) {
|
|
147
148
149
150
151
|
if(difficulty != D2S_DIFFICULTY_NORMAL ||
difficulty != D2S_DIFFICULTY_NIGHTMARE ||
difficulty != D2S_DIFFICULTY_HELL) {
fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",difficulty);
}
|
|
152
153
|
switch(specialQuestState) {
case D2S_SPECIALQUEST_AKARA_RESPEC:
|
|
154
155
156
|
// 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) {
|
|
157
|
d->quests[difficulty].akaraRespecData = 0x8001;
|
|
158
|
} else {
|
|
159
160
161
162
|
d->quests[difficulty].akaraRespecData = 0x2002;
}
}
break;
|
|
163
164
|
}
}
|