Remove the limits on the total number of special nodes in the game
This commit is contained in:
@@ -23,11 +23,11 @@ void cOutdoors::append(legacy::outdoor_record_type& old){
|
||||
// Collect a list of unused special nodes, to be used for fixing specials that could be triggered in a boat.
|
||||
std::vector<int> unused_special_slots;
|
||||
for(i = 0; i < 60; i++) {
|
||||
if(specials[i].type == eSpecType::NONE && specials[i].jumpto == -1) {
|
||||
if(old.specials[i].type == 0 && old.specials[i].jumpto == -1) {
|
||||
// Also make sure no specials jump to it
|
||||
bool is_free = true;
|
||||
for(j = 0; j < 60; j++) {
|
||||
if(specials[j].jumpto == i) is_free = false;
|
||||
if(old.specials[j].jumpto == i) is_free = false;
|
||||
}
|
||||
if(is_free) unused_special_slots.push_back(i);
|
||||
}
|
||||
@@ -110,6 +110,7 @@ void cOutdoors::append(legacy::outdoor_record_type& old){
|
||||
wandering_locs[i].x = old.wandering_locs[i].x;
|
||||
wandering_locs[i].y = old.wandering_locs[i].y;
|
||||
}
|
||||
specials.resize(60);
|
||||
for(i = 0; i < 60; i++)
|
||||
specials[i].append(old.specials[i]);
|
||||
}
|
||||
|
@@ -66,7 +66,7 @@ public:
|
||||
location sign_locs[8];
|
||||
std::array<cWandering,4> wandering, special_enc;
|
||||
location wandering_locs[4];
|
||||
std::array<cSpecial,60> specials;
|
||||
std::vector<cSpecial> specials;
|
||||
std::string out_name;
|
||||
// Using std::array here so we can have .size()
|
||||
// This'll make the transition smoother once it becomes a vector.
|
||||
|
@@ -146,6 +146,7 @@ void cScenario::append(legacy::scenario_data_type& old){
|
||||
}
|
||||
for(i = 0; i < 20; i++) scenario_timer_times[i] = old.scenario_timer_times[i];
|
||||
for(i = 0; i < 20; i++) scenario_timer_specs[i] = old.scenario_timer_specs[i];
|
||||
scen_specials.resize(256);
|
||||
for(i = 0; i < 256; i++) scen_specials[i].append(old.scen_specials[i]);
|
||||
for(i = 0; i < 10; i++) storage_shortcuts[i] = old.storage_shortcuts[i];
|
||||
last_out_edited.x = old.last_out_edited.x;
|
||||
|
@@ -78,7 +78,7 @@ public:
|
||||
std::array<cTerrain,256> ter_types;
|
||||
short scenario_timer_times[20];
|
||||
short scenario_timer_specs[20];
|
||||
std::array<cSpecial,256> scen_specials;
|
||||
std::vector<cSpecial> scen_specials;
|
||||
cItemStorage storage_shortcuts[10];
|
||||
location last_out_edited;
|
||||
short last_town_edited;
|
||||
|
@@ -66,6 +66,7 @@ void cTown::append(legacy::town_record_type& old){
|
||||
timer_spec_times[i] = old.timer_spec_times[i];
|
||||
timer_specs[i] = old.timer_specs[i];
|
||||
}
|
||||
specials.resize(100);
|
||||
for(i = 0; i < 100; i++)
|
||||
specials[i].append(old.specials[i]);
|
||||
difficulty = old.difficulty;
|
||||
@@ -104,9 +105,6 @@ cTown::cTown(cScenario& scenario, bool init_strings) : scenario(scenario) {
|
||||
timer_spec_times[i] = 0;
|
||||
timer_specs[i] = -1;
|
||||
}
|
||||
for(i = 0; i < 100; i++) {
|
||||
specials[i] = cSpecial();
|
||||
}
|
||||
difficulty = 0;
|
||||
bg_town = bg_fight = -1;
|
||||
strong_barriers = defy_scrying = defy_mapping = is_hidden = has_tavern = false;
|
||||
|
@@ -88,7 +88,7 @@ public:
|
||||
short spec_on_hostile;
|
||||
std::array<short,8> timer_spec_times;
|
||||
std::array<short,8> timer_specs;
|
||||
std::array<cSpecial,100> specials;
|
||||
std::vector<cSpecial> specials;
|
||||
bool strong_barriers : 1;
|
||||
bool defy_mapping : 1;
|
||||
bool defy_scrying : 1;
|
||||
|
@@ -282,6 +282,8 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
draw_rb_slot(i + right_top,0);
|
||||
mainPtr.display();
|
||||
change_made = true;
|
||||
size_t size_before;
|
||||
size_t pos_before = right_sbar->getPosition();
|
||||
switch(right_button_status[i + right_top].action) {
|
||||
case RB_CLEAR:
|
||||
break;
|
||||
@@ -300,25 +302,61 @@ bool handle_action(location the_point,sf::Event /*event*/) {
|
||||
start_item_editing(1);
|
||||
break;
|
||||
case RB_SCEN_SPEC:
|
||||
size_before = scenario.scen_specials.size();
|
||||
if(option_hit) {
|
||||
scenario.scen_specials[j] = cSpecial();
|
||||
if(j == size_before - 1)
|
||||
scenario.scen_specials.pop_back();
|
||||
else if(j == size_before)
|
||||
break;
|
||||
else scenario.scen_specials[j] = cSpecial();
|
||||
} else {
|
||||
if(j == size_before)
|
||||
scenario.scen_specials.emplace_back();
|
||||
if(!edit_spec_enc(j,0,nullptr) && j == size_before)
|
||||
scenario.scen_specials.pop_back();
|
||||
}
|
||||
else edit_spec_enc(j,0,nullptr);
|
||||
start_special_editing(0,1);
|
||||
start_special_editing(0,size_before == scenario.scen_specials.size());
|
||||
if(size_before > scenario.scen_specials.size())
|
||||
pos_before--;
|
||||
right_sbar->setPosition(pos_before);
|
||||
break;
|
||||
case RB_OUT_SPEC:
|
||||
size_before = current_terrain->specials.size();
|
||||
if(option_hit) {
|
||||
current_terrain->specials[j] = cSpecial();
|
||||
if(j == size_before - 1)
|
||||
current_terrain->specials.pop_back();
|
||||
else if(j == size_before)
|
||||
break;
|
||||
else current_terrain->specials[j] = cSpecial();
|
||||
} else {
|
||||
if(j == size_before)
|
||||
current_terrain->specials.emplace_back();
|
||||
if(!edit_spec_enc(j,1,nullptr) && j == size_before)
|
||||
current_terrain->specials.pop_back();
|
||||
}
|
||||
else edit_spec_enc(j,1,nullptr);
|
||||
start_special_editing(1,1);
|
||||
start_special_editing(1,size_before == current_terrain->specials.size());
|
||||
if(size_before > current_terrain->specials.size())
|
||||
pos_before--;
|
||||
right_sbar->setPosition(pos_before);
|
||||
break;
|
||||
case RB_TOWN_SPEC:
|
||||
size_before = town->specials.size();
|
||||
if(option_hit) {
|
||||
town->specials[j] = cSpecial();
|
||||
if(j == size_before - 1)
|
||||
town->specials.pop_back();
|
||||
else if(j == size_before)
|
||||
break;
|
||||
else town->specials[j] = cSpecial();
|
||||
} else {
|
||||
if(j == size_before)
|
||||
town->specials.emplace_back();
|
||||
if(!edit_spec_enc(j,2,nullptr) && j == size_before)
|
||||
town->specials.pop_back();
|
||||
}
|
||||
else edit_spec_enc(j,2,nullptr);
|
||||
start_special_editing(2,1);
|
||||
start_special_editing(2,size_before == town->specials.size());
|
||||
if(size_before > town->specials.size())
|
||||
pos_before--;
|
||||
right_sbar->setPosition(pos_before);
|
||||
break;
|
||||
case RB_SCEN_STR:
|
||||
if(option_hit) {
|
||||
@@ -2759,10 +2797,6 @@ void place_edit_special(location loc) {
|
||||
}
|
||||
if(i < 500) { // new special
|
||||
spec = get_fresh_spec(2);
|
||||
if(spec < 0) {
|
||||
giveError("You are out of special nodes in this town. Select Edit Special Nodes from the Town menu to clear out some of the special nodes.");
|
||||
return;
|
||||
}
|
||||
for(i = 0; i < town->special_locs.size(); i++)
|
||||
if(town->special_locs[i].spec < 0) {
|
||||
if(edit_spec_enc(spec,2,nullptr)) {
|
||||
@@ -2790,10 +2824,6 @@ void place_edit_special(location loc) {
|
||||
}
|
||||
if(i < 500) { // new special
|
||||
spec = get_fresh_spec(1);
|
||||
if(spec < 0) {
|
||||
giveError("You are out of special nodes in this outdoor section. Select Edit Special Nodes from the Outdoor menu to clear out some of the special nodes.");
|
||||
return;
|
||||
}
|
||||
for(i = 0; i < current_terrain->special_locs.size(); i++)
|
||||
if(current_terrain->special_locs[i].spec < 0) {
|
||||
if(edit_spec_enc(spec,1,nullptr)) {
|
||||
@@ -3195,7 +3225,7 @@ void start_special_editing(short mode,short just_redo_text) {
|
||||
right_sbar->show();
|
||||
|
||||
reset_rb();
|
||||
right_sbar->setMaximum(num_specs - NRSONPAGE);
|
||||
right_sbar->setMaximum(num_specs + 1 - NRSONPAGE);
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < num_specs; i++) {
|
||||
@@ -3215,6 +3245,12 @@ void start_special_editing(short mode,short just_redo_text) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::string make_new = std::to_string(num_specs) + " - Create New Special";
|
||||
switch(mode) {
|
||||
case 0: set_rb(num_specs, RB_SCEN_SPEC, num_specs, make_new); break;
|
||||
case 1: set_rb(num_specs, RB_OUT_SPEC, num_specs, make_new); break;
|
||||
case 2: set_rb(num_specs, RB_TOWN_SPEC, num_specs, make_new); break;
|
||||
}
|
||||
if(draw_full)
|
||||
redraw_screen();
|
||||
else for(i = 0; i < NRSONPAGE; i++)
|
||||
|
@@ -227,14 +227,8 @@ static bool pick_ter_flag(cDialog& me, std::string id, eKeyMod) {
|
||||
else if(choice == "town") which_type = 2;
|
||||
}
|
||||
short spec = me["flag1"].getTextAsNum();
|
||||
if(spec < 0 || spec > 255) {
|
||||
if(spec < 0)
|
||||
spec = get_fresh_spec(which_type);
|
||||
if(spec < 0) {
|
||||
giveError("You can't create a new 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.", &me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,which_type,&me))
|
||||
me["flag1"].setTextToNum(spec);
|
||||
return true;
|
||||
@@ -937,14 +931,8 @@ static bool edit_monst_abil_event_filter(cDialog& me,std::string hit,cMonster& m
|
||||
else abils.setPage(abils.getPage() + 1);
|
||||
} else if(hit == "edit-see") {
|
||||
short spec = me["onsee"].getTextAsNum();
|
||||
if(spec < 0 || spec > 255) {
|
||||
if(spec < 0)
|
||||
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.", &me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,0,&me))
|
||||
me["onsee"].setTextToNum(spec);
|
||||
} else if(hit == "pick-snd") {
|
||||
@@ -1145,11 +1133,6 @@ static bool edit_monst_abil_detail(cDialog& me, std::string hit, cMonster& monst
|
||||
case eMonstAbilTemplate::HIT_TRIGGERS:
|
||||
case eMonstAbilTemplate::DEATH_TRIGGERS:
|
||||
param = get_fresh_spec(0);
|
||||
if(param < 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.", &me);
|
||||
return true;
|
||||
}
|
||||
if(!edit_spec_enc(param,0,&me))
|
||||
return true;
|
||||
break;
|
||||
@@ -1302,14 +1285,8 @@ static bool edit_monst_abil_detail(cDialog& me, std::string hit, cMonster& monst
|
||||
if(abil == eMonstAbil::SPECIAL || abil == eMonstAbil::HIT_TRIGGER || abil == eMonstAbil::DEATH_TRIGGER)
|
||||
abil_dlg["pick-extra1"].attachClickHandler([&](cDialog& me,std::string,eKeyMod) -> bool {
|
||||
short spec = me["extra1"].getTextAsNum();
|
||||
if(spec < 0 || spec > 255) {
|
||||
if(spec < 0)
|
||||
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.", &me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,0,&me))
|
||||
me["extra1"].setTextToNum(spec);
|
||||
return true;
|
||||
@@ -1789,14 +1766,8 @@ static bool edit_item_abil_event_filter(cDialog& me, std::string hit, cItem& ite
|
||||
} else if(hit == "str1-choose") {
|
||||
save_item_abils(me, item);
|
||||
short spec = me["str1"].getTextAsNum();
|
||||
if(spec < 0 || spec > 255) {
|
||||
if(spec < 0)
|
||||
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.", &me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,0,&me)) {
|
||||
item.abil_data[0] = spec;
|
||||
me["str1"].setTextToNum(spec);
|
||||
@@ -1957,18 +1928,10 @@ static bool edit_spec_item_event_filter(cDialog& me, std::string hit, cSpecItem&
|
||||
} else if(hit == "edit-spec") {
|
||||
if(!save_spec_item(me, item, which)) return true;
|
||||
short spec = me["spec"].getTextAsNum();
|
||||
if((spec < 0) || (spec >= 256)) {
|
||||
if(spec < 0)
|
||||
spec = get_fresh_spec(0);
|
||||
if(spec < 0) {
|
||||
giveError("You can't create a new special encounter because there are no more free scenario special nodes.",
|
||||
"To free a special node, set its type to No Special and set its Jump To special to -1.",&me);
|
||||
return true;
|
||||
}
|
||||
if(edit_spec_enc(spec,0,&me))
|
||||
me["spec"].setTextToNum(spec);
|
||||
}
|
||||
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, item, which);
|
||||
|
||||
}
|
||||
@@ -2647,14 +2610,8 @@ static bool edit_scenario_events_event_filter(cDialog& me, std::string item_hit,
|
||||
// item_hit is of the form editN; we need an ID of the form nodeN
|
||||
item_hit.replace(0, 4, "node");
|
||||
short spec = me[item_hit].getTextAsNum();
|
||||
if(spec < 0 || spec > 255) {
|
||||
if(spec < 0)
|
||||
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;
|
||||
|
@@ -751,11 +751,6 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
|
||||
case 's': case 'S':
|
||||
choose_string = false;
|
||||
store = val < 0 ? get_fresh_spec(mode) : val;
|
||||
if(store < 0) {
|
||||
giveError("You can't create a new 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.",&me);
|
||||
return true;
|
||||
}
|
||||
me[field].setTextToNum(store);
|
||||
save_spec_enc(me, edit_stack);
|
||||
if(mode == 0)
|
||||
@@ -838,15 +833,26 @@ bool edit_spec_enc(short which_node,short mode,cDialog* parent) {
|
||||
cSpecial the_node;
|
||||
node_stack_t edit_stack;
|
||||
|
||||
if(mode == 0)
|
||||
if(mode == 0) {
|
||||
if(which_node >= scenario.scen_specials.size()) {
|
||||
giveError("That special node does not exist. You can create a new node by setting the field to -1 and trying again.", parent);
|
||||
return false;
|
||||
}
|
||||
the_node = scenario.scen_specials[which_node];
|
||||
else if(mode == 1)
|
||||
} else if(mode == 1) {
|
||||
if(which_node >= current_terrain->specials.size()) {
|
||||
giveError("That special node does not exist. You can create a new node by setting the field to -1 and trying again.", parent);
|
||||
return false;
|
||||
}
|
||||
the_node = current_terrain->specials[which_node];
|
||||
else if(mode == 2)
|
||||
} else if(mode == 2) {
|
||||
if(which_node >= town->specials.size()) {
|
||||
giveError("That special node does not exist. You can create a new node by setting the field to -1 and trying again.", parent);
|
||||
return false;
|
||||
}
|
||||
the_node = town->specials[which_node];
|
||||
if(the_node.pic < 0)
|
||||
the_node.pic = 0;
|
||||
|
||||
}
|
||||
|
||||
cDialog special("edit-special-node",parent);
|
||||
special.attachClickHandlers(std::bind(commit_spec_enc, _1, _2, std::ref(edit_stack)), {"okay", "back"});
|
||||
special.attachClickHandlers(std::bind(edit_spec_enc_type, _1, _2, std::ref(edit_stack)), {
|
||||
@@ -883,11 +889,17 @@ short get_fresh_spec(short which_mode) {
|
||||
store_node = current_terrain->specials[i];
|
||||
if(which_mode == 2)
|
||||
store_node = town->specials[i];
|
||||
if(store_node.type == eSpecType::NONE && store_node.jumpto == -1 && store_node.pic == -1)
|
||||
if(store_node.type == eSpecType::NONE && store_node.jumpto == -1)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
switch(which_mode) {
|
||||
case 0: scenario.scen_specials.emplace_back(); break;
|
||||
case 1: current_terrain->specials.emplace_back(); break;
|
||||
case 2: town->specials.emplace_back(); break;
|
||||
}
|
||||
|
||||
return num_specs;
|
||||
}
|
||||
|
||||
static bool edit_spec_text_event_filter(cDialog& me, std::string item_hit, short str_mode, short* str1, short* str2) {
|
||||
|
@@ -185,14 +185,8 @@ static bool edit_placed_monst_adv_time_flag(cDialog& me, std::string, bool losin
|
||||
|
||||
static bool edit_placed_monst_adv_death(cDialog& me, cTownperson& monst) {
|
||||
short spec = monst.special_on_kill;
|
||||
if(spec < 0) {
|
||||
if(spec < 0)
|
||||
spec = get_fresh_spec(2);
|
||||
if(spec < 0) {
|
||||
giveError("You can't create a new town 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.", &me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,2,&me))
|
||||
me["death"].setTextToNum(spec);
|
||||
return true;
|
||||
@@ -636,14 +630,8 @@ static bool edit_out_wand_spec(cDialog& me, std::string hit, short which, cOutdo
|
||||
save_out_wand(me, which, wand, 100);
|
||||
std::string fld = "on" + hit.substr(5);
|
||||
short spec = me[fld].getTextAsNum();
|
||||
if(spec < 0 || spec >= 60) {
|
||||
if(spec < 0)
|
||||
spec = get_fresh_spec(1);
|
||||
if(spec < 0) {
|
||||
giveError("You can't create a new 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.",&me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,1,&me))
|
||||
me[fld].setTextToNum(spec);
|
||||
return true;
|
||||
@@ -771,14 +759,8 @@ static void put_town_events_in_dlog(cDialog& me) {
|
||||
static bool edit_town_events_event_filter(cDialog& me, std::string item_hit, eKeyMod) {
|
||||
std::string id = item_hit.substr(4);
|
||||
short spec = me["spec" + id].getTextAsNum();
|
||||
if(spec < 0 || spec > 99) {
|
||||
if(spec < 0)
|
||||
spec = get_fresh_spec(2);
|
||||
if(spec < 0) {
|
||||
giveError("You can't create a new 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.",&me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,2,&me))
|
||||
me["spec" + id].setTextToNum(spec);
|
||||
return true;
|
||||
@@ -841,14 +823,8 @@ static void put_advanced_town_in_dlog(cDialog& me) {
|
||||
static bool edit_advanced_town_special(cDialog& me, std::string hit, eKeyMod) {
|
||||
std::string fld = hit.substr(5);
|
||||
short spec = me[fld].getTextAsNum();
|
||||
if(spec < 0 || spec > 99) {
|
||||
if(spec < 0)
|
||||
spec = get_fresh_spec(2);
|
||||
if(spec < 0) {
|
||||
giveError("You can't create a new town 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.", &me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,2,&me)) {
|
||||
me[fld].setTextToNum(spec);
|
||||
}
|
||||
@@ -1205,14 +1181,8 @@ static bool select_talk_node_value(cDialog& me, std::string item_hit, const std:
|
||||
} else if(item_hit == "chooseA") {
|
||||
int spec = me["extra1"].getTextAsNum();
|
||||
int mode = talk_node.type == eTalkNode::CALL_TOWN_SPEC ? 2 : 0;
|
||||
if(spec < 0 || spec >= 100) {
|
||||
if(spec < 0)
|
||||
spec = get_fresh_spec(mode);
|
||||
if(spec < 0) {
|
||||
giveError("You can't create a new 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.",&me);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(edit_spec_enc(spec,mode,&me))
|
||||
me["extra1"].setTextToNum(spec);
|
||||
}
|
||||
|
Reference in New Issue
Block a user