diff --git a/rsrc/dialogs/edit-boats.xml b/rsrc/dialogs/edit-boats.xml
deleted file mode 100644
index 52d39652..00000000
--- a/rsrc/dialogs/edit-boats.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
diff --git a/rsrc/dialogs/edit-horses.xml b/rsrc/dialogs/edit-horses.xml
deleted file mode 100644
index f1e2d78a..00000000
--- a/rsrc/dialogs/edit-horses.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
diff --git a/rsrc/dialogs/edit-vehicle.xml b/rsrc/dialogs/edit-vehicle.xml
new file mode 100644
index 00000000..dbe393db
--- /dev/null
+++ b/rsrc/dialogs/edit-vehicle.xml
@@ -0,0 +1,21 @@
+
+
+
diff --git a/rsrc/graphics/edbuttons.png b/rsrc/graphics/edbuttons.png
index 0d610c86..b458d3d3 100644
Binary files a/rsrc/graphics/edbuttons.png and b/rsrc/graphics/edbuttons.png differ
diff --git a/src/classes/scenario.cpp b/src/classes/scenario.cpp
index bc9d2852..ec082d39 100644
--- a/src/classes/scenario.cpp
+++ b/src/classes/scenario.cpp
@@ -135,6 +135,8 @@ void cScenario::import_legacy(legacy::scenario_data_type& old){
rating = eContentRating(old.rating);
// TODO: Is this used anywhere?
uses_custom_graphics = old.uses_custom_graphics;
+ boats.resize(30);
+ horses.resize(30);
for(short i = 0; i < 30; i++) {
boats[i].import_legacy(old.scen_boats[i]);
horses[i].import_legacy(old.scen_horses[i]);
diff --git a/src/classes/scenario.hpp b/src/classes/scenario.hpp
index 9d999d9d..a9fee5a2 100644
--- a/src/classes/scenario.hpp
+++ b/src/classes/scenario.hpp
@@ -76,8 +76,8 @@ public:
eContentRating rating;
std::vector custom_graphics;
std::vector scen_monsters;
- std::array boats;
- std::array horses;
+ std::vector boats;
+ std::vector horses;
std::vector ter_types;
std::array scenario_timers;
std::vector scen_specials;
diff --git a/src/scenedit/scen.actions.cpp b/src/scenedit/scen.actions.cpp
index dc2bff6b..3376e456 100644
--- a/src/scenedit/scen.actions.cpp
+++ b/src/scenedit/scen.actions.cpp
@@ -72,7 +72,7 @@ ePalBtn out_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_EDIT_TOWN, PAL_ERASE_TOWN, PAL_BLANK, PAL_BLANK, PAL_EDIT_SIGN, PAL_TEXT_AREA, PAL_WANDER, PAL_CHANGE, PAL_ZOOM, PAL_BLANK},
{PAL_SPEC, PAL_COPY_SPEC, PAL_PASTE_SPEC, PAL_ERASE_SPEC, PAL_EDIT_SPEC, PAL_SPEC_SPOT, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK},
- {PAL_BLANK, PAL_ROAD, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK},
+ {PAL_BOAT, PAL_HORSE, PAL_ROAD, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK},
{PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK},
{PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK, PAL_BLANK},
};
@@ -81,7 +81,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_BLANK, PAL_ROAD, PAL_BLANK, 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_BLANK, 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},
};
@@ -132,6 +132,7 @@ static cursor_type get_edit_cursor() {
case MODE_PLACE_STONE_BLOCK: case MODE_PLACE_FIRE_BARRIER:
case MODE_PLACE_FORCE_BARRIER: case MODE_PLACE_QUICKFIRE:
case MODE_PLACE_FORCECAGE: case MODE_PLACE_SFX:
+ case MODE_PLACE_HORSE: case MODE_PLACE_BOAT:
case MODE_TOGGLE_SPECIAL_DOT: case MODE_TOGGLE_ROAD:
case MODE_DRAWING:
@@ -1131,6 +1132,32 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
overall_mode = MODE_DRAWING;
change_made = true;
break;
+ case MODE_PLACE_BOAT: case MODE_PLACE_HORSE: {
+ auto& all = overall_mode == MODE_PLACE_BOAT ? scenario.boats : scenario.horses;
+ auto iter = std::find_if(all.begin(), all.end(), [](const cVehicle& what) {
+ if(editing_town && cur_town != what.which_town) return false;
+ else if(!editing_town && what.which_town != 200) return false;
+ return what.loc == spot_hit;
+ });
+ if(iter == all.end()) {
+ iter = std::find_if(all.begin(), all.end(), [](const cVehicle& what) {
+ return what.which_town < 0;
+ });
+ if(iter == all.end()) {
+ all.emplace_back();
+ iter = all.end() - 1;
+ }
+ iter->loc = spot_hit;
+ iter->which_town = editing_town ? cur_town : 200;
+ iter->property = false;
+ iter->exists = false;
+ if(!editing_town) iter->sector = cur_out;
+ }
+ if(!edit_vehicle(*iter, iter - all.begin(), overall_mode == MODE_PLACE_BOAT))
+ all.erase(iter);
+ overall_mode = MODE_DRAWING;
+ break;
+ }
case MODE_INTRO_SCREEN:
case MODE_EDIT_TYPES:
case MODE_MAIN_SCREEN:
@@ -1507,6 +1534,14 @@ static bool handle_toolpal_action(location cur_point2) {
draw_mode = DRAW_MONST;
set_up_terrain_buttons(true);
break;
+ case PAL_BOAT:
+ set_string("Place/edit boat","Select boat location");
+ overall_mode = MODE_PLACE_BOAT;
+ break;
+ case PAL_HORSE:
+ set_string("Place/edit horse","Select horse location");
+ overall_mode = MODE_PLACE_HORSE;
+ break;
}
return true;
}
diff --git a/src/scenedit/scen.core.cpp b/src/scenedit/scen.core.cpp
index ead9de11..453790bf 100644
--- a/src/scenedit/scen.core.cpp
+++ b/src/scenedit/scen.core.cpp
@@ -2533,75 +2533,44 @@ void edit_save_rects() {
save_dlg.run();
}
-static bool save_vehicles(cDialog& me, cVehicle* vehicles, const short page) {
- for(short i = 0; i < 6; i++) {
- std::string id = std::to_string(i + 1);
- vehicles[6 * page + i].which_town = me["town" + id].getTextAsNum();
- if(cre(vehicles[6 * page + i].which_town,
- -1,199,"Town number must be from 0 to 199 (or -1 for it to not exist).","",&me)) return false;
- vehicles[6 * page + i].loc.x = me["x" + id].getTextAsNum();
- if(cre(vehicles[6 * page + i].loc.x,
- 0,63,"coordinates must be from 0 to 63.","",&me)) return false;
- vehicles[6 * page + i].loc.y = me["y" + id].getTextAsNum();
- if(cre(vehicles[6 * page + i].loc.y,
- 0,63,"coordinates must be from 0 to 63.","",&me)) return false;
- vehicles[6 * page + i].property = dynamic_cast(me["owned" + id]).getState() != led_off;
+static void put_vehicle_area(cDialog& me, const cVehicle& what) {
+ std::ostringstream sout;
+ if(what.which_town == 200) {
+ sout << "Outdoors @ " << what.sector;
+ } else {
+ sout << "Town " << what.which_town;
}
- return true;
+ me["area"].setText(sout.str());
}
-static void put_vehicles_in_dlog(cDialog& me, cVehicle* vehicles, const short page) {
- for(short i = 0; i < 6; i++) {
- std::string id = std::to_string(i + 1);
- me["num" + id].setTextToNum(6 * page + i);
- me["town" + id].setTextToNum(vehicles[6 * page + i].which_town);
- me["x" + id].setTextToNum(vehicles[6 * page + i].loc.x);
- me["y" + id].setTextToNum(vehicles[6 * page + i].loc.y);
- dynamic_cast(me["owned" + id]).setState(vehicles[6 * page + i].property ? led_red : led_off);
- }
-}
-
-static bool edit_vehicles_event_filter(cDialog& me, std::string hit, cVehicle* vehicles, size_t nVehicles, size_t& page) {
-
- if(hit == "okay") {
- if(save_vehicles(me, vehicles, page))
- me.toast(true);
- } else if(hit == "left") {
- if(!save_vehicles(me, vehicles, page)) return true;
- if(page == 0) page = (nVehicles - 1) / 6;
- else page--;
- put_vehicles_in_dlog(me, vehicles, page);
- } else if(hit == "right") {
- if(!save_vehicles(me, vehicles, page)) return true;
- page++;
- if(page > (nVehicles - 1) / 6) page = 0;
- put_vehicles_in_dlog(me, vehicles, page);
- }
- return true;
-}
-
-void edit_horses() {
+bool edit_vehicle(cVehicle& what, int num, bool is_boat) {
using namespace std::placeholders;
- size_t page = 0;
+ cDialog dlg("edit-vehicle");
+ dlg["okay"].attachClickHandler(std::bind(&cDialog::toast, &dlg, true));
+ dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, &dlg, false));
+ dlg["del"].attachClickHandler([](cDialog& me, std::string, eKeyMod) {
+ me.setResult(false);
+ return me.toast(false);
+ });
- cDialog horse_dlg("edit-horses");
- horse_dlg.attachClickHandlers(std::bind(edit_vehicles_event_filter, _1, _2, scenario.horses.data(), 30, std::ref(page)), {"okay", "left", "right"});
+ put_vehicle_area(dlg, what);
+ dlg["loc"].setText(boost::lexical_cast(what.loc));
+ dlg["num"].setTextToNum(num);
+ dlg["title"].setText(is_boat ? "Edit Boat" : "Edit Horse");
- put_vehicles_in_dlog(horse_dlg, scenario.horses.data(), page);
+ cLed& prop = dynamic_cast(dlg["owned"]);
+ prop.setState(what.property ? led_red : led_off);
- horse_dlg.run();
-}
-
-void edit_boats() {
- using namespace std::placeholders;
- size_t page = 0;
+ dlg.setResult(true);
+ dlg.run();
+ if(!dlg.getResult())
+ return false;
- cDialog boat_dlg("edit-boats");
- boat_dlg.attachClickHandlers(std::bind(edit_vehicles_event_filter, _1, _2, scenario.boats.data(), 30, std::ref(page)), {"okay", "left", "right"});
-
- put_vehicles_in_dlog(boat_dlg, scenario.boats.data(), page);
-
- boat_dlg.run();
+ if(dlg.accepted()) {
+ what.property = prop.getState() != led_off;
+ what.exists = true;
+ }
+ return what.exists;
}
static bool save_add_town(cDialog& me) {
diff --git a/src/scenedit/scen.core.hpp b/src/scenedit/scen.core.hpp
index e1252c3e..897e4f3f 100644
--- a/src/scenedit/scen.core.hpp
+++ b/src/scenedit/scen.core.hpp
@@ -13,7 +13,6 @@ 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_horses();
void edit_add_town();
void edit_item_placement();
void edit_scen_details();
@@ -21,7 +20,7 @@ bool edit_make_scen_2(short& out_w, short& out_h, short& town_l, short& town_m,
bool edit_make_scen_1(std::string& filename,std::string& title,bool& grass);
void edit_scenario_events();
bool build_scenario();
-void edit_boats();
+bool edit_vehicle(class cVehicle& what, int num, bool is_boat);
bool check_range_msg(cDialog& me,std::string id,bool losing,long min_val,long max_val,std::string fld_name,std::string xtra);
bool check_range(cDialog& me,std::string id,bool losing,long min_val,long max_val,std::string fld_name);
diff --git a/src/scenedit/scen.global.hpp b/src/scenedit/scen.global.hpp
index e8aaa262..29491503 100644
--- a/src/scenedit/scen.global.hpp
+++ b/src/scenedit/scen.global.hpp
@@ -29,6 +29,7 @@
enum eScenMode {
MODE_DRAWING = 0,
+ MODE_TOGGLE_ROAD = 1,
MODE_SET_WANDER_POINTS = 2,
MODE_ROOM_RECT = 3,
MODE_PLACE_ITEM = 4,
@@ -42,7 +43,8 @@ enum eScenMode {
MODE_PLACE_SOUTH_ENTRANCE = 12,
MODE_PLACE_WEST_ENTRANCE = 13,
MODE_FLOOD_FILL = 14,
- MODE_TOGGLE_ROAD = 15,
+ MODE_PLACE_HORSE = 15,
+ MODE_PLACE_BOAT = 16,
MODE_PLACE_FORCECAGE = 19,
MODE_PLACE_WEB = 20,
MODE_PLACE_CRATE = 21,
@@ -102,6 +104,7 @@ enum ePalBtn {
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,
PAL_SFX_SB = 50, PAL_SFX_MB = 51, PAL_SFX_LB = 52, PAL_SFX_SS = 53, PAL_SFX_LS = 54, PAL_SFX_ASH = 55, PAL_SFX_BONE = 56, PAL_SFX_ROCK = 57, PAL_ROAD = 58,
PAL_ARROW_UP = 9, PAL_ARROW_DOWN = 69, PAL_TERRAIN = 29, PAL_ITEM = 39, PAL_MONST = 49,
+ PAL_BOAT = 60, PAL_HORSE = 61,
};
#endif
diff --git a/src/scenedit/scen.main.cpp b/src/scenedit/scen.main.cpp
index 3fd04e75..646cc327 100644
--- a/src/scenedit/scen.main.cpp
+++ b/src/scenedit/scen.main.cpp
@@ -375,14 +375,6 @@ void handle_menu_choice(eMenu item_hit) {
edit_save_rects();
change_made = true;
break;
- case eMenu::SCEN_HORSES:
- edit_horses();
- change_made = true;
- break;
- case eMenu::SCEN_BOATS:
- edit_boats();
- change_made = true;
- break;
case eMenu::TOWN_VARYING:
edit_add_town();
change_made = true;
diff --git a/src/scenedit/scen.menus.hpp b/src/scenedit/scen.menus.hpp
index 5d00aaac..5df22f4b 100644
--- a/src/scenedit/scen.menus.hpp
+++ b/src/scenedit/scen.menus.hpp
@@ -20,7 +20,7 @@ enum class eMenu {
// Scenario menu
TOWN_CREATE, OUT_RESIZE, SCEN_DETAILS, SCEN_INTRO, TOWN_START,
SCEN_SPECIALS, SCEN_TEXT, SCEN_JOURNALS, TOWN_IMPORT, OUT_IMPORT,
- SCEN_SAVE_ITEM_RECTS, SCEN_HORSES, SCEN_BOATS,
+ 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,
diff --git a/src/scenedit/scen.menus.mac.mm b/src/scenedit/scen.menus.mac.mm
index e1f9e05d..d86d933f 100644
--- a/src/scenedit/scen.menus.mac.mm
+++ b/src/scenedit/scen.menus.mac.mm
@@ -55,7 +55,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::TOWN_IMPORT, eMenu::OUT_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
- eMenu::SCEN_HORSES, eMenu::SCEN_BOATS, eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
+ eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,
};
static const eMenu town_choices[] = {
diff --git a/src/scenedit/scen.menus.win.cpp b/src/scenedit/scen.menus.win.cpp
index a3078036..a92c8e29 100644
--- a/src/scenedit/scen.menus.win.cpp
+++ b/src/scenedit/scen.menus.win.cpp
@@ -83,7 +83,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::TOWN_IMPORT, eMenu::OUT_IMPORT, eMenu::SCEN_SAVE_ITEM_RECTS,
- eMenu::SCEN_HORSES, eMenu::SCEN_BOATS, eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
+ eMenu::TOWN_VARYING, eMenu::SCEN_TIMERS, eMenu::SCEN_ITEM_SHORTCUTS,
eMenu::TOWN_DELETE, eMenu::SCEN_DATA_DUMP, eMenu::SCEN_TEXT_DUMP,
};
static const eMenu town_choices[] = {