diff --git a/osx/scenedit/scen.actions.cpp b/osx/scenedit/scen.actions.cpp index 510f08ad..89638594 100644 --- a/osx/scenedit/scen.actions.cpp +++ b/osx/scenedit/scen.actions.cpp @@ -321,7 +321,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { if(option_hit) { scenario.scen_specials[j] = null_spec_node; } - else edit_spec_enc(j,0); + else edit_spec_enc(j,0,nullptr); //get_str(s2,22,scenario.scen_specials[j].type + 1); //sprintf((char *) str,"%d - %-30.30s",j,(char *) s2); //set_rb(j,4000 + j,(char *) str,0); @@ -331,7 +331,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { if(option_hit) { current_terrain.specials[j] = null_spec_node; } - else edit_spec_enc(j,1); + else edit_spec_enc(j,1,nullptr); //get_str(s2,22,current_terrain.specials[j].type + 1); //sprintf((char *) str,"%d - %-30.30s",j,(char *) s2); //set_rb(j,5000 + j,(char *) str,0); @@ -341,7 +341,7 @@ bool handle_action(location the_point,sf::Event /*event*/) { if(option_hit) { town->specials[j] = null_spec_node; } - else edit_spec_enc(j,2); + else edit_spec_enc(j,2,nullptr); //get_str(s2,22,town.specials[j].type + 1); //sprintf((char *) str,"%d - %-30.30s",j,(char *) s2); //set_rb(j,6000 + j,(char *) str,0); @@ -2860,7 +2860,7 @@ void place_edit_special(location loc) { if(editing_town) { for(i = 0; i < 50; i++) if((town->special_locs[i].x == loc.x) && (town->special_locs[i].y == loc.y)) { - edit_spec_enc(town->spec_id[i],2); + edit_spec_enc(town->spec_id[i],2,nullptr); i = 500; } if(i < 500) { // new special @@ -2873,7 +2873,7 @@ void place_edit_special(location loc) { if(town->special_locs[i].x == 100) { town->special_locs[i] = loc; town->spec_id[i] = spec; - edit_spec_enc(spec,2); + edit_spec_enc(spec,2,nullptr); if(town->specials[spec].pic < 0) town->special_locs[i].x = 100; @@ -2893,7 +2893,7 @@ void place_edit_special(location loc) { } for(i = 0; i < 18; i++) if((current_terrain.special_locs[i].x == loc.x) && (current_terrain.special_locs[i].y == loc.y)) { - edit_spec_enc(current_terrain.special_id[i],1); + edit_spec_enc(current_terrain.special_id[i],1,nullptr); i = 500; } if(i < 500) { // new special @@ -2906,7 +2906,7 @@ void place_edit_special(location loc) { if(current_terrain.special_locs[i].x == 100) { current_terrain.special_locs[i] = loc; current_terrain.special_id[i] = spec; - edit_spec_enc(spec,1); + edit_spec_enc(spec,1,nullptr); if(current_terrain.specials[spec].pic < 0) current_terrain.special_locs[i].x = 100; diff --git a/osx/scenedit/scen.core.cpp b/osx/scenedit/scen.core.cpp index 93004a3e..c07ca287 100644 --- a/osx/scenedit/scen.core.cpp +++ b/osx/scenedit/scen.core.cpp @@ -1233,7 +1233,7 @@ static bool edit_spec_item_event_filter(cDialog& me, std::string item_hit, cSpec } me["spec"].setTextToNum(spec); } - edit_spec_enc(spec,0); + edit_spec_enc(spec,0,&me); if(spec >= 0 && spec < 256 && scenario.scen_specials[spec].pic < 0) me["spec"].setTextToNum(-1); save_spec_item(me, store_item, which_item); @@ -1736,130 +1736,97 @@ bool build_scenario() { return false; } -void set_starting_loc_filter (short item_hit) { -#if 0 - char str[256]; - short i,j,k; - - switch(item_hit) { - case 5: - i = CDGN(805,2); - j = CDGN(805,3); - k = CDGN(805,4); - if((i < 0) || (i >= scenario.num_towns)) { - sprintf((char *) str,"The starting town must be from 0 to %d.",scenario.num_towns - 1); - give_error((char *) str,"",805); - break; - } - if((j < 0) || (j >= max_dim[scenario.town_size[i]] - 1) || - (k < 0) || (k >= max_dim[scenario.town_size[i]] - 1)) { - give_error("This coordinate is not inside the bounds of the town.","",805); - break; - } - scenario.which_town_start = i; - scenario.where_start.x = j; - scenario.where_start.y = k; - toast_dialog(); - break; - case 12: - toast_dialog(); - break; +static bool check_location_bounds(cDialog& me, std::string id, bool losing) { + if(!losing) return true; + // TODO: Use town->max_dim() instead of max_dim[town_size] + // (Requires all towns to be in memory though.) + short town_num = me["town-num"].getTextAsNum(); + short dim = me[id].getTextAsNum(); + if(dim < 0 || dim >= max_dim[scenario.town_size[town_num]]) { + giveError("This coordinate is not inside the bounds of the town."); + return false; } -#endif -} - -void set_starting_loc() { -#if 0 - // ignore parent in Mac version - short town_strs_hit; - - cd_create_dialog_parent_num(805,0); - - CDSN(805,2,scenario.which_town_start); - CDSN(805,3,scenario.where_start.x); - CDSN(805,4,scenario.where_start.y); - - town_strs_hit = cd_run_dialog(); - - - cd_kill_dialog(805); -#endif -} - -bool save_scenario_events() { -#if 0 - short i; - - for(i = 0; i < 10; i++) { - scenario.scenario_timer_times[i] = CDGN(811,2 + i); - if((scenario.scenario_timer_times[i] > 0) && - (scenario.scenario_timer_times[i] % 10 != 0)) { - give_error("All scenario event times must be multiples of 10 (e.g. 100, 150, 1000, etc.).","",811); - return false; - } - scenario.scenario_timer_specs[i] = CDGN(811,12 + i); - if(cre(scenario.scenario_timer_specs[i],-1,255,"The scenario special nodes must be between 0 at 255 (or -1 for no special)." - ,"",811)) return false; - } -#endif return true; } -void put_scenario_events_in_dlog() { -#if 0 - short i; - - for(i = 0; i < 10; i++) { - CDSN(811,2 + i,scenario.scenario_timer_times[i]); - CDSN(811,12 + i,scenario.scenario_timer_specs[i]); +static bool set_starting_loc_filter(cDialog& me, std::string, eKeyMod) { + if(me.toast(true)) { + scenario.which_town_start = me["town-num"].getTextAsNum(); + scenario.where_start.x = me["town-x"].getTextAsNum(); + scenario.where_start.y = me["town-y"].getTextAsNum(); } -#endif + return true; } -void edit_scenario_events_event_filter (short item_hit) { -#if 0 - short spec; +void set_starting_loc() { + using namespace std::placeholders; + // ignore parent in Mac version - switch(item_hit) { - case 22: - if(save_scenario_events()) - toast_dialog(); - break; - default: - if((item_hit >= 30) && (item_hit <= 39)) { - if(!save_scenario_events()) - break; - spec = CDGN(811,item_hit - 30 + 12); - if((spec < 0) || (spec > 255)) { - spec = get_fresh_spec(0); - if(spec < 0) { - give_error("You can't create a new scenario special encounter because there are no more free special nodes.", - "To free a special node, set its type to No Special and set its Jump To special to -1.",811); - break; - } - CDSN(811,item_hit - 30 + 12,spec); - } - edit_spec_enc(spec,0,811); - if((spec >= 0) && (spec < 256) && (scenario.scen_specials[spec].pic < 0)) - CDSN(811,item_hit - 30 + 12,-1); - } - break; + cDialog loc_dlg("set-start-loc.xml"); + loc_dlg["cancel"].attachClickHandler(std::bind(&cDialog::toast, &loc_dlg, false)); + loc_dlg["okay"].attachClickHandler(set_starting_loc_filter); + loc_dlg["town-num"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, scenario.num_towns - 1, "The starting town")); + loc_dlg.attachFocusHandlers(check_location_bounds, {"town-x", "town-y"}); + + loc_dlg["town-num"].setTextToNum(scenario.which_town_start); + loc_dlg["town-x"].setTextToNum(scenario.where_start.x); + loc_dlg["town-y"].setTextToNum(scenario.where_start.y); + + loc_dlg.run(); +} + +static bool save_scenario_events(cDialog& me, std::string, eKeyMod) { + short i; + + if(!me.toast(true)) return true; + + for(i = 0; i < 10; i++) { + std::string id = std::to_string(i + 1); + scenario.scenario_timer_times[i] = me["time" + id].getTextAsNum(); + scenario.scenario_timer_specs[i] = me["node" + id].getTextAsNum(); } -#endif + return true; +} + +static bool check_scenario_timer_time(cDialog& me, std::string id, bool losing) { + if(!losing) return true; + int val = me[id].getTextAsNum(); + if(val > 0 && val % 10 != 0) { + giveError("All scenario event times must be multiples of 10 (e.g. 100, 150, 1000, etc.)."); + return false; + } + return true; +} + +static bool edit_scenario_events_event_filter(cDialog& me, std::string item_hit, eKeyMod) { + short spec = me[item_hit].getTextAsNum(); + if(spec < 0 || spec > 255) { + spec = get_fresh_spec(0); + if(spec < 0) { + giveError("You can't create a new scenario special encounter because there are no more free special nodes.", + "To free a special node, set its type to No Special and set its Jump To special to -1."); + return true; + } + } + if(edit_spec_enc(spec,0,&me)) + me[item_hit].setTextToNum(spec); + return true; } void edit_scenario_events() { -#if 0 - // ignore parent in Mac version - short advanced_town_hit; + using namespace std::placeholders; + cDialog evt_dlg("edit-scenario-events.xml"); + evt_dlg["okay"].attachClickHandler(save_scenario_events); + for(int i = 0; i < 10; i++) { + std::string id = std::to_string(i + 1); + evt_dlg["time" + id].attachFocusHandler(check_scenario_timer_time); + evt_dlg["node" + id].attachFocusHandler(std::bind(check_range_msg, _1, _2, _3, -1, 255, "The scenario special node", "-1 for no special")); + evt_dlg["edit" + id].attachClickHandler(edit_scenario_events_event_filter); + evt_dlg["time" + id].setTextToNum(scenario.scenario_timer_times[i]); + evt_dlg["node" + id].setTextToNum(scenario.scenario_timer_specs[i]); + } - cd_create_dialog_parent_num(811,0); - - put_scenario_events_in_dlog(); - - advanced_town_hit = cd_run_dialog(); - - cd_kill_dialog(811); -#endif + evt_dlg.run(); } + diff --git a/osx/scenedit/scen.keydlgs.cpp b/osx/scenedit/scen.keydlgs.cpp index 4bab6b88..adb53e91 100644 --- a/osx/scenedit/scen.keydlgs.cpp +++ b/osx/scenedit/scen.keydlgs.cpp @@ -489,6 +489,7 @@ static bool edit_spec_enc_event_filter(cDialog& me, std::string item_hit, short& if(item_hit == "okay") { if(save_spec_enc(me, which_mode, which_node)) me.toast(true); + me.setResult(true); } else if(item_hit == "back") { if(!save_spec_enc(me, which_mode, which_node)) return true; @@ -503,6 +504,7 @@ static bool edit_spec_enc_event_filter(cDialog& me, std::string item_hit, short& return true; } me.toast(false); + me.setResult(false); } else if(me[item_hit].getText() == "Create/Edit") { if(!save_spec_enc(me, which_mode, which_node)) return true; @@ -706,7 +708,7 @@ static bool edit_spec_enc_event_filter(cDialog& me, std::string item_hit, short& } // mode - 0 scen 1 - out 2 - town -void edit_spec_enc(short which_node,short mode) { +bool edit_spec_enc(short which_node,short mode,cDialog* parent) { // ignore parent in Mac version using namespace std::placeholders; @@ -722,7 +724,7 @@ void edit_spec_enc(short which_node,short mode) { if(store_spec_node.pic < 0) store_spec_node.pic = 0; - cDialog special("edit-special-node.xml"); + cDialog special("edit-special-node.xml",parent); auto callback = std::bind(edit_spec_enc_event_filter, _1, _2, std::ref(mode), std::ref(which_node)); special.attachClickHandlers(callback, {"okay", "cancel", "back"}); special.attachClickHandlers(callback, {"general", "oneshot", "affectpc", "ifthen", "town", "out"}); @@ -733,6 +735,7 @@ void edit_spec_enc(short which_node,short mode) { put_spec_enc_in_dlog(special, which_node); special.run(); + return special.getResult(); } short get_fresh_spec(short which_mode) { diff --git a/osx/scenedit/scen.keydlgs.h b/osx/scenedit/scen.keydlgs.h index fc87817c..83a3db1d 100644 --- a/osx/scenedit/scen.keydlgs.h +++ b/osx/scenedit/scen.keydlgs.h @@ -13,7 +13,7 @@ pic_num_t choose_graphic(short cur_choice,ePicType g_type,cDialog* parent); short choose_text_res(std::string res_list,short first_t,short last_t,unsigned short cur_choice,cDialog* parent,const char *title); short choose_text(eStrType list, unsigned short cur_choice, cDialog* parent,const char* title); void edit_text_str(short which_str,short mode); -void edit_spec_enc(short which_node,short mode); +bool edit_spec_enc(short which_node,short mode,cDialog* parent); short get_fresh_spec(short which_mode); void edit_spec_text(short mode,short *str1,short *str2,cDialog* parent); void edit_dialog_text(short mode,short *str1,cDialog* parent); diff --git a/rsrc/dialogs/edit-scenario-events.xml b/rsrc/dialogs/edit-scenario-events.xml new file mode 100644 index 00000000..1226bd4e --- /dev/null +++ b/rsrc/dialogs/edit-scenario-events.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Scenario event timers + + At certain time intervals, you can have a scenario special node be called. + Enter below the number of moves between each calling of the special node, and the number of the node to call. + Press the Create/Edit button to make a new special. + + + For more information on how this works, see the documentation. + + Number of moves between each call. + Scenario special node to call. + + Note: If you leave the time between calls at 0, no special node is called. + Don’t have special nodes called too often ... it slows the game down. + + + + + + + + + + + + + Also, the time between events must be a multiple of 10. + + \ No newline at end of file diff --git a/rsrc/dialogs/set-start-loc.xml b/rsrc/dialogs/set-start-loc.xml new file mode 100644 index 00000000..f717fd77 --- /dev/null +++ b/rsrc/dialogs/set-start-loc.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + Enter the town the party will start the scenario in. + Also enter the x-y location in the town to place the party at. + Don’t forget to place that town somewhere in your scenario. + + Starting Location + Start location: X = + Y = + + + NOTE: You also need to set the starting location outdoors. + This is where the party ends up when they leave town for the first time. + To set this, use the Set Starting Location option in the outdoors menu. + + \ No newline at end of file