Remove the Edit Saved Item Rectangles menu item in favour of a toolbar button.

The limit of 3 saved item rectangles has been removed - you can now add as many as you want.
However, the 1 per town limit is now strictly enforced.

The saved item rectangle is now shown with a cyan border when editing town.
This commit is contained in:
2025-03-02 15:19:56 -05:00
committed by Celtic Minstrel
parent c60d151ed3
commit a1bc923de8
30 changed files with 103 additions and 205 deletions

View File

@@ -87,7 +87,7 @@ ePalBtn town_buttons[6][10] = {
{PAL_PENCIL, PAL_BRUSH_LG, PAL_BRUSH_SM, PAL_SPRAY_LG, PAL_SPRAY_SM, PAL_ERASER, PAL_DROPPER, PAL_RECT_HOLLOW, PAL_RECT_FILLED, PAL_BUCKET},
{PAL_ENTER_N, PAL_ENTER_W, PAL_ENTER_S, PAL_ENTER_E, PAL_EDIT_SIGN, PAL_TEXT_AREA, PAL_WANDER, PAL_CHANGE, PAL_ZOOM, PAL_TERRAIN},
{PAL_SPEC, PAL_COPY_SPEC, PAL_PASTE_SPEC, PAL_ERASE_SPEC, PAL_EDIT_SPEC, PAL_SPEC_SPOT, PAL_EDIT_ITEM, PAL_SAME_ITEM, PAL_ERASE_ITEM, PAL_ITEM},
{PAL_BOAT, PAL_HORSE, PAL_ROAD, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_EDIT_MONST, PAL_SAME_MONST, PAL_ERASE_MONST, PAL_MONST},
{PAL_BOAT, PAL_HORSE, PAL_ROAD, PAL_BLANK, PAL_BLANK, PAL_EDIT_STORAGE, PAL_EDIT_MONST, PAL_SAME_MONST, PAL_ERASE_MONST, PAL_MONST},
{PAL_WEB, PAL_CRATE, PAL_BARREL, PAL_BLOCK, PAL_FIRE_BARR, PAL_FORCE_BARR, PAL_QUICKFIRE, PAL_FORCECAGE, PAL_ERASE_FIELD, PAL_BLANK},
{PAL_SFX_SB, PAL_SFX_MB, PAL_SFX_LB, PAL_SFX_SS, PAL_SFX_LS, PAL_SFX_ASH, PAL_SFX_BONE, PAL_SFX_ROCK, PAL_BLANK, PAL_BLANK},
};
@@ -152,6 +152,7 @@ static cursor_type get_edit_cursor() {
case MODE_ROOM_RECT: case MODE_SET_TOWN_RECT:
case MODE_HOLLOW_RECT: case MODE_FILLED_RECT:
case MODE_STORAGE_RECT:
return mode_count == 2 ? topleft_curs : bottomright_curs;
case MODE_ERASE_CREATURE: case MODE_ERASE_ITEM:
@@ -731,6 +732,7 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
break;
case MODE_ROOM_RECT: case MODE_SET_TOWN_RECT: case MODE_HOLLOW_RECT: case MODE_FILLED_RECT:
case MODE_STORAGE_RECT:
if(mouse_button_held)
break;
if(mode_count == 2) {
@@ -754,7 +756,7 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
town->in_town_rect = working_rect;
change_made = true;
}
else { // MODE_ROOM_RECT
else if(overall_mode == MODE_ROOM_RECT) {
auto& area_descs = cur_area->area_desc;
auto iter = std::find_if(area_descs.begin(), area_descs.end(), [](const info_rect_t& r) {
return r.right == 0;
@@ -771,6 +773,10 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
}
change_made = true;
}
else if(overall_mode == MODE_STORAGE_RECT) {
scenario.store_item_rects[cur_town] = working_rect;
change_made = true;
}
overall_mode = MODE_DRAWING;
break;
case MODE_SET_WANDER_POINTS:
@@ -1327,6 +1333,11 @@ static bool handle_toolpal_action(location cur_point2) {
mode_count = 2;
set_string("Create room rectangle","Select upper left corner");
break;
case PAL_EDIT_STORAGE:
overall_mode = MODE_STORAGE_RECT;
mode_count = 2;
set_string("Create saved item rect","Select upper left corner");
break;
case PAL_WANDER:
overall_mode = MODE_SET_WANDER_POINTS;
mode_count = 4;

View File

@@ -2563,67 +2563,6 @@ bool edit_shop(size_t which_shop, cDialog* parent) {
return shop_dlg.accepted();
}
static void put_save_rects_in_dlog(cDialog& me) {
for(short i = 0; i < 3; i++) {
std::string id = std::to_string(i + 1);
me["top" + id].setTextToNum(scenario.store_item_rects[i].top);
me["left" + id].setTextToNum(scenario.store_item_rects[i].left);
me["bottom" + id].setTextToNum(scenario.store_item_rects[i].bottom);
me["right" + id].setTextToNum(scenario.store_item_rects[i].right);
me["town" + id].setTextToNum(scenario.store_item_towns[i]);
}
}
static bool save_save_rects(cDialog& me) {
for(short i = 0; i < 3; i++) {
std::string id = std::to_string(i + 1);
scenario.store_item_rects[i].top = me["top" + id].getTextAsNum();
scenario.store_item_rects[i].left = me["left" + id].getTextAsNum();
scenario.store_item_rects[i].bottom = me["bottom" + id].getTextAsNum();
scenario.store_item_rects[i].right = me["right" + id].getTextAsNum();
scenario.store_item_towns[i] = me["town" + id].getTextAsNum();
if((scenario.store_item_towns[i] < -1) || (scenario.store_item_towns[i] >= 200)) {
showError("Towns must be in 0 to 200 range (or -1 for no save items rectangle).","",&me);
return false;
}
}
if(((scenario.store_item_towns[0] == scenario.store_item_towns[1]) &&
(scenario.store_item_towns[0] >= 0) && (scenario.store_item_towns[1] >= 0))
||
((scenario.store_item_towns[2] == scenario.store_item_towns[1]) &&
(scenario.store_item_towns[2] >= 0) && (scenario.store_item_towns[1] >= 0))
||
((scenario.store_item_towns[2] == scenario.store_item_towns[0]) &&
(scenario.store_item_towns[2] >= 0) && (scenario.store_item_towns[0] >= 0))
) {
showError("The three towns towns with saved item rectangles must be different.","",&me);
return false;
}
return true;
}
static bool edit_save_rects_event_filter(cDialog& me, std::string item_hit) {
if(item_hit == "cancel") {
me.toast(false);
} else if(item_hit == "okay") {
if(save_save_rects(me))
me.toast(true);
}
return true;
}
void edit_save_rects() {
using namespace std::placeholders;
cDialog save_dlg(*ResMgr::dialogs.get("edit-save-rects"));
save_dlg.attachClickHandlers(std::bind(edit_save_rects_event_filter, _1, _2), {"okay"});
put_save_rects_in_dlog(save_dlg);
save_dlg.run();
}
static void put_vehicle_area(cDialog& me, const cVehicle& what) {
std::ostringstream sout;
if(what.which_town == 200) {

View File

@@ -12,7 +12,6 @@ cItem edit_item_abil(cItem starting_record,short which_item,cDialog& parent);
bool edit_spec_item(short which_item);
bool edit_quest(size_t which_quest);
bool edit_shop(size_t which_shop, cDialog* parent = nullptr);
void edit_save_rects();
void edit_add_town();
void edit_item_placement();
void edit_scen_details();

View File

@@ -176,16 +176,14 @@ void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
data.PushElement("town-start", scenario.where_start);
data.PushElement("outdoor-start", scenario.out_sec_start);
data.PushElement("sector-start", scenario.out_start);
for(int i = 0; i < 3; i++) {
if(scenario.store_item_towns[i] >= 0) {
data.OpenElement("store-items");
data.PushAttribute("top", scenario.store_item_rects[i].top);
data.PushAttribute("left", scenario.store_item_rects[i].left);
data.PushAttribute("bottom", scenario.store_item_rects[i].bottom);
data.PushAttribute("right", scenario.store_item_rects[i].right);
data.PushAttribute("town", scenario.store_item_towns[i]);
data.CloseElement("store-items");
}
for(auto p : scenario.store_item_rects) {
data.OpenElement("store-items");
data.PushAttribute("top", p.second.top);
data.PushAttribute("left", p.second.left);
data.PushAttribute("bottom", p.second.bottom);
data.PushAttribute("right", p.second.right);
data.PushAttribute("town", p.first);
data.CloseElement("store-items");
}
for(int i = 0; i < scenario.town_mods.size(); i++) {
if(scenario.town_mods[i].spec >= 0) {

View File

@@ -30,7 +30,7 @@ enum eScenMode {
MODE_PLACE_ITEM = 4,
MODE_EDIT_ITEM = 5,
MODE_TOGGLE_SPECIAL_DOT = 6,
MODE_SET_TOWN_START = 7, // unused; for something I'd like to add
MODE_SET_TOWN_START = 7,
MODE_PLACE_SAME_CREATURE = 8,
MODE_SET_TOWN_RECT = 9,
MODE_PLACE_NORTH_ENTRANCE = 10,
@@ -40,6 +40,7 @@ enum eScenMode {
MODE_FLOOD_FILL = 14,
MODE_PLACE_HORSE = 15,
MODE_PLACE_BOAT = 16,
MODE_STORAGE_RECT = 17,
MODE_PLACE_FORCECAGE = 19,
MODE_PLACE_WEB = 20,
MODE_PLACE_CRATE = 21,
@@ -93,7 +94,7 @@ enum eStrMode {
enum ePalBtn {
PAL_BLANK = -1,
PAL_PENCIL = 0, PAL_BRUSH_LG = 1, PAL_BRUSH_SM = 2, PAL_SPRAY_LG = 3, PAL_SPRAY_SM = 4, PAL_DROPPER = 5, PAL_RECT_HOLLOW = 6, PAL_RECT_FILLED = 7, PAL_BUCKET = 8,
PAL_ZOOM = 10, PAL_ERASER = 11, PAL_EDIT_SIGN = 12, PAL_TEXT_AREA = 13, PAL_WANDER = 14, PAL_CHANGE = 15, PAL_ERASE_TOWN = 16, PAL_EDIT_TOWN = 17,
PAL_ZOOM = 10, PAL_ERASER = 11, PAL_EDIT_SIGN = 12, PAL_TEXT_AREA = 13, PAL_WANDER = 14, PAL_CHANGE = 15, PAL_ERASE_TOWN = 16, PAL_EDIT_TOWN = 17, PAL_EDIT_STORAGE = 18,
PAL_EDIT_ITEM = 20, PAL_SAME_ITEM = 21, PAL_ERASE_ITEM = 22, PAL_SPEC = 23, PAL_COPY_SPEC = 24, PAL_PASTE_SPEC = 25, PAL_ERASE_SPEC = 26, PAL_EDIT_SPEC = 27,
PAL_EDIT_MONST = 30, PAL_SAME_MONST = 31, PAL_ERASE_MONST = 32, PAL_ENTER_N = 34, PAL_ENTER_W = 35, PAL_ENTER_S = 36, PAL_ENTER_E = 37,
PAL_WEB = 40, PAL_CRATE = 41, PAL_BARREL = 42, PAL_FIRE_BARR = 43, PAL_FORCE_BARR = 44, PAL_QUICKFIRE = 45, PAL_SPEC_SPOT = 46, PAL_BLOCK = 47, PAL_FORCECAGE = 48, PAL_ERASE_FIELD = 33,

View File

@@ -941,6 +941,17 @@ void draw_terrain(){
draw_rect.inset(10, 13);
draw_rect.offset(TER_RECT_UL_X, TER_RECT_UL_Y);
frame_rect(mainPtr(), draw_rect, sf::Color::White);
// draw stored item rect
auto iter = scenario.store_item_rects.find(cur_town);
if(iter != scenario.store_item_rects.end()) {
draw_rect.left = 22 + 28 * (iter->second.left - cen_x + 4);
draw_rect.right = 22 + 28 * (iter->second.right - cen_x + 4);
draw_rect.top = 24 + 36 * (iter->second.top - cen_y + 4);
draw_rect.bottom = 24 + 36 * (iter->second.bottom - cen_y + 4);
draw_rect.inset(-8, -11);
draw_rect.offset(TER_RECT_UL_X, TER_RECT_UL_Y);
frame_rect(mainPtr(), draw_rect, sf::Color::Cyan);
}
}
clip_rect(mainPtr(), terrain_rect);

View File

@@ -609,10 +609,6 @@ void handle_menu_choice(eMenu item_hit) {
redraw_screen();
}
break;
case eMenu::SCEN_SAVE_ITEM_RECTS:
edit_save_rects();
change_made = true;
break;
case eMenu::TOWN_VARYING:
edit_add_town();
change_made = true;

View File

@@ -63,7 +63,6 @@ void OpenBoESceneditMenu::add_persistent_menu_items(tgui::MenuBar::Ptr& menubar)
{ { "Scenario", "Advanced", "Advanced Scenario Details" }, eMenu::SCEN_ADV_DETAILS },
{ { "Scenario", "Advanced", "Import Town" }, eMenu::TOWN_IMPORT },
{ { "Scenario", "Advanced", "Import Outdoor Sector" }, eMenu::OUT_IMPORT },
{ { "Scenario", "Advanced", "Edit Saved Item Rectangles" }, eMenu::SCEN_SAVE_ITEM_RECTS },
{ { "Scenario", "Advanced", "Set Variable Town Entry" }, eMenu::TOWN_VARYING },
{ { "Scenario", "Advanced", "Set Scenario Event Timers" }, eMenu::SCEN_TIMERS },
{ { "Scenario", "Advanced", "Edit Item Placement Shortcuts" }, eMenu::SCEN_ITEM_SHORTCUTS },

View File

@@ -22,7 +22,6 @@ enum class eMenu {
LAUNCH_HERE, LAUNCH_START, LAUNCH_ENTRANCE, TOWN_CREATE, OUT_RESIZE,
SCEN_DETAILS, SCEN_ADV_DETAILS, SCEN_INTRO, TOWN_START,
SCEN_SPECIALS, SCEN_TEXT, SCEN_JOURNALS, TOWN_IMPORT, OUT_IMPORT,
SCEN_SAVE_ITEM_RECTS,
TOWN_VARYING, SCEN_TIMERS, SCEN_ITEM_SHORTCUTS, TOWN_DELETE,
SCEN_DATA_DUMP, SCEN_TEXT_DUMP,
SCEN_PICS, SCEN_SHEETS, SCEN_SNDS,

View File

@@ -59,7 +59,7 @@ void init_menubar() {
eMenu::LAUNCH_HERE, eMenu::LAUNCH_START, eMenu::LAUNCH_ENTRANCE, eMenu::NONE,
eMenu::TOWN_CREATE, eMenu::OUT_RESIZE, eMenu::NONE,
eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::SCEN_SHEETS, eMenu::SCEN_PICS, eMenu::SCEN_SNDS, eMenu::NONE, eMenu::NONE,
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::SCEN_ADV_DETAILS, eMenu::TOWN_IMPORT, eMenu::OUT_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::SCEN_ADV_DETAILS, eMenu::TOWN_IMPORT, eMenu::OUT_IMPORT,
eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,
};

View File

@@ -79,7 +79,7 @@ void init_menubar() {
eMenu::TOWN_CREATE, eMenu::OUT_RESIZE, eMenu::NONE,
eMenu::SCEN_DETAILS, eMenu::SCEN_INTRO, eMenu::SCEN_SHEETS, eMenu::SCEN_PICS, eMenu::SCEN_SNDS, eMenu::NONE, eMenu::NONE,
eMenu::SCEN_SPECIALS, eMenu::SCEN_TEXT, eMenu::SCEN_JOURNALS, eMenu::SCEN_ADV_DETAILS,
eMenu::TOWN_IMPORT, eMenu::OUT_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
eMenu::TOWN_IMPORT, eMenu::OUT_IMPORT,
eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,
};

View File

@@ -789,6 +789,14 @@ static void put_advanced_town_in_dlog(cDialog& me) {
dynamic_cast<cLed&>(me["noscry"]).setState(town->defy_scrying ? led_red : led_off);
dynamic_cast<cLed&>(me["barrier"]).setState(town->strong_barriers ? led_red : led_off);
dynamic_cast<cLed&>(me["tavern"]).setState(town->has_tavern ? led_red : led_off);
auto iter = scenario.store_item_rects.find(cur_town);
if(iter == scenario.store_item_rects.end())
me["saved-item-delete"].hide();
else {
std::ostringstream sout;
sout << "(" << iter->second.left << "," << iter->second.top << ") to (" << iter->second.right << "," << iter->second.bottom << ")";
me["saved-item-rect"].setText(sout.str());
}
}
static bool edit_advanced_town_special(cDialog& me, std::string hit, eKeyMod) {
@@ -867,7 +875,7 @@ void edit_advanced_town() {
me[fld].setTextToNum(bg_i);
return true;
}, {"pick-fight", "pick-town"});
static const std::vector<std::string> help_ids = {"exit-special-help", "special-help", "exit-help", "prop-help", "bg-help"};
static const std::vector<std::string> help_ids = {"exit-special-help", "special-help", "exit-help", "prop-help", "bg-help", "saved-help"};
town_dlg.attachClickHandlers([](cDialog& me, std::string which, eKeyMod) {
auto iter = std::find(help_ids.begin(), help_ids.end(), which);
if(iter == help_ids.end()) return true;
@@ -888,6 +896,13 @@ void edit_advanced_town() {
dynamic_cast<cLed&>(me[which]).defaultClickHandler(me, which, mod);
return true;
}, prop_ids);
bool delete_rect = false;
town_dlg["saved-item-delete"].attachClickHandler([&delete_rect](cDialog& me, std::string, eKeyMod) {
delete_rect = true;
me["saved-item-delete"].hide();
me["saved-item-rect"].setText("(none)");
return true;
});
using namespace std::placeholders;
auto focus_handler = std::bind(check_range_msg, _1, _2, _3, -1, 21, _4, "-1 to use scenario default");
town_dlg["bg-fight"].attachFocusHandler(std::bind(focus_handler, _1, _2, _3, "Combat Background"));
@@ -896,6 +911,8 @@ void edit_advanced_town() {
put_advanced_town_in_dlog(town_dlg);
town_dlg.run();
if(town_dlg.accepted() && delete_rect)
scenario.store_item_rects.erase(cur_town);
}
static bool save_town_wand(cDialog& me, std::string, eKeyMod) {