diff --git a/Source/diablo.cpp b/Source/diablo.cpp index e50b62433bd..d8974ce86fc 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -2843,293 +2843,412 @@ void DisableInputEventHandler(const SDL_Event &event, uint16_t modState) MainWndProc(event); } -void LoadGameLevel(bool firstflag, lvl_entry lvldir) +void LoadGameLevelStopMusic(_music_id neededTrack) { - _music_id neededTrack = GetLevelMusic(leveltype); - ClearFloatingNumbers(); - if (neededTrack != sgnMusicTrack) music_stop(); +} + +void LoadGameLevelStartMusic(_music_id neededTrack) +{ + if (sgnMusicTrack != neededTrack) + music_start(neededTrack); + + if (MinimizePaused) { + music_mute(); + } +} + +void LoadGameLevelResetCursor() +{ if (pcurs > CURSOR_HAND && pcurs < CURSOR_FIRSTITEM) { NewCursor(CURSOR_HAND); } - SetRndSeed(DungeonSeeds[currlevel]); - IncProgress(); - LoadTrns(); - MakeLightTable(); - LoadLevelSOLData(); - IncProgress(); - LoadLvlGFX(); - SetDungeonMicros(); - ClearClxDrawCache(); - IncProgress(); +} - if (firstflag) { - CloseInventory(); - qtextflag = false; - if (!HeadlessMode) { - InitInv(); - InitQuestText(); - InitInfoBoxGfx(); - InitHelp(); - } - InitStores(); - InitAutomapOnce(); - } - if (!setlevel) { - SetRndSeed(DungeonSeeds[currlevel]); - } else { +void SetRndSeedForDungeonLevel() +{ + if (setlevel) { // Maps are not randomly generated, but the monsters max hitpoints are. // So we need to ensure that we have a stable seed when generating quest/set-maps. // For this purpose we reuse the normal dungeon seeds. SetRndSeed(DungeonSeeds[static_cast(setlvlnum)]); + } else { + SetRndSeed(DungeonSeeds[currlevel]); } +} +void LoadGameLevelFirstFlagEntry() +{ + CloseInventory(); + qtextflag = false; + if (!HeadlessMode) { + InitInv(); + InitQuestText(); + InitInfoBoxGfx(); + InitHelp(); + } + InitStores(); + InitAutomapOnce(); +} + +void LoadGameLevelStores() +{ if (leveltype == DTYPE_TOWN) { SetupTownStores(); } else { FreeStoreMem(); } +} - if (firstflag || lvldir == ENTRY_LOAD) { - bool isHellfireSaveGame = gbIsHellfireSaveGame; - gbIsHellfireSaveGame = gbIsHellfire; - LoadStash(); - gbIsHellfireSaveGame = isHellfireSaveGame; - } +void LoadGameLevelStash() +{ + bool isHellfireSaveGame = gbIsHellfireSaveGame; - IncProgress(); - InitAutomap(); + gbIsHellfireSaveGame = gbIsHellfire; + LoadStash(); + gbIsHellfireSaveGame = isHellfireSaveGame; +} - if (leveltype != DTYPE_TOWN && lvldir != ENTRY_LOAD) { - InitLighting(); - } +void LoadGameLevelDungeon(bool firstflag, lvl_entry lvldir, const Player &myPlayer) +{ + if (firstflag || lvldir == ENTRY_LOAD || !myPlayer._pLvlVisited[currlevel] || gbIsMultiplayer) { + HoldThemeRooms(); + [[maybe_unused]] uint32_t mid1Seed = GetLCGEngineState(); + InitGolems(); + InitObjects(); + [[maybe_unused]] uint32_t mid2Seed = GetLCGEngineState(); - InitLevelMonsters(); - IncProgress(); + IncProgress(); - Player &myPlayer = *MyPlayer; + InitMonsters(); + InitItems(); + CreateThemeRooms(); - if (!setlevel) { - CreateLevel(lvldir); IncProgress(); - SetRndSeed(DungeonSeeds[currlevel]); - if (leveltype != DTYPE_TOWN) { - GetLevelMTypes(); - InitThemes(); - if (!HeadlessMode) - LoadAllGFX(); - } else if (!HeadlessMode) { - IncProgress(); -#if !defined(USE_SDL1) && !defined(__vita__) - InitVirtualGamepadGFX(renderer); + [[maybe_unused]] uint32_t mid3Seed = GetLCGEngineState(); + InitMissiles(); + InitCorpses(); +#ifdef _DEBUG + SetDebugLevelSeedInfos(mid1Seed, mid2Seed, mid3Seed, GetLCGEngineState()); #endif - IncProgress(); - InitMissileGFX(gbIsHellfire); - IncProgress(); - IncProgress(); - } + SavePreLighting(); IncProgress(); - if (lvldir == ENTRY_RTNLVL) { - ViewPosition = GetMapReturnPosition(); - if (Quests[Q_BETRAYER]._qactive == QUEST_DONE) - Quests[Q_BETRAYER]._qvar2 = 2; - } - if (lvldir == ENTRY_WARPLVL) - GetPortalLvlPos(); + if (gbIsMultiplayer) + DeltaLoadLevel(); + } else { + HoldThemeRooms(); + InitGolems(); + InitMonsters(); + InitMissiles(); + InitCorpses(); IncProgress(); - for (Player &player : Players) { - if (player.plractive && player.isOnActiveLevel()) { - InitPlayerGFX(player); + LoadLevel(); + + IncProgress(); + } +} + +void LoadGameLevelSyncPlayerEntry(lvl_entry lvldir) +{ + for (Player &player : Players) { + if (player.plractive && player.isOnActiveLevel() && (!player._pLvlChanging || &player == MyPlayer)) { + if (player._pHitPoints > 0) { if (lvldir != ENTRY_LOAD) - InitPlayer(player, firstflag); + SyncInitPlrPos(player); + } else { + dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer; } } + } +} - PlayDungMsgs(); - InitMultiView(); - IncProgress(); +void LoadGameLevelLightVision() +{ + if (leveltype != DTYPE_TOWN) { + memcpy(dLight, dPreLight, sizeof(dLight)); // resets the light on entering a level to get rid of incorrect light + ChangeLightXY(Players[MyPlayerId].lightId, Players[MyPlayerId].position.tile); // forces player light refresh + ProcessLightList(); + ProcessVisionList(); + } +} + +void LoadGameLevelReturn() +{ + ViewPosition = GetMapReturnPosition(); + if (Quests[Q_BETRAYER]._qactive == QUEST_DONE) + Quests[Q_BETRAYER]._qvar2 = 2; +} - bool visited = false; - for (const Player &player : Players) { - if (player.plractive) - visited = visited || player._pLvlVisited[currlevel]; +void LoadGameLevelInitPlayers(bool firstflag, lvl_entry lvldir) +{ + for (Player &player : Players) { + if (player.plractive && player.isOnActiveLevel()) { + InitPlayerGFX(player); + if (lvldir != ENTRY_LOAD) + InitPlayer(player, firstflag); } + } +} - SetRndSeed(DungeonSeeds[currlevel]); +void LoadGameLevelSetVisited() +{ + bool visited = false; + for (const Player &player : Players) { + if (player.plractive) + visited = visited || player._pLvlVisited[currlevel]; + } +} - if (leveltype != DTYPE_TOWN) { - if (firstflag || lvldir == ENTRY_LOAD || !myPlayer._pLvlVisited[currlevel] || gbIsMultiplayer) { - HoldThemeRooms(); - [[maybe_unused]] uint32_t mid1Seed = GetLCGEngineState(); - InitGolems(); - InitObjects(); - [[maybe_unused]] uint32_t mid2Seed = GetLCGEngineState(); - IncProgress(); - InitMonsters(); - InitItems(); - CreateThemeRooms(); - IncProgress(); - [[maybe_unused]] uint32_t mid3Seed = GetLCGEngineState(); - InitMissiles(); - InitCorpses(); -#ifdef _DEBUG - SetDebugLevelSeedInfos(mid1Seed, mid2Seed, mid3Seed, GetLCGEngineState()); -#endif - SavePreLighting(); - IncProgress(); +void LoadGameLevelTown(bool firstflag, lvl_entry lvldir, const Player &myPlayer) +{ + for (int i = 0; i < MAXDUNX; i++) { // NOLINT(modernize-loop-convert) + for (int j = 0; j < MAXDUNY; j++) { + dFlags[i][j] |= DungeonFlag::Lit; + } + } - if (gbIsMultiplayer) - DeltaLoadLevel(); - } else { - HoldThemeRooms(); - InitGolems(); - InitMonsters(); - InitMissiles(); - InitCorpses(); - IncProgress(); - LoadLevel(); - IncProgress(); - } - } else { - for (int i = 0; i < MAXDUNX; i++) { // NOLINT(modernize-loop-convert) - for (int j = 0; j < MAXDUNY; j++) { - dFlags[i][j] |= DungeonFlag::Lit; - } - } + InitTowners(); + InitStash(); + InitItems(); + InitMissiles(); - InitTowners(); - InitStash(); - InitItems(); - InitMissiles(); - IncProgress(); + IncProgress(); - if (!firstflag && lvldir != ENTRY_LOAD && myPlayer._pLvlVisited[currlevel] && !gbIsMultiplayer) - LoadLevel(); - if (gbIsMultiplayer) - DeltaLoadLevel(); + if (!firstflag && lvldir != ENTRY_LOAD && myPlayer._pLvlVisited[currlevel] && !gbIsMultiplayer) + LoadLevel(); + if (gbIsMultiplayer) + DeltaLoadLevel(); + + IncProgress(); + + for (int x = 0; x < DMAXX; x++) + for (int y = 0; y < DMAXY; y++) + UpdateAutomapExplorer({ x, y }, MAP_EXP_SELF); +} + +void LoadGameLevelSetLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer) +{ + LoadSetMap(); + IncProgress(); + GetLevelMTypes(); + IncProgress(); + InitGolems(); + InitMonsters(); + IncProgress(); + if (!HeadlessMode) { +#if !defined(USE_SDL1) && !defined(__vita__) + InitVirtualGamepadGFX(renderer); +#endif + InitMissileGFX(gbIsHellfire); + IncProgress(); + } + InitCorpses(); + IncProgress(); + + if (lvldir == ENTRY_WARPLVL) + GetPortalLvlPos(); + IncProgress(); - IncProgress(); - for (int x = 0; x < DMAXX; x++) - for (int y = 0; y < DMAXY; y++) - UpdateAutomapExplorer({ x, y }, MAP_EXP_SELF); + for (Player &player : Players) { + if (player.plractive && player.isOnActiveLevel()) { + InitPlayerGFX(player); + if (lvldir != ENTRY_LOAD) + InitPlayer(player, firstflag); } - if (UseMultiplayerQuests()) - ResyncMPQuests(); - else - ResyncQuests(); + } + IncProgress(); + InitMultiView(); + IncProgress(); + + if (firstflag || lvldir == ENTRY_LOAD || !myPlayer._pSLvlVisited[setlvlnum] || gbIsMultiplayer) { + InitItems(); + SavePreLighting(); } else { - LoadSetMap(); - IncProgress(); + LoadLevel(); + } + if (gbIsMultiplayer) { + DeltaLoadLevel(); + if (!UseMultiplayerQuests()) + ResyncQuests(); + } + + PlayDungMsgs(); + InitMissiles(); + IncProgress(); +} + +void LoadGameLevelStandardLevel(bool firstflag, lvl_entry lvldir, const Player &myPlayer) +{ + CreateLevel(lvldir); + + IncProgress(); + + SetRndSeedForDungeonLevel(); + + if (leveltype != DTYPE_TOWN) { GetLevelMTypes(); + InitThemes(); + if (!HeadlessMode) + LoadAllGFX(); + } else if (!HeadlessMode) { IncProgress(); - InitGolems(); - InitMonsters(); - IncProgress(); - if (!HeadlessMode) { + #if !defined(USE_SDL1) && !defined(__vita__) - InitVirtualGamepadGFX(renderer); + InitVirtualGamepadGFX(renderer); #endif - InitMissileGFX(gbIsHellfire); - IncProgress(); - } - InitCorpses(); - IncProgress(); - if (lvldir == ENTRY_WARPLVL) - GetPortalLvlPos(); IncProgress(); - for (Player &player : Players) { - if (player.plractive && player.isOnActiveLevel()) { - InitPlayerGFX(player); - if (lvldir != ENTRY_LOAD) - InitPlayer(player, firstflag); - } - } + InitMissileGFX(gbIsHellfire); + IncProgress(); - PlayDungMsgs(); - InitMultiView(); IncProgress(); + } - if (firstflag || lvldir == ENTRY_LOAD || !myPlayer._pSLvlVisited[setlvlnum] || gbIsMultiplayer) { - InitItems(); - SavePreLighting(); - } else { - LoadLevel(); - } - if (gbIsMultiplayer) { - DeltaLoadLevel(); - if (!UseMultiplayerQuests()) - ResyncQuests(); - } + IncProgress(); - InitMissiles(); - IncProgress(); + if (lvldir == ENTRY_RTNLVL) { + LoadGameLevelReturn(); } - SyncPortals(); + if (lvldir == ENTRY_WARPLVL) + GetPortalLvlPos(); - for (Player &player : Players) { - if (player.plractive && player.isOnActiveLevel() && (!player._pLvlChanging || &player == MyPlayer)) { - if (player._pHitPoints > 0) { - if (lvldir != ENTRY_LOAD) - SyncInitPlrPos(player); - } else { - dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer; - } - } + IncProgress(); + + LoadGameLevelInitPlayers(firstflag, lvldir); + InitMultiView(); + + IncProgress(); + + LoadGameLevelSetVisited(); + + SetRndSeedForDungeonLevel(); + + if (leveltype == DTYPE_TOWN) { + LoadGameLevelTown(firstflag, lvldir, myPlayer); + } else { + LoadGameLevelDungeon(firstflag, lvldir, myPlayer); + } + + PlayDungMsgs(); + + if (UseMultiplayerQuests()) + ResyncMPQuests(); + else + ResyncQuests(); +} + +void LoadGameLevelCrypt() +{ + if (CornerStone.isAvailable()) { + CornerstoneLoad(CornerStone.position); + } + if (Quests[Q_NAKRUL]._qactive == QUEST_DONE && currlevel == 24) { + SyncNakrulRoom(); + } +} + +void LoadGameLevelCalculateCursor() +{ + // Recalculate mouse selection of entities after level change/load + LastMouseButtonAction = MouseActionType::None; + sgbMouseDown = CLICK_NONE; + ResetItemlabelHighlighted(); // level changed => item changed + pcursmonst = -1; // ensure pcurstemp is set to a valid value + CheckCursMove(); +} + +void LoadGameLevel(bool firstflag, lvl_entry lvldir) +{ + _music_id neededTrack = GetLevelMusic(leveltype); + + ClearFloatingNumbers(); + LoadGameLevelStopMusic(neededTrack); + LoadGameLevelResetCursor(); + SetRndSeedForDungeonLevel(); + + IncProgress(); + + LoadTrns(); + MakeLightTable(); + LoadLevelSOLData(); + + IncProgress(); + + LoadLvlGFX(); + SetDungeonMicros(); + ClearClxDrawCache(); + + IncProgress(); + + if (firstflag) { + LoadGameLevelFirstFlagEntry(); + } + + SetRndSeedForDungeonLevel(); + + LoadGameLevelStores(); + + if (firstflag || lvldir == ENTRY_LOAD) { + LoadGameLevelStash(); + } + + IncProgress(); + + InitAutomap(); + + if (leveltype != DTYPE_TOWN && lvldir != ENTRY_LOAD) { + InitLighting(); + } + + InitLevelMonsters(); + + IncProgress(); + + Player &myPlayer = *MyPlayer; + + if (setlevel) { + LoadGameLevelSetLevel(firstflag, lvldir, myPlayer); + } else { + LoadGameLevelStandardLevel(firstflag, lvldir, myPlayer); } + SyncPortals(); + LoadGameLevelSyncPlayerEntry(lvldir); + IncProgress(); IncProgress(); if (firstflag) { InitMainPanel(); } + IncProgress(); + UpdateMonsterLights(); UnstuckChargers(); - if (leveltype != DTYPE_TOWN) { - memcpy(dLight, dPreLight, sizeof(dLight)); // resets the light on entering a level to get rid of incorrect light - ChangeLightXY(Players[MyPlayerId].lightId, Players[MyPlayerId].position.tile); // forces player light refresh - ProcessLightList(); - ProcessVisionList(); - } + + LoadGameLevelLightVision(); if (leveltype == DTYPE_CRYPT) { - if (CornerStone.isAvailable()) { - CornerstoneLoad(CornerStone.position); - } - if (Quests[Q_NAKRUL]._qactive == QUEST_DONE && currlevel == 24) { - SyncNakrulRoom(); - } + LoadGameLevelCrypt(); } #ifndef USE_SDL1 ActivateVirtualGamepad(); #endif - - if (sgnMusicTrack != neededTrack) - music_start(neededTrack); - - if (MinimizePaused) { - music_mute(); - } + LoadGameLevelStartMusic(neededTrack); CompleteProgress(); - // Recalculate mouse selection of entities after level change/load - LastMouseButtonAction = MouseActionType::None; - sgbMouseDown = CLICK_NONE; - ResetItemlabelHighlighted(); // level changed => item changed - pcursmonst = -1; // ensure pcurstemp is set to a valid value - CheckCursMove(); + LoadGameLevelCalculateCursor(); } bool game_loop(bool bStartup)