diff --git a/changelog.md b/changelog.md index be4936c5..eddc3ea3 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # BetterEdit 6 +## v6.6.1 + * Auto-saved changes are now discarded if you exit without saving + * Fix Auto-Save countdown being permanently stuck on screen + * Fix Layer Controls being clipped a little off-screen + * Fix Group Offset not working + * Expand Changelog to include historical versions of BetterEdit too for the sake of fun + ## v6.6.0 * Add keybinds for Save Level, Build Helper, Align X, Align Y, Edit Object, Edit Group, Edit Special, Copy Values, Paste State, Paste Color, and Toggle Link Controls diff --git a/mod.json b/mod.json index 6691994c..4eb08a77 100644 --- a/mod.json +++ b/mod.json @@ -1,6 +1,6 @@ { - "geode": "3.1.1", - "version": "6.6.0", + "geode": "3.2.0", + "version": "6.6.1", "gd": { "win": "2.206", "mac": "2.206", diff --git a/src/features/CrashRecovery.cpp b/src/features/CrashRecovery.cpp deleted file mode 100644 index 9b940bbb..00000000 --- a/src/features/CrashRecovery.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include - -using namespace geode::prelude; - -class $modify(LevelEditorLayer) { - $override - bool init(GJGameLevel* level, bool unk) { - if (!LevelEditorLayer::init(level, unk)) - return false; - - if (!Mod::get()->template getSettingValue("soft-save-enabled")) { - return true; - } - - return true; - } -}; diff --git a/src/features/NextFreeOffset.cpp b/src/features/NextFreeOffset.cpp index a048eb75..ed035a54 100644 --- a/src/features/NextFreeOffset.cpp +++ b/src/features/NextFreeOffset.cpp @@ -1,6 +1,7 @@ #include #include +#include #include using namespace geode::prelude; diff --git a/src/features/TypeInZLayer.cpp b/src/features/TypeInZLayer.cpp index 0dfc4873..fff2ecf1 100644 --- a/src/features/TypeInZLayer.cpp +++ b/src/features/TypeInZLayer.cpp @@ -26,6 +26,9 @@ class $modify(TypeInUI, EditorUI) { auto layerMenu = this->getChildByID("layer-menu"); layerMenu->setContentSize({ 130, layerMenu->getContentSize().height }); + // Otherwise it clippety clips off the screen + layerMenu->setPositionX(layerMenu->getPositionX() - 10); + auto layerLockSpr = CCSprite::createWithSpriteFrameName("GJ_lockGray_001.png"); layerLockSpr->setScale(.75f); auto layerLockBtn = CCMenuItemSpriteExtra::create( diff --git a/src/features/ViewTab/PortalLineColors.cpp b/src/features/ViewTab/PortalLineColors.cpp index ba0d9dee..2ddc8d13 100644 --- a/src/features/ViewTab/PortalLineColors.cpp +++ b/src/features/ViewTab/PortalLineColors.cpp @@ -1,3 +1,5 @@ +// geode-begin-ignore-all + // #include // #include // #include diff --git a/src/features/backups/AutoSave.cpp b/src/features/backups/AutoSave.cpp index 899b627e..39a3ba17 100644 --- a/src/features/backups/AutoSave.cpp +++ b/src/features/backups/AutoSave.cpp @@ -1,5 +1,6 @@ #include #include "Backup.hpp" +#include "QuickSave.hpp" using namespace geode::prelude; @@ -46,7 +47,7 @@ class $modify(AutoSaveUI, EditorUI) { // Make sure the autosave notification exists if (!m_fields->autoSaveCountdownNotification) { m_fields->autoSaveCountdownNotification = Notification::create( - "", CCSprite::createWithSpriteFrameName("GJ_timeIcon_001.png"), 0 + "", CCSprite::createWithSpriteFrameName("GJ_timeIcon_001.png"), COUNTDOWN.count() ); m_fields->autoSaveCountdownNotification->show(); } @@ -64,10 +65,8 @@ class $modify(AutoSaveUI, EditorUI) { this->onStopPlaytest(nullptr); } - // Save level (using QuickSave if enabled) - auto layer = EditorPauseLayer::create(m_editorLayer); - layer->saveLevel(); - layer->release(); + // Save level + createAutoSave(m_editorLayer); // Create backup auto res = Backup::create(m_editorLayer->m_level, true); diff --git a/src/features/QuickSave.cpp b/src/features/backups/QuickSave.cpp similarity index 50% rename from src/features/QuickSave.cpp rename to src/features/backups/QuickSave.cpp index 8c124318..e4f19d3c 100644 --- a/src/features/QuickSave.cpp +++ b/src/features/backups/QuickSave.cpp @@ -1,16 +1,28 @@ +#include "QuickSave.hpp" #include #include #include #include #include +#include using namespace geode::prelude; static std::filesystem::path getQuickSaveDir() { return Mod::get()->getSaveDir() / "quicksave"; } -static std::filesystem::path getQuickSaveFile(GJGameLevel* level) { - return getQuickSaveDir() / fmt::format("{}.gmd", EditorIDs::getID(level)); + +// Autosave is stored separately, as if you press Exit without saving in the +// editor then that should discard autosaves too, but not quicksaves +static std::filesystem::path getAutoSaveDir() { + return Mod::get()->getSaveDir() / "autosave"; +} + +static bool CREATING_AUTO_SAVE = false; +void ::createAutoSave(LevelEditorLayer* lel) { + CREATING_AUTO_SAVE = true; + fakeEditorPauseLayer(lel)->saveLevel(); + CREATING_AUTO_SAVE = false; } static bool SKIP_NEXT_LLM_SAVE = false; @@ -27,6 +39,7 @@ class $modify(GManager) { if (isLLM) { std::error_code ec; std::filesystem::remove_all(getQuickSaveDir(), ec); + std::filesystem::remove_all(getAutoSaveDir(), ec); } } }; @@ -37,15 +50,49 @@ class $modify(EditorPauseLayer) { // In any case we need to still run the rest of `saveLevel` to have GD // update the level state but for quicksave we just skip the function // saving CCLocalLevels - SKIP_NEXT_LLM_SAVE = Mod::get()->template getSettingValue("quick-save"); + SKIP_NEXT_LLM_SAVE = Mod::get()->template getSettingValue("quick-save") || CREATING_AUTO_SAVE; EditorPauseLayer::saveLevel(); + auto dir = CREATING_AUTO_SAVE ? getAutoSaveDir() : getQuickSaveDir(); + CREATING_AUTO_SAVE = false; + // Save to individual file regardless as a backup if saving crashes - (void)file::createDirectoryAll(getQuickSaveDir()); - auto res = gmd::exportLevelAsGmd(m_editorLayer->m_level, getQuickSaveFile(m_editorLayer->m_level)); + (void)file::createDirectoryAll(dir); + auto res = gmd::exportLevelAsGmd( + m_editorLayer->m_level, + dir / fmt::format("{}.gmd", EditorIDs::getID(m_editorLayer->m_level)) + ); if (!res) { - log::error("Unable to quicksave level '{}': {}", m_editorLayer->m_level->m_levelName, res.unwrapErr()); + log::error("Unable to save level '{}': {}", m_editorLayer->m_level->m_levelName, res.unwrapErr()); + } + } + + $override + void FLAlert_Clicked(FLAlertLayer* fl, bool btn2) { + // Discard autosaves on exit without save + if (fl->getTag() == 1 && btn2) { + log::warn("Discarding autosaved changes"); + std::error_code ec; + std::filesystem::remove_all( + getAutoSaveDir() / fmt::format("{}.gmd", EditorIDs::getID(m_editorLayer->m_level)), + ec + ); } + EditorPauseLayer::FLAlert_Clicked(fl, btn2); + } + + $override + void onExitNoSave(CCObject*) { + auto fl = FLAlertLayer::create( + this, + "Exit", + "Exit without saving? All unsaved changes will be lost!\n" + "All auto-saved changes will also be discarded!", + "Cancel", "Exit", + 300 + ); + fl->setTag(1); + fl->show(); } }; class $modify(MenuLayer) { @@ -54,7 +101,9 @@ class $modify(MenuLayer) { return false; // Check if there's quicksaved crash data - for (auto file : file::readDirectory(getQuickSaveDir()).unwrapOrDefault()) { + auto files = file::readDirectory(getQuickSaveDir()).unwrapOrDefault(); + ranges::push(files, file::readDirectory(getAutoSaveDir()).unwrapOrDefault()); + for (auto file : files) { auto data = gmd::importGmdAsLevel(file); if (!data) continue; auto imported = *data; diff --git a/src/features/backups/QuickSave.hpp b/src/features/backups/QuickSave.hpp new file mode 100644 index 00000000..8fc2ff35 --- /dev/null +++ b/src/features/backups/QuickSave.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +using namespace geode::prelude; + +void createAutoSave(LevelEditorLayer* lel); diff --git a/src/utils/NextFreeOffsetInput.hpp b/src/utils/NextFreeOffsetInput.hpp index ca212d5e..98cca40a 100644 --- a/src/utils/NextFreeOffsetInput.hpp +++ b/src/utils/NextFreeOffsetInput.hpp @@ -50,6 +50,7 @@ class NextFreeOffsetInput : public CCNode { m_input->setString(numToString(s_value)); } m_input->setCallback([](auto str) { + log::info("hi: {}", str); if (auto value = numFromString(str)) { s_value = clamp(value.unwrap(), Source::MIN_VALUE, Source::MAX_VALUE); } diff --git a/src/utils/Pro.cpp b/src/utils/Pro.cpp index fd1150dc..d8ca5d15 100644 --- a/src/utils/Pro.cpp +++ b/src/utils/Pro.cpp @@ -5,5 +5,6 @@ using namespace geode::prelude; bool isProUIEnabled() { auto pro = Loader::get()->getLoadedMod("hjfod.betteredit-pro"); + // geode-ignore-unknown-setting return pro && pro->template getSettingValue("pro-ui"); } diff --git a/src/utils/Warn.hpp b/src/utils/Warn.hpp index 89bf8928..418d22cb 100644 --- a/src/utils/Warn.hpp +++ b/src/utils/Warn.hpp @@ -26,3 +26,5 @@ #define BE_ALLOW_FAKE_ENUMS #define BE_ALLOW_UNUSED_PARAMS #endif + +#define $be_ensure_hookable(...) static_assert(requires { __VA_ARGS__; })