@ -279,7 +279,7 @@ bool AiL::OnUserCreate(){
Inventory : : AddItem ( " Minor Health Potion " s , 3 ) ;
Inventory : : AddItem ( " Minor Health Potion " s , 3 ) ;
Inventory : : AddItem ( " Bandages " s , 10 ) ;
Inventory : : AddItem ( " Bandages " s , 10 ) ;
LoadLevel ( " starting_map " _S ) ;
LoadLevel ( " starting_map " _S , NO_MUSIC_CHANGE ) ;
ChangePlayerClass ( WARRIOR ) ;
ChangePlayerClass ( WARRIOR ) ;
GameState : : Initialize ( ) ;
GameState : : Initialize ( ) ;
@ -1821,14 +1821,22 @@ void AiL::InitializeLevel(std::string mapFile,MapName map){
}
}
}
}
void AiL : : LoadLevel ( MapName map ) {
void AiL : : LoadLevel ( MapName map , MusicChange changeMusic ) {
LoadingScreen : : loading = true ;
LoadingScreen : : loading = true ;
_PrepareLevel ( map , changeMusic ) ;
}
void AiL : : _PrepareLevel ( MapName map , MusicChange changeMusic ) {
LoadingScreen : : Reset ( ) ;
previousLevel = currentLevel ;
currentLevel = map ;
# pragma region Reset all data (Loading phase 1)
# pragma region Reset all data (Loading phase 1)
if ( game - > MAP_DATA . count ( map ) = = 0 ) ERR ( std : : format ( " WARNING! Could not load map {}! Does not exist! Refer to levels.txt for valid maps. " , map ) ) ;
LoadingScreen : : AddPhase ( [ & ] ( ) {
if ( game - > MAP_DATA [ map ] . GetMapType ( ) = = " Hub " & & GameState : : STATE ! = GameState : : states [ States : : GAME_HUB ] ) ERR ( " WARNING! A hub level should only be initiated in the GAME_HUB game state! " ) ;
if ( game - > MAP_DATA . count ( GetCurrentLevel ( ) ) = = 0 ) ERR ( std : : format ( " WARNING! Could not load map {}! Does not exist! Refer to levels.txt for valid maps. " , map ) ) ;
if ( game - > MAP_DATA [ GetCurrentLevel ( ) ] . GetMapType ( ) = = " Hub " & & GameState : : STATE ! = GameState : : states [ States : : GAME_HUB ] ) ERR ( " WARNING! A hub level should only be initiated in the GAME_HUB game state! " ) ;
# pragma region Reset Environmental Audio
# pragma region Reset Environmental Audio
for ( EnvironmentalAudio & audio : MAP_DATA [ GetCurrentLevel ( ) ] . environmentalAudioData ) {
for ( EnvironmentalAudio & audio : MAP_DATA [ previousLevel ] . environmentalAudioData ) {
audio . Deactivate ( ) ;
audio . Deactivate ( ) ;
}
}
# pragma endregion
# pragma endregion
@ -1842,7 +1850,6 @@ void AiL::LoadLevel(MapName map){
GameEvent : : events . clear ( ) ;
GameEvent : : events . clear ( ) ;
worldColor = WHITE ;
worldColor = WHITE ;
worldColorFunc = [ & ] ( vi2d pos ) { return game - > worldColor ; } ;
worldColorFunc = [ & ] ( vi2d pos ) { return game - > worldColor ; } ;
currentLevel = map ;
levelTime = 0 ;
levelTime = 0 ;
bossName = " " ;
bossName = " " ;
encounterDuration = 0 ;
encounterDuration = 0 ;
@ -1858,13 +1865,15 @@ void AiL::LoadLevel(MapName map){
GetPlayer ( ) - > GetCastInfo ( ) = { } ;
GetPlayer ( ) - > GetCastInfo ( ) = { } ;
GetPlayer ( ) - > ResetAccumulatedXP ( ) ;
GetPlayer ( ) - > ResetAccumulatedXP ( ) ;
# pragma endregion
ZONE_LIST = game - > MAP_DATA [ game - > GetCurrentLevel ( ) ] . ZoneData ;
ZONE_LIST = game - > MAP_DATA [ game - > GetCurrentLevel ( ) ] . ZoneData ;
return true ;
} ) ;
# pragma endregion
# pragma region Monster Spawn Data Setup (Loading phase 2)
# pragma region Monster Spawn Data Setup (Loading phase 2)
for ( auto & [ key , value ] : MAP_DATA [ map ] . SpawnerData ) {
LoadingScreen : : AddPhase ( [ & ] ( ) {
SpawnerTag & spawnData = MAP_DATA [ map ] . SpawnerData [ key ] ;
for ( auto & [ key , value ] : MAP_DATA [ GetCurrentLevel ( ) ] . SpawnerData ) {
SpawnerTag & spawnData = MAP_DATA [ GetCurrentLevel ( ) ] . SpawnerData [ key ] ;
std : : vector < std : : pair < std : : string , vf2d > > monster_list ;
std : : vector < std : : pair < std : : string , vf2d > > monster_list ;
vf2d spawnerRadius = vf2d { spawnData . ObjectData . GetFloat ( " width " ) , spawnData . ObjectData . GetFloat ( " height " ) } / 2 ;
vf2d spawnerRadius = vf2d { spawnData . ObjectData . GetFloat ( " width " ) , spawnData . ObjectData . GetFloat ( " height " ) } / 2 ;
@ -1874,11 +1883,14 @@ void AiL::LoadLevel(MapName map){
}
}
SPAWNER_LIST . push_back ( MonsterSpawner { { spawnData . ObjectData . GetFloat ( " x " ) , spawnData . ObjectData . GetFloat ( " y " ) } , spawnerRadius * 2 , monster_list , spawnData . upperLevel , spawnData . bossNameDisplay } ) ;
SPAWNER_LIST . push_back ( MonsterSpawner { { spawnData . ObjectData . GetFloat ( " x " ) , spawnData . ObjectData . GetFloat ( " y " ) } , spawnerRadius * 2 , monster_list , spawnData . upperLevel , spawnData . bossNameDisplay } ) ;
}
}
return true ;
} ) ;
# pragma endregion
# pragma endregion
# pragma region Identify Upper Foreground Tiles (Loading phase 3)
# pragma region Identify Upper Foreground Tiles (Loading phase 3)
LoadingScreen : : AddPhase ( [ & ] ( ) {
auto GetUpperZones = [ & ] ( ) {
auto GetUpperZones = [ & ] ( ) {
for ( auto & zoneSet : MAP_DATA [ map ] . ZoneData ) {
for ( auto & zoneSet : MAP_DATA [ GetCurrentLevel ( ) ] . ZoneData ) {
if ( zoneSet . first = = " UpperZone " ) { //We are interested in all upper zones.
if ( zoneSet . first = = " UpperZone " ) { //We are interested in all upper zones.
return zoneSet . second ;
return zoneSet . second ;
}
}
@ -1892,7 +1904,7 @@ void AiL::LoadLevel(MapName map){
int zoneH = zone . zone . bottom ( ) . start . y / game - > GetCurrentMapData ( ) . tilewidth - zoneY ;
int zoneH = zone . zone . bottom ( ) . start . y / game - > GetCurrentMapData ( ) . tilewidth - zoneY ;
for ( int x = zoneX ; x < zoneX + zoneW ; x + + ) {
for ( int x = zoneX ; x < zoneX + zoneW ; x + + ) {
for ( int y = zoneY ; y < zoneY + zoneH ; y + + ) {
for ( int y = zoneY ; y < zoneY + zoneH ; y + + ) {
for ( LayerTag & layer : MAP_DATA [ map ] . LayerData ) {
for ( LayerTag & layer : MAP_DATA [ GetCurrentLevel ( ) ] . LayerData ) {
int tile = layer . tiles [ y ] [ x ] - 1 ;
int tile = layer . tiles [ y ] [ x ] - 1 ;
TilesheetData tileSheet = GetTileSheet ( currentLevel , tile ) ;
TilesheetData tileSheet = GetTileSheet ( currentLevel , tile ) ;
int tileSheetIndex = tile - ( tileSheet . firstgid - 1 ) ;
int tileSheetIndex = tile - ( tileSheet . firstgid - 1 ) ;
@ -1903,9 +1915,12 @@ void AiL::LoadLevel(MapName map){
}
}
}
}
}
}
return true ;
} ) ;
# pragma endregion
# pragma endregion
# pragma region Foreground and Upper Foreground Tile Fade Group Setup (Loading phase 4)
# pragma region Foreground and Upper Foreground Tile Fade Group Setup (Loading phase 4)
LoadingScreen : : AddPhase ( [ & ] ( ) {
std : : set < vi2d > foregroundTilesAdded , upperForegroundTilesAdded ;
std : : set < vi2d > foregroundTilesAdded , upperForegroundTilesAdded ;
for ( int x = 0 ; x < GetCurrentMapData ( ) . width ; x + + ) {
for ( int x = 0 ; x < GetCurrentMapData ( ) . width ; x + + ) {
for ( int y = 0 ; y < GetCurrentMapData ( ) . height ; y + + ) {
for ( int y = 0 ; y < GetCurrentMapData ( ) . height ; y + + ) {
@ -1993,9 +2008,12 @@ void AiL::LoadLevel(MapName map){
for ( TileGroup & group : upperForegroundTileGroups ) {
for ( TileGroup & group : upperForegroundTileGroups ) {
std : : sort ( group . GetTiles ( ) . begin ( ) , group . GetTiles ( ) . end ( ) , [ ] ( TileRenderData & t1 , TileRenderData & t2 ) { return t1 . layerID < t2 . layerID ; } ) ;
std : : sort ( group . GetTiles ( ) . begin ( ) , group . GetTiles ( ) . end ( ) , [ ] ( TileRenderData & t1 , TileRenderData & t2 ) { return t1 . layerID < t2 . layerID ; } ) ;
}
}
return true ;
} ) ;
# pragma endregion
# pragma endregion
# pragma region Foreground and Upper Foreground Tile Fade Group Individual Object Grouping Splitting (Loading phase 5)
# pragma region Foreground and Upper Foreground Tile Fade Group Individual Object Grouping Splitting (Loading phase 5)
LoadingScreen : : AddPhase ( [ & ] ( ) {
auto SplitUp = [ & ] ( std : : vector < TileGroup > & group ) {
auto SplitUp = [ & ] ( std : : vector < TileGroup > & group ) {
std : : multimap < vi2d , TileRenderData > data ;
std : : multimap < vi2d , TileRenderData > data ;
using TileDataGroup = std : : multimap < vi2d , TileRenderData > ; //See below.
using TileDataGroup = std : : multimap < vi2d , TileRenderData > ; //See below.
@ -2060,19 +2078,25 @@ void AiL::LoadLevel(MapName map){
} ;
} ;
SplitUp ( foregroundTileGroups ) ;
SplitUp ( foregroundTileGroups ) ;
SplitUp ( upperForegroundTileGroups ) ;
SplitUp ( upperForegroundTileGroups ) ;
return true ;
} ) ;
# pragma endregion
# pragma endregion
# pragma region Bridge Layer Setup (Loading Phase 6)
# pragma region Bridge Layer Setup (Loading Phase 6)
LoadingScreen : : AddPhase ( [ & ] ( ) {
bridgeLayerIndex = - 1 ;
bridgeLayerIndex = - 1 ;
for ( int counter = 0 ; LayerTag & layer : MAP_DATA [ map ] . LayerData ) {
for ( int counter = 0 ; LayerTag & layer : MAP_DATA [ GetCurrentLevel ( ) ] . LayerData ) {
if ( IsBridgeLayer ( layer ) ) {
if ( IsBridgeLayer ( layer ) ) {
bridgeLayerIndex = counter ;
bridgeLayerIndex = counter ;
}
}
counter + + ;
counter + + ;
}
}
return true ;
} ) ;
# pragma endregion
# pragma endregion
# pragma region Setup NPCs (Loading Phase 7)
# pragma region Setup NPCs (Loading Phase 7)
LoadingScreen : : AddPhase ( [ & ] ( ) {
for ( NPCData data : game - > MAP_DATA [ game - > GetCurrentLevel ( ) ] . npcs ) {
for ( NPCData data : game - > MAP_DATA [ game - > GetCurrentLevel ( ) ] . npcs ) {
if ( Unlock : : IsUnlocked ( data . unlockCondition ) ) {
if ( Unlock : : IsUnlocked ( data . unlockCondition ) ) {
MONSTER_LIST . push_back ( Monster { data . spawnPos , MONSTER_DATA [ data . name ] } ) ;
MONSTER_LIST . push_back ( Monster { data . spawnPos , MONSTER_DATA [ data . name ] } ) ;
@ -2080,9 +2104,12 @@ void AiL::LoadLevel(MapName map){
MONSTER_LIST . back ( ) . npcData = data ;
MONSTER_LIST . back ( ) . npcData = data ;
}
}
}
}
return true ;
} ) ;
# pragma endregion
# pragma endregion
# pragma region Setup Player and Camera (Loading Phase 8)
# pragma region Setup Player and Camera (Loading Phase 8)
LoadingScreen : : AddPhase ( [ & ] ( ) {
player - > GetAbility1 ( ) . cooldown = 0.f ;
player - > GetAbility1 ( ) . cooldown = 0.f ;
player - > GetAbility2 ( ) . cooldown = 0.f ;
player - > GetAbility2 ( ) . cooldown = 0.f ;
player - > GetAbility3 ( ) . cooldown = 0.f ;
player - > GetAbility3 ( ) . cooldown = 0.f ;
@ -2093,23 +2120,54 @@ void AiL::LoadLevel(MapName map){
player - > useItem3 . cooldown = 0.f ;
player - > useItem3 . cooldown = 0.f ;
player - > upperLevel = false ; //Assume player starts on lower level.
player - > upperLevel = false ; //Assume player starts on lower level.
player - > ForceSetPos ( MAP_DATA [ map ] . MapData . playerSpawnLocation ) ; //Normal set pos does one axis and then the other, so this will make sure that we actually end up at the right spot and ignore collision rules.
player - > ForceSetPos ( MAP_DATA [ GetCurrentLevel ( ) ] . MapData . playerSpawnLocation ) ; //Normal set pos does one axis and then the other, so this will make sure that we actually end up at the right spot and ignore collision rules.
vf2d cameraStartPos = player - > GetPos ( ) + vf2d ( - 24 * 6 , 0 ) ;
vf2d cameraStartPos = player - > GetPos ( ) + vf2d ( - 24 * 6 , 0 ) ;
camera . MoveCamera ( cameraStartPos ) ;
camera . MoveCamera ( cameraStartPos ) ;
return true ;
} ) ;
# pragma endregion
# pragma endregion
# pragma region Setup Pathfinding (Loading Phase 9)
# pragma region Setup Pathfinding (Loading Phase 9)
LoadingScreen : : AddPhase ( [ & ] ( ) {
pathfinder . Initialize ( ) ;
pathfinder . Initialize ( ) ;
return true ;
} ) ;
# pragma endregion
# pragma endregion
if ( changeMusic = = PLAY_LEVEL_MUSIC ) {
# pragma region Audio Preparation (Loading Phase 10)
LoadingScreen : : AddPhase ( [ & ] ( ) {
Audio : : SetAudioEvent ( " Default Volume " ) ;
Audio : : SetAudioEvent ( " Default Volume " ) ;
game - > audioEngine . fullyLoaded = true ; //We assume there's no audio to load, so we just set the audio as fully loaded by default.
game - > audioEngine . fullyLoaded = true ; //We assume there's no audio to load, so we just set the audio as fully loaded by default.
if ( MAP_DATA [ map ] . bgmSongName . length ( ) > 0 ) {
if ( MAP_DATA [ GetCurrentLevel ( ) ] . bgmSongName . length ( ) > 0 ) {
Audio : : Play BGM ( MAP_DATA [ map ] . bgmSongName ) ;
Audio : : Prepare BGM ( MAP_DATA [ GetCurrentLevel ( ) ] . bgmSongName ) ;
DisableFadeIn ( true ) ;
DisableFadeIn ( true ) ;
}
}
LoadingScreen : : loading = false ;
return true ;
} ) ;
# pragma endregion
//Until the audio has stopped (by waiting for a set amount of time), we will respect the audio engine's wishes and not proceed.
LoadingScreen : : DeferLoad ( [ & ] ( ) { return audioEngine . playBGMWaitTime = = 0.f ; } ) ; //This is the wait time for the audio engine to finish.
# pragma region Audio Channel Loading (Count based on Audio::GetPrepareBGMLoopIterations)
for ( int i = 0 ; i < Audio : : GetPrepareBGMLoopIterations ( MAP_DATA [ GetCurrentLevel ( ) ] . bgmSongName ) ; i + + ) {
LoadingScreen : : AddPhase ( [ & ] ( ) {
Audio : : UpdateLoop ( ) ;
return true ;
} ) ;
}
# pragma endregion
LoadingScreen : : AddPhase ( [ & ] ( ) {
Audio : : BGM & track = audioEngine . bgm [ audioEngine . GetTrackName ( ) ] ;
for ( int trackID : track . GetChannelIDs ( ) ) {
audioEngine . Engine ( ) . Play ( trackID , true ) ;
}
return true ;
} ) ;
}
}
}
bool AiL : : IsUpperForegroundTile ( int tileID ) {
bool AiL : : IsUpperForegroundTile ( int tileID ) {
@ -3113,7 +3171,7 @@ void AiL::RenderFadeout(){
}
}
bool AiL : : GamePaused ( ) {
bool AiL : : GamePaused ( ) {
return fadeOutDuration > 0 | | disableFadeIn | | paused ;
return fadeOutDuration > 0 | | disableFadeIn | | paused | | LoadingScreen : : loading ;
}
}
void AiL : : PauseGame ( ) {
void AiL : : PauseGame ( ) {
@ -3351,9 +3409,9 @@ const bool AiL::GameInitialized()const {
rcode AiL : : LoadResource ( Renderable & renderable , std : : string_view imgPath , bool filter , bool clamp ) {
rcode AiL : : LoadResource ( Renderable & renderable , std : : string_view imgPath , bool filter , bool clamp ) {
rcode returnCode ;
rcode returnCode ;
if ( gamepack . Loaded ( ) ) {
if ( gamepack . Loaded ( ) ) {
returnCode = renderable . Load ( std : : string ( imgPath ) , & gamepack ) ;
returnCode = renderable . Load ( std : : string ( imgPath ) , & gamepack , filter , clamp ) ;
} else {
} else {
returnCode = renderable . Load ( std : : string ( imgPath ) ) ;
returnCode = renderable . Load ( std : : string ( imgPath ) , nullptr , filter , clamp ) ;
if ( " GENERATE_GAMEPACK " _B ) {
if ( " GENERATE_GAMEPACK " _B ) {
gamepack . AddFile ( std : : string ( imgPath ) ) ;
gamepack . AddFile ( std : : string ( imgPath ) ) ;
}
}