Blame view

d2quest.c 7.73 KB
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
    }
Imanol-Mikel Barba Sabariego authored
19
    memcpy(descriptions,(&checkpointDescriptions) + (quest * 16 * sizeof(const char*)), 16 * sizeof(const char*));
20
    return 0;
Imanol-Mikel Barba Sabariego authored
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;
    }
Imanol-Mikel Barba Sabariego authored
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];
Imanol-Mikel Barba Sabariego authored
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];
Imanol-Mikel Barba Sabariego authored
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];
Imanol-Mikel Barba Sabariego authored
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];
Imanol-Mikel Barba Sabariego authored
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;
Imanol-Mikel Barba Sabariego authored
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;
    }
Imanol-Mikel Barba Sabariego authored
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;
Imanol-Mikel Barba Sabariego authored
67
    }
68
    return 0;
Imanol-Mikel Barba Sabariego authored
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) {
Imanol-Mikel Barba Sabariego authored
96
    // To reset the quest, just zero out the whole thing
Imanol-Mikel Barba Sabariego authored
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;
    }
Imanol-Mikel Barba Sabariego authored
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) {
Imanol-Mikel Barba Sabariego authored
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???)
Imanol-Mikel Barba Sabariego authored
113
    if(bool) {
114
        return setQuestCompleted(d,quest,difficulty,1);
Imanol-Mikel Barba Sabariego authored
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;
        }
Imanol-Mikel Barba Sabariego authored
123
        questData |= D2S_QUEST_STATUS_REWARD_AVAILABLE;
124
        return setQuestStatus(d,quest,difficulty,questData);
Imanol-Mikel Barba Sabariego authored
125
    }
126
127
}
128
int setQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, int bool) {
Imanol-Mikel Barba Sabariego authored
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;
    }
Imanol-Mikel Barba Sabariego authored
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;
    }
Imanol-Mikel Barba Sabariego authored
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;
Imanol-Mikel Barba Sabariego authored
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;
Imanol-Mikel Barba Sabariego authored
175
176
    switch(specialQuestState) {
        case D2S_SPECIALQUEST_AKARA_RESPEC:
Imanol-Mikel Barba Sabariego authored
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) {
Imanol-Mikel Barba Sabariego authored
180
                    d->quests[difficulty].akaraRespecData = 0x8001;
Imanol-Mikel Barba Sabariego authored
181
                } else {
Imanol-Mikel Barba Sabariego authored
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
}