#include "d2char.h" #include "d2quest.h" #include const char* getQuestName(D2S_QUEST quest) { if(quest > D2S_QUESTDATA_NUMQUESTS) { fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest); 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; } memcpy(descriptions,(&checkpointDescriptions) + (quest * 16 * sizeof(const char*)), 16 * sizeof(const char*)); return 0; } int getQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t* data) { 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; } if(quest >= D2S_QUEST_DEN_OF_EVIL && quest <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) { *data = d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[quest]; } else if(quest >= D2S_QUEST_RADAMENT_LAIR && quest <= D2S_QUEST_SEVEN_TOMBS) { *data = d->quests[difficulty].actData[D2S_ACT2].questCheckpoints[quest - D2S_QUEST_RADAMENT_LAIR]; } else if(quest >= D2S_QUEST_GOLDEN_BIRD && quest <= D2S_QUEST_GUARDIAN) { *data = d->quests[difficulty].actData[D2S_ACT3].questCheckpoints[quest - D2S_QUEST_GOLDEN_BIRD]; } else if(quest >= D2S_QUEST_FALLEN_ANGEL && quest <= D2S_QUEST_TERROR_END) { *data = 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) { *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; } return 0; } int setQuestStatus(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY difficulty, uint16_t questData) { 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; } 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; } else { fprintf(stderr,"libd2char error: quest %d doesn't exist\n",quest); return -1; } return 0; } 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; } 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; } 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; } int setQuestStarted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY 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 = 0; if(getQuestStatus(d,quest,difficulty,&questData) < 0) { return -1; } if(bool) { questData = D2S_QUEST_STATUS_STARTED; } else { questData = 0x0000; } return setQuestStatus(d,quest,difficulty,questData); } int setQuestRewardCollected(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY 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) { return setQuestCompleted(d,quest,difficulty,1); } else { if(setQuestCompleted(d,quest,difficulty,0) < 0) { return -1; } uint16_t questData; if(getQuestStatus(d,quest,difficulty,&questData) < 0) { return -1; } questData |= D2S_QUEST_STATUS_REWARD_AVAILABLE; return setQuestStatus(d,quest,difficulty,questData); } } int setQuestCompleted(D2QuestData* d, D2S_QUEST quest, D2S_DIFFICULTY 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; if(getQuestStatus(d,quest,difficulty,&questData) < 0) { return -1; } 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; } return setQuestStatus(d,quest,difficulty,questData); } 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; } int ret = 0; switch(specialQuestState) { case D2S_SPECIALQUEST_AKARA_RESPEC: ret = d->quests[difficulty].akaraRespecData & D2S_QUEST_STATUS_REWARD_AVAILABLE; break; default: fprintf(stderr,"libd2char error: invalid special quest %d\n",specialQuestState); ret = -1; break; } return ret; } int setSpecialQuestStatus(D2QuestData* d, D2S_SPECIALQUEST specialQuestState, D2S_DIFFICULTY difficulty, int bool) { 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; } int ret = 0; 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; default: fprintf(stderr,"libd2char error: invalid special quest %d\n",specialQuestState); ret = -1; break; } return ret; }