diff --git a/CMakeLists.txt b/CMakeLists.txt index 3301e1a..9d3b79c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,10 @@ cmake_minimum_required(VERSION 3.21) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -if (APPLE) - set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") -endif() +set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") set(CMAKE_CXX_VISIBILITY_PRESET hidden) -project(BetterSafe VERSION 1.0.3) +project(BetterSafe VERSION 1.0.4) add_library(${PROJECT_NAME} SHARED src/BetterSafe.cpp diff --git a/changelog.md b/changelog.md index 71fa6fd..c069e76 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,7 @@ # Better Safe Changelog +## v1.0.4 (2024-09-21) +- Fixed a bug where the level cache would reload when switching between months + ## v1.0.3 (2024-09-14) - Fixed a bug where the game would crash when viewing the daily/weekly level previews diff --git a/mod.json b/mod.json index e8584dc..e2b48b8 100644 --- a/mod.json +++ b/mod.json @@ -1,16 +1,15 @@ { - "geode": "3.6.1", + "geode": "3.7.1", "gd": { "android": "2.206", "win": "2.206", "mac": "2.206" }, - "version": "v1.0.3", + "version": "v1.0.4", "id": "hiimjustin000.better_safe", "name": "Better Safe", "developer": "hiimjustin000", "description": "A mod that expands The Safe with a calendar.", - "repository": "https://github.com/hiimjustin000/BetterSafe", "settings": { "sunday-first": { "name": "Sunday First", diff --git a/src/BSCalendarPopup.cpp b/src/BSCalendarPopup.cpp index 0a72f81..1ca4b16 100644 --- a/src/BSCalendarPopup.cpp +++ b/src/BSCalendarPopup.cpp @@ -225,7 +225,8 @@ void BSCalendarPopup::loadMonth() { for (auto& level : levelSafe) ids.push_back(std::to_string(level.id)); auto searchObject = GJSearchObject::create(SearchType::MapPackOnClick, string::join(ids, ",")); auto glm = GameLevelManager::sharedState(); - if (auto storedLevels = glm->getStoredOnlineLevels(searchObject->getKey())) loadLevelsFinished(storedLevels, searchObject->getKey()); + std::string key = searchObject->getKey(); + if (auto storedLevels = glm->getStoredOnlineLevels(key.substr(std::max(0, (int)key.size() - 256)).c_str())) loadLevelsFinished(storedLevels, searchObject->getKey()); else glm->getOnlineLevels(searchObject); } @@ -275,14 +276,16 @@ void BSCalendarPopup::setupMonth() { if (gameLevelIt == levels.end()) continue; auto gameLevel = *gameLevelIt; - auto diffFrame = safeLevel.difficulty == -1 ? "diffIcon_auto_btn_001.png" : fmt::format("diffIcon_{:02d}_btn_001.png", safeLevel.difficulty); + auto levelDifficulty = BetterSafe::getDifficultyFromLevel(gameLevel); + auto diffFrame = levelDifficulty == -1 ? "diffIcon_auto_btn_001.png" : fmt::format("diffIcon_{:02d}_btn_001.png", levelDifficulty); if (auto moreDifficulties = Loader::get()->getLoadedMod("uproxide.more_difficulties")) { auto legacy = moreDifficulties->getSettingValue("legacy-difficulties"); - if (moreDifficulties->getSavedValue("casual", true) && safeLevel.difficulty == 3 && safeLevel.stars == 4) + auto levelStars = gameLevel->m_stars.value(); + if (moreDifficulties->getSavedValue("casual", true) && levelDifficulty == 3 && levelStars == 4) diffFrame = legacy ? "uproxide.more_difficulties/MD_Difficulty04Small_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty04Small.png"; - else if (moreDifficulties->getSavedValue("tough", true) && safeLevel.difficulty == 4 && safeLevel.stars == 7) + else if (moreDifficulties->getSavedValue("tough", true) && levelDifficulty == 4 && levelStars == 7) diffFrame = legacy ? "uproxide.more_difficulties/MD_Difficulty07Small_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty07Small.png"; - else if (moreDifficulties->getSavedValue("cruel", true) && safeLevel.difficulty == 5 && safeLevel.stars == 9) + else if (moreDifficulties->getSavedValue("cruel", true) && levelDifficulty == 5 && levelStars == 9) diffFrame = legacy ? "uproxide.more_difficulties/MD_Difficulty09Small_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty09Small.png"; } auto hasBetweenDemon = false; @@ -295,13 +298,14 @@ void BSCalendarPopup::setupMonth() { auto diffIcon = CCSprite::createWithSpriteFrameName(diffFrame.c_str()); diffIcon->setScale(0.75f); auto featureFrame = ""; - switch (safeLevel.feature) { + auto levelFeature = gameLevel->m_featured > 0 ? gameLevel->m_isEpic + 1 : 0; + switch (levelFeature) { case 1: featureFrame = "GJ_featuredCoin_001.png"; break; case 2: featureFrame = "GJ_epicCoin_001.png"; break; case 3: featureFrame = "GJ_epicCoin2_001.png"; break; case 4: featureFrame = "GJ_epicCoin3_001.png"; break; } - if (safeLevel.feature > 0) { + if (levelFeature > 0) { auto featureIcon = CCSprite::createWithSpriteFrameName(featureFrame); featureIcon->setPosition(diffIcon->getContentSize() / 2 + CCPoint { 0.0f, -5.5f }); if (hasBetweenDemon) featureIcon->setPositionY(9.5f); diff --git a/src/BSHoverNode.cpp b/src/BSHoverNode.cpp index f1f93f7..340eb42 100644 --- a/src/BSHoverNode.cpp +++ b/src/BSHoverNode.cpp @@ -33,12 +33,12 @@ bool BSHoverNode::init(SafeLevel const& level, GJGameLevel* gameLevel, MiniFunct dailyLabel->setScale(0.3f); addChild(dailyLabel); - auto nameLabel = CCLabelBMFont::create(level.name.c_str(), "bigFont.fnt"); + auto nameLabel = CCLabelBMFont::create(gameLevel->m_levelName.c_str(), "bigFont.fnt"); nameLabel->setPosition(40.0f, 55.0f); nameLabel->setScale(0.5f); addChild(nameLabel); - auto creatorLabel = CCLabelBMFont::create(fmt::format("by {}", level.creator).c_str(), "goldFont.fnt"); + auto creatorLabel = CCLabelBMFont::create(("by " + std::string(gameLevel->m_creatorName)).c_str(), "goldFont.fnt"); creatorLabel->setPosition(40.0f, 43.0f); creatorLabel->setScale(0.4f); addChild(creatorLabel); @@ -59,19 +59,21 @@ bool BSHoverNode::init(SafeLevel const& level, GJGameLevel* gameLevel, MiniFunct addChild(starLayout); auto gsm = GameStatsManager::sharedState(); - auto starsLabel = CCLabelBMFont::create(std::to_string(level.stars).c_str(), "bigFont.fnt"); + auto starsLabel = CCLabelBMFont::create(std::to_string(gameLevel->m_stars.value()).c_str(), "bigFont.fnt"); starsLabel->setScale(0.4f); - auto completedLevel = gsm->m_completedLevels->objectForKey(fmt::format("c_{}", level.id)); + auto levelID = gameLevel->m_levelID.value(); + auto completedLevel = gsm->m_completedLevels->objectForKey(fmt::format("c_{}", levelID).c_str()); starsLabel->setColor(completedLevel ? ccColor3B { 255, 255, 50 } : ccColor3B { 255, 255, 255 }); starLayout->addChild(starsLabel); starLayout->addChild(CCSprite::createWithSpriteFrameName("star_small01_001.png")); - for (int i = 1; i <= level.coins; i++) { - auto coinStr = fmt::format("{}_{}", level.id, i); + auto coinsVerified = gameLevel->m_coinsVerified.value() > 0; + for (int i = 1; i <= gameLevel->m_coins; i++) { + auto coinStr = fmt::format("{}_{}", levelID, i); auto hasCoin = gsm->hasUserCoin(coinStr.c_str()) || gsm->hasPendingUserCoin(coinStr.c_str()); auto coinSprite = CCSprite::createWithSpriteFrameName("usercoin_small01_001.png"); - if (level.coinsVerified) coinSprite->setColor(hasCoin ? ccColor3B { 255, 255, 255 } : ccColor3B { 165, 165, 165 }); + if (coinsVerified) coinSprite->setColor(hasCoin ? ccColor3B { 255, 255, 255 } : ccColor3B { 165, 165, 165 }); else coinSprite->setColor(hasCoin ? ccColor3B { 255, 175, 75 } : ccColor3B { 165, 113, 48 }); starLayout->addChild(coinSprite); } diff --git a/src/BetterSafe.cpp b/src/BetterSafe.cpp index a8f6ab8..2f7aa0d 100644 --- a/src/BetterSafe.cpp +++ b/src/BetterSafe.cpp @@ -33,13 +33,6 @@ void BetterSafe::loadDailySafe(EventListener&& listenerRef, Loadin .id = PROPERTY_OR_DEFAULT(level, "id", is_number, as_int, 0), .timelyID = PROPERTY_OR_DEFAULT(level, "dailyID", is_number, as_int, 0), .dates = dates, - .name = PROPERTY_OR_DEFAULT(level, "name", is_string, as_string, ""), - .creator = PROPERTY_OR_DEFAULT(level, "creator", is_string, as_string, ""), - .stars = PROPERTY_OR_DEFAULT(level, "stars", is_number, as_int, 0), - .difficulty = PROPERTY_OR_DEFAULT(level, "difficulty", is_number, as_int, 0), - .feature = PROPERTY_OR_DEFAULT(level, "feature", is_number, as_int, 0), - .coins = PROPERTY_OR_DEFAULT(level, "coins", is_number, as_int, 0), - .coinsVerified = PROPERTY_OR_DEFAULT(level, "coinsVerified", is_bool, as_bool, false), .weekly = false, .tier = PROPERTY_OR_DEFAULT(level, "tier", is_number, as_int, 0) }); @@ -78,13 +71,6 @@ void BetterSafe::loadWeeklySafe(EventListener&& listenerRef, Loadi .id = PROPERTY_OR_DEFAULT(level, "id", is_number, as_int, 0), .timelyID = PROPERTY_OR_DEFAULT(level, "weeklyID", is_number, as_int, 0), .dates = dates, - .name = PROPERTY_OR_DEFAULT(level, "name", is_string, as_string, ""), - .creator = PROPERTY_OR_DEFAULT(level, "creator", is_string, as_string, ""), - .stars = PROPERTY_OR_DEFAULT(level, "stars", is_number, as_int, 0), - .difficulty = PROPERTY_OR_DEFAULT(level, "difficulty", is_number, as_int, 0), - .feature = PROPERTY_OR_DEFAULT(level, "feature", is_number, as_int, 0), - .coins = PROPERTY_OR_DEFAULT(level, "coins", is_number, as_int, 0), - .coinsVerified = PROPERTY_OR_DEFAULT(level, "coinsVerified", is_bool, as_bool, false), .weekly = true, .tier = PROPERTY_OR_DEFAULT(level, "tier", is_number, as_int, 0) }); @@ -111,3 +97,10 @@ std::vector BetterSafe::getMonth(int year, int month, bool weekly) { } return levels; } + +int BetterSafe::getDifficultyFromLevel(GJGameLevel* level) { + if (level->m_demon > 0) return level->m_demonDifficulty > 0 ? level->m_demonDifficulty + 4 : 6; + else if (level->m_autoLevel) return -1; + else if (level->m_ratings < 5) return 0; + else return level->m_ratingsSum / level->m_ratings; +} diff --git a/src/BetterSafe.hpp b/src/BetterSafe.hpp index 987eb73..dffc717 100644 --- a/src/BetterSafe.hpp +++ b/src/BetterSafe.hpp @@ -13,13 +13,6 @@ struct SafeLevel { int id; int timelyID; std::vector dates; - std::string name; - std::string creator; - int stars; - int difficulty; - int feature; - int coins; - bool coinsVerified; bool weekly; int tier; }; @@ -33,4 +26,5 @@ class BetterSafe { static void loadDailySafe(EventListener&&, LoadingCircle*, MiniFunction); static void loadWeeklySafe(EventListener&&, LoadingCircle*, MiniFunction); static std::vector getMonth(int year, int month, bool weekly); + static int getDifficultyFromLevel(GJGameLevel* level); };