add methods get_special_string to check access bounds of spec_strs...

This commit is contained in:
ALONSO Laurent
2021-10-22 13:39:28 +02:00
committed by Celtic Minstrel
parent 0c269c420c
commit a51ba34650
16 changed files with 143 additions and 67 deletions

View File

@@ -273,7 +273,8 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_head
if(i % 2 == 0) scenario.special_items[(i-60)/2].name = tmp; if(i % 2 == 0) scenario.special_items[(i-60)/2].name = tmp;
else scenario.special_items[(i-60)/2].descr = tmp; else scenario.special_items[(i-60)/2].descr = tmp;
} else if(i >= 260) continue; // These were never ever used, for some reason. } else if(i >= 260) continue; // These were never ever used, for some reason.
else scenario.spec_strs[i-160] = tmp; else
scenario.get_special_string(i-160) = tmp;
} }
fclose(file_id); fclose(file_id);
@@ -888,9 +889,9 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario) {
timers++; timers++;
} else if(type == "string") { } else if(type == "string") {
game->GetAttribute("id", &strnum); game->GetAttribute("id", &strnum);
if(strnum >= scenario.spec_strs.size()) // changeme: add a maximum and discard data if not in a range if(strnum >= scenario.spec_strs.size() && strnum<10000)
scenario.spec_strs.resize(strnum + 1); scenario.spec_strs.resize(strnum + 1);
game->GetText(&scenario.spec_strs[strnum], false); game->GetText(&scenario.get_special_string(strnum), false);
} else if(type == "journal") { } else if(type == "journal") {
game->GetAttribute("id", &strnum); game->GetAttribute("id", &strnum);
if(strnum >= scenario.journal_strs.size()) // changeme: add a maximum and discard data if not in a range if(strnum >= scenario.journal_strs.size()) // changeme: add a maximum and discard data if not in a range
@@ -1133,7 +1134,7 @@ void readItemsFromXml(ticpp::Document&& data, cScenario& scenario) {
throw xBadNode(type, elem->Row(), elem->Column(), fname); throw xBadNode(type, elem->Row(), elem->Column(), fname);
int which_item; int which_item;
elem->GetAttribute("id", &which_item); elem->GetAttribute("id", &which_item);
if(which_item >= scenario.scen_items.size() && which_item<5000) // checkme: what is a reasonnable maximum for the item if(which_item >= scenario.scen_items.size() && which_item<5000) // checkme: what is a reasonable maximum for the item
scenario.scen_items.resize(which_item + 1); scenario.scen_items.resize(which_item + 1);
cItem& the_item = scenario.get_item(which_item); cItem& the_item = scenario.get_item(which_item);
the_item = cItem(); the_item = cItem();
@@ -1654,9 +1655,9 @@ void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) {
} else if(type == "string") { } else if(type == "string") {
int str; int str;
elem->GetAttribute("id", &str); elem->GetAttribute("id", &str);
if(str >= out.spec_strs.size()) if(str >= out.spec_strs.size() && str<10000) // CHECKME: 10000 is probably too big?
out.spec_strs.resize(str + 1); out.spec_strs.resize(str + 1);
elem->GetText(&out.spec_strs[str], false); elem->GetText(&out.get_special_string(str), false);
} else throw xBadNode(type, elem->Row(), elem->Column(), fname); } else throw xBadNode(type, elem->Row(), elem->Column(), fname);
} }
if(!found_name) if(!found_name)
@@ -1781,9 +1782,9 @@ void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) {
} else if(type == "string") { } else if(type == "string") {
int str; int str;
elem->GetAttribute("id", &str); elem->GetAttribute("id", &str);
if(str >= town->spec_strs.size()) if(str >= town->spec_strs.size() && str<10000)
town->spec_strs.resize(str + 1); town->spec_strs.resize(str + 1);
elem->GetText(&town->spec_strs[str], false); elem->GetText(&town->get_special_string(str), false);
} else if(type == "item") { } else if(type == "item") {
int which_item; int which_item;
elem->GetAttribute("id", &which_item); elem->GetAttribute("id", &which_item);
@@ -1888,19 +1889,20 @@ void readDialogueFromXml(ticpp::Document&& data, cSpeech& talk, int town_num) {
id %= 10; id %= 10;
std::set<std::string> reqs = {"title", "look", "name", "job"}; std::set<std::string> reqs = {"title", "look", "name", "job"};
Iterator<Element> who; Iterator<Element> who;
cPersonality &people=talk.people[id];
for(who = who.begin(elem.Get()); who != who.end(); who++) { for(who = who.begin(elem.Get()); who != who.end(); who++) {
who->GetValue(&type); who->GetValue(&type);
reqs.erase(type); reqs.erase(type);
if(type == "title") { if(type == "title") {
who->GetText(&talk.people[id].title, false); who->GetText(&people.title, false);
} else if(type == "look") { } else if(type == "look") {
who->GetText(&talk.people[id].look, false); who->GetText(&people.look, false);
} else if(type == "name") { } else if(type == "name") {
who->GetText(&talk.people[id].name, false); who->GetText(&people.name, false);
} else if(type == "job") { } else if(type == "job") {
who->GetText(&talk.people[id].job, false); who->GetText(&people.job, false);
} else if(type == "unknown") { } else if(type == "unknown") {
who->GetText(&talk.people[id].dunno, false); who->GetText(&people.dunno, false);
} else throw xBadNode(type, who->Row(), who->Column(), fname); } else throw xBadNode(type, who->Row(), who->Column(), fname);
} }
if(!reqs.empty()) if(!reqs.empty())
@@ -2348,7 +2350,7 @@ bool load_town_v1(fs::path scen_file, short which_town, cTown& the_town, legacy:
else if(i >= 17 && i < 20) else if(i >= 17 && i < 20)
the_town.comment[i-17] = tmp; the_town.comment[i-17] = tmp;
else if(i >= 20 && i < 120) else if(i >= 20 && i < 120)
the_town.spec_strs[i-20] = tmp; the_town.get_special_string(i-20) = tmp;
else if(i >= 120 && i < 140) else if(i >= 120 && i < 140)
the_town.sign_locs[i-120].text = tmp; the_town.sign_locs[i-120].text = tmp;
} }
@@ -2460,7 +2462,7 @@ bool load_outdoors_v1(fs::path scen_file, location which_out,cOutdoors& the_out,
else if(i == 9) the_out.comment = tmp; else if(i == 9) the_out.comment = tmp;
else if(i < 9) the_out.area_desc[i-1].descr = tmp; else if(i < 9) the_out.area_desc[i-1].descr = tmp;
else if(i >= 10 && i < 100) else if(i >= 10 && i < 100)
the_out.spec_strs[i-10] = tmp; the_out.get_special_string(i-10) = tmp;
else if(i >= 100 && i < 108) else if(i >= 100 && i < 108)
the_out.sign_locs[i-100].text = tmp; the_out.sign_locs[i-100].text = tmp;
} }

View File

@@ -585,7 +585,7 @@ static void handle_talk(location destination, bool& did_something, bool& need_re
small_talk = -univ.town.monst[i].personality; small_talk = -univ.town.monst[i].personality;
std::string str = "No response."; std::string str = "No response.";
if(small_talk > 1000 && small_talk < 1000 + univ.scenario.spec_strs.size()) if(small_talk > 1000 && small_talk < 1000 + univ.scenario.spec_strs.size())
str = univ.scenario.spec_strs[small_talk - 1000]; str = univ.scenario.get_special_string(small_talk - 1000);
// TODO: Come up with a set of pre-cooked responses. // TODO: Come up with a set of pre-cooked responses.
add_string_to_buf("Talk: " + str, 4); add_string_to_buf("Talk: " + str, 4);
} else if (univ.town.monst[i].active) { } else if (univ.town.monst[i].active) {

View File

@@ -1114,8 +1114,8 @@ void handle_talk_event(location p) {
run_special(eSpecCtx::TALK, eSpecCtxType::TOWN, a, univ.party.town_loc, &s1, &s2); run_special(eSpecCtx::TALK, eSpecCtxType::TOWN, a, univ.party.town_loc, &s1, &s2);
// check s1 & s2 to see if we got diff str, and, if so, munch old strs // check s1 & s2 to see if we got diff str, and, if so, munch old strs
if((s1 >= 0) || (s2 >= 0)) { if((s1 >= 0) || (s2 >= 0)) {
save_talk_str1 = s1 >= 0 ? univ.town->spec_strs[s1] : ""; save_talk_str1 = s1 >= 0 ? univ.town->get_special_string(s1) : "";
save_talk_str2 = s2 >= 0 ? univ.town->spec_strs[s2] : ""; save_talk_str2 = s2 >= 0 ? univ.town->get_special_string(s2) : "";
} }
get_strs(save_talk_str1, save_talk_str2, eSpecCtxType::TOWN, s1, s2); get_strs(save_talk_str1, save_talk_str2, eSpecCtxType::TOWN, s1, s2);
put_pc_screen(); put_pc_screen();
@@ -1125,8 +1125,8 @@ void handle_talk_event(location p) {
run_special(eSpecCtx::TALK, eSpecCtxType::SCEN, a, univ.party.town_loc, &s1, &s2); run_special(eSpecCtx::TALK, eSpecCtxType::SCEN, a, univ.party.town_loc, &s1, &s2);
// check s1 & s2 to see if we got diff str, and, if so, munch old strs // check s1 & s2 to see if we got diff str, and, if so, munch old strs
if((s1 >= 0) || (s2 >= 0)) { if((s1 >= 0) || (s2 >= 0)) {
save_talk_str1 = s1 >= 0 ? univ.scenario.spec_strs[s1] : ""; save_talk_str1 = s1 >= 0 ? univ.scenario.get_special_string(s1) : "";
save_talk_str2 = s2 >= 0 ? univ.scenario.spec_strs[s2] : ""; save_talk_str2 = s2 >= 0 ? univ.scenario.get_special_string(s2) : "";
} }
get_strs(save_talk_str1, save_talk_str2, eSpecCtxType::SCEN, s1, s2); get_strs(save_talk_str1, save_talk_str2, eSpecCtxType::SCEN, s1, s2);
put_pc_screen(); put_pc_screen();

View File

@@ -690,21 +690,21 @@ void cStringRecorder::operator()(cDialog& me) {
std::string str1, str2; std::string str1, str2;
switch(type) { switch(type) {
case NOTE_SCEN: case NOTE_SCEN:
str1 = univ.scenario.spec_strs[label1]; str1 = univ.scenario.get_special_string(label1);
if (label2>=univ.scenario.spec_strs.size()) if (label2>=univ.scenario.spec_strs.size())
add_string_to_buf("cStringRecorder()[scenario]: empty label 2."); add_string_to_buf("cStringRecorder()[scenario]: empty label 2.");
else else
str2 = univ.scenario.spec_strs[label2]; str2 = univ.scenario.spec_strs[label2];
break; break;
case NOTE_TOWN: case NOTE_TOWN:
str1 = univ.town->spec_strs[label1]; str1 = univ.town->get_special_string(label1);
if (label2>=univ.town->spec_strs.size()) if (label2>=univ.town->spec_strs.size())
add_string_to_buf("cStringRecorder()[town]: empty label 2."); add_string_to_buf("cStringRecorder()[town]: empty label 2.");
else else
str2 = univ.town->spec_strs[label2]; str2 = univ.town->spec_strs[label2];
break; break;
case NOTE_OUT: case NOTE_OUT:
str1 = univ.scenario.outdoors[label1b][label2b]->spec_strs[label1]; str1 = univ.scenario.outdoors[label1b][label2b]->get_special_string(label1);
// memory problem, ie. called with label=65535(-1) // memory problem, ie. called with label=65535(-1)
if (label2>=univ.scenario.outdoors[label1b][label2b]->spec_strs.size()) if (label2>=univ.scenario.outdoors[label1b][label2b]->spec_strs.size())
add_string_to_buf("cStringRecorder()[out]: empty label 2."); add_string_to_buf("cStringRecorder()[out]: empty label 2.");

View File

@@ -641,11 +641,11 @@ void story_dialog(std::string title, str_num_t first, str_num_t last, eSpecCtxTy
cur++; cur++;
} }
if(which_str_type == eSpecCtxType::SCEN) if(which_str_type == eSpecCtxType::SCEN)
me["str"].setText(univ.scenario.spec_strs[cur]); me["str"].setText(univ.scenario.get_special_string(cur));
else if(which_str_type == eSpecCtxType::OUTDOOR) else if(which_str_type == eSpecCtxType::OUTDOOR)
me["str"].setText(univ.out->spec_strs[cur]); me["str"].setText(univ.out->get_special_string(cur));
else if(which_str_type == eSpecCtxType::TOWN) else if(which_str_type == eSpecCtxType::TOWN)
me["str"].setText(univ.town->spec_strs[cur]); me["str"].setText(univ.town->get_special_string(cur));
return true; return true;
}, {"left", "right", "done"}); }, {"left", "right", "done"});
story_dlg["left"].triggerClickHandler(story_dlg, "left", eKeyMod()); story_dlg["left"].triggerClickHandler(story_dlg, "left", eKeyMod());

View File

@@ -4584,21 +4584,21 @@ void get_strs(std::string& str1,std::string& str2,eSpecCtxType cur_type,short wh
switch(cur_type) { switch(cur_type) {
case eSpecCtxType::SCEN: case eSpecCtxType::SCEN:
if(which_str1 >= 0) if(which_str1 >= 0)
str1 = univ.scenario.spec_strs[which_str1]; str1 = univ.scenario.get_special_string(which_str1);
if(which_str2 >= 0) if(which_str2 >= 0)
str2 = univ.scenario.spec_strs[which_str2]; str2 = univ.scenario.get_special_string(which_str2);
break; break;
case eSpecCtxType::OUTDOOR: case eSpecCtxType::OUTDOOR:
if(which_str1 >= 0) if(which_str1 >= 0)
str1 = univ.out->spec_strs[which_str1]; str1 = univ.out->get_special_string(which_str1);
if(which_str2 >= 0) if(which_str2 >= 0)
str2 = univ.out->spec_strs[which_str2]; str2 = univ.out->get_special_string(which_str2);
break; break;
case eSpecCtxType::TOWN: case eSpecCtxType::TOWN:
if(which_str1 >= 0) if(which_str1 >= 0)
str1 = univ.town->spec_strs[which_str1]; str1 = univ.town->get_special_string(which_str1);
if(which_str2 >= 0) if(which_str2 >= 0)
str2 = univ.town->spec_strs[which_str2]; str2 = univ.town->get_special_string(which_str2);
break; break;
} }
@@ -4614,7 +4614,7 @@ void set_campaign_flag(short sdf_a, short sdf_b, short cpf_a, short cpf_b, short
// get_send = true: Retrieve value from Campaign Flag and put in SDF // get_send = true: Retrieve value from Campaign Flag and put in SDF
try { try {
if(str >= 0 && str < univ.scenario.spec_strs.size()) { if(str >= 0 && str < univ.scenario.spec_strs.size()) {
std::string cp_id = univ.scenario.spec_strs[str]; std::string const &cp_id = univ.scenario.spec_strs[str];
if(get_send) if(get_send)
univ.party.stuff_done[sdf_a][sdf_b] = univ.cpn_flag(cpf_a, cpf_b, cp_id); univ.party.stuff_done[sdf_a][sdf_b] = univ.cpn_flag(cpf_a, cpf_b, cp_id);
else else

View File

@@ -17,6 +17,27 @@
#include "oldstructs.hpp" #include "oldstructs.hpp"
#include "scenario.hpp" #include "scenario.hpp"
std::string &cOutdoors::get_special_string(int id)
{
if (id>=0 && id<spec_strs.size())
return spec_strs[id];
if (id>=0 && id<200) {
spec_strs.resize(id+1);
return spec_strs[id];
}
static std::string badString;
badString="Bad Special String";
return badString;
}
std::string const &cOutdoors::get_special_string(int id) const
{
if (id>=0 && id<spec_strs.size())
return spec_strs[id];
static std::string badString="Bad Special String";
return badString;
}
void cOutdoors::import_legacy(legacy::outdoor_record_type const &old){ void cOutdoors::import_legacy(legacy::outdoor_record_type const &old){
ambient_sound = AMBIENT_NONE; ambient_sound = AMBIENT_NONE;
// Collect a list of unused special nodes, to be used for fixing specials that could be triggered in a boat. // Collect a list of unused special nodes, to be used for fixing specials that could be triggered in a boat.

View File

@@ -74,6 +74,9 @@ public:
explicit cOutdoors(cScenario& scenario); explicit cOutdoors(cScenario& scenario);
void import_legacy(legacy::outdoor_record_type const &old); void import_legacy(legacy::outdoor_record_type const &old);
void reattach(cScenario& to); void reattach(cScenario& to);
std::string &get_special_string(int id);
std::string const &get_special_string(int id) const;
}; };
#endif #endif

View File

@@ -303,12 +303,34 @@ cShop &cScenario::get_shop(int shop)
return badShop; return badShop;
} }
std::string &cScenario::get_special_string(int id)
{
if (id>=0 && id<spec_strs.size())
return spec_strs[id];
if (id>=0 && id<200) {
spec_strs.resize(id+1);
return spec_strs[id];
}
static std::string badString;
badString="Bad Special String";
return badString;
}
std::string const &cScenario::get_special_string(int id) const
{
if (id>=0 && id<spec_strs.size())
return spec_strs[id];
static std::string badString="Bad Special String";
return badString;
}
static cTerrain getBadTerrain() { static cTerrain getBadTerrain() {
cTerrain badTerrain; cTerrain badTerrain;
badTerrain.picture = -3; badTerrain.picture = -3;
badTerrain.map_pic = -3; badTerrain.map_pic = -3;
return badTerrain; return badTerrain;
} }
cTerrain const &cScenario::get_terrain(ter_num_t ter) const cTerrain const &cScenario::get_terrain(ter_num_t ter) const
{ {
if (ter<ter_types.size()) if (ter<ter_types.size())

View File

@@ -58,6 +58,8 @@ public:
cSpecItem &get_special_item(item_num_t item); cSpecItem &get_special_item(item_num_t item);
cShop const &get_shop(int shop) const; cShop const &get_shop(int shop) const;
cShop &get_shop(int shop); cShop &get_shop(int shop);
std::string &get_special_string(int id);
std::string const &get_special_string(int id) const;
cTerrain const &get_terrain(ter_num_t ter) const; cTerrain const &get_terrain(ter_num_t ter) const;
cTerrain &get_terrain(ter_num_t ter); cTerrain &get_terrain(ter_num_t ter);

View File

@@ -128,6 +128,27 @@ void cTown::init_start() {
in_town_rect.right = s - 4; in_town_rect.right = s - 4;
} }
std::string &cTown::get_special_string(int id)
{
if (id>=0 && id<spec_strs.size())
return spec_strs[id];
if (id>=0 && id<200) {
spec_strs.resize(id+1);
return spec_strs[id];
}
static std::string badString;
badString="Bad Special String";
return badString;
}
std::string const &cTown::get_special_string(int id) const
{
if (id>=0 && id<spec_strs.size())
return spec_strs[id];
static std::string badString="Bad Special String";
return badString;
}
void cTown::cWandering::import_legacy(legacy::wandering_type const &old){ void cTown::cWandering::import_legacy(legacy::wandering_type const &old){
monst[0] = old.monst[0]; monst[0] = old.monst[0];
monst[1] = old.monst[1]; monst[1] = old.monst[1];

View File

@@ -119,6 +119,8 @@ public:
bool is_item_taken(size_t i) const; bool is_item_taken(size_t i) const;
void clear_items_taken(); void clear_items_taken();
void set_item_taken(size_t i, bool val = true); void set_item_taken(size_t i, bool val = true);
std::string &get_special_string(int id);
std::string const &get_special_string(int id) const;
}; };
std::ostream& operator<< (std::ostream& out, eLighting light); std::ostream& operator<< (std::ostream& out, eLighting light);

View File

@@ -446,11 +446,11 @@ static bool handle_rb_action(location the_point, bool option_hit) {
scenario.spec_strs.pop_back(); scenario.spec_strs.pop_back();
else if(j == size_before) else if(j == size_before)
scenario.spec_strs.resize(size_before + 8, "*"); scenario.spec_strs.resize(size_before + 8, "*");
else scenario.spec_strs[j] = "*"; else scenario.get_special_string(j) = "*";
} else { } else {
if(j == size_before) if(j == size_before)
scenario.spec_strs.emplace_back("*"); scenario.spec_strs.emplace_back("*");
if(!edit_text_str(j,STRS_SCEN) && j == size_before && scenario.spec_strs[j] == "*") if(!edit_text_str(j,STRS_SCEN) && j == size_before && scenario.get_special_string(j) == "*")
scenario.spec_strs.pop_back(); scenario.spec_strs.pop_back();
} }
start_string_editing(STRS_SCEN,size_before == scenario.spec_strs.size()); start_string_editing(STRS_SCEN,size_before == scenario.spec_strs.size());
@@ -465,11 +465,11 @@ static bool handle_rb_action(location the_point, bool option_hit) {
current_terrain->spec_strs.pop_back(); current_terrain->spec_strs.pop_back();
else if(j == size_before) else if(j == size_before)
current_terrain->spec_strs.resize(size_before + 8, "*"); current_terrain->spec_strs.resize(size_before + 8, "*");
else current_terrain->spec_strs[j] = "*"; else current_terrain->get_special_string(j) = "*";
} else { } else {
if(j == size_before) if(j == size_before)
current_terrain->spec_strs.emplace_back("*"); current_terrain->spec_strs.emplace_back("*");
if(!edit_text_str(j,STRS_OUT) && j == size_before && current_terrain->spec_strs[j] == "*") if(!edit_text_str(j,STRS_OUT) && j == size_before && current_terrain->get_special_string(j) == "*")
current_terrain->spec_strs.pop_back(); current_terrain->spec_strs.pop_back();
} }
start_string_editing(STRS_OUT,size_before == current_terrain->spec_strs.size()); start_string_editing(STRS_OUT,size_before == current_terrain->spec_strs.size());
@@ -484,11 +484,11 @@ static bool handle_rb_action(location the_point, bool option_hit) {
town->spec_strs.pop_back(); town->spec_strs.pop_back();
else if(j == size_before) else if(j == size_before)
town->spec_strs.resize(size_before + 8, "*"); town->spec_strs.resize(size_before + 8, "*");
else town->spec_strs[j] = "*"; else town->get_special_string(j) = "*";
} else { } else {
if(j == size_before) if(j == size_before)
town->spec_strs.emplace_back("*"); town->spec_strs.emplace_back("*");
if(!edit_text_str(j,STRS_TOWN) && j == size_before && town->spec_strs[j] == "*") if(!edit_text_str(j,STRS_TOWN) && j == size_before && town->get_special_string(j) == "*")
town->spec_strs.pop_back(); town->spec_strs.pop_back();
} }
start_string_editing(STRS_TOWN,size_before == town->spec_strs.size()); start_string_editing(STRS_TOWN,size_before == town->spec_strs.size());
@@ -2547,15 +2547,15 @@ void start_string_editing(eStrMode mode,short just_redo_text) {
std::ostringstream str; std::ostringstream str;
switch(mode) { switch(mode) {
case 0: case 0:
str << i << " - " << scenario.spec_strs[i].substr(0,30); str << i << " - " << scenario.get_special_string(i).substr(0,30);
set_rb(i,RB_SCEN_STR, i,str.str()); set_rb(i,RB_SCEN_STR, i,str.str());
break; break;
case 1: case 1:
str << i << " - " << current_terrain->spec_strs[i].substr(0,30); str << i << " - " << current_terrain->get_special_string(i).substr(0,30);
set_rb(i,RB_OUT_STR, i,str.str()); set_rb(i,RB_OUT_STR, i,str.str());
break; break;
case 2: case 2:
str << i << " - " << town->spec_strs[i].substr(0,30); str << i << " - " << town->get_special_string(i).substr(0,30);
set_rb(i,RB_TOWN_STR, i,str.str()); set_rb(i,RB_TOWN_STR, i,str.str());
break; break;
case 3: case 3:

View File

@@ -227,7 +227,7 @@ void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
data.CloseElement("quest"); data.CloseElement("quest");
} }
for(size_t i = 0; i < scenario.shops.size(); i++) { for(size_t i = 0; i < scenario.shops.size(); i++) {
cShop& shop = scenario.shops[i]; cShop const &shop = scenario.shops[i];
data.OpenElement("shop"); data.OpenElement("shop");
data.PushElement("name", shop.getName()); data.PushElement("name", shop.getName());
data.PushElement("type", shop.getType()); data.PushElement("type", shop.getType());

View File

@@ -68,9 +68,9 @@ static void ensure_str(eStrMode str_mode, size_t which) {
static std::string& fetch_str(eStrMode str_mode, size_t which) { static std::string& fetch_str(eStrMode str_mode, size_t which) {
ensure_str(str_mode, which); ensure_str(str_mode, which);
switch(str_mode) { switch(str_mode) {
case 0: return scenario.spec_strs[which]; case 0: return scenario.get_special_string(which);
case 1: return current_terrain->spec_strs[which]; case 1: return current_terrain->get_special_string(which);
case 2: return town->spec_strs[which]; case 2: return town->get_special_string(which);
case 3: return scenario.journal_strs[which]; case 3: return scenario.journal_strs[which];
case 4: return current_terrain->sign_locs[which].text; case 4: return current_terrain->sign_locs[which].text;
case 5: return town->sign_locs[which].text; case 5: return town->sign_locs[which].text;

View File

@@ -313,11 +313,14 @@ void cParty::import_legacy(legacy::setup_save_type const & old){
} }
void cParty::cConvers::import_legacy(legacy::talk_save_type const &old, const cScenario& scenario){ void cParty::cConvers::import_legacy(legacy::talk_save_type const &old, const cScenario& scenario){
who_said = scenario.towns[old.personality / 10]->talking.people[old.personality % 10].title; if (old.personality<0) // fixme: add an error message here
return;
cTown const *town=scenario.towns[old.personality/10];
who_said = town->talking.people[old.personality%10].title;
in_town = scenario.towns[old.town_num]->name; in_town = scenario.towns[old.town_num]->name;
int strnums[2] = {old.str1, old.str2};
std::string* strs[2] = {&the_str1, &the_str2};
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
int num=i==0 ? old.str1 : old.str2;
std::string &str=i==0 ? the_str1 : the_str2;
// Okay, so there's a ton of different places where the actual strings might be found. // Okay, so there's a ton of different places where the actual strings might be found.
// 0 means no string // 0 means no string
// 10 + n is the "look" string for the nth personality in the town (ie, n is personality % 10) // 10 + n is the "look" string for the nth personality in the town (ie, n is personality % 10)
@@ -327,21 +330,21 @@ void cParty::cConvers::import_legacy(legacy::talk_save_type const &old, const cS
// 40 + 2n + 1 is the second string from the nth talk not in the town // 40 + 2n + 1 is the second string from the nth talk not in the town
// 2000 + n is the nth town special text // 2000 + n is the nth town special text
// 3000 + n is the nth scenario special text // 3000 + n is the nth scenario special text
if(strnums[i] == 0) continue; if(num == 0) continue;
if(strnums[i] >= 3000) if(num >= 3000)
strs[i]->assign(scenario.spec_strs[strnums[i] - 3000]); str.assign(scenario.get_special_string(num - 3000));
else if(strnums[i] >= 2000) else if(num >= 2000)
strs[i]->assign(scenario.towns[old.personality / 10]->spec_strs[strnums[i] - 2000]); str.assign(town->get_special_string(num - 2000));
else if(strnums[i] >= 40 && strnums[i] % 2 == 0) else if(num >= 40 && num % 2 == 0)
strs[i]->assign(scenario.towns[old.personality / 10]->talking.talk_nodes[(strnums[i] - 40) / 2].str1); str.assign(town->talking.talk_nodes[(num - 40) / 2].str1);
else if(strnums[i] >= 40 && strnums[i] % 2 == 1) else if(num >= 40 && num % 2 == 1)
strs[i]->assign(scenario.towns[old.personality / 10]->talking.talk_nodes[(strnums[i] - 40) / 2].str2); str.assign(town->talking.talk_nodes[(num - 40) / 2].str2);
else if(strnums[i] >= 30) else if(num >= 30)
strs[i]->assign(scenario.towns[old.personality / 10]->talking.people[old.personality % 10].job); str.assign(town->talking.people[num-30].job);
else if(strnums[i] >= 20) else if(num >= 20)
strs[i]->assign(scenario.towns[old.personality / 10]->talking.people[old.personality % 10].name); str.assign(town->talking.people[num-20].name);
else if(strnums[i] >= 10) else if(num >= 10)
strs[i]->assign(scenario.towns[old.personality / 10]->talking.people[old.personality % 10].look); str.assign(town->talking.people[num-10].look);
} }
} }
@@ -350,17 +353,17 @@ void cParty::cEncNote::import_legacy(int16_t const (& old)[2], const cScenario&
// TODO: Need to verify that I have the correct offsets here. // TODO: Need to verify that I have the correct offsets here.
switch(old[0] / 1000) { switch(old[0] / 1000) {
case 0: case 0:
the_str = scenario.spec_strs[old[0] - 160]; the_str = scenario.get_special_string(old[0] - 160);
where = scenario.scen_name; // Best we can do here; the actual location is long forgotten where = scenario.scen_name; // Best we can do here; the actual location is long forgotten
type = NOTE_SCEN; type = NOTE_SCEN;
break; break;
case 1: case 1:
the_str = scenario.outdoors[old[1] % scenario.outdoors.width()][old[1] / scenario.outdoors.width()]->spec_strs[old[0] - 1010]; the_str = scenario.outdoors[old[1] % scenario.outdoors.width()][old[1] / scenario.outdoors.width()]->get_special_string(old[0] - 1010);
where = scenario.outdoors[old[1] % scenario.outdoors.width()][old[1] / scenario.outdoors.width()]->name; where = scenario.outdoors[old[1] % scenario.outdoors.width()][old[1] / scenario.outdoors.width()]->name;
type = NOTE_OUT; type = NOTE_OUT;
break; break;
case 2: case 2:
the_str = scenario.towns[old[1]]->spec_strs[old[0] - 2020]; the_str = scenario.towns[old[1]]->get_special_string(old[0] - 2020);
where = scenario.towns[old[1]]->name; where = scenario.towns[old[1]]->name;
type= NOTE_TOWN; type= NOTE_TOWN;
break; break;