diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/koopatlas/pathmanager.cpp | 11 | ||||
-rw-r--r-- | src/koopatlas/starcoin.cpp | 224 | ||||
-rw-r--r-- | src/koopatlas/starcoin.h | 4 | ||||
-rw-r--r-- | src/newer.cpp | 25 |
4 files changed, 246 insertions, 18 deletions
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 95c545f..70f3fab 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -209,8 +209,15 @@ void dWMPathManager_c::unlockPaths() { SpammyReport("UNLOCKING PATHS: All complete @ %p\n", in); - for (int i = 0; i < pathLayer->nodeCount; i++) - NodeAvailabilityData[i] = pathLayer->nodes[i]->isUnlocked(); + for (int i = 0; i < pathLayer->nodeCount; i++) { + dKPNode_s *node = pathLayer->nodes[i]; + NodeAvailabilityData[i] = node->isUnlocked(); + + if (node->type == node->LEVEL && node->isUnlocked() && node->levelNumber[1] != 99) { + save->completions[node->levelNumber[0]-1][node->levelNumber[1]-1] |= COND_UNLOCKED; + OSReport("beets: %d-%d\n", node->levelNumber[0], node->levelNumber[1]); + } + } // did anything become newly available?! newlyAvailablePaths = 0; diff --git a/src/koopatlas/starcoin.cpp b/src/koopatlas/starcoin.cpp index 3b8372e..49ff46f 100644 --- a/src/koopatlas/starcoin.cpp +++ b/src/koopatlas/starcoin.cpp @@ -92,9 +92,6 @@ int dWMStarCoin_c::onCreate() { }; layout.getTextBoxes(tbNames, &LeftTitle, 8); - WriteBMGToTextBox(BtnBackText, GetBMG(), 3, 1, 0); - WriteBMGToTextBox(BtnWorldSelText, GetBMG(), 4, 11, 0); - layoutLoaded = true; } @@ -176,19 +173,200 @@ void dWMStarCoin_c::setRightArrowVisible(bool value) { bool dWMStarCoin_c::canScrollLeft() const { - return (currentSection > 0); + return (currentSectionIndex > 1); } bool dWMStarCoin_c::canScrollRight() const { - // TODO - return false; + return (currentSectionIndex < (availableSectionCount - 1)); } void dWMStarCoin_c::loadInfo() { - // TODO + WriteBMGToTextBox(BtnBackText, GetBMG(), 3, 1, 0); + WriteBMGToTextBox(BtnWorldSelText, GetBMG(), 4, 11, 0); + + int unspentCoins = getUnspentStarCoinCount(); + int coins = getStarCoinCount(); + + WriteNumberToTextBox(&unspentCoins, UnspentCoinCount, false); + WriteNumberToTextBox(&coins, TotalCoinCount, false); + + currentSection = -1; + currentSectionIndex = -1; + availableSectionCount = 0; + + SaveBlock *save = GetSaveFile()->GetBlock(-1); + int wantedSection = save->newerWorldID; + + // figure out which sections should be available + for (int i = 0; i < dLevelInfo_c::s_info.sectionCount(); i++) { + dLevelInfo_c::section_s *section = dLevelInfo_c::s_info.getSectionByIndex(i); + OSReport("Checking section %d\n", i); + + bool haveLevels; + for (int j = 0; j < section->levelCount; j++) { + dLevelInfo_c::entry_s *l = §ion->levels[j]; + if (l->flags & 2) { + if (save->GetLevelCondition(l->worldSlot, l->levelSlot) & COND_UNLOCKED) { + haveLevels = true; + break; + } + } + } + + if (haveLevels) { + OSReport("section %d has levels\n", i); + if (i == wantedSection) { + OSReport("It was the wanted section\n"); + currentSection = wantedSection; + currentSectionIndex = availableSectionCount; + } + OSReport("Assigned to ID %d\n", availableSectionCount); + sectionIndices[availableSectionCount++] = i; + OSReport("{%d, %d, %d, %d, %d, %d, %d, %d, ...}\n", + sectionIndices[0], + sectionIndices[1], + sectionIndices[2], + sectionIndices[3], + sectionIndices[4], + sectionIndices[5], + sectionIndices[6], + sectionIndices[7] + ); + } + } + + // if we didn't find the wanted one, use the first one available + if (currentSectionIndex == -1) { + currentSectionIndex = 0; + currentSection = sectionIndices[0]; + } + OSReport("{%d, %d, %d, %d, %d, %d, %d, %d, ...}\n", + sectionIndices[0], + sectionIndices[1], + sectionIndices[2], + sectionIndices[3], + sectionIndices[4], + sectionIndices[5], + sectionIndices[6], + sectionIndices[7] + ); } void dWMStarCoin_c::loadSectionInfo() { - // TODO + dLevelInfo_c::entry_s *visibleLevels[COLUMN_COUNT][ROW_COUNT]; + + // reset everything... everything + for (int i = 0; i < COLUMN_COUNT; i++) { + for (int j = 0; j < SHINE_COUNT; j++) + Shine[i][j]->SetVisible(false); + + for (int j = 0; j < ROW_COUNT; j++) { + visibleLevels[i][j] = 0; + + LevelName[i][j]->SetVisible(false); + + for (int k = 0; k < 3; k++) { + CoinOutline[i][j][k]->SetVisible(false); + Coin[i][j][k]->SetVisible(false); + } + } + } + + // get everything we'll need + SaveBlock *save = GetSaveFile()->GetBlock(-1); + dLevelInfo_c *linfo = &dLevelInfo_c::s_info; + + dLevelInfo_c::entry_s *names[COLUMN_COUNT]; + for (int i = 0; i < COLUMN_COUNT; i++) + names[i] = linfo->searchByDisplayNum(currentSection, 100+i); + + bool useSubworlds = (COLUMN_COUNT > 1) && names[1]; + + int currentPosition[COLUMN_COUNT]; + int currentColumn = 0; // only incremented in single-subworld mode + + for (int i = 0; i < COLUMN_COUNT; i++) + currentPosition[i] = 0; + + dLevelInfo_c::section_s *section = linfo->getSectionByIndex(currentSection); + + int earnedCoins = 0, earnableCoins = 0; + // earnedCoins is calculated later + + for (int i = 0; i < section->levelCount; i++) { + dLevelInfo_c::entry_s *level = §ion->levels[i]; + + // only pay attention to real levels + if (!(level->flags & 2)) + continue; + + earnableCoins += 3; + + // is this level unlocked? + u32 conds = save->GetLevelCondition(level->worldSlot, level->levelSlot); + + if (!(conds & COND_UNLOCKED)) + continue; + + // well, let's give it a slot + if (useSubworlds) { + currentColumn = (level->flags & 0x400) ? 1 : 0; + } else { + if (currentPosition[currentColumn] >= ROW_COUNT) + currentColumn++; + } + + visibleLevels[currentColumn][currentPosition[currentColumn]++] = level; + } + + // if the first column is empty, then move the second one over + if (currentPosition[0] == 0 && useSubworlds) { + for (int i = 0; i < currentPosition[1]; i++) { + visibleLevels[0][i] = visibleLevels[1][i]; + visibleLevels[1][i] = 0; + } + + names[0] = names[1]; + names[1] = 0; + } + + // work out the names + WriteAsciiToTextBox(LeftTitle, linfo->getNameForLevel(names[0])); + if (names[1]) + WriteAsciiToTextBox(RightTitle, linfo->getNameForLevel(names[1])); + RightTitle->SetVisible(names[1] != 0); + + // load all level info + for (int col = 0; col < COLUMN_COUNT; col++) { + for (int row = 0; row < ROW_COUNT; row++) { + dLevelInfo_c::entry_s *level = visibleLevels[col][row]; + if (!level) + continue; + + u32 conds = save->GetLevelCondition(level->worldSlot, level->levelSlot); + + if (!(row & 1)) { + int shineID = row / 2; + if (shineID < SHINE_COUNT) + Shine[col][shineID]->SetVisible(true); + } + + for (int coin = 0; coin < 3; coin++) { + CoinOutline[col][row][coin]->SetVisible(true); + + if (conds & (COND_COIN1 << coin)) { + Coin[col][row][coin]->SetVisible(true); + earnedCoins++; + } + } + + LevelName[col][row]->SetVisible(true); + WriteAsciiToTextBox(LevelName[col][row], linfo->getNameForLevel(level)); + } + } + + // set up coin things + WriteNumberToTextBox(&earnedCoins, EarnedCoinCount, false); + WriteNumberToTextBox(&earnableCoins, EarnedCoinMax, false); } @@ -231,11 +409,33 @@ void dWMStarCoin_c::executeState_Wait() { willExit = true; state.setState(&StateID_HideSectionWait); } else if ((nowPressed & WPAD_LEFT) && canScrollLeft()) { - currentSection--; + currentSection = sectionIndices[--currentSectionIndex]; + OSReport("Set section to %d from index %d\n", currentSection, currentSectionIndex); + OSReport("{%d, %d, %d, %d, %d, %d, %d, %d, ...}\n", + sectionIndices[0], + sectionIndices[1], + sectionIndices[2], + sectionIndices[3], + sectionIndices[4], + sectionIndices[5], + sectionIndices[6], + sectionIndices[7] + ); willExit = false; state.setState(&StateID_HideSectionWait); } else if ((nowPressed & WPAD_RIGHT) && canScrollRight()) { - currentSection++; + currentSection = sectionIndices[++currentSectionIndex]; + OSReport("Set section to %d from index %d\n", currentSection, currentSectionIndex); + OSReport("{%d, %d, %d, %d, %d, %d, %d, %d, ...}\n", + sectionIndices[0], + sectionIndices[1], + sectionIndices[2], + sectionIndices[3], + sectionIndices[4], + sectionIndices[5], + sectionIndices[6], + sectionIndices[7] + ); willExit = false; state.setState(&StateID_HideSectionWait); } @@ -263,12 +463,12 @@ void dWMStarCoin_c::executeState_HideSectionWait() { void dWMStarCoin_c::endState_HideSectionWait() { } void dWMStarCoin_c::beginState_HideWait() { - layout.enableNonLoopAnim(SHOW_ALL); + layout.enableNonLoopAnim(SHOW_ALL, true); layout.grpHandlers[SHOW_ALL].frameCtrl.flags = 3; // NO_LOOP | REVERSE } void dWMStarCoin_c::executeState_HideWait() { if (!layout.isAnimOn(SHOW_ALL)) - state.setState(&StateID_Wait); + state.setState(&StateID_Hidden); } void dWMStarCoin_c::endState_HideWait() { visible = false; diff --git a/src/koopatlas/starcoin.h b/src/koopatlas/starcoin.h index 3d931e8..5e88343 100644 --- a/src/koopatlas/starcoin.h +++ b/src/koopatlas/starcoin.h @@ -35,9 +35,13 @@ class dWMStarCoin_c : public dActor_c { ROW_COUNT = 9, COLUMN_COUNT = 2, SHINE_COUNT = 5, + MAX_SECTION_COUNT = 16, }; int currentSection; + int currentSectionIndex; + bool sectionIndices[MAX_SECTION_COUNT]; + int availableSectionCount; bool isLeftArrowVisible, isRightArrowVisible; bool willExit; diff --git a/src/newer.cpp b/src/newer.cpp index d1894ba..dd0d99c 100644 --- a/src/newer.cpp +++ b/src/newer.cpp @@ -1,6 +1,19 @@ #include <newer.h> #include <game.h> +void WriteAsciiToTextBox(nw4r::lyt::TextBox *tb, const char *source) { + int i = 0; + wchar_t buffer[1024]; + while (i < 1023 && source[i]) { + buffer[i] = source[i]; + i++; + } + buffer[i] = 0; + + tb->SetString(buffer); +} + + void getNewerLevelNumberString(int world, int level, wchar_t *dest) { static const wchar_t *numberKinds[] = { // 0-19 are handled by code @@ -46,9 +59,8 @@ void getNewerLevelNumberString(int world, int level, wchar_t *dest) { } } -int getStarCoinCount() { +int getUnspentStarCoinCount() { SaveBlock *save = GetSaveFile()->GetBlock(-1); - int coinsSpent = save->credits_hiscore; int coinsEarned = 0; for (int w = 0; w < 10; w++) { @@ -61,6 +73,11 @@ int getStarCoinCount() { } } - int coinsLeft = coinsEarned - coinsSpent; - return coinsLeft; + return coinsEarned; +} + +int getStarCoinCount() { + SaveBlock *save = GetSaveFile()->GetBlock(-1); + int coinsSpent = save->credits_hiscore; + return getUnspentStarCoinCount() - coinsSpent; } |