Remove the limits on the total number of special nodes in the game

This commit is contained in:
2015-02-01 18:16:13 -05:00
parent c37ede5a04
commit eaeb9690c3
10 changed files with 99 additions and 124 deletions

View File

@@ -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]);
}

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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++)

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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);
}