diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6225beb..b5ca862 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,13 +32,13 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Checkout Pro - uses: actions/checkout@v4 - with: - repository: HJfod/BetterEditPro - path: pro - token: ${{ secrets.ACCESS_TOKEN }} - ref: v6 + # - name: Checkout Pro + # uses: actions/checkout@v4 + # with: + # repository: HJfod/BetterEditPro + # path: pro + # token: ${{ secrets.ACCESS_TOKEN }} + # ref: v6 - name: Build the mod uses: geode-sdk/build-geode-mod@main diff --git a/CMakeLists.txt b/CMakeLists.txt index f8df685..4e34ff6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden) project(BetterEdit VERSION 1.0.0) -if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/pro/) +if (NOT DONT_INCLUDE_PRO AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/pro/) message(STATUS "Including Pro features") set(BE_PRO_FOUND TRUE) else() @@ -26,11 +26,7 @@ file(GLOB SOURCES ) if (${BE_PRO_FOUND}) - file(GLOB PRO_SOURCES - pro/*.cpp - pro/features/*.cpp - pro/ui/*.cpp - ) + include(pro/ProSources.cmake) endif() add_library(${PROJECT_NAME} SHARED ${SOURCES} ${PRO_SOURCES}) @@ -39,6 +35,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC "src") if (${BE_PRO_FOUND}) target_include_directories(${PROJECT_NAME} PUBLIC "") target_compile_definitions(${PROJECT_NAME} PUBLIC BETTEREDIT_PRO) + + include(pro/OpenSSL.cmake) endif() if (NOT DEFINED ENV{GEODE_SDK}) diff --git a/changelog.md b/changelog.md index 8af6275..5f92839 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,10 @@ # BetterEdit 6 +## v6.6.3 + * Add a Support button to the pause menu (that can be hidden through the popup) + * Add Developer Mode setting + * Fix a bug with backups overwriting the level + ## v6.6.2 * Fix bugs with auto-save that made it impossible to save any new progress as well as causing levels to be duplicated and made it impossible to delete levels diff --git a/mod.json b/mod.json index e7eab50..1a91d7e 100644 --- a/mod.json +++ b/mod.json @@ -1,6 +1,6 @@ { "geode": "3.2.0", - "version": "6.6.2", + "version": "6.6.3", "gd": { "win": "2.206", "mac": "2.206", @@ -57,7 +57,10 @@ "ViewTabSheet": [ "resources/view/*.png" ] - } + }, + "sprites": [ + "resources/images/*.png" + ] }, "settings": { "auto-save-rate": { @@ -164,6 +167,12 @@ "name": "Show Grid on Size Change", "description": "If the grid is currently hidden and you use the controls to change its size, its toggled on", "platforms": ["win", "android64"] + }, + "dev-mode": { + "type": "bool", + "default": false, + "name": "Developer Mode", + "description": "Enables some features intended for Developers" } }, "tags": ["editor", "enhancement", "utility", "customization"] diff --git a/resources/images/support-popup.png b/resources/images/support-popup.png new file mode 100644 index 0000000..7ba35c7 Binary files /dev/null and b/resources/images/support-popup.png differ diff --git a/resources/support-btn-glow.png b/resources/support-btn-glow.png new file mode 100644 index 0000000..511be1e Binary files /dev/null and b/resources/support-btn-glow.png differ diff --git a/resources/support-btn.png b/resources/support-btn.png new file mode 100644 index 0000000..9e34b7a Binary files /dev/null and b/resources/support-btn.png differ diff --git a/src/features/CopyParticleString.cpp b/src/features/CopyParticleString.cpp new file mode 100644 index 0000000..2d8a55c --- /dev/null +++ b/src/features/CopyParticleString.cpp @@ -0,0 +1,68 @@ +#include + +using namespace geode::prelude; + +class $modify(CopyParticleStringPopup, CreateParticlePopup) { + $override + bool init(ParticleGameObject* obj, CCArray* objs, gd::string str) { + if (!CreateParticlePopup::init(obj, objs, str)) + return false; + + if (!Mod::get()->template getSettingValue("dev-mode")) { + return true; + } + + auto menu = CCMenu::create(); + menu->setID("side-menu"_spr); + menu->setPosition(m_obContentSize.width / 2 - 100, 30); + + if (obj) { + auto copySpr = ButtonSprite::create("CS", "bigFont.fnt", "GJ_button_05.png", .8f); + auto copyBtn = CCMenuItemSpriteExtra::create( + copySpr, this, menu_selector(CopyParticleStringPopup::onCopyString) + ); + menu->addChild(copyBtn); + + auto pasteSpr = ButtonSprite::create("PS", "bigFont.fnt", "GJ_button_05.png", .8f); + auto pasteBtn = CCMenuItemSpriteExtra::create( + pasteSpr, this, menu_selector(CopyParticleStringPopup::onPasteString) + ); + menu->addChild(pasteBtn); + } + + menu->setLayout(RowLayout::create()->setDefaultScaleLimits(.1f, .3f)); + m_mainLayer->addChild(menu); + + handleTouchPriority(this); + + return true; + } + + void onCopyString(CCObject*) { + if (m_targetObject) { + if (clipboard::write(GameToolbox::saveParticleToString(m_particle))) { + Notification::create( + "Copied Particle String to Clipboard", + NotificationIcon::Success + )->show(); + } + else { + Notification::create( + "Unable to copy Particle String", + NotificationIcon::Error + )->show(); + } + } + } + void onPasteString(CCObject*) { + if (auto obj = m_targetObject) { + this->onClose(nullptr); + obj->setParticleString(clipboard::read()); + CreateParticlePopup::create(obj, nullptr)->show(); + Notification::create( + "Pasted Particle String from Clipboard", + NotificationIcon::Success + )->show(); + } + } +}; diff --git a/src/features/NextFreeOffset.cpp b/src/features/NextFreeOffset.cpp index ed035a5..0c6869e 100644 --- a/src/features/NextFreeOffset.cpp +++ b/src/features/NextFreeOffset.cpp @@ -25,7 +25,7 @@ struct GroupIDSource final { if (auto eobj = typeinfo_cast(obj)) { used.insert(eobj->m_centerGroupID); used.insert(eobj->m_targetGroupID); - used.insert(eobj->m_activateGroup); + log::info("targetGroupID: {}", eobj->m_targetGroupID); } } }; diff --git a/src/features/about/AboutBEButton.cpp b/src/features/about/AboutBEButton.cpp index 58332b1..8779a88 100644 --- a/src/features/about/AboutBEButton.cpp +++ b/src/features/about/AboutBEButton.cpp @@ -2,6 +2,7 @@ #include #include #include "AboutBEPopup.hpp" +#include "SupportPopup.hpp" using namespace geode::prelude; @@ -11,6 +12,65 @@ class $modify(AboutBEPauseLayer, EditorPauseLayer) { if (!EditorPauseLayer::init(lel)) return false; + if (!Mod::get()->template getSavedValue("dont-show-support-button")) { + if (auto topMenu = this->getChildByID("top-menu")) { + auto supportSpr = CCSprite::createWithSpriteFrameName("support-btn.png"_spr); + + auto glow = CCSprite::createWithSpriteFrameName("support-btn-glow.png"_spr); + glow->setZOrder(2); + glow->setBlendFunc({ GL_SRC_ALPHA, GL_ONE }); + glow->setOpacity(125); + glow->runAction(CCRepeat::create( + CCSequence::create( + CCEaseInOut::create(CCFadeTo::create(1.5f, 0), 4.f), + CCEaseInOut::create(CCFadeTo::create(1.5f, 125), 4.f), + nullptr + ), + 1000 + )); + supportSpr->addChildAtPosition(glow, Anchor::Center); + + auto particleFall = GameToolbox::particleFromString("37a-1a2a0.33a15a-90a92a0a0a59a0a0a-10a0a0a0a0a1a1a0a48a1a0a0a0a0.27451a0a1a0a0a1a0a165a1a0a0.686275a0a0.235294a0a1a0a0a0a0.61a0a0a0a0a0a0a0a0a2a1a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0", nullptr, false); + particleFall->setZOrder(-1); + particleFall->setScaleX(1.61f); + particleFall->setScaleY(1.61f); + supportSpr->addChildAtPosition(particleFall, Anchor::Bottom); + + auto particleTop1 = GameToolbox::particleFromString("5a-1a2a0.33a15a-90a180a0a0a59a0a0a-10a0a0a0a0a20a1a75a48a1a0a0a0a0.27451a0a1a0a2a1a0a165a1a0a0.686275a0a0.235294a0a1a0a0a0a0.61a0a21a8a29a22a-11a40a1a2a1a0a0a0a158a0a0a0a0a0a0a0a0a0a0a0a0a0a0", nullptr, false); + particleTop1->setPosition({ supportSpr->getContentWidth() * .25f, supportSpr->getContentHeight() / 2 }); + particleTop1->setZOrder(1); + particleTop1->setScaleX(.91f); + particleTop1->setScaleY(.91f); + particleTop1->setOpacity(105); + supportSpr->addChild(particleTop1); + + auto particleTop2 = GameToolbox::particleFromString("5a-1a2a0.33a15a-90a180a0a0a59a0a0a-10a0a0a0a0a20a1a75a48a1a0a0a0a0.27451a0a1a0a2a1a0a165a1a0a0.686275a0a0.235294a0a1a0a0a0a0.61a0a21a8a29a22a-11a40a1a2a1a0a0a0a158a0a0a0a0a0a0a0a0a0a0a0a0a0a0", nullptr, false); + particleTop2->setPosition({ supportSpr->getContentWidth() * .75f, supportSpr->getContentHeight() / 2 }); + particleTop2->setZOrder(1); + particleTop2->setScaleX(.91f); + particleTop2->setScaleY(.91f); + particleTop2->setOpacity(105); + supportSpr->addChild(particleTop2); + + supportSpr->setScale(.8f); + supportSpr->runAction(CCRepeat::create( + CCSequence::create( + CCEaseInOut::create(CCScaleTo::create(1.5f, .7f), 4.f), + CCEaseInOut::create(CCScaleTo::create(1.5f, .8f), 4.f), + nullptr + ), + 1000 + )); + + auto supportBtn = CCMenuItemSpriteExtra::create( + supportSpr, this, menu_selector(AboutBEPauseLayer::onSupport) + ); + supportBtn->setID("support-be-btn"_spr); + topMenu->addChild(supportBtn); + topMenu->updateLayout(); + } + } + auto menu = this->getChildByID("guidelines-menu"); auto spr = CCSprite::createWithSpriteFrameName("be-button.png"_spr); @@ -72,6 +132,9 @@ class $modify(AboutBEPauseLayer, EditorPauseLayer) { )); } + void onSupport(CCObject*) { + SupportPopup::create(true)->show(); + } void onAbout(CCObject*) { AboutBEPopup::create()->show(); } diff --git a/src/features/about/AboutBEPopup.cpp b/src/features/about/AboutBEPopup.cpp index abc12d0..fd8f553 100644 --- a/src/features/about/AboutBEPopup.cpp +++ b/src/features/about/AboutBEPopup.cpp @@ -1,5 +1,6 @@ #include "AboutBEPopup.hpp" #include "ChangelogPopup.hpp" +#include "SupportPopup.hpp" #include #include #include @@ -184,7 +185,8 @@ bool AboutBEPopup::setup() { } void AboutBEPopup::onSupport(CCObject*) { - openSupportPopup(Mod::get()); + SupportPopup::create(false)->show(); + // openSupportPopup(Mod::get()); } void AboutBEPopup::onSuggestFeature(CCObject*) { diff --git a/src/features/about/SupportPopup.cpp b/src/features/about/SupportPopup.cpp new file mode 100644 index 0000000..42f8577 --- /dev/null +++ b/src/features/about/SupportPopup.cpp @@ -0,0 +1,78 @@ +#include "SupportPopup.hpp" +#include + +bool SupportPopup::setup(bool showDontShowAgain) { + m_bgSprite->setVisible(false); + + auto bg = CCSprite::create("support-popup.png"_spr); + m_mainLayer->addChildAtPosition(bg, Anchor::Center); + + auto invisibleSupportSpr = ButtonSprite::create("Support", "goldFont.fnt", "GJ_button_01.png", .8f); + invisibleSupportSpr->setScale(1.8f); + invisibleSupportSpr->setVisible(false); + auto invisibleSupportBtn = CCMenuItemSpriteExtra::create( + invisibleSupportSpr, this, menu_selector(SupportPopup::onKofi) + ); + m_buttonMenu->addChildAtPosition(invisibleSupportBtn, Anchor::Center, ccp(0, 20)); + + + auto bottomMenu = CCMenu::create(); + bottomMenu->setContentWidth(100); + bottomMenu->setAnchorPoint({ .5f, .5f }); + + auto supportSpr = ButtonSprite::create("Support", "goldFont.fnt", "GJ_button_01.png", .8f); + auto supportBtn = CCMenuItemSpriteExtra::create( + supportSpr, this, menu_selector(SupportPopup::onKofi) + ); + bottomMenu->addChild(supportBtn); + + bottomMenu->setLayout(RowLayout::create()->setDefaultScaleLimits(.1f, 1.f)); + m_mainLayer->addChildAtPosition(bottomMenu, Anchor::Bottom, ccp(0, 18)); + + + if (showDontShowAgain) { + auto shutupMenu = CCMenu::create(); + shutupMenu->setContentWidth(100); + shutupMenu->setAnchorPoint({ 1, .5f }); + + auto shutupSpr = ButtonSprite::create("Don't Show Again", "goldFont.fnt", "GJ_button_01.png", .8f); + auto shutupBtn = CCMenuItemSpriteExtra::create( + shutupSpr, this, menu_selector(SupportPopup::onDontShowAgain) + ); + shutupMenu->addChild(shutupBtn); + + shutupMenu->setLayout(RowLayout::create()->setDefaultScaleLimits(.1f, .5f)); + m_mainLayer->addChildAtPosition(shutupMenu, Anchor::TopRight, ccp(15, 5)); + } + + return true; +} + +void SupportPopup::onKofi(CCObject*) { + web::openLinkInBrowser("https://ko-fi.com/HJfod"); +} + +void SupportPopup::onDontShowAgain(CCObject*) { + Mod::get()->setSavedValue("dont-show-support-button", true); + this->onClose(nullptr); + if (auto btn = CCScene::get()->querySelector("support-be-btn"_spr)) { + btn->removeFromParent(); + } + FLAlertLayer::create( + "Support", + "If you want to support BetterEdit in the future, you can find the " + "support button in the About popup!\n\n" + "This button won't be shown again :)", + "OK" + )->show(); +} + +SupportPopup* SupportPopup::create(bool showDontShowAgain) { + auto ret = new SupportPopup(); + if (ret && ret->initAnchored(410, 270, showDontShowAgain)) { + ret->autorelease(); + return ret; + } + CC_SAFE_DELETE(ret); + return nullptr; +} diff --git a/src/features/about/SupportPopup.hpp b/src/features/about/SupportPopup.hpp new file mode 100644 index 0000000..c3bb5c9 --- /dev/null +++ b/src/features/about/SupportPopup.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +using namespace geode::prelude; + +class SupportPopup : public Popup { +protected: + bool setup(bool showDontShowAgain) override; + + void onKofi(CCObject*); + void onDontShowAgain(CCObject*); + +public: + static SupportPopup* create(bool showDontShowAgain); +}; diff --git a/src/features/backups/QuickSave.cpp b/src/features/backups/QuickSave.cpp index 66cfd72..4fa151e 100644 --- a/src/features/backups/QuickSave.cpp +++ b/src/features/backups/QuickSave.cpp @@ -5,6 +5,7 @@ #include #include #include +#include using namespace geode::prelude; @@ -69,6 +70,10 @@ class $modify(EditorPauseLayer) { $override void FLAlert_Clicked(FLAlertLayer* fl, bool btn2) { + if (isViewOnlyEditor(m_editorLayer)) { + return EditorPauseLayer::FLAlert_Clicked(fl, btn2); + } + // Discard autosaves on exit without save if (fl->getTag() == 1 && btn2) { log::warn("Discarding autosaved changes"); @@ -82,7 +87,11 @@ class $modify(EditorPauseLayer) { } $override - void onExitNoSave(CCObject*) { + void onExitNoSave(CCObject* sender) { + if (isViewOnlyEditor(m_editorLayer)) { + return EditorPauseLayer::onExitNoSave(sender); + } + auto fl = FLAlertLayer::create( this, "Exit", diff --git a/src/utils/Editor.cpp b/src/utils/Editor.cpp new file mode 100644 index 0000000..beaa367 --- /dev/null +++ b/src/utils/Editor.cpp @@ -0,0 +1,10 @@ +#include "Editor.hpp" + +std::vector getSelectedObjects(EditorUI* ui) { + if (ui->m_selectedObject) { + return std::vector({ ui->m_selectedObject }); + } + else { + return ccArrayToVector(ui->m_selectedObjects); + } +} diff --git a/src/utils/Editor.hpp b/src/utils/Editor.hpp new file mode 100644 index 0000000..c536a3f --- /dev/null +++ b/src/utils/Editor.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +using namespace geode::prelude; + +std::vector getSelectedObjects(EditorUI* ui);