From 95e2c3c004b9881b346b433bd2039922fb5988c9 Mon Sep 17 00:00:00 2001 From: ketmar Date: Thu, 23 Aug 2018 18:29:41 +0000 Subject: [PATCH] added help screens and map (press F1 in pause screen to see 'em) FossilOrigin-Name: 16c05c66f7275e587d17514a8cf0c173a74ac3cf3acfa18e1f117029fd55ac75 --- GameLevel.vc | 153 ++++++++++++++++++++++++++++++++++++++--- packages/Generator/LevelGen.vc | 23 ++++--- spelunky_main.vc | 21 +++++- 3 files changed, 177 insertions(+), 20 deletions(-) diff --git a/GameLevel.vc b/GameLevel.vc index fb67f9f..bfc7c2a 100644 --- a/GameLevel.vc +++ b/GameLevel.vc @@ -47,6 +47,9 @@ transient name lastMusicName; transient float accumTime; transient bool gamePaused = false; +transient bool gameShowHelp = false; +transient int gameHelpScreen = 0; +const int MaxGameHelpScreen = 2; transient bool checkWater; transient int liquidTileCount; // cached /*transient*/ int damselSaved; @@ -105,6 +108,7 @@ int udjatAlarm; int time; // in frames int lastUsedObjectId; transient int lastRenderTime = -1; +transient int pausedTime; MapEntity deadItemsHead; @@ -821,7 +825,6 @@ void generateLevel () { udjatAlarm = 0; if (resetBMCOG) { resetBMCOG = false; - global.cityOfGold = false; global.genBlackMarket = false; } @@ -931,6 +934,14 @@ void generateLevel () { setupGhostTime(); if (global.cityOfGold == 1 || global.genBlackMarket) resetBMCOG = true; + + if (global.cityOfGold == 1) { + lg.mapSprite = 'sMapTemple'; + lg.mapTitle = "City of Gold"; + } else if (global.blackMarket) { + lg.mapSprite = 'sMapJungle'; + lg.mapTitle = "Black Market"; + } } @@ -1964,10 +1975,13 @@ final void thinkOne (MapEntity o, optional bool doHeldObject, optional bool dont final void processThinkers (float timeDelta) { if (timeDelta <= 0) return; if (gamePaused) { + ++pausedTime; if (onBeforeFrame) onBeforeFrame(false); if (onAfterFrame) onAfterFrame(false); keysNextFrame(); return; + } else { + pausedTime = 0; } accumTime += timeDelta; bool wasFrame = false; @@ -3073,6 +3087,20 @@ final void drawSpriteAt (name sprName, float frnumf, int x0, int y0, optional bo } +final void drawSpriteAtS3 (name sprName, float frnumf, int x0, int y0) { + if (!sprName) return; + auto spr = sprStore[sprName]; + if (!spr || !spr.frames.length) return; + x0 *= 3; + y0 *= 3; + int frnum = max(0, trunc(frnumf))%spr.frames.length; + auto sfr = spr.frames[frnum]; + int sx0 = x0-sfr.xofs*3; + int sy0 = y0-sfr.yofs*3; + sfr.tex.blitAt(sx0, sy0, 3); +} + + // x0 and y0 are non-scaled (and will be scaled) final void drawTextAt (int x0, int y0, string text, optional int scale) { if (!text) return; @@ -3116,6 +3144,7 @@ void renderCompass (float currFrameDelta) { } else if (exitX > vx1-16) { drawSpriteAt(hasMessage ? 'sCompassSmallRight' : 'sCompassRight', 0, 304, exitY-vy0); } + break; // only the first exit } } @@ -3482,23 +3511,130 @@ final void drawTextAtS3Centered (int y0, string text, optional int hiColor1, opt } -void renderPauseOverlay () { - int scale = 3; +void renderHelpOverlay () { + Video.color = 0; + Video.fillRect(0, 0, Video.screenWidth, Video.screenHeight); - sprStore.loadFont('sFont'); - Video.color = 0xff_ff_00; - int hiColor = 0x00_ff_00; + int tx = 16; + int txoff = 0; // text x pos offset (for multi-color lines) + int ty = 8; + if (gameHelpScreen) { + sprStore.loadFont('sFontSmall'); + Video.color = 0xff_ff_ff; + drawTextAtS3Centered(ty, va("HELP (PAGE ~%d~ OF ~%d~)", gameHelpScreen, MaxGameHelpScreen), 0xff_ff_00); + ty += 24; + } + + if (gameHelpScreen == 1) { + sprStore.loadFont('sFontSmall'); + Video.color = 0xff_ff_00; drawTextAtS3(tx, ty, "INVENTORY BASICS"); ty += 16; + Video.color = 0xff_ff_ff; + drawTextAtS3(tx, ty, global.expandString("Press $SWITCH to cycle through items."), 0x00_ff_00); + ty += 8; + ty += 56; + Video.color = 0xff_ff_ff; + drawSpriteAtS3('sHelpSprite1', -1, 64, 96); + } else if (gameHelpScreen == 2) { + sprStore.loadFont('sFontSmall'); + Video.color = 0xff_ff_00; + drawTextAtS3(tx, ty, "SELLING TO SHOPKEEPERS"); ty += 16; + Video.color = 0xff_ff_ff; + drawTextAtS3(tx, ty, global.expandString("Press $PAY to offer your currently"), 0x00_ff_00); ty += 8; + drawTextAtS3(tx, ty, "held item to the shopkeeper."); ty += 16; + drawTextAtS3(tx, ty, "If the shopkeeper is interested, "); ty += 8; + //drawTextAtS3(tx, ty, global.expandString("press $PAY again to complete the sale."), 0x00_ff_00); ty += 72; + drawTextAtS3(tx, ty, global.expandString("press $PAY again to complete"), 0x00_ff_00); + drawTextAtS3(tx, ty+8, "the sale."); + ty += 72; + drawSpriteAtS3('sHelpSell', -1, 112, 100); + drawTextAtS3(tx, ty, "Purchasing goods from the shopkeeper"); ty += 8; + drawTextAtS3(tx, ty, "will increase the funds he has"); ty += 8; + drawTextAtS3(tx, ty, "available to buy your unwanted stuff."); ty += 8; + } else { + // map + sprStore.loadFont('sFont'); + Video.color = 0xff_ff_ff; + drawTextAtS3(136, 8, "MAP"); + + Video.color = 0xff_ff_00; + drawTextAtS3Centered(24, lg.mapTitle); + + if (lg.mapSprite) { + auto spf = sprStore[lg.mapSprite].frames[0]; + int mapX = 160-spf.width/2; + int mapY = 120-spf.height/2; + //mapTitleX = 160-string_length(global.mapTitle)*8/2; + + Video.color = 0xff_ff_ff; + drawSpriteAtS3(lg.mapSprite, -1, mapX, mapY); + + if (lg.mapSprite != 'sMapDefault') { + int mx = -1, my = -1; + + // set position of player icon + switch (global.currLevel) { + case 1: mx = 81; my = 22; break; + case 2: mx = 113; my = 63; break; + case 3: mx = 197; my = 86; break; + case 4: mx = 133; my = 109; break; + case 5: mx = 181; my = 22; break; + case 6: mx = 126; my = 64; break; + case 7: mx = 158; my = 112; break; + case 8: mx = 66; my = 80; break; + case 9: mx = 30; my = 26; break; + case 10: mx = 88; my = 54; break; + case 11: mx = 148; my = 81; break; + case 12: mx = 210; my = 205; break; + case 13: mx = 66; my = 17; break; + case 14: mx = 146; my = 17; break; + case 15: mx = 82; my = 77; break; + case 16: mx = 178; my = 81; break; + } - drawTextAt(256, 432, "PAUSED", scale); + if (mx >= 0) { + int plrx = mx+player.ix/16; + int plry = my+player.iy/16; + name plrspr = 'sMapSpelunker'; + if (global.isDamsel) plrspr = 'sMapDamsel'; + else if (global.isTunnelMan) plrspr = 'sMapTunnel'; + auto ss = sprStore[plrspr]; + drawSpriteAtS3(plrspr, (pausedTime/2)%ss.frames.length, mapX+plrx, mapY+plry); + // exit door icon + if (global.hasCompass && allExits.length) { + drawSpriteAtS3('sMapRedDot', -1, mapX+mx+allExits[0].ix/16, mapY+my+allExits[0].iy/16); + } + } + } + } + } sprStore.loadFont('sFontSmall'); + Video.color = 0xff_ff_00; + drawTextAtS3Centered(232, "PRESS ~SPACE~/~LEFT~/~RIGHT~ TO CHANGE PAGE", 0x00_ff_00); + + Video.color = 0xff_ff_ff; +} + + +void renderPauseOverlay () { + //drawTextAt(256, 432, "PAUSED", scale); + + if (gameShowHelp) { renderHelpOverlay(); return; } + + Video.color = 0xff_ff_00; + //int hiColor = 0x00_ff_00; int n = 120; if (isTutorialRoom()) { - drawTextAt(40, n-24, "TUTORIAL CAVE", scale); + sprStore.loadFont('sFont'); + drawTextAtS3(40, n-24, "TUTORIAL CAVE"); } else if (isNormalLevel()) { + sprStore.loadFont('sFont'); + drawTextAtS3Centered(n-32, va("LEVEL ~%d~", global.currLevel), 0x00_ff_00); + sprStore.loadFont('sFontSmall'); + int depth = round((174.8*(global.currLevel-1)+(player.iy+8)*0.34)*(global.config.scumMetric ? 0.3048 : 1.0)*10); string depthStr = va("DEPTH: ~%d.%d~ %s", depth/10, depth%10, (global.config.scumMetric ? "METRES" : "FEET")); drawTextAtS3Centered(n-16, depthStr, 0x00_ff_00); @@ -3511,6 +3647,7 @@ void renderPauseOverlay () { drawTextAtS3Centered(n+64, va("LEVEL TIME: ~%s~", time2str((time-levelStartTime)/30)), 0x00_ff_00); } + sprStore.loadFont('sFontSmall'); Video.color = 0xff_ff_ff; drawTextAtS3Centered(240-2-8, "~ESC~-RETURN ~F10~-QUIT ~CTRL+DEL~-SUICIDE", 0xff_7f_00); drawTextAtS3Centered(2, "~O~PTIONS REDEFINE ~K~EYS ~S~TATISTICS", 0xff_7f_00); diff --git a/packages/Generator/LevelGen.vc b/packages/Generator/LevelGen.vc index 130b4f9..1d115e1 100644 --- a/packages/Generator/LevelGen.vc +++ b/packages/Generator/LevelGen.vc @@ -54,6 +54,9 @@ name musicName; bool finalBossLevel; bool alwaysLit; +name mapSprite; +string mapTitle; + private RType[DefaultLevelWidth*DefaultLevelHeight] roomPoss; RType[DefaultLevelWidth*DefaultLevelHeight] roomPath; RPD[DefaultLevelWidth*DefaultLevelHeight] roomPathDisp; @@ -182,37 +185,37 @@ protected void preSetup () { global.levelType = 1; bgImgName = 'bgCave'; musicName = 'musLush'; - //global.mapSprite = sMapJungle; - //global.mapTitle = "The Jungle"; + mapSprite = 'sMapJungle'; + mapTitle = "The Jungle"; } else if (global.currLevel > 8 && global.currLevel < 13) { if (global.config.optIdolForEachLevelType && global.levelType != 2) global.idol = false; global.levelType = 2; bgImgName = 'bgCave'; musicName = 'musIce'; - //global.mapSprite = sMapIce; - //global.mapTitle = "The Ice Caves"; + mapSprite = 'sMapIce'; + mapTitle = "The Ice Caves"; } else if (global.currLevel > 12 && global.currLevel < 16) { if (global.config.optIdolForEachLevelType && global.levelType != 3) global.idol = false; global.levelType = 3; bgImgName = 'bgTemple'; musicName = 'musTemple'; - //global.mapSprite = sMapTemple; - //global.mapTitle = "The Temple"; + mapSprite = 'sMapTemple'; + mapTitle = "The Temple"; } else if (global.currLevel == 16) { //if (global.config.optIdolForEachLevelType && global.levelType != 4) global.idol = false; global.levelType = 4; bgImgName = 'bgTemple'; //!musicName = 'musBoss'; musicName = ''; // olmec will start it - //global.mapSprite = sMapTemple; - //global.mapTitle = "Olmec's Chamber"; + mapSprite = 'sMapTemple'; + mapTitle = "Olmec's Chamber"; if (global.config.bizarrePlus) global.cityOfGold = true; finalBossLevel = true; } else { if (global.config.optIdolForEachLevelType && global.levelType != 0) global.idol = false; global.levelType = 0; - //global.mapSprite = sMapMines; - //global.mapTitle = "The Mines"; + mapSprite = 'sMapMines'; + mapTitle = "The Mines"; } /*!??? diff --git a/spelunky_main.vc b/spelunky_main.vc index 33bbb1c..94ef68b 100644 --- a/spelunky_main.vc +++ b/spelunky_main.vc @@ -918,6 +918,8 @@ final void unpauseGame () { if (level.gamePaused) { if (doGameSavingPlaying != Replay.None) level.keysRestoreState(savedKeyState); level.gamePaused = false; + level.gameShowHelp = false; + level.gameHelpScreen = 0; //lastThinkerTime = 0; global.resumeAllSounds(); } @@ -941,8 +943,10 @@ final void beforeNewFrame (bool frameSkip) { if (level.isKeyDown(GameConfig::Key.Down)) level.viewStart.y += delta; } else { level.disablePlayerThink = false; + level.fixCamera(); } */ + level.fixCamera(); if (!level.gamePaused) { // save seeds for afterframe processing @@ -1636,8 +1640,9 @@ final void onEvent (ref event_t evt) { if (evt.type == ev_keyup && evt.keycode == K_ESCAPE) { unpauseGame(); return; } if (evt.type == ev_keydown) { + if (evt.keycode == K_SPACE && level && showHelp == 2 && level.gameShowHelp) evt.keycode = K_RIGHTARROW; switch (evt.keycode) { - //case K_F1: if (showHelp > 1) showHelp = 1; else unpauseGame(); return; + case K_F1: if (showHelp == 2 && level) level.gameShowHelp = !level.gameShowHelp; if (level.gameShowHelp) level.gameHelpScreen = 0; return; case K_F2: if (showHelp != 2) unpauseGame(); return; case K_F10: Video.requestQuit(); return; case K_F12: if (showHelp != 2) showHelp = 3-showHelp; return; @@ -1650,6 +1655,18 @@ final void onEvent (ref event_t evt) { if (drawStats) statsMoveDown(); return; + case K_LEFTARROW: case K_PAD4: + if (level && showHelp == 2 && level.gameShowHelp) { + if (level.gameHelpScreen) --level.gameHelpScreen; else level.gameHelpScreen = GameLevel::MaxGameHelpScreen; + } + return; + + case K_RIGHTARROW: case K_PAD6: + if (level && showHelp == 2 && level.gameShowHelp) { + level.gameHelpScreen = (level.gameHelpScreen+1)%(GameLevel::MaxGameHelpScreen+1); + } + return; + case K_F6: { // save level saveGame("level"); @@ -2129,7 +2146,7 @@ void performTimeCheck () { void setupCheats () { - return; + //return; global.currLevel = 2; startMode = StartMode.Alive; -- 2.11.4.GIT