From 4ffec215332646def877215f6d46e5e34bf9ad5b Mon Sep 17 00:00:00 2001 From: Fleeym <61891787+Fleeym@users.noreply.github.com> Date: Fri, 13 Oct 2023 00:26:57 +0300 Subject: [PATCH 1/2] add group and color offsets for next free --- CMakeLists.txt | 1 + src/Features/OffsetNextFree/OffsetManager.hpp | 26 +++ .../OffsetNextFree/OffsetNextFree.cpp | 206 ++++++++++++++++++ .../OffsetNextFree/OffsetNextFreePopup.cpp | 146 +++++++++++++ .../OffsetNextFree/OffsetNextFreePopup.hpp | 33 +++ src/Features/OffsetNextFree/OffsetType.hpp | 6 + 6 files changed, 418 insertions(+) create mode 100644 src/Features/OffsetNextFree/OffsetManager.hpp create mode 100644 src/Features/OffsetNextFree/OffsetNextFree.cpp create mode 100644 src/Features/OffsetNextFree/OffsetNextFreePopup.cpp create mode 100644 src/Features/OffsetNextFree/OffsetNextFreePopup.hpp create mode 100644 src/Features/OffsetNextFree/OffsetType.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e2808f04..c08db58d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ file(GLOB SOURCES src/features/VisibilityToggle/*.cpp src/features/BetterScaling/*.cpp src/features/StartPosSwitcher/*.cpp + src/features/OffsetNextFree/*.cpp src/features/*.cpp src/other/*.cpp src/*.cpp diff --git a/src/Features/OffsetNextFree/OffsetManager.hpp b/src/Features/OffsetNextFree/OffsetManager.hpp new file mode 100644 index 00000000..0c61ae94 --- /dev/null +++ b/src/Features/OffsetNextFree/OffsetManager.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +using namespace geode::prelude; + +class OffsetManager : public CCObject { +protected: + inline static OffsetManager* s_instance = nullptr; + +public: + size_t m_groupOffset = 0; + size_t m_colorOffset = 0; + static OffsetManager* get() { + if (!s_instance) { + s_instance = new OffsetManager; + if (s_instance) { + return s_instance; + } + CC_SAFE_DELETE(s_instance); + return nullptr; + } + + return s_instance; + } +}; \ No newline at end of file diff --git a/src/Features/OffsetNextFree/OffsetNextFree.cpp b/src/Features/OffsetNextFree/OffsetNextFree.cpp new file mode 100644 index 00000000..e284d65e --- /dev/null +++ b/src/Features/OffsetNextFree/OffsetNextFree.cpp @@ -0,0 +1,206 @@ +#include +#include +#include +#include + +#include "OffsetNextFreePopup.hpp" +#include "OffsetManager.hpp" + +using namespace geode::prelude; + +class $modify(LevelEditorLayer) { + int getNextColorChannel() { + std::array usedColors = this->getUsedColors(); + auto offset = OffsetManager::get()->m_colorOffset; + for (int i = 1; i < 1000; i++) { + if (!usedColors[i] && i >= offset) { + return i; + } + } + return 999; + } + + int getNextFreeGroupID(CCArray* p0) { + auto objects = this->getAllObjects(); + auto offset = OffsetManager::get()->m_groupOffset; + std::array usedGroups = this->getUsedGroups(CCArrayExt(objects)); + for (size_t i = 1; i < 1000; i++) { + if (!usedGroups[i] && i >= offset) { + return i; + } + } + return 999; + } + + std::array getUsedGroups(CCArrayExt objects) { + std::array ret; + std::fill(ret.begin(), ret.end(), false); + for (auto object : objects) { + for (short id : object->getGroupIDs()) { + ret[id] = true; + } + } + + return ret; + } + + std::array getUsedColors() { + std::array ret; + std::fill(ret.begin(), ret.end(), false); + for (auto object : CCArrayExt(m_objects)) { + if (object->m_baseColor) { + int colorID = 0; + if (object->m_baseColor->m_colorID == 0) { + colorID = object->m_baseColor->m_defaultColorID; + } else { + colorID = object->m_baseColor->m_colorID; + } + + if (colorID < 1000) { + ret[colorID] = true; + } + } + + if (object->m_detailColor) { + int colorID = 0; + if (object->m_detailColor->m_colorID == 0) { + colorID = object->m_detailColor->m_defaultColorID; + } else { + colorID = object->m_detailColor->m_colorID; + } + + if (colorID < 1000) { + ret[colorID] = true; + } + } + } + auto effectManager = GJEffectManager::get(); + for (auto colorAction : effectManager->m_colorActionsForColor) { + if (!colorAction) { + continue; + } + ccColor3B white = {255, 255, 255}; + bool isDefaultColor = colorAction->m_fromColor == white && + colorAction->m_targetColor == white && + colorAction->m_duration == 0; + + if (isDefaultColor || colorAction->m_colorID > 999) { + continue; + } + + ret[colorAction->m_colorID] = true; + } + + return ret; + } + + bool colorExists(int colorID) { + bool ret = false; + for (auto object : CCArrayExt(m_objects)) { + if (object->m_baseColor) { + if ( + (object->m_baseColor->m_colorID == 0 && + object->m_baseColor->m_defaultColorID == colorID) || + object->m_baseColor->m_colorID == colorID + ) { + ret = true; + break; + } + } + if (object->m_detailColor) { + if ( + (object->m_detailColor->m_colorID == 0 && + object->m_detailColor->m_defaultColorID == colorID) || + object->m_detailColor->m_colorID == colorID + ) { + ret = true; + break; + } + } + } + return ret; + } +}; + +class $modify(OffsetCustomizeObjectLayer, CustomizeObjectLayer) { + bool init(GameObject* target, CCArray* targets) { + if (!CustomizeObjectLayer::init(target, targets)) { + return false; + } + auto offset = OffsetManager::get()->m_colorOffset; + std::string sprite; + if (offset == 0) { + sprite = "GJ_button_04.png"; + } else { + sprite = "GJ_button_02.png"; + } + + auto spr = ButtonSprite::create(std::to_string(offset).c_str(), 20, true, "goldFont.fnt", sprite.c_str(), 25, 0.6f); + auto button = CCMenuItemSpriteExtra::create( + spr, + this, + menu_selector(OffsetCustomizeObjectLayer::openOffsetPopup) + ); + button->setID("offset-button"_spr); + auto menu = static_cast(m_mainLayer->getChildByID("next-free-menu")); + menu->addChild(button); + menu->updateLayout(); + + return true; + } + + void openOffsetPopup(CCObject* sender) { + OffsetNextFreePopup::create(OffsetType::Color, this)->show(); + } +}; + +class $modify(OffsetSetGroupIDLayer, SetGroupIDLayer) { + bool init(GameObject* object, CCArray* objects) { + if (!SetGroupIDLayer::init(object, objects)) { + return false; + } + + auto menu = getChildOfType(this->m_mainLayer, 0); + auto offset = OffsetManager::get()->m_groupOffset; + std::string sprite; + if (offset == 0) { + sprite = "GJ_button_04.png"; + } else { + sprite = "GJ_button_02.png"; + } + + auto spr = ButtonSprite::create(std::to_string(offset).c_str(), 20, true, "goldFont.fnt", sprite.c_str(), 25, 0.6f); + auto button = CCMenuItemSpriteExtra::create( + spr, + this, + menu_selector(OffsetSetGroupIDLayer::openOffsetPopup) + ); + button->setID("offset-button"_spr); + menu->addChild(button); + button->setPosition(-85.f, 175.f); + + // This is some high level badassery + for (auto object : CCArrayExt(menu->getChildren())) { + auto buttonSprite = getChildOfType(object, 0); + if (!buttonSprite) { + continue; + } + + auto label = getChildOfType(buttonSprite, 0); + if (!label) { + continue; + } + + std::string labelStr = label->getString(); + if (labelStr == "Next Free") { + object->setPositionX(-140.f); + } + } + + return true; + } + + void openOffsetPopup(CCObject* sender) { + OffsetNextFreePopup::create(OffsetType::Group, this)->show(); + } +}; \ No newline at end of file diff --git a/src/Features/OffsetNextFree/OffsetNextFreePopup.cpp b/src/Features/OffsetNextFree/OffsetNextFreePopup.cpp new file mode 100644 index 00000000..cc6d00bd --- /dev/null +++ b/src/Features/OffsetNextFree/OffsetNextFreePopup.cpp @@ -0,0 +1,146 @@ +#include "OffsetNextFreePopup.hpp" + +bool OffsetNextFreePopup::setup(OffsetType offsetType, FLAlertLayer* parent) { + this->setTitle("Setup Offset"); + m_offsetType = offsetType; + m_parent = parent; + auto pos = CCDirector::sharedDirector()->getWinSize() / 2; + size_t offset = 0; + + switch (offsetType) { + case OffsetType::Color: + offset = OffsetManager::get()->m_colorOffset; + break; + case OffsetType::Group: + offset = OffsetManager::get()->m_groupOffset; + break; + } + + auto bg = CCScale9Sprite::create("square02b_001.png", { 0.0f, 0.0f, 80.0f, 80.0f }); + bg->setScale(0.5f); + bg->setColor({ 0, 0, 0 }); + bg->setOpacity(100); + bg->setContentSize({ 115.0f, 75.0f }); + bg->setPosition(pos); + bg->setID("offset-input-bg"_spr); + m_mainLayer->addChild(bg); + + auto input = CCTextInputNode::create(60.0f, 30.0f, "0", "bigFont.fnt"); + input->setPosition(pos); + input->setLabelPlaceholderColor({ 120, 120, 120 }); + input->setAllowedChars("0123456789"); + input->m_maxLabelLength = 4; + input->setScale(0.7f); + input->setID("offset-input"_spr); + if (offset != 0) { + input->setString(std::to_string(offset).c_str()); + } + m_offsetInput = input; + m_mainLayer->addChild(input); + + auto center = CCDirector::sharedDirector()->getWinSize() / 2; + + auto menu = CCMenu::create(); + menu->setID("offset-menu"_spr); + auto spr = ButtonSprite::create("Apply", 50, true, "goldFont.fnt", "GJ_button_01.png", 30, 1.f); + auto okButton = CCMenuItemSpriteExtra::create( + spr, + this, + menu_selector(OffsetNextFreePopup::onClose) + ); + okButton->setID("ok-button"_spr); + okButton->setPositionY(-50.f); + menu->addChild(okButton); + + if (offset != 0) { + auto spr2 = CCSprite::createWithSpriteFrameName("GJ_trashBtn_001.png"); + spr2->setScale(0.6f); + auto clearButton = CCMenuItemSpriteExtra::create( + spr2, + this, + menu_selector(OffsetNextFreePopup::onClear) + ); + clearButton->setID("clear-button"_spr); + clearButton->setPosition(-65.f, -50.f); + menu->addChild(clearButton); + } + + m_mainLayer->addChild(menu); + return true; +} + +void OffsetNextFreePopup::onClose(CCObject* sender) { + this->updateOffset(); + this->updateParentButton(); + switch (m_offsetType) { + case OffsetType::Color: { + auto parent = static_cast(m_parent); + parent->onNextColorChannel(sender); + } break; + case OffsetType::Group: { + auto parent = static_cast(m_parent); + parent->onNextGroupID1(sender); + } break; + } + Popup::onClose(sender); +} + +size_t OffsetNextFreePopup::getOffsetFromInput() { + size_t offset = 0; + std::string strValue = m_offsetInput->getString(); + if (strValue.length() != 0) { + try { + offset = std::stoi(strValue); + } catch (...) {} + } + if (offset > 999) { + offset = 999; + } + + return offset; +} + +void OffsetNextFreePopup::updateOffset() { + auto offset = this->getOffsetFromInput(); + switch (m_offsetType) { + case OffsetType::Color: + OffsetManager::get()->m_colorOffset = offset; + break; + case OffsetType::Group: + OffsetManager::get()->m_groupOffset = offset; + break; + } +} + +void OffsetNextFreePopup::updateParentButton() { + size_t offset; + switch (m_offsetType) { + case OffsetType::Color: + offset = OffsetManager::get()->m_colorOffset; + break; + case OffsetType::Group: + offset = OffsetManager::get()->m_groupOffset; + break; + } + std::string sprite; + if (offset == 0) { + sprite = "GJ_button_04.png"; + } else { + sprite = "GJ_button_02.png"; + } + + auto spr = ButtonSprite::create(std::to_string(offset).c_str(), 20, true, "goldFont.fnt", sprite.c_str(), 25, 0.6f); + CCMenu* menu; + menu = static_cast(m_parent->m_mainLayer->getChildByID("next-free-menu")); + if (!menu) { + menu = getChildOfType(m_parent->m_mainLayer, 0); + } + auto button = static_cast(menu->getChildByID("offset-button"_spr)); + button->setNormalImage(spr); +} + +void OffsetNextFreePopup::onClear(CCObject* sender) { + m_offsetInput->setString("0"); + + this->onClose(sender); +} \ No newline at end of file diff --git a/src/Features/OffsetNextFree/OffsetNextFreePopup.hpp b/src/Features/OffsetNextFree/OffsetNextFreePopup.hpp new file mode 100644 index 00000000..58122cec --- /dev/null +++ b/src/Features/OffsetNextFree/OffsetNextFreePopup.hpp @@ -0,0 +1,33 @@ +#include +#include + +#include "OffsetType.hpp" +#include "OffsetManager.hpp" + +using namespace geode::prelude; + +class OffsetNextFreePopup : public Popup { +protected: + OffsetType m_offsetType; + CCTextInputNode* m_offsetInput = nullptr; + FLAlertLayer* m_parent = nullptr; + bool setup(OffsetType offsetType, FLAlertLayer* parent) override; + + virtual void onClose(CCObject*) override; +public: + size_t getOffsetFromInput(); + void updateOffset(); + void updateParentButton(); + void onClear(CCObject*); + + static OffsetNextFreePopup* create(OffsetType offsetType, FLAlertLayer* parent) { + auto ret = new OffsetNextFreePopup; + if (ret && ret->init(175.f, 150.f, offsetType, parent, "GJ_square02.png")) { + ret->autorelease(); + return ret; + } + + CC_SAFE_DELETE(ret); + return nullptr; + } +}; \ No newline at end of file diff --git a/src/Features/OffsetNextFree/OffsetType.hpp b/src/Features/OffsetNextFree/OffsetType.hpp new file mode 100644 index 00000000..a6bcb1cd --- /dev/null +++ b/src/Features/OffsetNextFree/OffsetType.hpp @@ -0,0 +1,6 @@ +#pragma once + +enum OffsetType { + Color, + Group +}; \ No newline at end of file From 78583a22a0b8eb2b406b6162b99968634dc0184a Mon Sep 17 00:00:00 2001 From: Fleeym <61891787+Fleeym@users.noreply.github.com> Date: Fri, 13 Oct 2023 00:28:26 +0300 Subject: [PATCH 2/2] whoops use 1000 size instead of 1100 --- src/Features/OffsetNextFree/OffsetNextFree.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Features/OffsetNextFree/OffsetNextFree.cpp b/src/Features/OffsetNextFree/OffsetNextFree.cpp index e284d65e..aa40df91 100644 --- a/src/Features/OffsetNextFree/OffsetNextFree.cpp +++ b/src/Features/OffsetNextFree/OffsetNextFree.cpp @@ -10,7 +10,7 @@ using namespace geode::prelude; class $modify(LevelEditorLayer) { int getNextColorChannel() { - std::array usedColors = this->getUsedColors(); + std::array usedColors = this->getUsedColors(); auto offset = OffsetManager::get()->m_colorOffset; for (int i = 1; i < 1000; i++) { if (!usedColors[i] && i >= offset) { @@ -44,8 +44,8 @@ class $modify(LevelEditorLayer) { return ret; } - std::array getUsedColors() { - std::array ret; + std::array getUsedColors() { + std::array ret; std::fill(ret.begin(), ret.end(), false); for (auto object : CCArrayExt(m_objects)) { if (object->m_baseColor) {