#include "d2char.h" #include "d2quest.h" void getCheckpointDescriptions(unsigned int quest, const char* *descriptions[16]) { memcpy(descriptions,(&checkpointDescriptions) + (quest * 16 * sizeof(const char*)), 16 * sizeof(const char*)); } uint16_t getQuestStatus(D2QuestData* d, unsigned int quest, unsigned int difficulty) { if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) { return d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest]; } else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) { return d->quests[difficulty].actData[D2S_ACT2].questCheckpoints[quest - D2S_QUEST_RADAMENT_LAIR]; } else if(quest >= D2S_QUEST_GOLDEN_BIRD && quest <= D2S_QUEST_GUARDIAN) { return d->quests[difficulty].actData[D2S_ACT3].questCheckpoints[quest - D2S_QUEST_GOLDEN_BIRD]; } else if(quest >= D2S_QUEST_FALLEN_ANGEL && quest <= D2S_QUEST_TERROR_END) { return d->quests[difficulty].actData[D2S_ACT4].questCheckpoints[quest - D2S_QUEST_FALLEN_ANGEL]; } else if(quest >= D2S_QUEST_SIEGE_ON_HARROGATH && quest <= D2S_QUEST_EVE_OF_DESTRUCTION) { return d->quests[difficulty].expansionAct.questCheckpoints[quest - D2S_QUEST_SIEGE_ON_HARROGATH]; } return D2S_QUEST_UNKNOWN; } void setQuestStatus(D2QuestData* d, unsigned int quest, unsigned int difficulty, uint16_t questData) { 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; } } int isQuestStarted(D2QuestData* d, unsigned int quest, unsigned int difficulty) { return getQuestStatus(d,quest,difficulty) & D2S_QUEST_STATUS_STARTED; } int isQuestRewardCollected(D2QuestData* d, unsigned int quest, unsigned int difficulty) { return !(getQuestStatus(d,quest,difficulty) & D2S_QUEST_STATUS_REWARD_AVAILABLE); } int isQuestCompleted(D2QuestData* d, unsigned int quest, unsigned int difficulty) { return getQuestStatus(d,quest,difficulty) & D2S_QUEST_STATUS_COMPLETED; } void setQuestStarted(D2QuestData* d, unsigned int quest, unsigned int difficulty, int bool) { // To reset the quest, just zero out the whole thing // To set as started, just set bit 2 and clear the rest uint16_t questData = getQuestStatus(d,quest,difficulty); if(bool) { questData = D2S_QUEST_STATUS_STARTED; } else { questData = 0x0000; } setQuestStatus(d,quest,difficulty,questData); } void setQuestRewardCollected(D2QuestData* d, unsigned int quest, unsigned int difficulty, int bool) { // To reset, just clear bit 0 and set bit 1. // Do the inverse to set reward as collected (but why whould you tho???) if(bool) { setQuestCompleted(d,quest,difficulty,1); } else { setQuestCompleted(d,quest,difficulty,0); uint16_t questData = getQuestStatus(d,quest,difficulty); questData |= D2S_QUEST_STATUS_REWARD_AVAILABLE; setQuestStatus(d,quest,difficulty,questData); } } void setQuestCompleted(D2QuestData* d, unsigned int quest, unsigned int difficulty, int bool) { // 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 uint16_t questData = getQuestStatus(d,quest,difficulty); 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; } setQuestStatus(d,quest,difficulty,questData); } int getSpecialQuestStatus(D2QuestData* d, unsigned int specialQuestState, unsigned int difficulty) { int ret = 0; switch(specialQuestState) { case D2S_SPECIALQUEST_AKARA_RESPEC: ret = d->quests[difficulty].akaraRespecData & D2S_QUEST_STATUS_REWARD_AVAILABLE; break; } return ret; } void setSpecialQuestStatus(D2QuestData* d, unsigned int specialQuestState, unsigned int difficulty, int bool) { switch(specialQuestState) { case D2S_SPECIALQUEST_AKARA_RESPEC: // 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) { d->quests[difficulty].akaraRespecData = 0x8001; } else { d->quests[difficulty].akaraRespecData = 0x2002; } } break; } }