From 8f72f5956756cee972e101173e8efd3ef1b70c9b Mon Sep 17 00:00:00 2001 From: Imanol-Mikel Barba Sabariego Date: Mon, 13 Jul 2020 03:53:30 +0100 Subject: [PATCH] Finished quests stuff --- d2char.h | 2 ++ d2quest.c | 56 +++++++++++++++++++++++++++++++++++++++++++------------- d2quest.h | 5 +++++ 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/d2char.h b/d2char.h index ad703a0..785d0a3 100644 --- a/d2char.h +++ b/d2char.h @@ -95,6 +95,8 @@ typedef struct __attribute__((packed)){ uint8_t NPCIntroductions[D2S_NPCDATA_LENGTH]; // TODO: Not implemented } D2CharHeader; +// TODO: All setX functions + uint32_t calcChecksum(D2CharHeader* c, void* charData); int checkChecksum(D2CharHeader* c, void* charData); int isHardcore(D2CharHeader* c); diff --git a/d2quest.c b/d2quest.c index 5c47d7e..f516aa0 100644 --- a/d2quest.c +++ b/d2quest.c @@ -20,41 +20,71 @@ uint16_t getQuestStatus(D2QuestData* d, unsigned int quest, unsigned int difficu 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) { - // TODO - return 0; + return getQuestStatus(d,quest,difficulty) & D2S_QUEST_STATUS_STARTED; } int isQuestRewardCollected(D2QuestData* d, unsigned int quest, unsigned int difficulty) { - // TODO - return 0; + return !(getQuestStatus(d,quest,difficulty) & D2S_QUEST_STATUS_REWARD_AVAILABLE); } int isQuestCompleted(D2QuestData* d, unsigned int quest, unsigned int difficulty) { - // TODO - return 0; + 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 the 2nd bit and clear the rest - - // TODO + // 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???) - - // TODO + 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 - - // TODO + 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) { diff --git a/d2quest.h b/d2quest.h index 56c76da..f9e049e 100644 --- a/d2quest.h +++ b/d2quest.h @@ -518,6 +518,7 @@ void getCheckpointDescriptions(unsigned int quest, const char* *descriptions[16] // Returns quest status for the specified quest and act. uint16_t getQuestStatus(D2QuestData* d, unsigned int quest, unsigned int difficulty); +void setQuestStatus(D2QuestData* d, unsigned int quest, unsigned int difficulty, uint16_t questData); int isQuestStarted(D2QuestData* d, unsigned int quest, unsigned int difficulty); int isQuestRewardCollected(D2QuestData* d, unsigned int quest, unsigned int difficulty); @@ -526,6 +527,10 @@ int isQuestCompleted(D2QuestData* d, unsigned int quest, unsigned int difficulty // Set bool to 1 to set the status or 0 to remove it void setQuestStarted(D2QuestData* d, unsigned int quest, unsigned int difficulty, int bool); void setQuestRewardCollected(D2QuestData* d, unsigned int quest, unsigned int difficulty, int bool); +// When called to set the request to NOT completed (`bool` = 0), this will NOT set the reward collected status +// which *may* render the quest unobtainable, this is done in case we may want to further modify the quest state. +// If you want to mark the quest as not completed just to get the reward, please use `setQuestRewardCollected()` +// instead. void setQuestCompleted(D2QuestData* d, unsigned int quest, unsigned int difficulty, int bool); // Some quests have extra fields outside their quest data that govern certain states of the quest -- libgit2 0.22.2