diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj index 7e267dac..e296c594 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj @@ -523,6 +523,10 @@ + + + + @@ -820,6 +824,10 @@ + + + + diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters index 44dac6c3..2aa2f719 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters @@ -998,6 +998,9 @@ Source Files + + Source Files + diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index fd783417..8fa30f3f 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -80,6 +80,7 @@ All rights reserved. #include "LoadingScreen.h" #include "Tutorial.h" #include "SteamKeyboardCallbackHandler.h" +#include "SteamStatsReceivedHandler.h" INCLUDE_EMITTER_LIST INCLUDE_ITEM_CATEGORIES @@ -337,6 +338,9 @@ bool AiL::OnUserCreate(){ if(steamKeyboardCallbackListener==nullptr){ steamKeyboardCallbackListener=new SteamKeyboardCallbackHandler(); } + if(steamStatsReceivedHandlerListener==nullptr){ + steamStatsReceivedHandlerListener=new SteamStatsReceivedHandler(); + } #endif utils::datafile::INITIAL_SETUP_COMPLETE=true; diff --git a/Adventures in Lestoria/AdventuresInLestoria.h b/Adventures in Lestoria/AdventuresInLestoria.h index e79af930..e1ed7e99 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.h +++ b/Adventures in Lestoria/AdventuresInLestoria.h @@ -59,6 +59,7 @@ All rights reserved. class SteamKeyboardCallbackHandler; +class SteamStatsReceivedHandler; #define CreateBullet(type) BULLET_LIST.push_back(std::make_unique(type #define EndBullet )); @@ -189,6 +190,7 @@ private: #endif Audio audioEngine; SteamKeyboardCallbackHandler*steamKeyboardCallbackListener=nullptr; + SteamStatsReceivedHandler*steamStatsReceivedHandlerListener=nullptr; public: AiL(); bool OnUserCreate() override; diff --git a/Adventures in Lestoria/SaveFile.cpp b/Adventures in Lestoria/SaveFile.cpp index cdd49cf1..708477fd 100644 --- a/Adventures in Lestoria/SaveFile.cpp +++ b/Adventures in Lestoria/SaveFile.cpp @@ -134,8 +134,6 @@ const void SaveFile::SaveGame(){ saveFile["Game Time"].SetReal(game->GetRuntime()); saveFile["TravelingMerchant"].SetString(std::string(Merchant::GetCurrentTravelingMerchant().GetKeyName())); - saveFile["Achievement"]["KillCount"].SetInt(Unlock::GetKillCount()); - #pragma region Save Keyboard/Controller mappings //NOTE: We are shadowing code from InputKeyboardWindow! If at some point the retrival method for getting input displays changes, we likely will be changing the code here as well! //ALSO NOTE: The menu inputs are saved to the system file while gameplay inputs are per-character and saved to the character settings file! @@ -392,12 +390,6 @@ void SaveFile::LoadFile(){ } } - #pragma region Achievement-related loading - if(loadFile.HasProperty("Achievement.KillCount")){ - Unlock::SetKillCount(loadFile.GetProperty("Achievement.KillCount").GetInt()); - } - #pragma endregion - GameState::ChangeState(States::OVERWORLD_MAP,0.5f); }else{ LOG(std::format("WARNING! File {} does not exist for loading!","save_file_path"_S+std::format("save.{:04}",saveFileID))); diff --git a/Adventures in Lestoria/State_MainMenu.cpp b/Adventures in Lestoria/State_MainMenu.cpp index 0fe0480e..6b29014d 100644 --- a/Adventures in Lestoria/State_MainMenu.cpp +++ b/Adventures in Lestoria/State_MainMenu.cpp @@ -42,6 +42,9 @@ All rights reserved. #include "Key.h" #include "ItemDrop.h" #include "util.h" +#ifndef __EMSCRIPTEN__ + #include +#endif INCLUDE_game diff --git a/Adventures in Lestoria/SteamStatsReceivedHandler.cpp b/Adventures in Lestoria/SteamStatsReceivedHandler.cpp new file mode 100644 index 00000000..3896355e --- /dev/null +++ b/Adventures in Lestoria/SteamStatsReceivedHandler.cpp @@ -0,0 +1,54 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#include "SteamStatsReceivedHandler.h" +#include "olcUTIL_DataFile.h" +#include "DEFINES.h" +#include "Unlock.h" +#include "config.h" +#include "Error.h" + +INCLUDE_DATA + +#ifndef __EMSCRIPTEN__ + void SteamStatsReceivedHandler::SteamStatsReceived( UserStatsReceived_t* pCallback ){ + if(pCallback->m_eResult==k_EResultOK){ + SteamUserStats()->GetStat("Achievement.Kill Unlocks.Total Kill API Name"_S.c_str(),&Unlock::monsterKillCount); + LOG(std::format("Retried monster kill count: {}",Unlock::monsterKillCount)); + } + } +#endif \ No newline at end of file diff --git a/Adventures in Lestoria/SteamStatsReceivedHandler.h b/Adventures in Lestoria/SteamStatsReceivedHandler.h new file mode 100644 index 00000000..f5f7f9ee --- /dev/null +++ b/Adventures in Lestoria/SteamStatsReceivedHandler.h @@ -0,0 +1,47 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once +#ifndef __EMSCRIPTEN__ + #include "steam/steam_api.h" +#endif + +#ifndef __EMSCRIPTEN__ +class SteamStatsReceivedHandler{ + STEAM_CALLBACK(SteamStatsReceivedHandler,SteamStatsReceived,UserStatsReceived_t); +}; +#endif \ No newline at end of file diff --git a/Adventures in Lestoria/TODO.txt b/Adventures in Lestoria/TODO.txt index e682e7cd..67d19640 100644 --- a/Adventures in Lestoria/TODO.txt +++ b/Adventures in Lestoria/TODO.txt @@ -33,32 +33,8 @@ SetAchievement File Hash on Save/Load. -Movement still possible when alt-tabbing - -KILL_SLIME_1 -KILL_SLIME_2 -KILL_SLIME_3 -CAMP_UNLOCK -BLACKSMITH_UNLOCK -CHAPTER1_COMPLETE -SLIME_KING -SLIME_KING_DESTROYER -URSULE -URSULE_DESTROYER -WARRIOR_LV5 -RANGER_LV5 -WIZARD_LV5 -WEAPON_LV5 -ARMOR_LV5 -ARMOR_LV10 -FULLY_DECKED_OUT - Include a Reset Achievements button in Settings - -Enhancing can also trigger the "fully decked out" achievement - - ============================================ Consider a "killed by player" / "marked by player" flag for monsters to determine if a player gets credit for a monster kill (for achievements) Make another actions config file for the main build (The app # is different) \ No newline at end of file diff --git a/Adventures in Lestoria/Unlock.cpp b/Adventures in Lestoria/Unlock.cpp index 82f9f75a..5ade3e85 100644 --- a/Adventures in Lestoria/Unlock.cpp +++ b/Adventures in Lestoria/Unlock.cpp @@ -51,7 +51,6 @@ int Unlock::monsterKillCount=0; void Unlock::Initialize(){ unlocks.clear(); - monsterKillCount=0; UnlockArea("WORLD_MAP"); } @@ -82,24 +81,16 @@ void Unlock::UnlockCurrentMap(){ void Unlock::IncreaseKillCount(){ monsterKillCount++; if(SteamUserStats()){ + SteamUserStats()->SetStat("Achievement.Kill Unlocks.Total Kill API Name"_S.c_str(),Unlock::monsterKillCount); datafile&killUnlocks=DATA.GetProperty("Achievement.Kill Unlocks"); for(auto&[key,size]:killUnlocks){ if(key.starts_with("Kill Monsters")){ int killRequirement=killUnlocks[key]["Monster Kill Count"].GetInt(); - if(monsterKillCount-1SetAchievement(killUnlocks[key]["API Name"].GetString().c_str()); SteamUserStats()->StoreStats(); } } } } -} - -const int Unlock::GetKillCount(){ - return monsterKillCount; -} - -void Unlock::SetKillCount(int newKillCount){ - monsterKillCount=newKillCount; } \ No newline at end of file diff --git a/Adventures in Lestoria/Unlock.h b/Adventures in Lestoria/Unlock.h index 7c947eea..0f4f8fee 100644 --- a/Adventures in Lestoria/Unlock.h +++ b/Adventures in Lestoria/Unlock.h @@ -43,10 +43,10 @@ All rights reserved. class Unlock{ friend class AiL; friend class SaveFile; + friend class SteamStatsReceivedHandler; static std::setunlocks; static void Initialize(); static int monsterKillCount; - static void SetKillCount(int newKillCount); public: //Provide a map's actual name to trigger unlocks for all connected areas. You can get the current map you are on via State_OverworldMap::GetCurrentConnectionPoint().map static void UnlockArea(std::string mapName); @@ -55,5 +55,4 @@ public: static bool IsUnlocked(std::string mapName); static bool IsUnlocked(ConnectionPoint&cp); static void IncreaseKillCount(); - static const int GetKillCount(); }; \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 0b6e2e6f..ff5f1cd6 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 0 #define VERSION_PATCH 0 -#define VERSION_BUILD 8548 +#define VERSION_BUILD 8551 #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 ac6d137c..b77c725f 100644 --- a/Adventures in Lestoria/assets/Campaigns/1_1_v2.tmx +++ b/Adventures in Lestoria/assets/Campaigns/1_1_v2.tmx @@ -1,5 +1,5 @@ - + diff --git a/Adventures in Lestoria/assets/config/Achievements.txt b/Adventures in Lestoria/assets/config/Achievements.txt index c5e78647..34451645 100644 --- a/Adventures in Lestoria/assets/config/Achievements.txt +++ b/Adventures in Lestoria/assets/config/Achievements.txt @@ -21,6 +21,8 @@ Achievement } Kill Unlocks { + Total Kill API Name = "MONSTER_KILL_COUNT" + # Achievements that start with "Kill Monsters" will be checked when a monster is killed. Kill Monsters 1 { diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index b4d1406e..2db95c75 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ