#include "d2char.h" #include "d2quest.h" #include int getQuestData(D2QuestData* d, D2S_QUEST_IDENTIFIER questID, D2Quest* quest, 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; } memcpy(quest,&quests[questID],sizeof(D2Quest)); quest->difficulty = difficulty; if(questID >= D2S_QUEST_DEN_OF_EVIL && questID <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) { quest->questData = d->quests[difficulty].actData[D2S_ACT1].questCheckpoints[questID]; } else if(questID >= D2S_QUEST_RADAMENT_LAIR && questID <= D2S_QUEST_SEVEN_TOMBS) { quest->questData = d->quests[difficulty].actData[D2S_ACT2].questCheckpoints[questID - D2S_QUEST_RADAMENT_LAIR]; } else if(questID >= D2S_QUEST_GOLDEN_BIRD && questID <= D2S_QUEST_GUARDIAN) { quest->questData = d->quests[difficulty].actData[D2S_ACT3].questCheckpoints[questID - D2S_QUEST_GOLDEN_BIRD]; } else if(questID >= D2S_QUEST_FALLEN_ANGEL && questID <= D2S_QUEST_TERROR_END) { quest->questData = d->quests[difficulty].actData[D2S_ACT4].questCheckpoints[questID - D2S_QUEST_FALLEN_ANGEL]; } else if(questID >= D2S_QUEST_SIEGE_ON_HARROGATH && questID <= D2S_QUEST_EVE_OF_DESTRUCTION) { quest->questData = d->quests[difficulty].expansionAct.questCheckpoints[questID - D2S_QUEST_SIEGE_ON_HARROGATH]; } else { fprintf(stderr,"libd2char error: quest %d doesn't exist\n",questID); return -1; } return 0; } int setQuestData(D2QuestData* d, D2S_QUEST_IDENTIFIER questID, D2Quest* quest) { if(quest->difficulty != D2S_DIFFICULTY_NORMAL || quest->difficulty != D2S_DIFFICULTY_NIGHTMARE || quest->difficulty != D2S_DIFFICULTY_HELL) { fprintf(stderr,"libd2char error: difficulty %d doesn't exist\n",quest->difficulty); return -1; } if(questID >= D2S_QUEST_DEN_OF_EVIL && questID <= D2S_QUEST_SISTERS_TO_THE_SLAUGHTER) { d->quests[quest->difficulty].actData[D2S_ACT1].questCheckpoints[questID] = quest->questData; } else if(questID >= D2S_QUEST_RADAMENT_LAIR && questID <= D2S_QUEST_SEVEN_TOMBS) { d->quests[quest->difficulty].actData[D2S_ACT2].questCheckpoints[questID - D2S_QUEST_RADAMENT_LAIR] = quest->questData; } else if(questID >= D2S_QUEST_GOLDEN_BIRD && questID <= D2S_QUEST_GUARDIAN) { d->quests[quest->difficulty].actData[D2S_ACT3].questCheckpoints[questID - D2S_QUEST_GOLDEN_BIRD] = quest->questData; } else if(questID >= D2S_QUEST_FALLEN_ANGEL && questID <= D2S_QUEST_TERROR_END) { d->quests[quest->difficulty].actData[D2S_ACT4].questCheckpoints[questID - D2S_QUEST_FALLEN_ANGEL] = quest->questData; } else if(questID >= D2S_QUEST_SIEGE_ON_HARROGATH && questID <= D2S_QUEST_EVE_OF_DESTRUCTION) { d->quests[quest->difficulty].expansionAct.questCheckpoints[questID - D2S_QUEST_SIEGE_ON_HARROGATH] = quest->questData; } else { fprintf(stderr,"libd2char error: quest %d doesn't exist\n",questID); return -1; } return 0; } int isQuestStarted(D2Quest* quest) { return quest->questData & D2S_QUEST_STATUS_STARTED; } int isQuestRewardCollected(D2Quest* quest) { return quest->questData & D2S_QUEST_STATUS_REWARD_AVAILABLE; } int isQuestCompleted(D2Quest* quest) { return quest->questData & D2S_QUEST_STATUS_COMPLETED; } void setQuestStarted(D2Quest* quest, int bool) { // To reset the quest, just zero out the whole thing // To set as started, just set bit 2 and clear the rest if(bool) { quest->questData = D2S_QUEST_STATUS_STARTED; } else { quest->questData = 0x0000; } } void setQuestRewardCollected(D2Quest* quest, 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(quest,1); } else { setQuestCompleted(quest,0); quest->questData |= D2S_QUEST_STATUS_REWARD_AVAILABLE; } } void setQuestCompleted(D2Quest* quest, 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 if(bool) { quest->questData &= ~D2S_QUEST_STATUS_REWARD_AVAILABLE; quest->questData |= D2S_QUEST_STATUS_COMPLETED; quest->questData |= D2S_QUEST_STATUS_SEEN_FINISH_ANIMATION; } else { quest->questData &= ~D2S_QUEST_STATUS_COMPLETED; quest->questData &= ~D2S_QUEST_STATUS_SEEN_FINISH_ANIMATION; } } 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; D2Quest quest; switch(specialQuestState) { case D2S_SPECIALQUEST_AKARA_RESPEC: // This operation only makes sense if the quest is actually completed, otherwise ignore request getQuestData(d,D2S_QUEST_DEN_OF_EVIL,&quest,difficulty); if(isQuestCompleted(&quest)) { 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; }