diff --git a/source/game/game.cpp b/source/game/game.cpp index a732982df..b540978d7 100644 --- a/source/game/game.cpp +++ b/source/game/game.cpp @@ -87,6 +87,10 @@ #include "fma\fma.h" #endif +#ifndef __GAME_GAMESLOT_H__ +#include "game\gameslot.h" +#endif + #include "gfx\actor.h" @@ -258,14 +262,41 @@ void CGameScene::think(int _frames) } else if(s_levelFinished) { + // Do the gameslot stuff.. + CGameSlotManager::GameSlot *gameSlot; + int level,chapter; + int openNextLevel,levelToOpen,chapterToOpen; + gameSlot=CGameSlotManager::getSlotData(); + level=getLevelNumber(); + chapter=getChapterNumber(); + + gameSlot->levelHasBeenCompleted(chapter-1,level-1); + if(level!=5&& // Don't open any levels after finishing a bonus level + !(level==4&&chapter==5)) // Don't open any levels after finishing final level + { + if(level!=4) + { + // Open next level in this chapter.. + levelToOpen=level+1; + chapterToOpen=chapter; + } + else + { + // Open first level in next chapter + levelToOpen=1; + chapterToOpen=chapter+1; + } + gameSlot->levelIsNowOpen(chapterToOpen-1,levelToOpen-1); + } + // Level finished - go to map or fma - if(getLevelNumber()==4) + if(level==4) { GameState::setNextScene(&FmaScene); } - else if(getLevelNumber()==5) + else if(level==5) { - if(getChapterNumber()==5) + if(chapter==5) { ShopScene.setGotoPartyScreen(); } diff --git a/source/game/gameslot.cpp b/source/game/gameslot.cpp index 2b544c267..f4a2a7516 100644 --- a/source/game/gameslot.cpp +++ b/source/game/gameslot.cpp @@ -130,6 +130,7 @@ void CGameSlotManager::eraseGameSlot(unsigned int _slot) slot->m_continues=INITIAL_CONTINUES; slot->m_maxLevelCompleted=0; + // Clear spatula and kelp token flags for(i=0;im_spatulaCollectedFlags[i][j]=0; } } - for(i=0;im_kelpTokensHeld=0; #endif + + // No party items held yet for(i=0;im_partyItemsHeld[i]=false; } + // Mark all levels except first as NOT_OPEN + // On a non-cd build, everything starts as open + slot->m_levelCompletionState[0]=LEVELCOMPETESTATE_OPEN; + for(i=1;im_levelCompletionState[i]=LEVELCOMPETESTATE_NOT_OPEN; + } } diff --git a/source/game/gameslot.h b/source/game/gameslot.h index 5572f059f..ea8b6fdca 100644 --- a/source/game/gameslot.h +++ b/source/game/gameslot.h @@ -51,6 +51,15 @@ public: NUM_CHAPTERS=5, NUM_LEVELS_WITH_SPATULAS=4, + NUM_LEVELS_PER_CHAPTER_WITH_QUEST_ITEMS=4, + NUM_BONUS_LEVELS_PER_CHAPTER=1, + }; + + enum + { + LEVELCOMPETESTATE_NOT_OPEN, // Level is not available to play + LEVELCOMPETESTATE_OPEN, // Level is available to play + LEVELCOMPETESTATE_COMPLETED, // Level has been completed }; @@ -64,6 +73,7 @@ public: unsigned char m_kelpTokenCollectedFlags[NUM_CHAPTERS][16]; // Same again.. unsigned char m_kelpTokensHeld; unsigned char m_partyItemsHeld[CShopScene::NUM_SHOP_ITEM_IDS]; + unsigned char m_levelCompletionState[NUM_CHAPTERS*(NUM_LEVELS_PER_CHAPTER_WITH_QUEST_ITEMS+NUM_BONUS_LEVELS_PER_CHAPTER)]; // Spat functions.. int getSpatulaCollectedCount(unsigned int _chapter,unsigned int _level) @@ -150,6 +160,45 @@ public: ASSERT(!m_partyItemsHeld[_itemNumber]); m_partyItemsHeld[_itemNumber]=true; } + + // Levels + int isLevelOpen(unsigned int _chapter,unsigned int _level) + { + int index; + index=(_chapter*(NUM_LEVELS_PER_CHAPTER_WITH_QUEST_ITEMS+NUM_BONUS_LEVELS_PER_CHAPTER))+_level; + return m_levelCompletionState[index]!=(int)LEVELCOMPETESTATE_NOT_OPEN; + } + int hasQustItemBeenCollected(unsigned int _chapter,unsigned int _level) + { + int index; + index=(_chapter*(NUM_LEVELS_PER_CHAPTER_WITH_QUEST_ITEMS+NUM_BONUS_LEVELS_PER_CHAPTER))+_level; + return m_levelCompletionState[index]==(int)LEVELCOMPETESTATE_COMPLETED; + } + void levelIsNowOpen(unsigned int _chapter,unsigned int _level) + { + int index; + index=(_chapter*(NUM_LEVELS_PER_CHAPTER_WITH_QUEST_ITEMS+NUM_BONUS_LEVELS_PER_CHAPTER))+_level; + if(m_levelCompletionState[index]==LEVELCOMPETESTATE_NOT_OPEN) + { + m_levelCompletionState[index]=LEVELCOMPETESTATE_OPEN; + } + } + void levelHasBeenCompleted(unsigned int _chapter,unsigned int _level) + { + int index; + index=(_chapter*(NUM_LEVELS_PER_CHAPTER_WITH_QUEST_ITEMS+NUM_BONUS_LEVELS_PER_CHAPTER))+_level; + m_levelCompletionState[index]=LEVELCOMPETESTATE_COMPLETED; + } + +#ifdef __VERSION_DEBUG__ + void debugCheatOpenAllLevels() + { + for(int i=1;im_kelpWorldLevel) + if(isLevelOpen(m_currentChapterSelection,i)) { - sFrameHdr *fh; - POLY_FT4 *ft4; + DVECTOR pos; - // Normal level - m_font->setColour(253,251,67); - sprintf(buf,"%d/%d",CGameSlotManager::getSlotData()->getSpatulaCollectedCount(m_currentChapterSelection,i),level->m_spatulaOrTokenCounts); - fh=sb->getFrameHeader(level->m_questItemFrame); - ft4=sb->printFT4(fh,pos.vx+MAP_LEVEL_WIDTH-fh->W,pos.vy+MAP_LEVEL_HEIGHT-fh->H,0,0,10); - if(!hasQuestItemBeenCollected(m_currentChapterSelection,i)) + pos=s_mapLevelPositions[i]; + + if(!level->m_kelpWorldLevel) { - setRGB0(ft4,50,50,50); + sFrameHdr *fh; + POLY_FT4 *ft4; + + // Normal level + m_font->setColour(253,251,67); + sprintf(buf,"%d/%d",CGameSlotManager::getSlotData()->getSpatulaCollectedCount(m_currentChapterSelection,i),level->m_spatulaOrTokenCounts); + fh=sb->getFrameHeader(level->m_questItemFrame); + ft4=sb->printFT4(fh,pos.vx+MAP_LEVEL_WIDTH-fh->W,pos.vy+MAP_LEVEL_HEIGHT-fh->H,0,0,10); + if(!hasQuestItemBeenCollected(m_currentChapterSelection,i)) + { + setRGB0(ft4,50,50,50); + } + } + else + { + // Bonuse level + m_font->setColour(67,251,67); + sprintf(buf,"%d/%d",CGameSlotManager::getSlotData()->getKelpTokenCollectedCount(m_currentChapterSelection,i),level->m_spatulaOrTokenCounts); } - } - else - { - // Bonuse level - m_font->setColour(67,251,67); - sprintf(buf,"%d/%d",CGameSlotManager::getSlotData()->getKelpTokenCollectedCount(m_currentChapterSelection,i),level->m_spatulaOrTokenCounts); - } - - m_font->print(pos.vx,pos.vy,buf); + m_font->print(pos.vx,pos.vy,buf); + } level++; } @@ -305,11 +307,16 @@ void CMapScene::renderPointer() void CMapScene::renderInstructions() { // Instructions + int renderChapterControls; SpriteBank *sb; sFrameHdr *fh1,*fh2; int width; int x,y; + + // If only the first chapter is open then you can't select other ones... + renderChapterControls=isChapterOpen(1)?true:false; + sb=CGameScene::getSpriteBank(); m_font->setColour(MAP_INSTRUCTIONS_TEXT_R,MAP_INSTRUCTIONS_TEXT_G,MAP_INSTRUCTIONS_TEXT_B); @@ -329,11 +336,20 @@ void CMapScene::renderInstructions() fh2=sb->getFrameHeader(FRM__BUTD); width=fh1->W+MAP_INSTRUCTIONS_GAP_BETWEEN_BUTTONS+fh2->W+MAP_INSTRUCTIONS_GAP_BETWEEN_BUTTONS_AND_TEXT+m_font->getStringWidth(STR__MAP_SCREEN__UP_DOWN_TO_SELECT_CHAPTER); x=256-(width/2); - sb->printFT4(fh1,x,y+MAP_INSTRUCTIONS_BUTTON_Y_OFFSET,0,0,0); + if(renderChapterControls) + { + sb->printFT4(fh1,x,y+MAP_INSTRUCTIONS_BUTTON_Y_OFFSET,0,0,0); + } x+=fh1->W+MAP_INSTRUCTIONS_GAP_BETWEEN_BUTTONS; - sb->printFT4(fh2,x,y+MAP_INSTRUCTIONS_BUTTON_Y_OFFSET,0,0,0); + if(renderChapterControls) + { + sb->printFT4(fh2,x,y+MAP_INSTRUCTIONS_BUTTON_Y_OFFSET,0,0,0); + } x+=fh2->W+MAP_INSTRUCTIONS_GAP_BETWEEN_BUTTONS_AND_TEXT; - m_font->print(x,y,STR__MAP_SCREEN__UP_DOWN_TO_SELECT_CHAPTER); + if(renderChapterControls) + { + m_font->print(x,y,STR__MAP_SCREEN__UP_DOWN_TO_SELECT_CHAPTER); + } y+=MAP_INSTRUCTIONS_Y_SPACE_BETWEEN_LINES; fh1=sb->getFrameHeader(FRM__BUTX); @@ -355,21 +371,50 @@ void CMapScene::think(int _frames) { if(!CFader::isFading()&&!m_readyToExit) { + int pad=PadGetDown(0); + // Change chapter - if(PadGetDown(0)&PAD_UP) + if(pad&PAD_UP) { - if(++m_currentChapterSelection>=MAP_NUM_CHAPTERS)m_currentChapterSelection=0; - generateMapScreenImage(); - } - else if(PadGetDown(0)&PAD_DOWN) - { - if(--m_currentChapterSelection<0)m_currentChapterSelection=MAP_NUM_CHAPTERS-1; + int nextChapter=m_currentChapterSelection; + do + { + nextChapter++; + if(nextChapter==MAP_NUM_CHAPTERS)nextChapter=0; + } + while(!isChapterOpen(nextChapter)); + if(nextChapter!=m_currentChapterSelection) + { + m_currentChapterSelection=nextChapter; + generateMapScreenImage(); + } + } + else if(pad&PAD_DOWN) + { + int nextChapter=m_currentChapterSelection; + do + { + nextChapter--; + if(nextChapter<0)nextChapter=MAP_NUM_CHAPTERS-1; + } + while(!isChapterOpen(nextChapter)); + if(nextChapter!=m_currentChapterSelection) + { + m_currentChapterSelection=nextChapter; + generateMapScreenImage(); + } + } +#ifdef __VERSION_DEBUG__ + else if(pad&PAD_L1) + { + CGameSlotManager::getSlotData()->debugCheatOpenAllLevels(); generateMapScreenImage(); } +#endif // Move cursor int lastLevel=m_currentLevelSelection; - if(PadGetDown(0)&PAD_LEFT) + if(pad&PAD_LEFT) { do { @@ -377,7 +422,7 @@ void CMapScene::think(int _frames) } while(!isLevelOpen(m_currentChapterSelection,m_currentLevelSelection)); } - else if(PadGetDown(0)&PAD_RIGHT) + else if(pad&PAD_RIGHT) { do { @@ -438,7 +483,7 @@ void CMapScene::think(int _frames) } if(m_pointerArrivedAtTarget&& - PadGetDown(0)&PAD_CROSS) + pad&PAD_CROSS) { CSoundMediator::playSfx(CSoundMediator::SFX_FRONT_END__OK); s_globalLevelSelectThing=s_mapLevelData[m_currentChapterSelection][m_currentLevelSelection].m_globalLevelNumber; @@ -540,7 +585,12 @@ DVECTOR CMapScene::getPointerTargetPosition() ---------------------------------------------------------------------- */ int CMapScene::isLevelOpen(unsigned int _chapter,unsigned int _level) { - return true; + return CGameSlotManager::getSlotData()->isLevelOpen(_chapter,_level); +} + +int CMapScene::isChapterOpen(unsigned int _chapter) +{ + return CGameSlotManager::getSlotData()->isLevelOpen(_chapter,0); } int CMapScene::getSpatulaCollectedCount(unsigned int _chapter,unsigned int _level) @@ -550,7 +600,7 @@ int CMapScene::getSpatulaCollectedCount(unsigned int _chapter,unsigned int _lev int CMapScene::hasQuestItemBeenCollected(unsigned int _chapter,unsigned int _level) { - return _level&1; + return CGameSlotManager::getSlotData()->hasQustItemBeenCollected(_chapter,_level); } diff --git a/source/map/map.h b/source/map/map.h index ce3820b87..3aee59d75 100644 --- a/source/map/map.h +++ b/source/map/map.h @@ -91,6 +91,7 @@ private: void copyImageToScreen(int _file,int _x,int _y,int _w,int _h); DVECTOR getPointerTargetPosition(); int isLevelOpen(unsigned int _chapter,unsigned int _level); + int isChapterOpen(unsigned int _chapter); int getSpatulaCollectedCount(unsigned int _chapter,unsigned int _level); int hasQuestItemBeenCollected(unsigned int _chapter,unsigned int _level);