From b089770efd332c15997905273bd9ed6eefd578ec Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 12 Jun 2025 13:59:39 -0500 Subject: [PATCH] undo/redo create/delete quest/shop --- src/scenedit/scen.actions.cpp | 46 ++++++++++++++++++++++++++++++++--- src/scenedit/scen.core.cpp | 5 ++-- src/scenedit/scen.undo.cpp | 40 ++++++++++++++++++++++++++++++ src/scenedit/scen.undo.hpp | 23 ++++++++++++++++++ 4 files changed, 107 insertions(+), 7 deletions(-) diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp index d61b34a6..44582ea3 100644 --- a/src/scenedit/scen.actions.cpp +++ b/src/scenedit/scen.actions.cpp @@ -639,15 +639,34 @@ static bool handle_rb_action(location the_point, bool option_hit) { case RB_QUEST: size_before = scenario.quests.size(); if(option_hit) { - if(j == scenario.quests.size() - 1) + // Delete last quest + if(j == scenario.quests.size() - 1){ + undo_list.add(action_ptr(new aCreateDeleteQuest(false, scenario.quests.back()))); + update_edit_menu(); scenario.quests.pop_back(); + } + // Clear quest (it can't be deleted fully) else { scenario.quests[j] = cQuest(); scenario.quests[j].name = "Unused Quest"; } } else { - if(!edit_quest(j) && j == size_before && scenario.quests[j].name == "New Quest") + bool is_new = (j == scenario.quests.size()); + if(edit_quest(j)){ + // Create new confirmed + if(is_new){ + undo_list.add(action_ptr(new aCreateDeleteQuest(true, scenario.quests.back()))); + update_edit_menu(); + } + // Quest edited + else{ + // TODO undo action + } + } + // Create new canceled + else if(is_new){ scenario.quests.pop_back(); + } } if(size_before > scenario.quests.size()) pos_before--; @@ -656,12 +675,31 @@ static bool handle_rb_action(location the_point, bool option_hit) { case RB_SHOP: size_before = scenario.shops.size(); if(option_hit) { - if(j == scenario.shops.size() - 1) + // Delete last shop + if(j == scenario.shops.size() - 1){ + undo_list.add(action_ptr(new aCreateDeleteShop(false, scenario.shops.back()))); + update_edit_menu(); scenario.shops.pop_back(); + } + // Clear shop (it can't be fully deleted) else scenario.shops[j] = cShop("Unused Shop"); } else { - if(!edit_shop(j) && j == size_before && scenario.shops[j].getName() == "New Shop") + bool is_new = (j == scenario.shops.size()); + if(edit_shop(j)){ + // Create new confirmed + if(is_new){ + undo_list.add(action_ptr(new aCreateDeleteShop(true, scenario.shops.back()))); + update_edit_menu(); + } + // Shop edited + else{ + // TODO undo action + } + } + // Create new canceled + else if(is_new){ scenario.shops.pop_back(); + } } start_shops_editing(); if(size_before > scenario.shops.size()) diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp index c9c642df..f8e108c3 100644 --- a/src/scenedit/scen.core.cpp +++ b/src/scenedit/scen.core.cpp @@ -2305,7 +2305,7 @@ static bool change_quest_dlog_page(cDialog& me, std::string dir, cQuest& quest, bool edit_quest(size_t which_quest) { using namespace std::placeholders; - if(which_quest == scenario.quests.size()) { + if(which_quest == scenario.quests.size()){ scenario.quests.resize(which_quest + 1); scenario.quests[which_quest].name = "New Quest"; } @@ -2667,8 +2667,7 @@ static bool add_shop_entry(cDialog& me, std::string type, cShop& shop, size_t wh bool edit_shop(size_t which_shop, cDialog* parent) { using namespace std::placeholders; - if(which_shop == scenario.shops.size()) - scenario.shops.emplace_back("New Shop"); + if(which_shop == scenario.shops.size()) scenario.shops.emplace_back("New Shop"); cShop shop = scenario.shops[which_shop]; if(shop.size() == 0 && (shop.getName() == "New Shop" || shop.getName() == "Unused Shop")) { cChoiceDlog new_shop_dlg("new-shop", {"magic", "heal", "custom", "cancel"}); diff --git a/src/scenedit/scen.undo.cpp b/src/scenedit/scen.undo.cpp index 1ccfb58a..5643c1ba 100644 --- a/src/scenedit/scen.undo.cpp +++ b/src/scenedit/scen.undo.cpp @@ -399,4 +399,44 @@ bool aCreateDeleteSpecialItem::redo_me() { } scenario.special_items.push_back(item); return true; +} + +bool aCreateDeleteQuest::undo_me() { + // If not editing quests, show it + if(overall_mode != MODE_EDIT_QUESTS){ + start_quest_editing(); + // TODO Go to scroll maximum + } + scenario.quests.pop_back(); + return true; +} + +bool aCreateDeleteQuest::redo_me() { + // If not editing quests, show it + if(overall_mode != MODE_EDIT_QUESTS){ + start_quest_editing(); + // TODO Go to scroll maximum + } + scenario.quests.push_back(quest); + return true; +} + +bool aCreateDeleteShop::undo_me() { + // If not editing shops, show it + if(overall_mode != MODE_EDIT_SHOPS){ + start_shops_editing(); + // TODO Go to scroll maximum + } + scenario.shops.pop_back(); + return true; +} + +bool aCreateDeleteShop::redo_me() { + // If not editing shops, show it + if(overall_mode != MODE_EDIT_SHOPS){ + start_shops_editing(); + // TODO Go to scroll maximum + } + scenario.shops.push_back(shop); + return true; } \ No newline at end of file diff --git a/src/scenedit/scen.undo.hpp b/src/scenedit/scen.undo.hpp index 22375548..04b8df35 100644 --- a/src/scenedit/scen.undo.hpp +++ b/src/scenedit/scen.undo.hpp @@ -6,6 +6,7 @@ #include "scenario/town.hpp" #include "scenario/scenario.hpp" #include "scenario/item.hpp" +#include "scenario/quest.hpp" #include "scenario/monster.hpp" #include "scenario/vehicle.hpp" @@ -245,6 +246,28 @@ public: item(item) {} }; +/// Action which adds new quest to the end of the list, or deletes from the end of the list +class aCreateDeleteQuest : public cAction { + cQuest quest; + bool undo_me() override; + bool redo_me() override; +public: + aCreateDeleteQuest(bool create, cQuest quest) : + cAction(create ? "Create Quest" : "Delete Quest", !create), + quest(quest) {} +}; + +/// Action which adds new shop to the end of the list, or deletes from the end of the list +class aCreateDeleteShop : public cAction { + cShop shop; + bool undo_me() override; + bool redo_me() override; +public: + aCreateDeleteShop(bool create, cShop shop) : + cAction(create ? "Create Shop" : "Delete Shop", !create), + shop(shop) {} +}; + /// Action which edits or clears a terrain type class aEditClearTerrain : public cAction { ter_num_t which;