diff options
Diffstat (limited to '')
-rw-r--r-- | src/koopatlas/pathmanager.cpp | 255 |
1 files changed, 252 insertions, 3 deletions
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index cf3e0eb..8c31d96 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -8,6 +8,25 @@ extern "C" void PlaySoundWithFunctionB4(void *spc, nw4r::snd::SoundHandle *handle, int id, int unk); u8 MaybeFinishingLevel[2] = {0xFF,0xFF}; +u8 LastLevelPlayed[2] = {0xFF,0xFF}; +bool CanFinishCoins = false; +bool CanFinishExits = false; +bool CanFinishWorld = false; +bool CanFinishAlmostAllCoins = false; +bool CanFinishAllCoins = false; +bool CanFinishAllExits = false; +bool CanFinishEverything = false; +void ResetAllCompletionCandidates() { + MaybeFinishingLevel[0] = 0xFF; + LastLevelPlayed[0] = 0xFF; + CanFinishCoins = false; + CanFinishExits = false; + CanFinishWorld = false; + CanFinishAlmostAllCoins = false; + CanFinishAllCoins = false; + CanFinishAllExits = false; + CanFinishEverything = false; +} void dWMPathManager_c::setup() { dScKoopatlas_c *wm = dScKoopatlas_c::instance; @@ -147,13 +166,74 @@ void dWMPathManager_c::setup() { // did we just beat a level? if (MaybeFinishingLevel[0] != 0xFF) { - SaveBlock *save = GetSaveFile()->GetBlock(-1); if (save->CheckLevelCondition(MaybeFinishingLevel[0], MaybeFinishingLevel[1], COND_NORMAL)) { shouldRequestSave = true; } + } - MaybeFinishingLevel[0] = 0xFF; + // have we got any completions? + u32 conds = save->GetLevelCondition(LastLevelPlayed[0], LastLevelPlayed[1]); + dLevelInfo_c::entry_s *whatEntry = + dLevelInfo_c::s_info.searchBySlot(LastLevelPlayed[0], LastLevelPlayed[1]); + + // how many exits? + int exits = 0, maxExits = 0; + if (whatEntry->flags & 0x10) { + maxExits++; + if (conds & COND_NORMAL) + exits++; + } + if (whatEntry->flags & 0x20) { + maxExits++; + if (conds & COND_SECRET) + exits++; + } + + completionMessageWorldNum = whatEntry->displayWorld; + + // now do all the message checks + int flag = 0, totalFlag = 0; + if (CanFinishCoins) { + totalFlag |= 1; + if ((conds & COND_COIN_ALL) == COND_COIN_ALL) { + flag |= 1; + completionMessageType = CMP_MSG_COINS; + } + } + if (CanFinishExits) { + totalFlag |= 2; + if (exits == maxExits) { + flag |= 2; + completionMessageType = CMP_MSG_EXITS; + } + } + if (CanFinishWorld && flag == totalFlag) + completionMessageType = CMP_MSG_WORLD; + + if (CanFinishAlmostAllCoins) { + if ((conds & COND_COIN_ALL) == COND_COIN_ALL) + completionMessageType = CMP_MSG_GLOBAL_COINS_EXC_W9; + } + + int gFlag = 0, gTotalFlag = 0; + if (CanFinishAllCoins) { + gTotalFlag |= 1; + if ((conds & COND_COIN_ALL) == COND_COIN_ALL) { + gFlag |= 1; + completionMessageType = CMP_MSG_GLOBAL_COINS; + } + } + if (CanFinishAllExits) { + gTotalFlag |= 2; + if (exits == maxExits) { + gFlag |= 2; + completionMessageType = CMP_MSG_GLOBAL_EXITS; + } } + if (CanFinishEverything && gFlag == gTotalFlag) + completionMessageType = CMP_MSG_EVERYTHING; + + ResetAllCompletionCandidates(); if (wm->isAfterKamekCutscene) copyWorldDefToSave(wm->mapData.findWorldDef(1)); @@ -180,6 +260,135 @@ dWMPathManager_c::~dWMPathManager_c() { MaybeFinishingLevel[1] = enteredLevel->levelSlot; } } + + // Now, a fuckton of checks for the various possible things we can finish! + dLevelInfo_c *li = &dLevelInfo_c::s_info; + u32 theseConds = save->GetLevelCondition(enteredLevel->worldSlot, enteredLevel->levelSlot); + + int coinCount = 0, exitCount = 0; + int globalCoinCount = 0, globalCoinCountExcW9 = 0, globalExitCount = 0; + + int totalCoinCount = 0, totalExitCount = 0; + int totalGlobalCoinCount = 0, totalGlobalCoinCountExcW9 = 0, totalGlobalExitCount = 0; + + for (int sIdx = 0; sIdx < li->sectionCount(); sIdx++) { + dLevelInfo_c::section_s *sect = li->getSectionByIndex(sIdx); + + for (int lIdx = 0; lIdx < sect->levelCount; lIdx++) { + dLevelInfo_c::entry_s *entry = §->levels[lIdx]; + u32 entryConds = save->GetLevelCondition(entry->worldSlot, entry->levelSlot); + + // Only track actual levels + if (!(entry->flags & 2)) + continue; + + // Counts for this world + if (entry->displayWorld == enteredLevel->displayWorld) { + totalCoinCount++; + if ((entryConds & COND_COIN_ALL) == COND_COIN_ALL) + coinCount++; + + // Normal exit + if (entry->flags & 0x10) { + totalExitCount++; + if (entryConds & COND_NORMAL) + exitCount++; + } + + // Secret exit + if (entry->flags & 0x20) { + totalExitCount++; + if (entryConds & COND_SECRET) + exitCount++; + } + } + + // Counts for everywhere + totalGlobalCoinCount++; + if ((entryConds & COND_COIN_ALL) == COND_COIN_ALL) + globalCoinCount++; + + if (entry->displayWorld != 9) { + totalGlobalCoinCountExcW9++; + if (entryConds & COND_COIN_ALL) + globalCoinCountExcW9++; + } + + // Normal exit + if (entry->flags & 0x10) { + totalGlobalExitCount++; + if (entryConds & COND_NORMAL) + globalExitCount++; + } + + // Secret exit + if (entry->flags & 0x20) { + totalGlobalExitCount++; + if (entryConds & COND_SECRET) + globalExitCount++; + } + } + } + + // So.. are we candidates for any of these? + ResetAllCompletionCandidates(); + + LastLevelPlayed[0] = enteredLevel->worldSlot; + LastLevelPlayed[1] = enteredLevel->levelSlot; + + int everythingFlag = 0, gEverythingFlag = 0; + if (coinCount == totalCoinCount) + everythingFlag |= 1; + if (exitCount == globalExitCount) + everythingFlag |= 2; + if (globalCoinCount == totalGlobalCoinCount) + gEverythingFlag |= 1; + if (globalExitCount == totalGlobalExitCount) + gEverythingFlag |= 2; + + // Check if we could obtain every star coin + if ((theseConds & COND_COIN_ALL) != COND_COIN_ALL) { + if ((coinCount + 1) == totalCoinCount) { + CanFinishCoins = true; + everythingFlag |= 1; + } + if ((globalCoinCount + 1) == totalGlobalCoinCount) { + CanFinishAllCoins = true; + gEverythingFlag |= 1; + } + if ((globalCoinCountExcW9 + 1) == totalGlobalCoinCountExcW9) + CanFinishAlmostAllCoins = true; + } + + // Check if we could obtain every exit + int elExits = 0, elTotalExits = 0; + if (enteredLevel->flags & 0x10) { + elTotalExits++; + if (theseConds & COND_NORMAL) + elExits++; + } + if (enteredLevel->flags & 0x20) { + elTotalExits++; + if (theseConds & COND_SECRET) + elExits++; + } + + if ((elExits + 1) == elTotalExits) { + if ((exitCount + 1) == totalExitCount) { + CanFinishExits = true; + everythingFlag |= 2; + } + if ((globalExitCount + 1) == totalGlobalExitCount) { + CanFinishAllExits = true; + gEverythingFlag |= 2; + } + } + + // And could we obtain EVERYTHING? + if ((CanFinishCoins || CanFinishExits) && everythingFlag == 3) + CanFinishWorld = true; + if ((CanFinishAllCoins || CanFinishAllExits) && gEverythingFlag == 3) + CanFinishEverything = true; } if (penguinSlideSound.Exists()) @@ -382,7 +591,7 @@ bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save, int sta bool dWMPathManager_c::doingThings() { - if (isEnteringLevel || (waitAfterUnlock > 0) || + if (isEnteringLevel || (waitAfterUnlock > 0) || (completionAnimDelay > 0) || (waitAtStart > 0) || (waitForAfterDeathAnim > 0) || (countdownToFadeIn > 0) || (unlockingAlpha != -1)) return true; @@ -461,6 +670,46 @@ void dWMPathManager_c::execute() { return; } + if (completionAnimDelay > 0) { + completionAnimDelay--; + if (dmGladDuration > 0) { + dmGladDuration--; + if (dmGladDuration == 0) + daWMPlayer_c::instance->startAnimation(wait_select, 1.0f, 0.0f, 0.0f); + } + if (completionAnimDelay == 0) + completionMessagePending = true; + return; + } + + // just in case + if (completionMessagePending) + return; + + if (completionMessageType > 0) { + OSReport("We have a completion message type: %d\n", completionMessageType); + + int whichSound; + if (completionMessageType == CMP_MSG_GLOBAL_COINS) { + whichSound = STRM_BGM_STAR_COIN_CMPLT_ALL; + completionAnimDelay = 240; + } else if (completionMessageType == CMP_MSG_EVERYTHING) { + whichSound = STRM_BGM_ALL_CMPLT_5STARS; + completionAnimDelay = 216; + } else { + whichSound = STRM_BGM_STAR_COIN_CMPLT_WORLD; + completionAnimDelay = 138; + } + + nw4r::snd::SoundHandle something; + PlaySoundWithFunctionB4(SoundRelatedClass, &something, whichSound, 1); + + daWMPlayer_c::instance->startAnimation(coin_comp, 1.0f, 0.0f, 0.0f); + dmGladDuration = 154; + + return; + } + if (waitAtStart > 0) { waitAtStart--; if (waitAtStart == 0) { |