From b3e6b997547c1b92f947be5aad7aefcb9d05774c Mon Sep 17 00:00:00 2001 From: Justin Pridgen Date: Sun, 23 Jun 2024 18:40:52 -0400 Subject: [PATCH] v1.2.1 --- .github/workflows/build.yml | 3 +- CMakeLists.txt | 3 +- changelog.md | 3 + mod.json | 6 +- src/FREditPopup.cpp | 49 ++++---- src/FREditPopup.hpp | 25 ++-- src/FRLevelInfoLayer.cpp | 208 ---------------------------------- src/FRLevelInfoLayer.hpp | 16 --- src/main.cpp | 219 +++++++++++++++++++++++++++++++++++- 9 files changed, 264 insertions(+), 268 deletions(-) delete mode 100644 src/FRLevelInfoLayer.cpp delete mode 100644 src/FRLevelInfoLayer.hpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d41131e..f5c4e01 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,6 +53,7 @@ jobs: with: name: Build Output path: ${{ steps.build.outputs.build-output }} + draft: name: Draft Release runs-on: ubuntu-latest @@ -102,5 +103,3 @@ jobs: tag_name: ${{ github.event.head_commit.message }} name: ${{ github.event.head_commit.message }} draft: true - body: | - Replace with release notes diff --git a/CMakeLists.txt b/CMakeLists.txt index 013e92a..4a97979 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,12 +4,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") set(CMAKE_CXX_VISIBILITY_PRESET hidden) -project(FakeRate VERSION 1.2.0) +project(FakeRate VERSION 1.2.1) add_library(${PROJECT_NAME} SHARED src/FakeRate.cpp src/FREditPopup.cpp - src/FRLevelInfoLayer.cpp src/main.cpp ) diff --git a/changelog.md b/changelog.md index c72c723..73ffa5b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,7 @@ # Fake Rate Changelog +## v1.2.1 (2024-06-23) +- Fixed gaps in the various fake rate popup elements + ## v1.2.0 (2024-06-22) - Revamped the fake rate popup - Allowed independent customization of difficulty, stars, and featured status diff --git a/mod.json b/mod.json index cf0ed56..9b29895 100644 --- a/mod.json +++ b/mod.json @@ -1,11 +1,11 @@ { - "geode": "3.0.0-beta.5", + "geode": "3.0.0", "gd": { "android": "2.206", "win": "2.206", "mac": "2.206" }, - "version": "v1.2.0", + "version": "v1.2.1", "id": "hiimjustin000.fake_rate", "name": "Fake Rate", "developer": "hiimjustin000", @@ -36,4 +36,4 @@ "interface", "online" ] -} \ No newline at end of file +} diff --git a/src/FREditPopup.cpp b/src/FREditPopup.cpp index ff3dea6..5f37b2a 100644 --- a/src/FREditPopup.cpp +++ b/src/FREditPopup.cpp @@ -1,18 +1,17 @@ #include "FREditPopup.hpp" -FREditPopup* FREditPopup::create(FRLevelInfoLayer* delegate, GJGameLevel* level, int stars, int feature, int difficulty, int mdo) { +FREditPopup* FREditPopup::create(GJGameLevel* level, int stars, int feature, int difficulty, int mdo, UpdateFakeRateCallback callback) { auto ret = new FREditPopup(); - if (ret && ret->initAnchored(300.0f, 200.0f, delegate, level, stars, feature, difficulty, mdo)) { + if (ret->initAnchored(300.0f, 200.0f, level, stars, feature, difficulty, mdo, callback)) { ret->autorelease(); return ret; } - CC_SAFE_DELETE(ret); + delete ret; return nullptr; } -bool FREditPopup::setup(FRLevelInfoLayer* delegate, GJGameLevel* level, int stars, int feature, int difficulty, int mdo) { +bool FREditPopup::setup(GJGameLevel* level, int stars, int feature, int difficulty, int mdo, UpdateFakeRateCallback callback) { setTitle("Fake Rate"); - m_delegate = delegate; m_level = level; m_stars = stars; m_feature = feature; @@ -74,7 +73,7 @@ bool FREditPopup::setup(FRLevelInfoLayer* delegate, GJGameLevel* level, int star m_buttonMenu->addChild(difficultyButton); auto starsButton = CCMenuItemExt::createSpriteExtra(ButtonSprite::create("Stars", "goldFont.fnt", "GJ_button_02.png", 0.8f), [this, stars](auto) { - auto popup = SetIDPopup::create(m_stars, 0, 127, "Set Stars", "Set", true, stars, 60.0f, false, false); + auto popup = SetIDPopup::create(m_stars, 0, 127, "Set Stars", "Set", true, stars, 0.0f, false, false); popup->m_delegate = this; popup->show(); }); @@ -90,7 +89,7 @@ bool FREditPopup::setup(FRLevelInfoLayer* delegate, GJGameLevel* level, int star featureButton->setPosition(200.0f, 70.0f); m_buttonMenu->addChild(featureButton); - auto addButton = CCMenuItemExt::createSpriteExtra(ButtonSprite::create("Add", "goldFont.fnt", "GJ_button_01.png", 0.8f), [this](auto) { + auto addButton = CCMenuItemExt::createSpriteExtra(ButtonSprite::create("Add", "goldFont.fnt", "GJ_button_01.png", 0.8f), [this, callback](auto) { auto vec = Mod::get()->getSavedValue>("fake-rate", {}); auto it = std::find_if(vec.begin(), vec.end(), [this](auto const& item) { return item.id == m_level->m_levelID; @@ -111,13 +110,13 @@ bool FREditPopup::setup(FRLevelInfoLayer* delegate, GJGameLevel* level, int star }); } Mod::get()->setSavedValue("fake-rate", vec); - m_delegate->updateFakeRate(m_stars, m_feature, m_difficulty, m_moreDifficultiesOverride, true, true); + callback(m_stars, m_feature, m_difficulty, m_moreDifficultiesOverride, true, true); onClose(nullptr); }); addButton->setPosition(150.0f, 30.0f); m_buttonMenu->addChild(addButton); - auto removeButton = CCMenuItemExt::createSpriteExtra(ButtonSprite::create("Remove", "goldFont.fnt", "GJ_button_06.png", 0.8f), [this](auto) { + auto removeButton = CCMenuItemExt::createSpriteExtra(ButtonSprite::create("Remove", "goldFont.fnt", "GJ_button_06.png", 0.8f), [this, callback](auto) { auto vec = Mod::get()->getSavedValue>("fake-rate", {}); if (vec.empty()) return; vec.erase(std::remove_if(vec.begin(), vec.end(), [this](auto const& item) { @@ -125,7 +124,7 @@ bool FREditPopup::setup(FRLevelInfoLayer* delegate, GJGameLevel* level, int star }), vec.end()); Mod::get()->setSavedValue("fake-rate", vec); auto stars = m_level->m_stars; - m_delegate->updateFakeRate(m_level->m_stars, m_level->m_featured > 1 ? m_level->m_isEpic + 1 : 0, FakeRate::getDifficultyFromLevel(m_level), + callback(m_level->m_stars, m_level->m_featured > 1 ? m_level->m_isEpic + 1 : 0, FakeRate::getDifficultyFromLevel(m_level), stars == 4 || stars == 7 || stars == 9 ? stars : 0, true, false); onClose(nullptr); }); @@ -171,36 +170,36 @@ FREditPopup::~FREditPopup() { m_coins->release(); } -FRSetDifficultyPopup* FRSetDifficultyPopup::create(int difficulty, int moreDifficultiesOverride, bool legacy, MiniFunction callback) { +FRSetDifficultyPopup* FRSetDifficultyPopup::create(int difficulty, int moreDifficultiesOverride, bool legacy, SetDifficultyCallback callback) { auto ret = new FRSetDifficultyPopup(); - if (ret && ret->initAnchored(300.0f, 250.0f, difficulty, moreDifficultiesOverride, legacy, callback)) { + if (ret->initAnchored(300.0f, 250.0f, difficulty, moreDifficultiesOverride, legacy, callback)) { ret->autorelease(); return ret; } - CC_SAFE_DELETE(ret); + delete ret; return nullptr; } -bool FRSetDifficultyPopup::setup(int difficulty, int moreDifficultiesOverride, bool legacy, MiniFunction callback) { - setTitle("Set Difficulty"); +bool FRSetDifficultyPopup::setup(int difficulty, int moreDifficultiesOverride, bool legacy, SetDifficultyCallback callback) { + setTitle("Select Difficulty"); m_difficulty = difficulty; m_moreDifficultiesOverride = moreDifficultiesOverride; m_legacy = legacy; auto menuRow1 = CCMenu::create(); - menuRow1->setLayout(RowLayout::create()->setGap(20.0f)); + menuRow1->setLayout(RowLayout::create()->setAxisAlignment(AxisAlignment::Even)); menuRow1->setPosition(150.0f, 185.0f); menuRow1->setContentSize({ 300.0f, 45.0f }); m_mainLayer->addChild(menuRow1); auto menuRow2 = CCMenu::create(); - menuRow2->setLayout(RowLayout::create()->setGap(20.0f)); + menuRow2->setLayout(RowLayout::create()->setAxisAlignment(AxisAlignment::Even)); menuRow2->setPosition(150.0f, 135.0f); menuRow2->setContentSize({ 300.0f, 45.0f }); m_mainLayer->addChild(menuRow2); auto menuRow3 = CCMenu::create(); - menuRow3->setLayout(RowLayout::create()->setGap(20.0f)); + menuRow3->setLayout(RowLayout::create()->setAxisAlignment(AxisAlignment::Even)); menuRow3->setPosition(150.0f, 80.0f); menuRow3->setContentSize({ 300.0f, 65.0f }); m_mainLayer->addChild(menuRow3); @@ -255,26 +254,26 @@ void FRSetDifficultyPopup::createDifficultyToggle(CCMenu* menu, int difficulty, menu->addChild(toggle); } -FRSetFeaturePopup* FRSetFeaturePopup::create(int feature, int difficulty, int moreDifficultiesOverride, bool legacy, MiniFunction callback) { +FRSetFeaturePopup* FRSetFeaturePopup::create(int feature, int difficulty, int moreDifficultiesOverride, bool legacy, SetFeatureCallback callback) { auto ret = new FRSetFeaturePopup(); - if (ret && ret->initAnchored(300.0f, 150.0f, feature, difficulty, moreDifficultiesOverride, legacy, callback)) { + if (ret->initAnchored(300.0f, 150.0f, feature, difficulty, moreDifficultiesOverride, legacy, callback)) { ret->autorelease(); return ret; } - CC_SAFE_DELETE(ret); + delete ret; return nullptr; } -bool FRSetFeaturePopup::setup(int feature, int difficulty, int moreDifficultiesOverride, bool legacy, MiniFunction callback) { - setTitle("Set Feature"); +bool FRSetFeaturePopup::setup(int feature, int difficulty, int moreDifficultiesOverride, bool legacy, SetFeatureCallback callback) { + setTitle("Select Feature"); m_feature = static_cast(feature); m_difficulty = difficulty; m_moreDifficultiesOverride = moreDifficultiesOverride; m_legacy = legacy; auto menuRow = CCMenu::create(); - menuRow->setLayout(RowLayout::create()->setGap(25.0f)); - menuRow->setPosition(150.0f, 75.0f); + menuRow->setLayout(RowLayout::create()->setAxisAlignment(AxisAlignment::Even)); + menuRow->setPosition(150.0f, 80.0f + (difficulty > 5 ? 5.0f : 0.0f)); menuRow->setContentSize({ 300.0f, 50.0f }); m_mainLayer->addChild(menuRow); diff --git a/src/FREditPopup.hpp b/src/FREditPopup.hpp index 2a4895c..2e64e84 100644 --- a/src/FREditPopup.hpp +++ b/src/FREditPopup.hpp @@ -1,8 +1,11 @@ -#include "FRLevelInfoLayer.hpp" +#include "FakeRate.hpp" -class FREditPopup : public Popup, SetIDPopupDelegate { +typedef MiniFunction UpdateFakeRateCallback; +typedef MiniFunction SetDifficultyCallback; +typedef MiniFunction SetFeatureCallback; + +class FREditPopup : public Popup, SetIDPopupDelegate { protected: - FRLevelInfoLayer* m_delegate; GJGameLevel* m_level; int m_stars; int m_feature; @@ -17,30 +20,30 @@ class FREditPopup : public Popup> { +class FRSetDifficultyPopup : public Popup { protected: int m_difficulty; int m_moreDifficultiesOverride; bool m_legacy; CCMenuItemSpriteExtra* m_selected; - bool setup(int, int, bool, MiniFunction) override; + bool setup(int, int, bool, SetDifficultyCallback) override; void createDifficultyToggle(CCMenu*, int, int); public: - static FRSetDifficultyPopup* create(int, int, bool, MiniFunction); + static FRSetDifficultyPopup* create(int, int, bool, SetDifficultyCallback); }; -class FRSetFeaturePopup : public Popup> { +class FRSetFeaturePopup : public Popup { protected: GJFeatureState m_feature; int m_difficulty; @@ -48,8 +51,8 @@ class FRSetFeaturePopup : public Popup) override; + bool setup(int, int, int, bool, SetFeatureCallback) override; void createFeatureToggle(CCMenu*, GJFeatureState); public: - static FRSetFeaturePopup* create(int, int, int, bool, MiniFunction); + static FRSetFeaturePopup* create(int, int, int, bool, SetFeatureCallback); }; diff --git a/src/FRLevelInfoLayer.cpp b/src/FRLevelInfoLayer.cpp deleted file mode 100644 index e6bcb35..0000000 --- a/src/FRLevelInfoLayer.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include "FREditPopup.hpp" - -void FRLevelInfoLayer::onModify(auto& self) { - (void)self.setHookPriority("LevelInfoLayer::init", -100); - (void)self.setHookPriority("LevelInfoLayer::levelDownloadFinished", -100); - (void)self.setHookPriority("LevelInfoLayer::levelUpdateFinished", -100); - (void)self.setHookPriority("LevelInfoLayer::likedItem", -100); -} - -bool FRLevelInfoLayer::init(GJGameLevel* level, bool challenge) { - if (!LevelInfoLayer::init(level, challenge)) return false; - - auto buttonSprite = CircleButtonSprite::createWithSprite("FR_fakeRateBtn_001.png"_spr, 1.0f, CircleBaseColor::Green, CircleBaseSize::Medium); - buttonSprite->getTopNode()->setScale(1.0f); - auto fakeRateButton = CCMenuItemExt::createSpriteExtra(buttonSprite, [this](auto) { - FREditPopup::create(this, m_level, m_fields->m_fakeRateData.stars, m_fields->m_fakeRateData.feature, - m_fields->m_fakeRateData.difficulty, m_fields->m_fakeRateData.moreDifficultiesOverride)->show(); - }); - fakeRateButton->setID("fake-rate-button"_spr); - auto leftSideMenu = getChildByID("left-side-menu"); - leftSideMenu->addChild(fakeRateButton); - leftSideMenu->updateLayout(); - - checkFakeRate(); - - return true; -} - -void FRLevelInfoLayer::levelDownloadFinished(GJGameLevel* level) { - LevelInfoLayer::levelDownloadFinished(level); - checkFakeRate(); -} - -void FRLevelInfoLayer::levelUpdateFinished(GJGameLevel* level, UpdateResponse response) { - LevelInfoLayer::levelUpdateFinished(level, response); - checkFakeRate(); -} - -void FRLevelInfoLayer::likedItem(LikeItemType type, int id, bool liked) { - LevelInfoLayer::likedItem(type, id, liked); - checkFakeRate(); -} - -void FRLevelInfoLayer::checkFakeRate() { - auto vec = Mod::get()->getSavedValue>("fake-rate", {}); - auto it = std::find_if(vec.begin(), vec.end(), [this](auto const& item) { return item.id == m_level->m_levelID; }); - auto stars = m_level->m_stars; - if (it != vec.end()) updateFakeRate(it->stars, it->feature, it->difficulty, it->moreDifficultiesOverride, false, true); - else m_fields->m_fakeRateData = { - .id = m_level->m_levelID, - .stars = stars, - .feature = m_level->m_featured > 1 ? m_level->m_isEpic + 1 : 0, - .difficulty = FakeRate::getDifficultyFromLevel(m_level), - .moreDifficultiesOverride = stars == 4 || stars == 7 || stars == 9 ? stars : 0 - }; -} - -void FRLevelInfoLayer::updateFakeRate(int stars, int feature, int difficulty, int mdo, bool update, bool coins) { - m_fields->m_fakeRateData = { - .id = m_level->m_levelID, - .stars = stars, - .feature = feature, - .difficulty = difficulty, - .moreDifficultiesOverride = mdo - }; - - if (auto betweenDifficultySprite = static_cast(getChildByID("hiimjustin000.demons_in_between/between-difficulty-sprite"))) { - betweenDifficultySprite->setVisible(false); - m_difficultySprite->setOpacity(255); - } - auto gddpOverride = false; - if (auto gddpDifficultySprite = static_cast(getChildByID("gddp-difficulty"))) { - gddpOverride = gddpDifficultySprite->isVisible(); - gddpDifficultySprite->setVisible(false); - m_difficultySprite->setOpacity(255); - } - if (Loader::get()->isModLoaded("itzkiba.grandpa_demon") && !gddpOverride) { - removeChildByTag(69420); - auto children = reinterpret_cast(getChildren()->data->arr); - for (int i = 0; i < getChildrenCount(); i++) { - if (children[i]->getID() == "grd-difficulty") children[i]->setVisible(false); - } - if (auto grdInfinity = getChildByID("grd-infinity")) grdInfinity->setVisible(false); - m_difficultySprite->setVisible(true); - if (auto featureGlow = m_difficultySprite->getChildByTag(69420)) - featureGlow->setPosition(m_difficultySprite->getContentSize() * 0.5f); - } - auto winSize = CCDirector::sharedDirector()->getWinSize(); - auto gsm = GameStatsManager::sharedState(); - auto showStars = stars > 0 || m_level->m_dailyID > 0 || m_level->m_gauntletLevel; - m_difficultySprite->updateDifficultyFrame(difficulty, GJDifficultyName::Long); - m_difficultySprite->updateFeatureState((GJFeatureState)feature); - CCNode* nodeToSetPosition = m_difficultySprite; - CCNode* difficultySpriteParent = m_difficultySprite->getParent(); - if (Loader::get()->isModLoaded("acaruso.horn")) { - auto children = getChildren(); - for (int i = 0; i < children->count(); i++) { - if (auto child = typeinfo_cast(children->objectAtIndex(i))) { - auto grandchildren = child->getChildren(); - if (!grandchildren || grandchildren->count() < 1) continue; - if (auto button = typeinfo_cast(grandchildren->objectAtIndex(0))) { - if (button->getNormalImage() == m_difficultySprite) { - nodeToSetPosition = child; - difficultySpriteParent = button; - break; - } - } - } - } - } - nodeToSetPosition->setPositionY(winSize.height / 2 + 56.0f + (difficulty > 5 ? 5.0f : 0.0f) + (showStars ? 10.0f : 0.0f)); - auto& position = nodeToSetPosition->getPosition(); - m_starsIcon->setPosition({ position.x + 8.0f, position.y - 30.0f - (difficulty > 5 ? 9.0f : 0.0f) }); - m_starsIcon->setVisible(showStars); - m_starsLabel->setPosition(m_starsIcon->getPositionX() - 8.0f, m_starsIcon->getPositionY()); - m_starsLabel->setString(std::to_string(stars).c_str()); - m_starsLabel->setVisible(showStars); - m_starsLabel->setColor({ 255, 255, (unsigned char)(gsm->hasCompletedLevel(m_level) ? 50 : 255) }); - for (int i = 0; i < m_coins->count(); i++) { - auto coin = static_cast(m_coins->objectAtIndex(i)); - coin->setPositionY(position.y - 31.5f - (showStars ? 14.0f : 0.0f) - - (m_level->m_gauntletLevel || m_level->m_dailyID > 0 ? 14.5f : 0.0f) - (difficulty > 5 ? 9.0f : 0.0f)); - auto coinStr = fmt::format("{}_{}", m_level->m_levelID.value(), i + 1); - if (m_level->m_dailyID > 0) coinStr += "_" + std::to_string(m_level->m_dailyID); - else if (m_level->m_gauntletLevel) coinStr += "_g"; - if (coins || m_level->m_coinsVerified == 1) - coin->setColor(gsm->hasUserCoin(coinStr.c_str()) || gsm->hasPendingUserCoin(coinStr.c_str()) ? ccColor3B { 255, 255, 255 } : ccColor3B { 165, 165, 165 }); - else coin->setColor(gsm->hasUserCoin(coinStr.c_str()) || gsm->hasPendingUserCoin(coinStr.c_str()) ? ccColor3B { 255, 175, 75 } : ccColor3B { 165, 113, 48 }); - } - if (m_level->m_dailyID > 0 || m_level->m_gauntletLevel) { - auto diamondLabel = static_cast(getChildByID("diamond-label")); - auto diamondIcon = getChildByID("diamond-icon"); - auto diamonds = stars > 1 ? stars + 2 : 0; - diamondLabel->setString(fmt::format("{}/{}", (int)floorf(diamonds * m_level->m_normalPercent / 100.0f), diamonds).c_str()); - diamondIcon->setPosition({ - position.x + diamondLabel->getScaledContentSize().width * 0.5f + 2.0f, - position.y - (difficulty > 5 ? 9.0f : 0.0f) - 44.5f - }); - diamondLabel->setPosition({ diamondIcon->getPositionX() - 8.0f, diamondIcon->getPositionY() }); - } - auto yPos = winSize.height / 2 + 51.0f + (showStars ? 10.0f : 0.0f); - auto yOffset = showStars ? 28.0f : 30.0f; - auto downloadsIcon = static_cast(m_icons->objectAtIndex(1)); - downloadsIcon->setPositionY(yPos + yOffset); - m_downloadsLabel->setPositionY(downloadsIcon->getPositionY()); - m_likesIcon->setPositionY(yPos + 1.0f); - m_likesLabel->setPositionY(m_likesIcon->getPositionY()); - auto lengthIcon = static_cast(m_icons->objectAtIndex(0)); - lengthIcon->setPositionY(yPos - yOffset); - m_lengthLabel->setPositionY(lengthIcon->getPositionY() + (m_exactLengthLabel->isVisible() ? 6.0f : 0.0f)); - m_orbsIcon->setVisible(showStars); - m_orbsLabel->setVisible(showStars); - if (showStars) { - m_orbsIcon->setPositionY(yPos - yOffset * 2.0f); - m_orbsLabel->setPositionY(m_orbsIcon->getPositionY()); - auto orbs = FakeRate::getBaseCurrency(stars); - auto totalOrbs = (int)floorf(orbs * 1.25f); - m_orbsLabel->setString(fmt::format("{}/{}", (int)floorf(m_level->m_normalPercent != 100 ? orbs * m_level->m_normalPercent / 100.0f : totalOrbs), totalOrbs).c_str()); - m_orbsLabel->limitLabelWidth(60.0f, 0.5f, 0.0f); - } - if (m_exactLengthLabel->isVisible()) m_exactLengthLabel->setPositionY(m_lengthLabel->getPositionY() - 14.0f); - - if (Loader::get()->isModLoaded("uproxide.more_difficulties")) fixMoreDifficultiesIncompatibility(difficultySpriteParent, mdo, !coins); -} - -void FRLevelInfoLayer::fixMoreDifficultiesIncompatibility(CCNode* difficultySpriteParent, int mdo, bool remove) { - auto spriteName = std::string(); - auto moreDifficultiesSprite = static_cast(getChildByID("uproxide.more_difficulties/more-difficulties-spr")); - if (moreDifficultiesSprite) { - moreDifficultiesSprite->setVisible(false); - spriteName = FakeRate::getSpriteName(moreDifficultiesSprite); - } - m_difficultySprite->setOpacity(255); - - auto legacy = Loader::get()->getLoadedMod("uproxide.more_difficulties")->getSettingValue("legacy-difficulties"); - auto pos = difficultySpriteParent->convertToWorldSpace({ - m_difficultySprite->getPositionX() + (legacy ? 0.0f : 0.25f), - m_difficultySprite->getPositionY() - (legacy ? 0.0f : 0.1f) - }); - auto frameName = ""; - auto stars = m_fields->m_fakeRateData.stars; - if (spriteName == "uproxide.more_difficulties/MD_DifficultyCP.png") { - moreDifficultiesSprite->setVisible(true); - m_difficultySprite->setOpacity(0); - } - else { - auto moreDifficultiesOverride = mdo; - auto starsRequested = m_level->m_starsRequested; - if (remove && (starsRequested == 4 || starsRequested == 7 || starsRequested == 9)) moreDifficultiesOverride = starsRequested; - if (moreDifficultiesOverride == 0) return; - switch (moreDifficultiesOverride) { - case 4: frameName = legacy ? "uproxide.more_difficulties/MD_Difficulty04_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty04.png"; break; - case 7: frameName = legacy ? "uproxide.more_difficulties/MD_Difficulty07_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty07.png"; break; - case 9: frameName = legacy ? "uproxide.more_difficulties/MD_Difficulty09_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty09.png"; break; - } - if (!moreDifficultiesSprite) { - moreDifficultiesSprite = CCSprite::createWithSpriteFrameName(frameName); - moreDifficultiesSprite->setID("uproxide.more_difficulties/more-difficulties-spr"); - addChild(moreDifficultiesSprite, 3); - } - else { - moreDifficultiesSprite->initWithSpriteFrameName(frameName); - moreDifficultiesSprite->setVisible(true); - } - moreDifficultiesSprite->setPosition(pos); - m_difficultySprite->setOpacity(0); - } -} diff --git a/src/FRLevelInfoLayer.hpp b/src/FRLevelInfoLayer.hpp deleted file mode 100644 index c789c3b..0000000 --- a/src/FRLevelInfoLayer.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "FakeRate.hpp" - -#include -class $modify(FRLevelInfoLayer, LevelInfoLayer) { - struct Fields { - FakeRateSaveData m_fakeRateData; - }; - static void onModify(auto& self); - bool init(GJGameLevel*, bool); - void levelDownloadFinished(GJGameLevel*) override; - void levelUpdateFinished(GJGameLevel*, UpdateResponse) override; - void likedItem(LikeItemType, int, bool) override; - void checkFakeRate(); - void updateFakeRate(int, int, int, int, bool, bool); - void fixMoreDifficultiesIncompatibility(CCNode*, int, bool); -}; diff --git a/src/main.cpp b/src/main.cpp index de45a34..917062c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,221 @@ -#include "FakeRate.hpp" +#include "FREditPopup.hpp" + +#include +class $modify(FRLevelInfoLayer, LevelInfoLayer) { + struct Fields { + FakeRateSaveData m_fakeRateData; + }; + + static void onModify(auto& self) { + (void)self.setHookPriority("LevelInfoLayer::init", -100); + (void)self.setHookPriority("LevelInfoLayer::levelDownloadFinished", -100); + (void)self.setHookPriority("LevelInfoLayer::levelUpdateFinished", -100); + (void)self.setHookPriority("LevelInfoLayer::likedItem", -100); + } + + bool init(GJGameLevel* level, bool challenge) { + if (!LevelInfoLayer::init(level, challenge)) return false; + + auto buttonSprite = CircleButtonSprite::createWithSprite("FR_fakeRateBtn_001.png"_spr, 1.0f, CircleBaseColor::Green, CircleBaseSize::Medium); + buttonSprite->getTopNode()->setScale(1.0f); + auto fakeRateButton = CCMenuItemExt::createSpriteExtra(buttonSprite, [this](auto) { + FREditPopup::create(m_level, m_fields->m_fakeRateData.stars, m_fields->m_fakeRateData.feature, + m_fields->m_fakeRateData.difficulty, m_fields->m_fakeRateData.moreDifficultiesOverride, + [this](int stars, int feature, int difficulty, int mdo, bool update, bool coins) { + updateFakeRate(stars, feature, difficulty, mdo, update, coins); + })->show(); + }); + fakeRateButton->setID("fake-rate-button"_spr); + auto leftSideMenu = getChildByID("left-side-menu"); + leftSideMenu->addChild(fakeRateButton); + leftSideMenu->updateLayout(); + + checkFakeRate(); + + return true; + } + + void levelDownloadFinished(GJGameLevel* level) override { + LevelInfoLayer::levelDownloadFinished(level); + checkFakeRate(); + } + + void levelUpdateFinished(GJGameLevel* level, UpdateResponse response) override { + LevelInfoLayer::levelUpdateFinished(level, response); + checkFakeRate(); + } + + void likedItem(LikeItemType type, int id, bool liked) override { + LevelInfoLayer::likedItem(type, id, liked); + checkFakeRate(); + } + + void checkFakeRate() { + auto vec = Mod::get()->getSavedValue>("fake-rate", {}); + auto it = std::find_if(vec.begin(), vec.end(), [this](auto const& item) { return item.id == m_level->m_levelID; }); + auto stars = m_level->m_stars; + if (it != vec.end()) updateFakeRate(it->stars, it->feature, it->difficulty, it->moreDifficultiesOverride, false, true); + else m_fields->m_fakeRateData = { + .id = m_level->m_levelID, + .stars = stars, + .feature = m_level->m_featured > 1 ? m_level->m_isEpic + 1 : 0, + .difficulty = FakeRate::getDifficultyFromLevel(m_level), + .moreDifficultiesOverride = stars == 4 || stars == 7 || stars == 9 ? stars : 0 + }; + } + + void updateFakeRate(int stars, int feature, int difficulty, int mdo, bool update, bool coins) { + m_fields->m_fakeRateData = { + .id = m_level->m_levelID, + .stars = stars, + .feature = feature, + .difficulty = difficulty, + .moreDifficultiesOverride = mdo + }; + + if (auto betweenDifficultySprite = static_cast(getChildByID("hiimjustin000.demons_in_between/between-difficulty-sprite"))) { + betweenDifficultySprite->setVisible(false); + m_difficultySprite->setOpacity(255); + } + auto gddpOverride = false; + if (auto gddpDifficultySprite = static_cast(getChildByID("gddp-difficulty"))) { + gddpOverride = gddpDifficultySprite->isVisible(); + gddpDifficultySprite->setVisible(false); + m_difficultySprite->setOpacity(255); + } + if (Loader::get()->isModLoaded("itzkiba.grandpa_demon") && !gddpOverride) { + removeChildByTag(69420); + auto children = reinterpret_cast(getChildren()->data->arr); + for (int i = 0; i < getChildrenCount(); i++) { + if (children[i]->getID() == "grd-difficulty") children[i]->setVisible(false); + } + if (auto grdInfinity = getChildByID("grd-infinity")) grdInfinity->setVisible(false); + m_difficultySprite->setVisible(true); + if (auto featureGlow = m_difficultySprite->getChildByTag(69420)) + featureGlow->setPosition(m_difficultySprite->getContentSize() * 0.5f); + } + auto winSize = CCDirector::sharedDirector()->getWinSize(); + auto gsm = GameStatsManager::sharedState(); + auto showStars = stars > 0 || m_level->m_dailyID > 0 || m_level->m_gauntletLevel; + m_difficultySprite->updateDifficultyFrame(difficulty, GJDifficultyName::Long); + m_difficultySprite->updateFeatureState((GJFeatureState)feature); + CCNode* nodeToSetPosition = m_difficultySprite; + CCNode* difficultySpriteParent = m_difficultySprite->getParent(); + if (Loader::get()->isModLoaded("acaruso.horn")) { + auto children = getChildren(); + for (int i = 0; i < children->count(); i++) { + if (auto child = typeinfo_cast(children->objectAtIndex(i))) { + auto grandchildren = child->getChildren(); + if (!grandchildren || grandchildren->count() < 1) continue; + if (auto button = typeinfo_cast(grandchildren->objectAtIndex(0))) { + if (button->getNormalImage() == m_difficultySprite) { + nodeToSetPosition = child; + difficultySpriteParent = button; + break; + } + } + } + } + } + nodeToSetPosition->setPositionY(winSize.height / 2 + 56.0f + (difficulty > 5 ? 5.0f : 0.0f) + (showStars ? 10.0f : 0.0f)); + auto& position = nodeToSetPosition->getPosition(); + m_starsIcon->setPosition({ position.x + 8.0f, position.y - 30.0f - (difficulty > 5 ? 9.0f : 0.0f) }); + m_starsIcon->setVisible(showStars); + m_starsLabel->setPosition(m_starsIcon->getPositionX() - 8.0f, m_starsIcon->getPositionY()); + m_starsLabel->setString(std::to_string(stars).c_str()); + m_starsLabel->setVisible(showStars); + m_starsLabel->setColor({ 255, 255, (unsigned char)(gsm->hasCompletedLevel(m_level) ? 50 : 255) }); + for (int i = 0; i < m_coins->count(); i++) { + auto coin = static_cast(m_coins->objectAtIndex(i)); + coin->setPositionY(position.y - 31.5f - (showStars ? 14.0f : 0.0f) + - (m_level->m_gauntletLevel || m_level->m_dailyID > 0 ? 14.5f : 0.0f) - (difficulty > 5 ? 9.0f : 0.0f)); + auto coinStr = fmt::format("{}_{}", m_level->m_levelID.value(), i + 1); + if (m_level->m_dailyID > 0) coinStr += "_" + std::to_string(m_level->m_dailyID); + else if (m_level->m_gauntletLevel) coinStr += "_g"; + if (coins || m_level->m_coinsVerified == 1) + coin->setColor(gsm->hasUserCoin(coinStr.c_str()) || gsm->hasPendingUserCoin(coinStr.c_str()) ? ccColor3B { 255, 255, 255 } : ccColor3B { 165, 165, 165 }); + else coin->setColor(gsm->hasUserCoin(coinStr.c_str()) || gsm->hasPendingUserCoin(coinStr.c_str()) ? ccColor3B { 255, 175, 75 } : ccColor3B { 165, 113, 48 }); + } + if (m_level->m_dailyID > 0 || m_level->m_gauntletLevel) { + auto diamondLabel = static_cast(getChildByID("diamond-label")); + auto diamondIcon = getChildByID("diamond-icon"); + auto diamonds = stars > 1 ? stars + 2 : 0; + diamondLabel->setString(fmt::format("{}/{}", (int)floorf(diamonds * m_level->m_normalPercent / 100.0f), diamonds).c_str()); + diamondIcon->setPosition({ + position.x + diamondLabel->getScaledContentSize().width * 0.5f + 2.0f, + position.y - (difficulty > 5 ? 9.0f : 0.0f) - 44.5f + }); + diamondLabel->setPosition({ diamondIcon->getPositionX() - 8.0f, diamondIcon->getPositionY() }); + } + auto yPos = winSize.height / 2 + 51.0f + (showStars ? 10.0f : 0.0f); + auto yOffset = showStars ? 28.0f : 30.0f; + auto downloadsIcon = static_cast(m_icons->objectAtIndex(1)); + downloadsIcon->setPositionY(yPos + yOffset); + m_downloadsLabel->setPositionY(downloadsIcon->getPositionY()); + m_likesIcon->setPositionY(yPos + 1.0f); + m_likesLabel->setPositionY(m_likesIcon->getPositionY()); + auto lengthIcon = static_cast(m_icons->objectAtIndex(0)); + lengthIcon->setPositionY(yPos - yOffset); + m_lengthLabel->setPositionY(lengthIcon->getPositionY() + (m_exactLengthLabel->isVisible() ? 6.0f : 0.0f)); + m_orbsIcon->setVisible(showStars); + m_orbsLabel->setVisible(showStars); + if (showStars) { + m_orbsIcon->setPositionY(yPos - yOffset * 2.0f); + m_orbsLabel->setPositionY(m_orbsIcon->getPositionY()); + auto orbs = FakeRate::getBaseCurrency(stars); + auto totalOrbs = (int)floorf(orbs * 1.25f); + m_orbsLabel->setString(fmt::format("{}/{}", (int)floorf(m_level->m_normalPercent != 100 ? orbs * m_level->m_normalPercent / 100.0f : totalOrbs), totalOrbs).c_str()); + m_orbsLabel->limitLabelWidth(60.0f, 0.5f, 0.0f); + } + if (m_exactLengthLabel->isVisible()) m_exactLengthLabel->setPositionY(m_lengthLabel->getPositionY() - 14.0f); + + if (Loader::get()->isModLoaded("uproxide.more_difficulties")) fixMoreDifficultiesIncompatibility(difficultySpriteParent, mdo, !coins); + } + + void fixMoreDifficultiesIncompatibility(CCNode* difficultySpriteParent, int mdo, bool remove) { + auto spriteName = std::string(); + auto moreDifficultiesSprite = static_cast(getChildByID("uproxide.more_difficulties/more-difficulties-spr")); + if (moreDifficultiesSprite) { + moreDifficultiesSprite->setVisible(false); + spriteName = FakeRate::getSpriteName(moreDifficultiesSprite); + } + m_difficultySprite->setOpacity(255); + + auto legacy = Loader::get()->getLoadedMod("uproxide.more_difficulties")->getSettingValue("legacy-difficulties"); + auto pos = difficultySpriteParent->convertToWorldSpace({ + m_difficultySprite->getPositionX() + (legacy ? 0.0f : 0.25f), + m_difficultySprite->getPositionY() - (legacy ? 0.0f : 0.1f) + }); + auto frameName = ""; + auto stars = m_fields->m_fakeRateData.stars; + if (spriteName == "uproxide.more_difficulties/MD_DifficultyCP.png") { + moreDifficultiesSprite->setVisible(true); + m_difficultySprite->setOpacity(0); + } + else { + auto moreDifficultiesOverride = mdo; + auto starsRequested = m_level->m_starsRequested; + if (remove && (starsRequested == 4 || starsRequested == 7 || starsRequested == 9)) moreDifficultiesOverride = starsRequested; + if (moreDifficultiesOverride == 0) return; + switch (moreDifficultiesOverride) { + case 4: frameName = legacy ? "uproxide.more_difficulties/MD_Difficulty04_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty04.png"; break; + case 7: frameName = legacy ? "uproxide.more_difficulties/MD_Difficulty07_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty07.png"; break; + case 9: frameName = legacy ? "uproxide.more_difficulties/MD_Difficulty09_Legacy.png" : "uproxide.more_difficulties/MD_Difficulty09.png"; break; + } + if (!moreDifficultiesSprite) { + moreDifficultiesSprite = CCSprite::createWithSpriteFrameName(frameName); + moreDifficultiesSprite->setID("uproxide.more_difficulties/more-difficulties-spr"); + addChild(moreDifficultiesSprite, 3); + } + else { + moreDifficultiesSprite->initWithSpriteFrameName(frameName); + moreDifficultiesSprite->setVisible(true); + } + moreDifficultiesSprite->setPosition(pos); + m_difficultySprite->setOpacity(0); + } + } +}; #include class $modify(FRLevelCell, LevelCell) {