diff --git a/Adventures in Lestoria/Adventures in Lestoria.tiled-project b/Adventures in Lestoria/Adventures in Lestoria.tiled-project index 698ed73e..830b418d 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.tiled-project +++ b/Adventures in Lestoria/Adventures in Lestoria.tiled-project @@ -15,7 +15,7 @@ "type": "enum", "values": [ "None", - "foresty_1_1" + "foresty1_1" ], "valuesAsFlags": false }, diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 14bb6c8c..94680b59 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -229,6 +229,8 @@ bool AiL::OnUserCreate(){ Inventory::AddItem("Shell Sword"); Inventory::AddItem("Ring of the Slime King",3); + Audio::Initialize(); + LoadLevel(LEVEL_NAMES["starting_map"_S]); ChangePlayerClass(WARRIOR); @@ -243,8 +245,6 @@ bool AiL::OnUserCreate(){ Stats::InitializeDamageReductionTable(); - Audio::Initialize(); - utils::datafile::INITIAL_SETUP_COMPLETE=true; ValidateGameStatus(); //Checks to make sure everything has been initialized properly. @@ -851,13 +851,15 @@ void AiL::RenderWorld(float fElapsedTime){ if(!IsForegroundTile(tileSheet,tileSheetIndex)&&!IsUpperForegroundTile(tileSheetIndex)&&!IsReflectiveTile(tileSheet,tileSheetIndex)){ if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});} RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY}); - if("debug_collision_boxes"_I){ - if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; - view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128}); - view.DrawRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,GREY); + #ifdef _DEBUG + if("debug_collision_boxes"_I){ + if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){ + geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; + view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128}); + view.DrawRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,GREY); + } } - } + #endif } } } @@ -877,13 +879,15 @@ void AiL::RenderWorld(float fElapsedTime){ if(layer.tag.data["class"]!="CollisionOnly"){visibleTiles.erase({x,y});} RenderTile({x,y},tileSheet,tileSheetIndex,{tileSheetX,tileSheetY}); } - if("debug_collision_boxes"_I){ - if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; - view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128}); - view.DrawRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,GREY); + #ifdef _DEBUG + if("debug_collision_boxes"_I){ + if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){ + geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; + view.FillRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128}); + view.DrawRectDecal(vi2d{x,y}*GetCurrentMap().tilewidth+collision.pos,collision.size,GREY); + } } - } + #endif } } }break; @@ -1061,11 +1065,13 @@ void AiL::RenderWorld(float fElapsedTime){ int tileSheetX=tileSheetIndex%tileSheetWidth; int tileSheetY=tileSheetIndex/tileSheetWidth; view.DrawPartialDecal(vi2d{x,y}*game->GetCurrentMap().tilewidth,{float(tileSheet.tileset->tilewidth),float(tileSheet.tileset->tileheight)},tileSheet.tileset->tileset->Decal(),vi2d{tileSheetX,tileSheetY}*game->GetCurrentMap().tilewidth,{float(tileSheet.tileset->tilewidth),float(tileSheet.tileset->tileheight)},{255,255,255,uint8_t(255-bridgeFadeFactor/TileGroup::FADE_TIME*TileGroup::FADE_AMT)}); - #ifdef DEBUG_COLLISIONS - if(tileSheet.tileset.collision.find(tileSheetIndex)!=tileSheet.tileset.collision.end()){ - geom2d::rectcollision=tileSheet.tileset.collision[tileSheetIndex].collision; - view.FillRectDecal(vi2d{x,y}*game->GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128}); - view.DrawRectDecal(vi2d{x,y}*game->GetCurrentMap().tilewidth+collision.pos,collision.size,GREY); + #ifdef _DEBUG + if("debug_collision_boxes"_I){ + if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){ + geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; + view.FillRectDecal(vi2d{x,y}*game->GetCurrentMap().tilewidth+collision.pos,collision.size,{0,0,0,128}); + view.DrawRectDecal(vi2d{x,y}*game->GetCurrentMap().tilewidth+collision.pos,collision.size,GREY); + } } #endif } @@ -1241,12 +1247,14 @@ void AiL::RenderWorld(float fElapsedTime){ } } - if(DEBUG_PATHFINDING){ - std::vectorpathing=game->pathfinder.Solve_AStar(player.get()->GetPos(),GetWorldMousePos(),8,player.get()->OnUpperLevel()); - for(vf2d&square:pathing){ - view.FillRectDecal(square*float(game->GetCurrentMap().tilewidth),{float(game->GetCurrentMap().tilewidth),float(game->GetCurrentMap().tilewidth)},DARK_GREEN); + #ifdef _DEBUG + if(DEBUG_PATHFINDING){ + std::vectorpathing=game->pathfinder.Solve_AStar(player.get()->GetPos(),GetWorldMousePos(),8,player.get()->OnUpperLevel()); + for(vf2d&square:pathing){ + view.FillRectDecal(square*float(game->GetCurrentMap().tilewidth),{float(game->GetCurrentMap().tilewidth),float(game->GetCurrentMap().tilewidth)},DARK_GREEN); + } } - } + #endif } Player*AiL::GetPlayer(){ @@ -1293,17 +1301,20 @@ void AiL::RenderHud(){ DrawShadowStringPropDecal(vf2d{float(ScreenWidth()/2),float(ScreenHeight()/4)-24}-GetTextSizeProp(displayText)/2,displayText,BLUE,VERY_DARK_BLUE); } DisplayBossEncounterInfo(); - if("debug_player_info"_I){ - DrawShadowStringDecal({0,128},player->GetPos().str()); - DrawShadowStringDecal({0,136},"Spd: "+std::to_string(player->GetMoveSpdMult())); - DrawShadowStringDecal({0,144},"HP Timer: "+std::to_string(player->hpRecoveryTimer)); - DrawShadowStringDecal({0,152},"HP Recovery Amt: "+std::to_string(player->GetHPRecoveryPct()*player->GetMaxHealth())); - if(!ISBLANK(GetLoadoutItem(0))){ - DrawShadowStringDecal({0,92},"Loadout Slot 1 Qty: "+std::to_string(GetLoadoutItem(0).lock()->Amt())); - } - DrawShadowStringDecal({0,1},"Selection: "+Menu::menus[INVENTORY_CONSUMABLES]->selection.str()); - DrawShadowStringDecal({0,12},"Button Hold Time: "+std::to_string(Menu::menus[INVENTORY_CONSUMABLES]->buttonHoldTime)); - }} + #ifdef _DEBUG + if("debug_player_info"_I){ + DrawShadowStringDecal({0,128},player->GetPos().str()); + DrawShadowStringDecal({0,136},"Spd: "+std::to_string(player->GetMoveSpdMult())); + DrawShadowStringDecal({0,144},"HP Timer: "+std::to_string(player->hpRecoveryTimer)); + DrawShadowStringDecal({0,152},"HP Recovery Amt: "+std::to_string(player->GetHPRecoveryPct()*player->GetMaxHealth())); + if(!ISBLANK(GetLoadoutItem(0))){ + DrawShadowStringDecal({0,92},"Loadout Slot 1 Qty: "+std::to_string(GetLoadoutItem(0).lock()->Amt())); + } + DrawShadowStringDecal({0,1},"Selection: "+Menu::menus[INVENTORY_CONSUMABLES]->selection.str()); + DrawShadowStringDecal({0,12},"Button Hold Time: "+std::to_string(Menu::menus[INVENTORY_CONSUMABLES]->buttonHoldTime)); + } + #endif +} void AiL::RenderCooldowns(){ std::vectorcooldowns{ @@ -1784,6 +1795,12 @@ void AiL::LoadLevel(MapName map){ camera.MoveCamera(cameraStartPos); pathfinder.Initialize(); + 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. + if(MAP_DATA[map].bgmSongName.length()>0){ + Audio::PlayBGM(MAP_DATA[map].bgmSongName); + DisableFadeIn(true); + } } bool AiL::IsUpperForegroundTile(int tileID){ @@ -2075,12 +2092,14 @@ datafile operator ""_A(const char*key,std::size_t len){ } void AiL::OutputDebugInfo(const char*key,std::size_t len){ - if(utils::datafile::DEBUG_ACCESS_OPTIONS){ - std::string k=std::string(key); - if(!k.starts_with("debug_")){ - std::cout<<"Reading "<DisableFadeIn(false); + } uint8_t alpha=0; if(fadeOutDuration>0){ fadeOutDuration=std::max(0.f,fadeOutDuration-GetElapsedTime()); @@ -2482,14 +2504,26 @@ void AiL::RenderFadeout(){ alpha=uint8_t(util::lerp(0,255,1-(fadeOutDuration/fadeOutTotalTime))); }else if(fadeInDuration>0){ - fadeInDuration=std::max(0.f,fadeInDuration-GetElapsedTime()); - alpha=uint8_t(util::lerp(255,0,1-(fadeInDuration/fadeOutTotalTime))); + if(!disableFadeIn){ + fadeInDuration=std::max(0.f,fadeInDuration-GetElapsedTime()); + alpha=uint8_t(util::lerp(255,0,1-(fadeInDuration/fadeOutTotalTime))); + }else{ + alpha=255; + } } FillRectDecal({0,0},GetScreenSize(),{0,0,0,alpha}); + + #ifdef _DEBUG + if("debug_transition_info"_I){ + DrawShadowStringDecal({2,2},"Alpha: "+std::to_string(alpha)); + DrawShadowStringDecal({2,14},"Disable Fade In: "+std::to_string(disableFadeIn)); + DrawShadowStringDecal({2,26},"Fully Loaded: "+std::to_string(audioEngine.fullyLoaded)); + } + #endif } bool AiL::GamePaused(){ - return fadeOutDuration>0; + return fadeOutDuration>0||disableFadeIn; } void AiL::EndGame(){ @@ -2585,4 +2619,8 @@ void AiL::OnRequestCompleted(const std::string_view receivedData)const{ std::string operator ""_FS(const char*key,std::size_t len){ AiL::OutputDebugInfo(key,len); return DATA.GetProperty(std::string(key,len)).GetFullString(); +} + +void AiL::DisableFadeIn(const bool disable){ + disableFadeIn=disable; } \ No newline at end of file diff --git a/Adventures in Lestoria/AdventuresInLestoria.h b/Adventures in Lestoria/AdventuresInLestoria.h index 5b6f5ac6..783e2a4d 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.h +++ b/Adventures in Lestoria/AdventuresInLestoria.h @@ -111,13 +111,14 @@ private: int chapter=1; //We start at chapter 1. std::array,3>loadout; float fadeOutDuration=0; - float fadeOutTotalTime=0; - float fadeInDuration=0; States::State transitionState=States::State::GAME_RUN; bool gameEnd=false; std::vectormonstersToBeSpawned; time_t gameStarted; std::functionresponseCallback; + float fadeInDuration=0; + float fadeOutTotalTime=0; + bool disableFadeIn=false; void ValidateGameStatus(); #ifndef __EMSCRIPTEN__ @@ -213,6 +214,7 @@ public: void InitializePlayerLevelCap(); void ResetGame(); void OnRequestCompleted(const std::string_view receivedData)const override; + void DisableFadeIn(const bool disable); struct TileGroupData{ vi2d tilePos; diff --git a/Adventures in Lestoria/Audio.cpp b/Adventures in Lestoria/Audio.cpp index 7f113b92..072209e9 100644 --- a/Adventures in Lestoria/Audio.cpp +++ b/Adventures in Lestoria/Audio.cpp @@ -98,6 +98,8 @@ void Audio::Initialize(){ defaultFadeTime=data.GetReal(); } } + + Self().bgm.SetInitialized(); } MiniAudio&Audio::Engine(){ @@ -108,6 +110,7 @@ void Audio::Play(const std::string_view sound){ }; void Audio::PlayBGM(const std::string_view sound,const bool loop){ BGM&track=Self().bgm[std::string(sound)]; + Self().fullyLoaded=false; StopBGM(); //Stop any currently playing track. Self().playParams={std::string(sound),loop}; Self().playBGMWaitTime=0.7f; @@ -131,13 +134,15 @@ const Volume&Audio::BGM::GetVolume(const Event&eventName,const ChannelID&id)cons } void Audio::BGM::Load(){ - BGM&bgm=Self().bgm[Self().currentBGM]; if(Self().BGMIsPlaying()){ - bgm.Unload(); + BGM&bgm=Self().bgm[Self().currentBGM]; + if(Self().BGMIsPlaying()){ + bgm.Unload(); + } } Self().currentBGM=songFileName; BGM&newBgm=Self().bgm[songFileName]; - if(newBgm.channels.size()>0)ERR(std::format("WARNING! The size of the channels list is greater than zero! Size: {}",bgm.channels.size())); + if(newBgm.channels.size()>0)ERR(std::format("WARNING! The size of the channels list is greater than zero! Size: {}",newBgm.channels.size())); for(const ChannelName&channel:newBgm.GetChannels()){ ChannelID soundID=Engine().LoadSound("bgm_directory"_S+channel); newBgm.channels.push_back(soundID); @@ -242,6 +247,11 @@ void Audio::Update(){ Engine().Play(trackID,Self().playParams.loop); channelListIndex++; } + Self().fullyLoaded=true; } } +} + +const bool Audio::BGMFullyLoaded(){ + return Self().fullyLoaded; } \ No newline at end of file diff --git a/Adventures in Lestoria/Audio.h b/Adventures in Lestoria/Audio.h index 2e481745..0a86b90f 100644 --- a/Adventures in Lestoria/Audio.h +++ b/Adventures in Lestoria/Audio.h @@ -39,6 +39,7 @@ All rights reserved. #include "olcPGEX_MiniAudio.h" #include "config.h" #include +#include "safemap.h" using SongName=std::string; using Event=std::string; @@ -49,6 +50,7 @@ using Volume=float; using VolumeList=std::vector; class Audio{ + friend class AiL; public: static Audio&Self(); static MiniAudio&Engine(); @@ -62,6 +64,7 @@ public: static const SongName&GetTrackName(); static void SetAudioEvent(const Event&eventName); static const bool BGMIsPlaying(); + static const bool BGMFullyLoaded(); //Fully loaded means when the audio buffer has finished filling up, which means sound is now playing. private: struct BGMPlayParams{ std::string sound; @@ -100,11 +103,11 @@ private: private: MiniAudio audioEngine; SongName currentBGM=""; - std::mapbgm; + safemapbgm; std::setevents; static float defaultFadeTime; Event currentAudioEvent="Default Volume"; - + bool fullyLoaded=true; float playBGMWaitTime=0.0f; BGMPlayParams playParams; }; diff --git a/Adventures in Lestoria/State_GameRun.cpp b/Adventures in Lestoria/State_GameRun.cpp index bce27994..9948feba 100644 --- a/Adventures in Lestoria/State_GameRun.cpp +++ b/Adventures in Lestoria/State_GameRun.cpp @@ -41,9 +41,11 @@ All rights reserved. #include "Menu.h" #include "ItemDrop.h" #include "VisualNovel.h" +#include "State_OverworldMap.h" INCLUDE_MONSTER_LIST INCLUDE_game +INCLUDE_LEVEL_NAMES void State_GameRun::OnStateChange(GameState*prevState){ if(Menu::IsMenuOpen()){ @@ -52,6 +54,7 @@ void State_GameRun::OnStateChange(GameState*prevState){ game->GetPlayer()->SetState(State::NORMAL); port=ViewPort::rectViewPort({0,0},{240,240},{24,24}); + #pragma region Test Text Decal Creation if(r.Decal()==nullptr){ r.Create(240,240); game->SetDrawTarget(r.Sprite()); @@ -66,6 +69,9 @@ void State_GameRun::OnStateChange(GameState*prevState){ game->SetDrawTarget(nullptr); r.Decal()->Update(); } + #pragma endregion + + game->LoadLevel(LEVEL_NAMES.at(State_OverworldMap::GetCurrentConnectionPoint().map)); } void State_GameRun::OnUserUpdate(AiL*game){ game->bossDisplayTimer=std::max(0.f,game->bossDisplayTimer-game->GetElapsedTime()); diff --git a/Adventures in Lestoria/State_OverworldMap.cpp b/Adventures in Lestoria/State_OverworldMap.cpp index bdd96e7e..d1201c10 100644 --- a/Adventures in Lestoria/State_OverworldMap.cpp +++ b/Adventures in Lestoria/State_OverworldMap.cpp @@ -215,8 +215,7 @@ void State_OverworldMap::StartLevel(){ if(State_OverworldMap::GetCurrentConnectionPoint().map.starts_with("STORY")){ VisualNovel::LoadVisualNovel(State_OverworldMap::GetCurrentConnectionPoint().map); }else{ - game->LoadLevel(LEVEL_NAMES.at(State_OverworldMap::GetCurrentConnectionPoint().map)); - GameState::ChangeState(States::GAME_RUN); + GameState::ChangeState(States::GAME_RUN,0.3f); } } diff --git a/Adventures in Lestoria/TMXParser.h b/Adventures in Lestoria/TMXParser.h index 8b554d5e..87bfb572 100644 --- a/Adventures in Lestoria/TMXParser.h +++ b/Adventures in Lestoria/TMXParser.h @@ -95,6 +95,7 @@ struct Map{ std::vector TilesetData; std::vector LayerData; std::string mapType=""; + std::string bgmSongName=""; std::setspawns; std::map SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID. std::map> ZoneData; @@ -144,6 +145,7 @@ class TMXParser{ #ifdef TMX_PARSER_SETUP #undef TMX_PARSER_SETUP #include "State_OverworldMap.h" + extern bool _MAP_LOAD_INFO; extern bool _DEBUG_MAP_LOAD_INFO; const std::string XMLTag::FormatTagData(std::maptiles){ std::string displayStr=""; @@ -285,7 +287,9 @@ class TMXParser{ if(valid&&data.length()>0){ if (newTag.tag.length()==0) { //Tag's empty, so first line is the tag. newTag.tag=data; - if(_DEBUG_MAP_LOAD_INFO)std::cout<<"Tag: "< Ask for a User ID -> Ask for a Save File Name -> Saves the Game -> Starts the Game - LOAD GAME -> Ask for a User ID -> Shows Available Files -> Click to Load -> Start Game - Audio Engine - Audio Ambience Zones - Menu Sound Effects @@ -21,7 +16,13 @@ Settings Menu -We have to save keybinds to the save file. -Smooth Movement -Click on title screen should not process as input immediately. + -Investigate why frame rate matters for intro screen. +-Warrior slash should occur even with no target +-Add in other story plates +-Faster main menu screen transition +-Simplify map collision tiles by removing the requirement for hidden boundaries. +-Loading should happen on fadeout. January 31st ============ @@ -46,4 +47,11 @@ Story proofreading/correcting/storyboarding - Export/Import Save Files Online/Offline -- Consider controls for fine-tuning music and how they sound during events. \ No newline at end of file +- Consider controls for fine-tuning music and how they sound during events. + +- Lock up unimplemented classes. + + + + +- Emscripten _DEBUG flag add as an option when building \ No newline at end of file diff --git a/Adventures in Lestoria/TSXParser.h b/Adventures in Lestoria/TSXParser.h index 16d6709c..bc2eab24 100644 --- a/Adventures in Lestoria/TSXParser.h +++ b/Adventures in Lestoria/TSXParser.h @@ -178,11 +178,15 @@ class TSXParser{ TileCollisionData data; data.collision=geom2d::rect{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}}; if(parsedTilesetInfo.CollisionData.count(previousTagID)){ - if(_DEBUG_MAP_LOAD_INFO)ERR("WARNING! There was already collision data defined for tile "<toggleGroup; diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index d03e1962..f692c8fa 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 5395 +#define VERSION_BUILD 5414 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/Campaigns/1_1_v2.tmx b/Adventures in Lestoria/assets/Campaigns/1_1_v2.tmx index 97fbaf70..37e7c29b 100644 --- a/Adventures in Lestoria/assets/Campaigns/1_1_v2.tmx +++ b/Adventures in Lestoria/assets/Campaigns/1_1_v2.tmx @@ -1,7 +1,7 @@ - + diff --git a/Adventures in Lestoria/assets/config/configuration.txt b/Adventures in Lestoria/assets/config/configuration.txt index b4d9b8ca..6c6a18e1 100644 --- a/Adventures in Lestoria/assets/config/configuration.txt +++ b/Adventures in Lestoria/assets/config/configuration.txt @@ -107,6 +107,9 @@ debug_access_options = 0 # Shows map loading output debug_map_load_info = 0 +# Shows state transition information +debug_transition_info = 0 + # Shows extra info about the player on the HUD debug_player_info = 0 diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 54ff5fcb..a41fefd6 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ