From 2b6812d48caaae621ec15022fa677dc6f71a6e02 Mon Sep 17 00:00:00 2001 From: Alphalaneous <38200084+Alphalaneous@users.noreply.github.com> Date: Fri, 25 Oct 2024 21:39:02 -0400 Subject: [PATCH] Label variables with RIFT, music cell colors --- CMakeLists.txt | 4 + README.md | 77 +++++++++ changelog.md | 7 + cmake/IncludeLibs.cmake | 12 ++ mod.json | 2 +- src/BackgroundColors.h | 8 + src/LabelValues.h | 311 ++++++++++++++++++++++++++++++++++++ src/Macros.h | 12 +- src/UIModding.cpp | 1 + src/Utils.h | 46 +++++- src/main.cpp | 7 +- src/nodes/CCLabelBMFont.h | 24 +++ src/nodes/CommentCell.h | 42 ++--- src/nodes/CustomMusicCell.h | 50 ++++++ src/nodes/LevelInfoLayer.h | 4 + 15 files changed, 570 insertions(+), 37 deletions(-) create mode 100644 changelog.md create mode 100644 cmake/IncludeLibs.cmake create mode 100644 src/LabelValues.h create mode 100644 src/nodes/CustomMusicCell.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d02cc32..fea0512 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ file(GLOB SOURCES add_library(${PROJECT_NAME} SHARED ${SOURCES}) + if (NOT DEFINED ENV{GEODE_SDK}) message(FATAL_ERROR "Unable to find Geode SDK! Please define GEODE_SDK environment variable to point to Geode") else() @@ -23,4 +24,7 @@ endif() add_subdirectory($ENV{GEODE_SDK} ${CMAKE_CURRENT_BINARY_DIR}/geode) +include(${CMAKE_SOURCE_DIR}/cmake/IncludeLibs.cmake) +target_link_libraries(${PROJECT_NAME} third_party) + setup_geode_mod(${PROJECT_NAME}) diff --git a/README.md b/README.md index b32094b..4261e5c 100644 --- a/README.md +++ b/README.md @@ -1375,6 +1375,81 @@ An example of this is: "easing-rate": 2 } ``` +# Label Variables + +Using RIFT, you can add variables to your CCLabelBMFonts in the text attribute. RIFT is a powerful string scripting tool (https://github.com/EclipseMenu/rift). It allows for you to run certain functions and read variables into a string. + +Some examples of using a variable in a CCLabelBMFont are: + +```json +{ + "attributes": { + "text": "MY NAME IS {toUpper(username)}!!!" + } +} +``` + +```json +{ + "attributes": { + "text": "I have half these stars {stars_stat * 2}" + } +} +``` + +Happy Textures comes with a ton of variables built in for your use in these labels. Here is a list: + +- `username`: Your username +- `game_version`: The version of GD you are playing on +- `geode_version`: The version of Geode you are using +- `previous_string`: The label string before you changed it (in case you want to modify it) +- `jumps_stat`: Your Total Jumps stat +- `attempts_stat`: Your Total Attempts stat +- `completed_levels_stat`: Your Completed Levels stat +- `completed_online_levels_stat`: Your Completed Online Levels stat +- `demons_stat`: Your Demons stat +- `stars_stat`: Your Stars stat +- `completed_map_packs_stat`: Your Completed Map Packs stat +- `gold_coins_stat`: Your Gold Coins stat +- `players_destroyed_stat`: Your Players Destroyed stat +- `liked_levels_stat`: Your Total Liked Levels stat +- `rated_lavels_stat`: Your Total Rated Levels stat +- `user_coins_stat`: Your User Coins stat +- `diamonds_stat`: Your Diamonds stat +- `current_orbs_stat`: Your Current Orbs stat +- `completed_dailies_stat`: Your Completed Daily Levels stat +- `fire_shards_stat`: Your Fire Shards stat +- `ice_shards_stat`: Your Ice Shards stat +- `poison_shards_stat`: Your Poison Shards stat +- `shadow_shards_stat`: Your Shadow Shards stat +- `lava_shards_stat`: Your Lava Shards stat +- `earth_shards_stat`: Your Earth Shards stat +- `blood_shards_stat`: Your Blood Shards stat +- `metal_shards_stat`: Your Metal Shards stat +- `light_shards_stat`: Your Light Shards stat +- `soul_shards_stat`: Your Soul Shards stat +- `demon_keys_stat`: Your Demon Keys stat +- `total_orbs_stat`: Your Total Orbs stat +- `moons_stat`: Your Moons stat +- `diamond_shards_stat`: Your Diamond Shards stat +- `completed_gauntlets_stat`: Your Completed Gauntlets stat +- `collected_list_rewards_stat`: Your Collected List Rewards stat + +The next variables require you to be within a level, either info, playing, or editing + +- `level_creator`: The creator of the level +- `level_name`: The name of the level +- `level_description`: The description of the level +- `level_id`: The ID of the level +- `level_normal_percent`: The percent you have in normal mode on the level +- `level_practice_percent`: The percent you have in practice mode on the level +- `level_attempts`: The attempts you have on the level +- `level_attempt_time`: The attempt time you have on the level +- `level_best_time`: The best time you have on the level +- `level_jumps`: The total jumps you have on the level +- `level_password`: The level password +- `level_stars`: The level stars/moons +- `level_length_value`: The level length in number form # Replaceable Textures @@ -1434,6 +1509,8 @@ A list of modifyable colors provided are as follows: - comment-cell-bg-odd - comment-cell-bg-even - comment-list-layer-bg +- music-cell-odd +- music-cell-even ## InfoLayer diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..8464761 --- /dev/null +++ b/changelog.md @@ -0,0 +1,7 @@ +## 1.6.0 +- Add extensive label variables with RIFT +- Add color changing for music library cells +- Code cleanup + +## <1.6.0 +- Add everything diff --git a/cmake/IncludeLibs.cmake b/cmake/IncludeLibs.cmake new file mode 100644 index 0000000..03af0df --- /dev/null +++ b/cmake/IncludeLibs.cmake @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.21) +add_library(third_party INTERFACE) + +CPMAddPackage("gh:EclipseMenu/rift#b8b31d6") + +if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND WIN32) + target_compile_definitions(rift PRIVATE _HAS_ITERATOR_DEBUGGING=0) +endif() + +target_link_libraries(third_party INTERFACE + rift +) \ No newline at end of file diff --git a/mod.json b/mod.json index 413b33a..19991a4 100644 --- a/mod.json +++ b/mod.json @@ -5,7 +5,7 @@ "android": "2.206", "mac": "2.206" }, - "version": "v1.5.2", + "version": "v1.6.0", "id": "alphalaneous.happy_textures", "name": "Happy Textures :3", "developer": "Alphalaneous", diff --git a/src/BackgroundColors.h b/src/BackgroundColors.h index 7638f23..082fda9 100644 --- a/src/BackgroundColors.h +++ b/src/BackgroundColors.h @@ -32,6 +32,10 @@ class $modify(CCDirector) { class $modify(LeaderboardsLayer) { + static void onModify(auto& self) { + (void) self.setHookPriority("LeaderboardsLayer::init", INT_MIN); + } + bool init(LeaderboardState p0) { if (!LeaderboardsLayer::init(p0)) return false; setBackground(this); @@ -41,6 +45,10 @@ class $modify(LeaderboardsLayer) { class $modify(LevelBrowserLayer) { + static void onModify(auto& self) { + (void) self.setHookPriority("LevelBrowserLayer::init", INT_MIN); + } + bool init(GJSearchObject* p0) { if (!LevelBrowserLayer::init(p0)) return false; setBackground(this); diff --git a/src/LabelValues.h b/src/LabelValues.h new file mode 100644 index 0000000..642ec0b --- /dev/null +++ b/src/LabelValues.h @@ -0,0 +1,311 @@ +#pragma once + +#include +#include +#include "Macros.h" + +using namespace geode::prelude; + +namespace LabelValues { + + static std::pair getUsername() { + + auto accountManager = GJAccountManager::get(); + std::string username = accountManager->m_accountID == 0 ? "Signed Out" : accountManager->m_username; + + return LABEL("username", username); + } + + static std::pair getGameVersion() { + return LABEL("game_version", GEODE_GD_VERSION_STRING); + } + + static std::pair getGeodeVersion() { + return LABEL("geode_version", Loader::get()->getVersion().toNonVString()); + } + + static std::pair getOriginalString(std::string str) { + return LABEL("previous_string", str); + } + + static std::pair getJumps() { + return LABEL("jumps_stat", STAT(1)); + } + + static std::pair getAttempts() { + return LABEL("attempts_stat", STAT(2)); + } + + static std::pair getCompletedLevels() { + return LABEL("completed_levels_stat", STAT(3)); + } + + static std::pair getCompletedOnlineLevels() { + return LABEL("completed_online_levels_stat", STAT(4)); + } + + static std::pair getDemons() { + return LABEL("demons_stat", STAT(5)); + } + + static std::pair getStars() { + return LABEL("stars_stat", STAT(6)); + } + + static std::pair getCompletedMapPacks() { + return LABEL("completed_map_packs_stat", STAT(7)); + } + + static std::pair getGoldCoins() { + return LABEL("gold_coins_stat", STAT(8)); + } + + static std::pair getPlayersDestroyed() { + return LABEL("players_destroyed_stat", STAT(9)); + } + + static std::pair getLikedLevels() { + return LABEL("liked_levels_stat", STAT(10)); + } + + static std::pair getRatedLevels() { + return LABEL("rated_levels_stat", STAT(11)); + } + + static std::pair getUserCoins() { + return LABEL("user_coins_stat", STAT(12)); + } + + static std::pair getDiamonds() { + return LABEL("diamonds_stat", STAT(13)); + } + + static std::pair getCurrentOrbs() { + return LABEL("current_orbs_stat", STAT(14)); + } + + static std::pair getCompletedDailies() { + return LABEL("completed_dailies_stat", STAT(15)); + } + + static std::pair getFireShards() { + return LABEL("fire_shards_stat", STAT(16)); + } + + static std::pair getIceShards() { + return LABEL("ice_shards_stat", STAT(17)); + } + + static std::pair getPoisonShards() { + return LABEL("poison_shards_stat", STAT(18)); + } + + static std::pair getShadowShards() { + return LABEL("shadow_shards_stat", STAT(19)); + } + + static std::pair getLavaShards() { + return LABEL("lava_shards_stat", STAT(20)); + } + + static std::pair getDemonKeys() { + return LABEL("demon_keys_stat", STAT(21)); + } + + static std::pair getTotalOrbs() { + return LABEL("total_orbs_stat", STAT(22)); + } + + static std::pair getEarthShards() { + return LABEL("earth_shards_stat", STAT(23)); + } + + static std::pair getBloodShards() { + return LABEL("blood_shards_stat", STAT(24)); + } + + static std::pair getMetalShards() { + return LABEL("metal_shards_stat", STAT(25)); + } + + static std::pair getLightShards() { + return LABEL("light_shards_stat", STAT(26)); + } + + static std::pair getSoulShards() { + return LABEL("soul_shards_stat", STAT(27)); + } + + static std::pair getMoons() { + return LABEL("moons_stat", STAT(28)); + } + + static std::pair getDiamondShards() { + return LABEL("diamond_shards_stat", STAT(29)); + } + + static std::pair getCompletedGauntlets() { + return LABEL("completed_gauntlets_stat", STAT(40)); + } + + static std::pair getCollectedListRewards() { + return LABEL("collected_list_rewards_stat", STAT(41)); + } + + static std::pair getLevelCreator() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_creator", level->m_creatorName); + } + return LABEL("level_creator", "null"); + } + + static std::pair getLevelName() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_name", level->m_levelName); + } + return LABEL("level_name", "null"); + } + + static std::pair getLevelDescription() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_description", level->m_levelDesc); + } + return LABEL("level_description", "null"); + } + + static std::pair getLevelID() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_id", level->m_levelID.value()); + } + return LABEL("level_id", "null"); + } + + static std::pair getNormalPercent() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_normal_percent", level->m_normalPercent.value()); + } + return LABEL("level_normal_percent", "null"); + } + + static std::pair getPracticePercent() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_practice_percent", level->m_practicePercent); + } + return LABEL("level_practice_percent", "null"); + } + + static std::pair getLevelAttempts() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_attempts", level->m_attempts.value()); + } + return LABEL("level_attempts", "null"); + } + + static std::pair getLevelAttemptTime() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_attempt_time", level->m_attemptTime.value()); + } + return LABEL("level_attempt_time", "null"); + } + + static std::pair getLevelBestTime() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_best_time", level->m_bestTime); + } + return LABEL("level_best_time", "null"); + } + + static std::pair getLevelJumps() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_jumps", level->m_jumps.value()); + } + return LABEL("level_jumps", "null"); + } + + static std::pair getLevelPassword() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_password", level->m_password.value()); + } + return LABEL("level_password", "null"); + } + + static std::pair getLevelStars() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_stars", level->m_stars.value()); + } + return LABEL("level_stars", "null"); + } + + static std::pair getLevelLengthValue() { + GJGameLevel* level = Utils::getLevel(); + if (level) { + return LABEL("level_length_value", level->m_levelLength); + } + return LABEL("level_length_value", "null"); + } + + static std::unordered_map getValueMap(std::string original) { + return { + getUsername(), + getGameVersion(), + getGeodeVersion(), + getOriginalString(original), + getJumps(), + getAttempts(), + getCompletedLevels(), + getCompletedOnlineLevels(), + getDemons(), + getStars(), + getCompletedMapPacks(), + getGoldCoins(), + getPlayersDestroyed(), + getLikedLevels(), + getRatedLevels(), + getUserCoins(), + getDiamonds(), + getCurrentOrbs(), + getCompletedDailies(), + getFireShards(), + getIceShards(), + getPoisonShards(), + getShadowShards(), + getLavaShards(), + getDemonKeys(), + getTotalOrbs(), + getEarthShards(), + getBloodShards(), + getMetalShards(), + getLightShards(), + getSoulShards(), + getMoons(), + getDiamondShards(), + getCompletedGauntlets(), + getCollectedListRewards(), + getLevelCreator(), + getLevelName(), + getLevelDescription(), + getLevelID(), + getNormalPercent(), + getPracticePercent(), + getLevelAttempts(), + getLevelAttemptTime(), + getLevelBestTime(), + getLevelJumps(), + getLevelPassword(), + getLevelStars(), + getLevelLengthValue() + }; + } +}; \ No newline at end of file diff --git a/src/Macros.h b/src/Macros.h index 48ecfe0..c397d2f 100644 --- a/src/Macros.h +++ b/src/Macros.h @@ -117,8 +117,10 @@ struct My##class : geode::Modify { \ };\ void method(paramType* p0){\ class::method(p0);\ - checkBG(0);\ - this->schedule(schedule_selector(My##class::checkBG));\ + if (UIModding::get()->doModify) {\ + checkBG(0);\ + this->schedule(schedule_selector(My##class::checkBG));\ + }\ }\ void checkBG(float dt) {\ CCLayerColor* child = getChildOfType(this, 0);\ @@ -146,4 +148,8 @@ struct My##class : geode::Modify { \ }\ }; -#define SAFE_RUN(method) retain(); method release(); \ No newline at end of file +#define SAFE_RUN(method) retain(); method release(); + +#define LABEL(name, value) {name, rift::Value::from(value)} + +#define STAT(key) Utils::getValidStat(#key) \ No newline at end of file diff --git a/src/UIModding.cpp b/src/UIModding.cpp index 69dc1b9..9ee7e82 100644 --- a/src/UIModding.cpp +++ b/src/UIModding.cpp @@ -860,6 +860,7 @@ void UIModding::setText(CCNode* node, matjson::Object attributes){ if (textObject) { MyCCLabelBMFont* myTextObject = static_cast(textObject); + myTextObject->setHappyTexturesModified(); textObject->setString(text.c_str()); if(myTextObject->m_fields->m_isLimited){ diff --git a/src/Utils.h b/src/Utils.h index 215a708..9b0cdb7 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -6,7 +6,7 @@ using namespace geode::prelude; namespace Utils { - inline void updateSprite(CCMenuItemSpriteExtra* button) { + static void updateSprite(CCMenuItemSpriteExtra* button) { auto sprite = button->getNormalImage(); auto size = sprite->getScaledContentSize(); @@ -15,7 +15,39 @@ namespace Utils { button->setContentSize(size); } - inline bool hasNode(CCNode* child, CCNode* node) { + template + static T getLayer() { + if (CCScene* scene = CCDirector::get()->m_pRunningScene) { + for (CCNode* node : CCArrayExt(scene->getChildren())) { + if (T layer = typeinfo_cast(node)) { + return layer; + } + } + } + return nullptr; + } + + static int getValidStat(std::string key) { + std::string val = GameStatsManager::sharedState()->m_playerStats->valueForKey(key)->m_sString; + + if (val.empty()) val = "0"; + Result result = geode::utils::numFromString(val); + if (result.isOk()) return result.unwrap(); + return -1; + } + + static GJGameLevel* getLevel() { + GJGameLevel* level = nullptr; + if (GJBaseGameLayer* gjbgl = GJBaseGameLayer::get()) { + level = gjbgl->m_level; + } + if (LevelInfoLayer* lil = Utils::getLayer()) { + level = lil->m_level; + } + return level; + } + + static bool hasNode(CCNode* child, CCNode* node) { CCNode* parent = child; while (true) { if (parent) { @@ -29,7 +61,7 @@ namespace Utils { return false; } - inline std::string strReplace(std::string subject, std::string search, std::string replace) { + static std::string strReplace(std::string subject, std::string search, std::string replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); @@ -40,7 +72,7 @@ namespace Utils { //fix texture loader fallback - inline CCSprite* getValidSprite(const char* sprName) { + static CCSprite* getValidSprite(const char* sprName) { CCSprite* spr = CCSprite::create(sprName); if (!spr || spr->getUserObject("geode.texture-loader/fallback")) { return nullptr; @@ -50,7 +82,7 @@ namespace Utils { //fix texture loader fallback - inline CCSprite* getValidSpriteFrame(const char* sprName) { + static CCSprite* getValidSpriteFrame(const char* sprName) { CCSprite* spr = CCSprite::createWithSpriteFrameName(sprName); if (!spr || spr->getUserObject("geode.texture-loader/fallback")) { return nullptr; @@ -58,7 +90,7 @@ namespace Utils { return spr; } - inline void setColorIfExists(CCRGBAProtocol* node, std::string colorId) { + static void setColorIfExists(CCRGBAProtocol* node, std::string colorId) { if (!node) return; std::optional dataOpt = UIModding::get()->getColors(colorId); if (dataOpt.has_value()) { @@ -68,7 +100,7 @@ namespace Utils { } } - inline std::string getSpriteName(CCSprite* sprite) { + static std::string getSpriteName(CCSprite* sprite) { if (auto texture = sprite->getTexture()) { for (auto [key, frame] : CCDictionaryExt(CCSpriteFrameCache::sharedSpriteFrameCache()->m_pSpriteFrames)) { if (frame->getTexture() == texture && frame->getRect() == sprite->getTextureRect()) return key; diff --git a/src/main.cpp b/src/main.cpp index e2f8748..5f1f785 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,9 +18,6 @@ #include "nodes/GJChestSprite.h" #include "nodes/CCTextInputNode.h" #include "nodes/LevelInfoLayer.h" +#include "nodes/CustomMusicCell.h" #include "icons/IconHandler.h" -#include "BackgroundColors.h" -#include "BackgroundColors.h" - -using namespace geode::prelude; - +#include "BackgroundColors.h" \ No newline at end of file diff --git a/src/nodes/CCLabelBMFont.h b/src/nodes/CCLabelBMFont.h index d9063ff..d1a2431 100644 --- a/src/nodes/CCLabelBMFont.h +++ b/src/nodes/CCLabelBMFont.h @@ -3,6 +3,9 @@ #include #include #include "../Utils.h" +#include "../LabelValues.h" +#include + using namespace geode::prelude; @@ -14,8 +17,29 @@ class $modify(MyCCLabelBMFont, CCLabelBMFont) { float m_limitMinScale = 1; bool m_isLimited = false; SEL_SCHEDULE m_schedule; + bool m_isHappyTexturesModified; }; + void setString(const char *newString, bool needUpdateLabel) { + + if (m_fields->m_isHappyTexturesModified) { + rift::Result scriptRes = rift::compile(std::string_view(newString)); + if (!scriptRes.isError()) { + rift::Script* script = scriptRes.unwrap(); + auto vars = LabelValues::getValueMap(getString()); + std::string newNewString = script->run(vars); + delete script; + return CCLabelBMFont::setString(newNewString.c_str(), needUpdateLabel); + } + } + + CCLabelBMFont::setString(newString, needUpdateLabel); + } + + void setHappyTexturesModified() { + m_fields->m_isHappyTexturesModified = true; + } + void limitLabelWidth(float width, float defaultScale, float minScale) { m_fields->m_limitWidth = width; diff --git a/src/nodes/CommentCell.h b/src/nodes/CommentCell.h index 9417d8e..92aa932 100644 --- a/src/nodes/CommentCell.h +++ b/src/nodes/CommentCell.h @@ -18,36 +18,36 @@ class $modify(MyCommentCell, CommentCell) { void loadFromComment(GJComment* p0) { CommentCell::loadFromComment(p0); - this->schedule(schedule_selector(MyCommentCell::checkBG)); + if (UIModding::get()->doModify) { + this->schedule(schedule_selector(MyCommentCell::checkBG)); + } } void checkBG(float dt) { if (CCLayerColor* child = getChildOfType(this, 0)) { if (m_fields->m_lastBG != child->getColor()) { m_fields->m_lastBG = child->getColor(); - if (UIModding::get()->doModify) { - CCLayer* layer = getChildOfType(this, 1); - CCScale9Sprite* bg = getChildOfType(layer, 0); - - if (child->getColor() == ccColor3B{161,88,44}) { - Utils::setColorIfExists(child, "comment-cell-odd"); - if (bg) { - Utils::setColorIfExists(child, "comment-cell-bg-odd"); - } - } - else if (child->getColor() == ccColor3B{194,114,62}) { - Utils::setColorIfExists(child, "comment-cell-even"); - if (bg) { - Utils::setColorIfExists(child, "comment-cell-bg-even"); - } - } - else if (child->getColor() == ccColor3B{156,85,42}) { - Utils::setColorIfExists(child, "comment-cell-small-odd"); + CCLayer* layer = getChildOfType(this, 1); + CCScale9Sprite* bg = getChildOfType(layer, 0); + + if (child->getColor() == ccColor3B{161,88,44}) { + Utils::setColorIfExists(child, "comment-cell-odd"); + if (bg) { + Utils::setColorIfExists(child, "comment-cell-bg-odd"); } - else if (child->getColor() == ccColor3B{144,79,39}) { - Utils::setColorIfExists(child, "comment-cell-small-even"); + } + else if (child->getColor() == ccColor3B{194,114,62}) { + Utils::setColorIfExists(child, "comment-cell-even"); + if (bg) { + Utils::setColorIfExists(child, "comment-cell-bg-even"); } } + else if (child->getColor() == ccColor3B{156,85,42}) { + Utils::setColorIfExists(child, "comment-cell-small-odd"); + } + else if (child->getColor() == ccColor3B{144,79,39}) { + Utils::setColorIfExists(child, "comment-cell-small-even"); + } } } } diff --git a/src/nodes/CustomMusicCell.h b/src/nodes/CustomMusicCell.h new file mode 100644 index 0000000..09d8fd2 --- /dev/null +++ b/src/nodes/CustomMusicCell.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +using namespace geode::prelude; + +class $modify(MyCustomMusicCell, CustomMusicCell) { + + static void onModify(auto& self) { + (void) self.setHookPriority("CustomMusicCell::loadFromObject", INT_MIN); + } + + struct Fields { + ccColor3B m_lastBG; + }; + + void loadFromObject(SongInfoObject* p0){ + CustomMusicCell::loadFromObject(p0); + if (UIModding::get()->doModify) { + checkBG(0); + this->schedule(schedule_selector(MyCustomMusicCell::checkBG)); + } + } + + void checkBG(float dt) { + CCLayerColor* child = getChildOfType(this, 0); + if (child) { + if (m_fields->m_lastBG != child->getColor()) { + m_fields->m_lastBG = child->getColor(); + if (child->getColor() == ccColor3B{75,75,75}) { + std::optional dataOpt = UIModding::get()->getColors("music-cell-odd"); + if (dataOpt.has_value()) { + ColorData data = dataOpt.value(); + child->setColor(data.color); + child->setOpacity(data.alpha); + } + } + else if (child->getColor() == ccColor3B{50,50,50}) { + std::optional dataOpt = UIModding::get()->getColors("music-cell-even"); + if (dataOpt.has_value()) { + ColorData data = dataOpt.value(); + child->setColor(data.color); + child->setOpacity(data.alpha); + } + } + } + } + } +}; \ No newline at end of file diff --git a/src/nodes/LevelInfoLayer.h b/src/nodes/LevelInfoLayer.h index be67222..81538ec 100644 --- a/src/nodes/LevelInfoLayer.h +++ b/src/nodes/LevelInfoLayer.h @@ -7,6 +7,10 @@ using namespace geode::prelude; class $modify(MyLevelInfoLayer, LevelInfoLayer) { + static void onModify(auto& self) { + (void) self.setHookPriority("LevelInfoLayer::loadLevelStep", INT_MIN); + } + struct Fields { bool m_didLoad; };