More read/write tests for town and outdoors, including maps/dialogue
Fixes: - For towns, the "has tavern" flag was not saved or loaded - Outdoor roads were not saved or loaded - For outdoor encounters, the "can't flee" and "forced" flags were not loaded, and "forced" was not saved --> These two flags have also been separated in the code
This commit is contained in:
@@ -1498,7 +1498,7 @@ void handle_monster_actions(bool& need_redraw, bool& need_reprint) {
|
||||
create_wand_monst();
|
||||
for(int i = 0; i < 10; i++)
|
||||
if(univ.party.out_c[i].exists)
|
||||
if((adjacent(univ.party.p_loc,univ.party.out_c[i].m_loc) || univ.party.out_c[i].what_monst.cant_flee >= 10)
|
||||
if((adjacent(univ.party.p_loc,univ.party.out_c[i].m_loc) || univ.party.out_c[i].what_monst.forced)
|
||||
&& univ.party.in_boat < 0 && !flying()) {
|
||||
store_wandering_special = univ.party.out_c[i].what_monst;
|
||||
if(handle_wandering_specials(0,0))
|
||||
@@ -1584,7 +1584,7 @@ void initiate_outdoor_combat(short i) {
|
||||
|
||||
// Is combat too easy?
|
||||
if((univ.party.get_level() > ((out_enc_lev_tot(i) * 5) / 3) ) && (out_enc_lev_tot(i) < 200)
|
||||
&& (univ.party.out_c[i].what_monst.cant_flee % 10 != 1)) {
|
||||
&& !univ.party.out_c[i].what_monst.cant_flee) {
|
||||
add_string_to_buf("Combat: Monsters fled!");
|
||||
univ.party.out_c[i].exists = false;
|
||||
return;
|
||||
|
@@ -117,6 +117,7 @@ cOutdoors::cOutdoors(cScenario& scenario) : scenario(&scenario) {
|
||||
for(j = 0; j < 48; j++) {
|
||||
terrain[i][j] = scenario.default_ground;
|
||||
special_spot[i][j] = false;
|
||||
roads[i][j] = false;
|
||||
}
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
@@ -134,7 +135,8 @@ void cOutdoors::cWandering::append(legacy::out_wandering_type old){
|
||||
spec_on_meet = old.spec_on_meet;
|
||||
spec_on_win = old.spec_on_win;
|
||||
spec_on_flee = old.spec_on_flee;
|
||||
cant_flee = old.cant_flee;
|
||||
cant_flee = old.cant_flee % 10 == 1;
|
||||
forced = old.cant_flee >= 10;
|
||||
end_spec1 = old.end_spec1;
|
||||
end_spec2 = old.end_spec2;
|
||||
}
|
||||
@@ -157,7 +159,7 @@ void cOutdoors::cWandering::writeTo(std::ostream& file, std::string prefix) cons
|
||||
file << prefix << "MEET " << spec_on_meet << '\n';
|
||||
file << prefix << "WIN " << spec_on_win << '\n';
|
||||
file << prefix << "FLEE " << spec_on_flee << '\n';
|
||||
file << prefix << "FLAGS " << cant_flee << '\n';
|
||||
file << prefix << "FLAGS " << cant_flee << ' ' << forced << '\n';
|
||||
file << prefix << "SDF " << end_spec1 << ' ' << end_spec2 << '\n';
|
||||
}
|
||||
|
||||
@@ -182,7 +184,7 @@ void cOutdoors::cWandering::readFrom(std::istream& file){
|
||||
else if(cur == "FLEE")
|
||||
sin >> spec_on_flee;
|
||||
else if(cur == "FLAGS")
|
||||
sin >> cant_flee;
|
||||
sin >> cant_flee >> forced;
|
||||
else if(cur == "SDF")
|
||||
sin >> end_spec1 >> end_spec2;
|
||||
}
|
||||
|
@@ -40,8 +40,9 @@ public:
|
||||
public:
|
||||
std::array<mon_num_t,7> monst;
|
||||
std::array<mon_num_t,3> friendly;
|
||||
short spec_on_meet,spec_on_win,spec_on_flee,cant_flee;
|
||||
short spec_on_meet,spec_on_win,spec_on_flee;
|
||||
short end_spec1,end_spec2;
|
||||
bool cant_flee, forced;
|
||||
|
||||
bool isNull();
|
||||
void append(legacy::out_wandering_type old);
|
||||
|
@@ -38,7 +38,7 @@ protected:
|
||||
public:
|
||||
class cWandering { // formerly wandering_type
|
||||
public:
|
||||
mon_num_t monst[4];
|
||||
std::array<mon_num_t,4> monst;
|
||||
|
||||
bool isNull();
|
||||
void append(legacy::wandering_type old);
|
||||
|
@@ -92,6 +92,7 @@ template<> void ticpp::Printer::PushElement(std::string tagName, cMonster::cAtta
|
||||
template<> void ticpp::Printer::PushElement(std::string tagName, cOutdoors::cWandering enc, bool) {
|
||||
OpenElement(tagName);
|
||||
PushAttribute("can-flee", !enc.cant_flee);
|
||||
PushAttribute("force", enc.forced);
|
||||
for(size_t i = 0; i < enc.monst.size(); i++) {
|
||||
PushElement("monster", enc.monst[i]);
|
||||
}
|
||||
@@ -719,6 +720,8 @@ void writeTownToXml(ticpp::Printer&& data, cTown& town) {
|
||||
data.PushElement("defy-scrying", true);
|
||||
if(town.is_hidden)
|
||||
data.PushElement("hidden", true);
|
||||
if(town.has_tavern)
|
||||
data.PushElement("tavern", true);
|
||||
data.CloseElement("flags");
|
||||
for(int i = 0; i < town.wandering.size(); i++) {
|
||||
if(town.wandering[i].isNull()) continue;
|
||||
@@ -849,6 +852,8 @@ map_data buildOutMapData(location which, cScenario& scenario) {
|
||||
terrain.set(x, y, sector.terrain[x][y]);
|
||||
if(sector.special_spot[x][y])
|
||||
terrain.addFeature(x, y, eMapFeature::FIELD, SPECIAL_SPOT);
|
||||
if(sector.roads[x][y])
|
||||
terrain.addFeature(x, y, eMapFeature::FIELD, SPECIAL_ROAD);
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; i < sector.special_locs.size(); i++) {
|
||||
|
@@ -520,8 +520,8 @@ static void put_out_wand_in_dlog(cDialog& me, short which, const cOutdoors::cWan
|
||||
// TODO: Wait a second, if 0 is no monster, does that mean it's impossible to use monster 0? Should 1 be subtracted here?
|
||||
else me[id].setText(scenario.scen_monsters[wand.friendly[i]].m_name);
|
||||
}
|
||||
dynamic_cast<cLed&>(me["no-flee"]).setState(wand.cant_flee % 10 == 1 ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["forced"]).setState(wand.cant_flee >= 10 ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["no-flee"]).setState(wand.cant_flee ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["forced"]).setState(wand.forced ? led_red : led_off);
|
||||
me["onmeet"].setTextToNum(wand.spec_on_meet);
|
||||
me["onwin"].setTextToNum(wand.spec_on_win);
|
||||
me["onflee"].setTextToNum(wand.spec_on_flee);
|
||||
@@ -536,11 +536,8 @@ static void save_out_wand(cDialog& me, short which, cOutdoors::cWandering& wand,
|
||||
wand.end_spec1 = me["endx"].getTextAsNum();
|
||||
wand.end_spec2 = me["endy"].getTextAsNum();
|
||||
|
||||
wand.cant_flee = 0;
|
||||
if(dynamic_cast<cLed&>(me["forced"]).getState() != led_off)
|
||||
wand.cant_flee += 10;
|
||||
if(dynamic_cast<cLed&>(me["no-flee"]).getState() != led_off)
|
||||
wand.cant_flee += 1;
|
||||
wand.forced = dynamic_cast<cLed&>(me["forced"]).getState() != led_off;
|
||||
wand.cant_flee = dynamic_cast<cLed&>(me["no-flee"]).getState() != led_off;
|
||||
|
||||
switch(mode) {
|
||||
case 0:
|
||||
|
@@ -1501,6 +1501,17 @@ void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) {
|
||||
auto& enc_list = type == "encounter" ? out.special_enc : out.wandering;
|
||||
int num_hostile = 0, num_friendly = 0;
|
||||
Iterator<Attribute> attr;
|
||||
for(attr = attr.begin(elem.Get()); attr != attr.end(); attr++) {
|
||||
std::string name, strval;
|
||||
attr->GetName(&name);
|
||||
attr->GetValue(&strval);
|
||||
bool val = strval == "true";
|
||||
if(name == "can-flee")
|
||||
enc_list[count].cant_flee = !val;
|
||||
else if(name == "force")
|
||||
enc_list[count].forced = val;
|
||||
else throw xBadAttr(type, name, attr->Row(), attr->Column(), fname);
|
||||
}
|
||||
Iterator<Element> enc;
|
||||
for(enc = enc.begin(elem.Get()); enc != enc.end(); enc++) {
|
||||
std::string type;
|
||||
@@ -1656,6 +1667,10 @@ void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) {
|
||||
flag->GetText(&val);
|
||||
if(val == "true")
|
||||
town->defy_scrying = true;
|
||||
} else if(type == "tavern") {
|
||||
flag->GetText(&val);
|
||||
if(val == "true")
|
||||
town->has_tavern = true;
|
||||
} else throw xBadNode(type, flag->Row(), flag->Column(), fname);
|
||||
}
|
||||
} else if(type == "wandering") {
|
||||
@@ -1891,6 +1906,8 @@ void loadOutMapData(map_data&& data, location which, cScenario& scen) {
|
||||
case eMapFeature::FIELD:
|
||||
if(feat.second == SPECIAL_SPOT)
|
||||
out.special_spot[x][y] = true;
|
||||
else if(feat.second == SPECIAL_ROAD)
|
||||
out.roads[x][y] = true;
|
||||
else throw xMapParseError(map_out_bad_field, feat.second, y, x, data.file);
|
||||
break;
|
||||
case eMapFeature::SIGN:
|
||||
|
Reference in New Issue
Block a user