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:
@@ -22,6 +22,7 @@
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="can-flee" type="bool" default="true"/>
|
||||
<xs:attribute name="force" type="bool" default="false"/>
|
||||
</xs:complexType>
|
||||
<xs:element name="sector">
|
||||
<xs:complexType>
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
<xs:element name="strong-barriers" minOccurs="0" type="bool"/>
|
||||
<xs:element name="defy-mapping" minOccurs="0" type="bool"/>
|
||||
<xs:element name="defy-scrying" minOccurs="0" type="bool"/>
|
||||
<xs:element name="tavern" minOccurs="0" type="bool"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
0&13,0&14,0&15,0&16
|
||||
0&17,0&18,0&19,0&20
|
||||
0&21,0&22,0&23,0&24
|
||||
0&25
|
||||
5
test/files/maps/fields_out.map
Normal file
5
test/files/maps/fields_out.map
Normal file
@@ -0,0 +1,5 @@
|
||||
1,2,3,4,5
|
||||
6,7,8,9,10
|
||||
11,12,13&9,14,15
|
||||
16,17,18&25,19,20
|
||||
21,22,23&25,24,25
|
||||
@@ -1,5 +1,3 @@
|
||||
<sector boes="2.0.0">
|
||||
<encounter>
|
||||
<monster human='false'/>
|
||||
</encounter>
|
||||
<encounter bad='no'/>
|
||||
</sector>
|
||||
5
test/files/outdoor/encounter_bad_monst_attr.xml
Normal file
5
test/files/outdoor/encounter_bad_monst_attr.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<sector boes="2.0.0">
|
||||
<encounter>
|
||||
<monster human='false'/>
|
||||
</encounter>
|
||||
</sector>
|
||||
26
test/files/outdoor/full.xml
Normal file
26
test/files/outdoor/full.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<sector boes="2.0.0">
|
||||
<name>Test Sector</name>
|
||||
<comment>Hello World!</comment>
|
||||
<sound>birds</sound>
|
||||
<encounter can-flee='false' force='true'>
|
||||
<monster>12</monster>
|
||||
<monster friendly='true'>15</monster>
|
||||
<onmeet>90</onmeet>
|
||||
<onwin>92</onwin>
|
||||
<onflee>84</onflee>
|
||||
<sdf x='202' y='19'/>
|
||||
</encounter>
|
||||
<wandering can-flee='false' force='true'>
|
||||
<monster>12</monster>
|
||||
<monster friendly='true'>15</monster>
|
||||
<onmeet>90</onmeet>
|
||||
<onwin>92</onwin>
|
||||
<onflee>84</onflee>
|
||||
<sdf x='202' y='19'/>
|
||||
</wandering>
|
||||
<sign id='7'>The best sign ever!</sign>
|
||||
<area top='4' left='8' bottom='9' right='12'>
|
||||
<![CDATA[Some random area Amazing!]]>
|
||||
</area>
|
||||
<string id='9'>A random special string</string>
|
||||
</sector>
|
||||
4
test/files/outdoor/sound.xml
Normal file
4
test/files/outdoor/sound.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<sector boes="2.0.0">
|
||||
<name>Test Sector</name>
|
||||
<sound>42</sound>
|
||||
</sector>
|
||||
37
test/files/talk/full.xml
Normal file
37
test/files/talk/full.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<dialogue boes="2.0.0">
|
||||
<personality id='0'>
|
||||
<title>Billy Kumquat</title>
|
||||
<look>You see a small boy juggling fruit.</look>
|
||||
<name>"I'm Billy Kumquat!"</name>
|
||||
<job>"I juggle!"</job>
|
||||
<unknown>"No clue!"</unknown>
|
||||
</personality>
|
||||
<node for='0'>
|
||||
<keyword>jugg</keyword>
|
||||
<type>reg</type>
|
||||
<text>"It's fun!"</text>
|
||||
</node>
|
||||
<node for='0'>
|
||||
<keyword>info</keyword>
|
||||
<type>buy-sdf</type>
|
||||
<param>1</param>
|
||||
<param>2</param>
|
||||
<param>3</param>
|
||||
<text>"There's a treasure hidden in the old tree!"</text>
|
||||
<text>"For a gold piece I'll tell you something interesting!"</text>
|
||||
</node>
|
||||
<node for='0'>
|
||||
<keyword>purc</keyword>
|
||||
<type>shop</type>
|
||||
<param>0</param>
|
||||
<param>4</param>
|
||||
<text>Billy Kumquat's Oddest Fruit</text>
|
||||
</node>
|
||||
<node for='0'>
|
||||
<keyword>kumq</keyword>
|
||||
<type>quest</type>
|
||||
<param>5</param>
|
||||
<text>"I'll reward you if you find me some bigger kumquats!"</text>
|
||||
<text>"Thanks for finding the bigger kumquats!"</text>
|
||||
</node>
|
||||
</dialogue>
|
||||
6
test/files/town/dup_onenter_condition.xml
Normal file
6
test/files/town/dup_onenter_condition.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<town boes="2.0.0">
|
||||
<size>32</size>
|
||||
<name>Hello World</name>
|
||||
<onenter condition='alive'>1</onenter>
|
||||
<onenter condition='alive'>2</onenter>
|
||||
</town>
|
||||
56
test/files/town/full.xml
Normal file
56
test/files/town/full.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<town boes="2.0.0">
|
||||
<size>32</size>
|
||||
<name>Test Town</name>
|
||||
<comment>This is a silly little comment.</comment>
|
||||
<bounds top='4' left='4' right='28' bottom='28'/>
|
||||
<difficulty>1</difficulty>
|
||||
<lighting>lit</lighting>
|
||||
<onenter condition='alive'>12</onenter>
|
||||
<onenter condition='dead'>13</onenter>
|
||||
<exit dir='n' x='4' y='16'/>
|
||||
<onexit dir='n'>52</onexit>
|
||||
<onoffend>42</onoffend>
|
||||
<timer freq='100'>15</timer>
|
||||
<flags>
|
||||
<chop day='18' event='4' kills='50000'/>
|
||||
<hidden>true</hidden>
|
||||
<strong-barriers>true</strong-barriers>
|
||||
<defy-mapping>true</defy-mapping>
|
||||
<defy-scrying>true</defy-scrying>
|
||||
<tavern>true</tavern>
|
||||
</flags>
|
||||
<wandering>
|
||||
<monster>40</monster>
|
||||
<monster>41</monster>
|
||||
<monster>42</monster>
|
||||
<monster>43</monster>
|
||||
</wandering>
|
||||
<sign id='1'>This is a sample sign.</sign>
|
||||
<string id='7'>Here is a town string.</string>
|
||||
<item id='2'>
|
||||
<type>120</type>
|
||||
<mod>2</mod>
|
||||
<charges>17</charges>
|
||||
<always>true</always>
|
||||
<property>true</property>
|
||||
<contained>true</contained>
|
||||
</item>
|
||||
<creature id='12'>
|
||||
<type>140</type>
|
||||
<attitude>hostile-b</attitude>
|
||||
<mobility>1</mobility>
|
||||
<sdf x='12' y='13'/>
|
||||
<encounter>50</encounter>
|
||||
<time type='after-event'>
|
||||
<day>17</day>
|
||||
<event>14</event>
|
||||
</time>
|
||||
<face>142</face>
|
||||
<personality>1</personality>
|
||||
<onkill>80</onkill>
|
||||
<ontalk>81</ontalk>
|
||||
</creature>
|
||||
<area top='14' left='16' bottom='20' right='22'>
|
||||
<![CDATA[This is a sample area description.]]>
|
||||
</area>
|
||||
</town>
|
||||
@@ -98,6 +98,17 @@ TEST_CASE("Loading map data from file") {
|
||||
CHECK(map.getFeatures(2, 5) == test);
|
||||
test[0].second = BARRIER_CAGE;
|
||||
CHECK(map.getFeatures(3, 5) == test);
|
||||
test[0].second = SPECIAL_ROAD;
|
||||
CHECK(map.getFeatures(0, 6) == test);
|
||||
}
|
||||
SECTION("With fields outdoors") {
|
||||
fin.open("files/maps/fields_out.map");
|
||||
map = load_map(fin, false, "fields_out.map");
|
||||
test.emplace_back(make_pair(eMapFeature::FIELD, SPECIAL_SPOT));
|
||||
CHECK(map.getFeatures(2, 2) == test);
|
||||
test[0].second = SPECIAL_ROAD;
|
||||
CHECK(map.getFeatures(2, 3) == test);
|
||||
CHECK(map.getFeatures(2, 4) == test);
|
||||
}
|
||||
SECTION("With town entrance") {
|
||||
fin.open("files/maps/towns_out.map");
|
||||
@@ -215,7 +226,6 @@ TEST_CASE("Interpreting loaded map data") {
|
||||
fin.open("files/maps/fields.map");
|
||||
map = load_map(fin, true, "fields.map");
|
||||
loadTownMapData(move(map), 0, scen);
|
||||
REQUIRE(scen.towns[0]->preset_fields.size() == 24);
|
||||
static const std::map<eFieldType, location> check = {
|
||||
{WALL_FORCE, {0,0}}, {WALL_FIRE, {1,0}}, {FIELD_ANTIMAGIC, {2,0}}, {CLOUD_STINK, {3,0}},
|
||||
{WALL_ICE, {0,1}}, {WALL_BLADES, {1,1}}, {CLOUD_SLEEP, {2,1}}, {OBJECT_BLOCK, {3,1}},
|
||||
@@ -223,7 +233,10 @@ TEST_CASE("Interpreting loaded map data") {
|
||||
{BARRIER_FIRE, {0,3}}, {BARRIER_FORCE, {1,3}}, {FIELD_QUICKFIRE, {2,3}}, {SFX_SMALL_BLOOD, {3,3}},
|
||||
{SFX_MEDIUM_BLOOD, {0,4}}, {SFX_LARGE_BLOOD, {1,4}}, {SFX_SMALL_SLIME, {2,4}}, {SFX_LARGE_SLIME, {3,4}},
|
||||
{SFX_ASH, {0,5}}, {SFX_BONES, {1,5}}, {SFX_RUBBLE, {2,5}}, {BARRIER_CAGE, {3,5}},
|
||||
{SPECIAL_ROAD, {0,6}},
|
||||
};
|
||||
CAPTURE(check.size());
|
||||
REQUIRE(scen.towns[0]->preset_fields.size() == check.size());
|
||||
set<eFieldType> found;
|
||||
for(const auto& fld : scen.towns[0]->preset_fields) {
|
||||
if(found.count(fld.type))
|
||||
@@ -237,6 +250,14 @@ TEST_CASE("Interpreting loaded map data") {
|
||||
if(found.size() != check.size())
|
||||
FAIL("Error: A field is missing!");
|
||||
}
|
||||
SECTION("With fields outdoors") {
|
||||
fin.open("files/maps/fields_out.map");
|
||||
map = load_map(fin, false, "fields_out.map");
|
||||
loadOutMapData(move(map), loc(0,0), scen);
|
||||
CHECK(scen.outdoors[0][0]->special_spot[2][2]);
|
||||
CHECK(scen.outdoors[0][0]->roads[2][3]);
|
||||
CHECK(scen.outdoors[0][0]->roads[2][4]);
|
||||
}
|
||||
SECTION("With town entrance") {
|
||||
fin.open("files/maps/towns_out.map");
|
||||
map = load_map(fin, false, "towns_out.map");
|
||||
|
||||
@@ -106,6 +106,15 @@ TEST_CASE("Saving map data to file") {
|
||||
test[0].second = OBJECT_BLOCK;
|
||||
CHECK(map.getFeatures(3, 3) == test);
|
||||
}
|
||||
SECTION("With fields outdoors") {
|
||||
map.addFeature(0, 0, eMapFeature::FIELD, SPECIAL_SPOT);
|
||||
map.addFeature(1, 1, eMapFeature::FIELD, SPECIAL_ROAD);
|
||||
in_and_out("fields outdoors", map, false);
|
||||
test.emplace_back(make_pair(eMapFeature::FIELD, SPECIAL_SPOT));
|
||||
CHECK(map.getFeatures(0, 0) == test);
|
||||
test[0].second = SPECIAL_ROAD;
|
||||
CHECK(map.getFeatures(1, 1) == test);
|
||||
}
|
||||
SECTION("With town entrance") {
|
||||
map.addFeature(0, 0, eMapFeature::TOWN, 4);
|
||||
in_and_out("town entry loc", map, false);
|
||||
@@ -249,6 +258,13 @@ TEST_CASE("Building map data") {
|
||||
if(found.size() != check.size())
|
||||
FAIL("Error: A field is missing!");
|
||||
}
|
||||
SECTION("With fields outdoors") {
|
||||
scen.outdoors[0][0]->special_spot[0][0] = true;
|
||||
scen.outdoors[0][0]->roads[1][1] = true;
|
||||
in_and_out(scen, false);
|
||||
CHECK(scen.outdoors[0][0]->special_spot[0][0]);
|
||||
CHECK(scen.outdoors[0][0]->roads[1][1]);
|
||||
}
|
||||
SECTION("With town entrance") {
|
||||
scen.outdoors[0][0]->city_locs.emplace_back(5, 6, 7);
|
||||
in_and_out(scen, false);
|
||||
|
||||
@@ -19,6 +19,9 @@ using namespace ticpp;
|
||||
extern Document xmlDocFromStream(istream& stream, string name);
|
||||
extern void readOutdoorsFromXml(Document&& data, cOutdoors& out);
|
||||
|
||||
bool operator==(const cOutdoors::cWandering& lhs, const cOutdoors::cWandering& rhs);
|
||||
ostream& operator<<(ostream& out, const cOutdoors::cWandering& enc);
|
||||
|
||||
TEST_CASE("Loading an outdoor section definition") {
|
||||
ifstream fin;
|
||||
cScenario scen;
|
||||
@@ -66,11 +69,16 @@ TEST_CASE("Loading an outdoor section definition") {
|
||||
doc = xmlDocFromStream(fin, "encounter_too_many_monst.xml");
|
||||
REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadNode);
|
||||
}
|
||||
SECTION("When an encounter monster has an invalid attribute") {
|
||||
SECTION("When an encounter has an invalid attribute") {
|
||||
fin.open("files/outdoor/encounter_bad_attr.xml");
|
||||
doc = xmlDocFromStream(fin, "encounter_bad_attr.xml");
|
||||
REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadAttr);
|
||||
}
|
||||
SECTION("When an encounter monster has an invalid attribute") {
|
||||
fin.open("files/outdoor/encounter_bad_monst_attr.xml");
|
||||
doc = xmlDocFromStream(fin, "encounter_bad_monst_attr.xml");
|
||||
REQUIRE_THROWS_AS(readOutdoorsFromXml(move(doc), sector), xBadAttr);
|
||||
}
|
||||
SECTION("When there are too many encounters") {
|
||||
fin.open("files/outdoor/encounter_too_many.xml");
|
||||
doc = xmlDocFromStream(fin, "encounter_too_many.xml");
|
||||
@@ -82,4 +90,66 @@ TEST_CASE("Loading an outdoor section definition") {
|
||||
REQUIRE_NOTHROW(readOutdoorsFromXml(move(doc), sector));
|
||||
CHECK(sector.out_name == "Test Sector");
|
||||
}
|
||||
SECTION("With an arbitrary ambient sound") {
|
||||
fin.open("files/outdoor/sound.xml");
|
||||
doc = xmlDocFromStream(fin, "sound.xml");
|
||||
REQUIRE_NOTHROW(readOutdoorsFromXml(move(doc), sector));
|
||||
CHECK(sector.ambient_sound == AMBIENT_CUSTOM);
|
||||
CHECK(sector.out_sound == 42);
|
||||
}
|
||||
SECTION("With all possible data") {
|
||||
cOutdoors::cWandering refEncounter;
|
||||
refEncounter.monst[0] = 12;
|
||||
refEncounter.friendly[0] = 15;
|
||||
refEncounter.spec_on_meet = 90;
|
||||
refEncounter.spec_on_win = 92;
|
||||
refEncounter.spec_on_flee = 84;
|
||||
refEncounter.end_spec1 = 202;
|
||||
refEncounter.end_spec2 = 19;
|
||||
refEncounter.cant_flee = true;
|
||||
refEncounter.forced = true;
|
||||
fin.open("files/outdoor/full.xml");
|
||||
doc = xmlDocFromStream(fin, "full.xml");
|
||||
REQUIRE_NOTHROW(readOutdoorsFromXml(move(doc), sector));
|
||||
CHECK(sector.comment == "Hello World!");
|
||||
CHECK(sector.ambient_sound == AMBIENT_BIRD);
|
||||
CHECK(sector.special_enc[0] == refEncounter);
|
||||
CHECK(sector.wandering[0] == refEncounter);
|
||||
REQUIRE(sector.sign_locs.size() >= 8);
|
||||
CHECK(sector.sign_locs[7].text == "The best sign ever!");
|
||||
REQUIRE(sector.info_rect.size() >= 1);
|
||||
CHECK(sector.info_rect[0].descr == "Some random area Amazing!");
|
||||
REQUIRE(sector.spec_strs.size() >= 10);
|
||||
CHECK(sector.spec_strs[9] == "A random special string");
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const cOutdoors::cWandering& lhs, const cOutdoors::cWandering& rhs) {
|
||||
if(lhs.monst != rhs.monst) return false;
|
||||
if(lhs.friendly != rhs.friendly) return false;
|
||||
if(lhs.spec_on_meet != rhs.spec_on_meet) return false;
|
||||
if(lhs.spec_on_win != rhs.spec_on_win) return false;
|
||||
if(lhs.spec_on_flee != rhs.spec_on_flee) return false;
|
||||
if(lhs.cant_flee != rhs.cant_flee) return false;
|
||||
if(lhs.forced != rhs.forced) return false;
|
||||
if(lhs.end_spec1 != rhs.end_spec1) return false;
|
||||
if(lhs.end_spec2 != rhs.end_spec2) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& out, const cOutdoors::cWandering& enc) {
|
||||
out << "Encounter {";
|
||||
out << "hostile = ";
|
||||
for(auto i : enc.monst)
|
||||
out << i << ' ';
|
||||
out << ", friendly = ";
|
||||
for(auto i : enc.friendly)
|
||||
out << i << ' ';
|
||||
out << ", on-meet = " << enc.spec_on_meet << " , ";
|
||||
out << "on-win = " << enc.spec_on_win << " , ";
|
||||
out << "on-flee = " << enc.spec_on_flee << " , ";
|
||||
out << "can-flee = " << !enc.cant_flee << " , ";
|
||||
out << "forced = " << enc.forced << " , ";
|
||||
out << "sdf = (" << enc.end_spec1 << ',' << enc.end_spec2 << ")}";
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ extern Document xmlDocFromStream(istream& stream, string name);
|
||||
extern void readOutdoorsFromXml(Document&& data, cOutdoors& out);
|
||||
extern void writeOutdoorsToXml(ticpp::Printer&& data, cOutdoors& sector);
|
||||
|
||||
extern bool operator==(const cOutdoors::cWandering& lhs, const cOutdoors::cWandering& rhs);
|
||||
extern ostream& operator<<(ostream& out, const cOutdoors::cWandering& enc);
|
||||
|
||||
static void in_and_out(string name, cOutdoors& out, cScenario& scen) {
|
||||
string fpath = "junk/out_";
|
||||
fpath += name;
|
||||
@@ -45,4 +48,47 @@ TEST_CASE("Saving an outdoors sector") {
|
||||
in_and_out("basic", out, scen);
|
||||
CHECK(out.out_name == "The Outdoors Test");
|
||||
}
|
||||
SECTION("With some optional information") {
|
||||
out.comment = "Let's make a comment about comments.";
|
||||
out.ambient_sound = AMBIENT_DRIP;
|
||||
out.sign_locs.emplace_back(0,0,"Guantanamo - 14 mi.");
|
||||
out.info_rect.emplace_back(0,0,1,1,"The heart of the wilderness");
|
||||
out.spec_strs.emplace_back("Something happened!");
|
||||
in_and_out("optional", out, scen);
|
||||
CHECK(out.comment == "Let's make a comment about comments.");
|
||||
CHECK(out.ambient_sound == AMBIENT_DRIP);
|
||||
REQUIRE(out.sign_locs.size() >= 1);
|
||||
CHECK(out.sign_locs[0].text == "Guantanamo - 14 mi.");
|
||||
REQUIRE(out.info_rect.size() >= 1);
|
||||
CHECK(out.info_rect[0].descr == "The heart of the wilderness");
|
||||
REQUIRE(out.spec_strs.size() >= 1);
|
||||
CHECK(out.spec_strs[0] == "Something happened!");
|
||||
}
|
||||
SECTION("With some encounters") {
|
||||
cOutdoors::cWandering spec, wand;
|
||||
|
||||
spec.monst[3] = 42;
|
||||
spec.monst[5] = 12;
|
||||
spec.spec_on_meet = 15;
|
||||
spec.spec_on_win = 12;
|
||||
spec.spec_on_flee = 9;
|
||||
spec.cant_flee = true;
|
||||
spec.forced = true;
|
||||
|
||||
wand.monst[2] = 80;
|
||||
wand.monst[6] = 90;
|
||||
wand.friendly[1] = 12;
|
||||
wand.end_spec1 = 210;
|
||||
wand.end_spec2 = 22;
|
||||
|
||||
REQUIRE(out.special_enc.size() >= 1);
|
||||
out.special_enc[0] = spec;
|
||||
REQUIRE(out.wandering.size() >= 1);
|
||||
out.wandering[0] = wand;
|
||||
in_and_out("encounters", out, scen);
|
||||
REQUIRE(out.special_enc.size() >= 1);
|
||||
CHECK(out.special_enc[0] == spec);
|
||||
REQUIRE(out.wandering.size() >= 1);
|
||||
CHECK(out.wandering[0] == wand);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,4 +121,35 @@ TEST_CASE("Loading a town dialogue definition") {
|
||||
CHECK(talk.people[0].name == "\"I'm Billy Kumquat!\"");
|
||||
CHECK(talk.people[0].job == "\"I juggle!\"");
|
||||
}
|
||||
SECTION("A full personality with several nodes") {
|
||||
fin.open("files/talk/full.xml");
|
||||
doc = xmlDocFromStream(fin, "full.xml");
|
||||
REQUIRE_NOTHROW(readDialogueFromXml(move(doc), talk, 0));
|
||||
CHECK(talk.people[0].dunno == "\"No clue!\"");
|
||||
REQUIRE(talk.talk_nodes.size() == 4);
|
||||
CHECK(talk.talk_nodes[0].personality == 0);
|
||||
CHECK(string(talk.talk_nodes[0].link1, 4) == "jugg");
|
||||
CHECK(talk.talk_nodes[0].type == eTalkNode::REGULAR);
|
||||
CHECK(talk.talk_nodes[0].str1 == "\"It's fun!\"");
|
||||
CHECK(talk.talk_nodes[1].personality == 0);
|
||||
CHECK(string(talk.talk_nodes[1].link1, 4) == "info");
|
||||
CHECK(talk.talk_nodes[1].type == eTalkNode::BUY_SDF);
|
||||
CHECK(talk.talk_nodes[1].extras[0] == 1);
|
||||
CHECK(talk.talk_nodes[1].extras[1] == 2);
|
||||
CHECK(talk.talk_nodes[1].extras[2] == 3);
|
||||
CHECK(talk.talk_nodes[1].str1 == "\"There's a treasure hidden in the old tree!\"");
|
||||
CHECK(talk.talk_nodes[1].str2 == "\"For a gold piece I'll tell you something interesting!\"");
|
||||
CHECK(talk.talk_nodes[2].personality == 0);
|
||||
CHECK(string(talk.talk_nodes[2].link1, 4) == "purc");
|
||||
CHECK(talk.talk_nodes[2].type == eTalkNode::SHOP);
|
||||
CHECK(talk.talk_nodes[2].extras[0] == 0);
|
||||
CHECK(talk.talk_nodes[2].extras[1] == 4);
|
||||
CHECK(talk.talk_nodes[2].str1 == "Billy Kumquat's Oddest Fruit");
|
||||
CHECK(talk.talk_nodes[3].personality == 0);
|
||||
CHECK(string(talk.talk_nodes[3].link1, 4) == "kumq");
|
||||
CHECK(talk.talk_nodes[3].type == eTalkNode::RECEIVE_QUEST);
|
||||
CHECK(talk.talk_nodes[3].extras[0] == 5);
|
||||
CHECK(talk.talk_nodes[3].str1 == "\"I'll reward you if you find me some bigger kumquats!\"");
|
||||
CHECK(talk.talk_nodes[3].str2 == "\"Thanks for finding the bigger kumquats!\"");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,5 +49,48 @@ TEST_CASE("Saving dialogue") {
|
||||
CHECK(talk.people[0].name == "\"My name is John Smith. How do you do?\"");
|
||||
CHECK(talk.people[0].job == "\"Isn't it obvious? I test things!\"");
|
||||
}
|
||||
SECTION("With some nodes") {
|
||||
talk.people[0].dunno = "\"I have no idea.\"";
|
||||
talk.talk_nodes.resize(4);
|
||||
strncpy(talk.talk_nodes[0].link1, "sell", 4);
|
||||
talk.talk_nodes[0].type = eTalkNode::SELL_ITEMS;
|
||||
talk.talk_nodes[0].str1 = "\"Ah, you have unwanted items? Never fear, I can take those off your hands!\"";
|
||||
strncpy(talk.talk_nodes[1].link1, "iden", 4);
|
||||
talk.talk_nodes[1].type = eTalkNode::IDENTIFY;
|
||||
talk.talk_nodes[1].extras[0] = 10;
|
||||
talk.talk_nodes[1].str1 = "\"Yes, I can identify your items for a mere 10 gold per item!\"";
|
||||
strncpy(talk.talk_nodes[2].link1, "test", 4);
|
||||
talk.talk_nodes[2].type = eTalkNode::RECEIVE_QUEST;
|
||||
talk.talk_nodes[2].extras[0] = 4;
|
||||
talk.talk_nodes[2].str1 = "\"Yes! In fact, you can help me to test things!\"";
|
||||
talk.talk_nodes[2].str2 = "\"Thanks for the help!\"";
|
||||
strncpy(talk.talk_nodes[3].link1, "boat", 4);
|
||||
talk.talk_nodes[3].type = eTalkNode::BUY_SHIP;
|
||||
talk.talk_nodes[3].extras[0] = 0;
|
||||
talk.talk_nodes[3].extras[1] = 5;
|
||||
talk.talk_nodes[3].extras[2] = 1;
|
||||
talk.talk_nodes[3].str1 = "\"You need a boat? Then you are in luck! I just happen to have a boat!\"";
|
||||
in_and_out("full", talk);
|
||||
CHECK(talk.people[0].dunno == "\"I have no idea.\"");
|
||||
REQUIRE(talk.talk_nodes.size() == 4);
|
||||
CHECK(string(talk.talk_nodes[0].link1, 4) == "sell");
|
||||
CHECK(talk.talk_nodes[0].type == eTalkNode::SELL_ITEMS);
|
||||
CHECK(talk.talk_nodes[0].str1 == "\"Ah, you have unwanted items? Never fear, I can take those off your hands!\"");
|
||||
CHECK(string(talk.talk_nodes[1].link1, 4) == "iden");
|
||||
CHECK(talk.talk_nodes[1].type == eTalkNode::IDENTIFY);
|
||||
CHECK(talk.talk_nodes[1].extras[0] == 10);
|
||||
CHECK(talk.talk_nodes[1].str1 == "\"Yes, I can identify your items for a mere 10 gold per item!\"");
|
||||
CHECK(string(talk.talk_nodes[2].link1, 4) == "test");
|
||||
CHECK(talk.talk_nodes[2].type == eTalkNode::RECEIVE_QUEST);
|
||||
CHECK(talk.talk_nodes[2].extras[0] == 4);
|
||||
CHECK(talk.talk_nodes[2].str1 == "\"Yes! In fact, you can help me to test things!\"");
|
||||
CHECK(talk.talk_nodes[2].str2 == "\"Thanks for the help!\"");
|
||||
CHECK(string(talk.talk_nodes[3].link1, 4) == "boat");
|
||||
CHECK(talk.talk_nodes[3].type == eTalkNode::BUY_SHIP);
|
||||
CHECK(talk.talk_nodes[3].extras[0] == 0);
|
||||
CHECK(talk.talk_nodes[3].extras[1] == 5);
|
||||
CHECK(talk.talk_nodes[3].extras[2] == 1);
|
||||
CHECK(talk.talk_nodes[3].str1 == "\"You need a boat? Then you are in luck! I just happen to have a boat!\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ TEST_CASE("Loading a town definition") {
|
||||
doc = xmlDocFromStream(fin, "size_not_first.xml");
|
||||
REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadNode);
|
||||
}
|
||||
SECTION("When the size is invalid") {
|
||||
fin.open("files/town/bad_size.xml");
|
||||
doc = xmlDocFromStream(fin, "bad_size.xml");
|
||||
REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadVal);
|
||||
}
|
||||
SECTION("When there is an invalid toplevel node") {
|
||||
fin.open("files/town/bad_toplevel.xml");
|
||||
doc = xmlDocFromStream(fin, "bad_toplevel.xml");
|
||||
@@ -66,6 +71,11 @@ TEST_CASE("Loading a town definition") {
|
||||
doc = xmlDocFromStream(fin, "bad_onenter_condition.xml");
|
||||
REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadVal);
|
||||
}
|
||||
SECTION("When the onenter condition is duplicated") {
|
||||
fin.open("files/town/dup_onenter_condition.xml");
|
||||
doc = xmlDocFromStream(fin, "dup_onenter_condition.xml");
|
||||
REQUIRE_THROWS_AS(readTownFromXml(move(doc), town, scen), xBadVal);
|
||||
}
|
||||
SECTION("When the onexit direction is invalid") {
|
||||
fin.open("files/town/bad_onexit_dir.xml");
|
||||
doc = xmlDocFromStream(fin, "bad_onexit_dir.xml");
|
||||
@@ -126,6 +136,61 @@ TEST_CASE("Loading a town definition") {
|
||||
CHECK(town->difficulty == 1);
|
||||
CHECK(town->lighting_type == LIGHT_NORMAL);
|
||||
}
|
||||
SECTION("With all possible data") {
|
||||
fin.open("files/town/full.xml");
|
||||
doc = xmlDocFromStream(fin, "full.xml");
|
||||
REQUIRE_NOTHROW(readTownFromXml(move(doc), town, scen));
|
||||
CHECK(town->comment[0] == "This is a silly little comment.");
|
||||
CHECK(town->spec_on_entry == 12);
|
||||
CHECK(town->spec_on_entry_if_dead == 13);
|
||||
CHECK(town->exit_locs[0] == loc(4,16));
|
||||
CHECK(town->exit_specs[0] == 52);
|
||||
CHECK(town->spec_on_hostile == 42);
|
||||
CHECK(town->town_chop_time == 18);
|
||||
CHECK(town->town_chop_key == 4);
|
||||
CHECK(town->max_num_monst == 50000);
|
||||
CHECK(town->is_hidden);
|
||||
CHECK(town->strong_barriers);
|
||||
CHECK(town->has_tavern);
|
||||
CHECK(town->defy_mapping);
|
||||
CHECK(town->defy_scrying);
|
||||
REQUIRE(town->timers.size() >= 1);
|
||||
CHECK(town->timers[0].node_type == 2);
|
||||
CHECK(town->timers[0].node == 15);
|
||||
CHECK(town->timers[0].time == 100);
|
||||
REQUIRE(town->wandering.size() >= 1);
|
||||
CHECK(town->wandering[0].monst[0] == 40);
|
||||
CHECK(town->wandering[0].monst[1] == 41);
|
||||
CHECK(town->wandering[0].monst[2] == 42);
|
||||
CHECK(town->wandering[0].monst[3] == 43);
|
||||
REQUIRE(town->sign_locs.size() >= 2);
|
||||
CHECK(town->sign_locs[1].text == "This is a sample sign.");
|
||||
REQUIRE(town->spec_strs.size() >= 8);
|
||||
CHECK(town->spec_strs[7] == "Here is a town string.");
|
||||
REQUIRE(town->preset_items.size() >= 3);
|
||||
CHECK(town->preset_items[2].code == 120);
|
||||
CHECK(town->preset_items[2].ability == 2);
|
||||
CHECK(town->preset_items[2].charges == 17);
|
||||
CHECK(town->preset_items[2].always_there);
|
||||
CHECK(town->preset_items[2].property);
|
||||
CHECK(town->preset_items[2].contained);
|
||||
REQUIRE(town->creatures.size() >= 13);
|
||||
CHECK(town->creatures[12].number == 140);
|
||||
CHECK(town->creatures[12].start_attitude == eAttitude::HOSTILE_B);
|
||||
CHECK(town->creatures[12].mobility == 1);
|
||||
CHECK(town->creatures[12].spec1 == 12);
|
||||
CHECK(town->creatures[12].spec2 == 13);
|
||||
CHECK(town->creatures[12].spec_enc_code == 50);
|
||||
CHECK(town->creatures[12].time_flag == eMonstTime::APPEAR_WHEN_EVENT);
|
||||
CHECK(town->creatures[12].monster_time == 17);
|
||||
CHECK(town->creatures[12].time_code == 14);
|
||||
CHECK(town->creatures[12].facial_pic == 142);
|
||||
CHECK(town->creatures[12].personality == 1);
|
||||
CHECK(town->creatures[12].special_on_kill == 80);
|
||||
CHECK(town->creatures[12].special_on_talk == 81);
|
||||
REQUIRE(town->room_rect.size() >= 1);
|
||||
CHECK(town->room_rect[0].descr == "This is a sample area description.");
|
||||
}
|
||||
|
||||
delete town;
|
||||
}
|
||||
|
||||
@@ -50,5 +50,107 @@ TEST_CASE("Saving a town") {
|
||||
CHECK(town->in_town_rect == rect(2,3,30,29));
|
||||
CHECK(town->difficulty == 1);
|
||||
CHECK(town->lighting_type == LIGHT_NONE);
|
||||
CHECK_FALSE(town->has_tavern);
|
||||
CHECK_FALSE(town->defy_scrying);
|
||||
}
|
||||
SECTION("With lots of optional information") {
|
||||
town->comment[2] = "Try a comment!";
|
||||
town->spec_on_entry = 42;
|
||||
town->spec_on_entry_if_dead = 19;
|
||||
town->spec_on_hostile = 47;
|
||||
town->exit_specs[0] = 16;
|
||||
town->exit_locs[0] = {24,2};
|
||||
town->town_chop_time = 25;
|
||||
town->town_chop_key = 6;
|
||||
town->max_num_monst = 100000;
|
||||
town->is_hidden = town->has_tavern = true;
|
||||
town->defy_scrying = town->defy_mapping = true;
|
||||
town->strong_barriers = true;
|
||||
REQUIRE(town->timers.size() >= 1);
|
||||
town->timers[0].node = 12;
|
||||
town->timers[0].time = 2500;
|
||||
REQUIRE(town->wandering.size() >= 1);
|
||||
town->wandering[0].monst = {7,8,9,10};
|
||||
town->sign_locs.emplace_back(0,0,"Sign #4279816");
|
||||
town->spec_strs.emplace_back("Something! With extra spaces!");
|
||||
town->room_rect.emplace_back(0,0,1,1,"Unknown Area . . .");
|
||||
in_and_out("optional", town, scen);
|
||||
CHECK(town->comment[2] == "Try a comment!");
|
||||
CHECK(town->spec_on_entry == 42);
|
||||
CHECK(town->spec_on_entry_if_dead == 19);
|
||||
CHECK(town->spec_on_hostile == 47);
|
||||
CHECK(town->exit_specs[0] == 16);
|
||||
CHECK(town->exit_locs[0] == loc(24,2));
|
||||
CHECK(town->town_chop_time == 25);
|
||||
CHECK(town->town_chop_key == 6);
|
||||
CHECK(town->max_num_monst == 100000);
|
||||
CHECK(town->is_hidden);
|
||||
CHECK(town->strong_barriers);
|
||||
CHECK(town->has_tavern);
|
||||
CHECK(town->defy_mapping);
|
||||
CHECK(town->defy_scrying);
|
||||
REQUIRE(town->timers.size() >= 1);
|
||||
CHECK(town->timers[0].node_type == 2);
|
||||
CHECK(town->timers[0].node == 12);
|
||||
CHECK(town->timers[0].time == 2500);
|
||||
REQUIRE(town->wandering.size() >= 1);
|
||||
CHECK(town->wandering[0].monst[0] == 7);
|
||||
CHECK(town->wandering[0].monst[1] == 8);
|
||||
CHECK(town->wandering[0].monst[2] == 9);
|
||||
CHECK(town->wandering[0].monst[3] == 10);
|
||||
REQUIRE(town->sign_locs.size() >= 1);
|
||||
CHECK(town->sign_locs[0].text == "Sign #4279816");
|
||||
REQUIRE(town->spec_strs.size() >= 1);
|
||||
CHECK(town->spec_strs[0] == "Something! With extra spaces!");
|
||||
REQUIRE(town->room_rect.size() >= 1);
|
||||
CHECK(town->room_rect[0].descr == "Unknown Area . . .");
|
||||
}
|
||||
SECTION("With a preset item") {
|
||||
town->preset_items.emplace_back();
|
||||
town->preset_items.back().code = 52;
|
||||
town->preset_items.back().ability = 9;
|
||||
town->preset_items.back().charges = 102;
|
||||
town->preset_items.back().always_there = true;
|
||||
town->preset_items.back().property = true;
|
||||
town->preset_items.back().contained = true;
|
||||
in_and_out("item", town, scen);
|
||||
REQUIRE(town->preset_items.size() >= 1);
|
||||
CHECK(town->preset_items[0].code == 52);
|
||||
CHECK(town->preset_items[0].ability == 9);
|
||||
CHECK(town->preset_items[0].charges == 102);
|
||||
CHECK(town->preset_items[0].always_there);
|
||||
CHECK(town->preset_items[0].property);
|
||||
CHECK(town->preset_items[0].contained);
|
||||
}
|
||||
SECTION("With a townsperson") {
|
||||
town->creatures.emplace_back();
|
||||
town->creatures.back().number = 60;
|
||||
town->creatures.back().start_attitude = eAttitude::DOCILE;
|
||||
town->creatures.back().mobility = 1;
|
||||
town->creatures.back().spec1 = 17;
|
||||
town->creatures.back().spec2 = 4;
|
||||
town->creatures.back().spec_enc_code = 3;
|
||||
town->creatures.back().time_flag = eMonstTime::DISAPPEAR_WHEN_EVENT;
|
||||
town->creatures.back().time_code = 5;
|
||||
town->creatures.back().monster_time = 16;
|
||||
town->creatures.back().facial_pic = 56;
|
||||
town->creatures.back().personality = 8;
|
||||
town->creatures.back().special_on_kill = 9;
|
||||
town->creatures.back().special_on_talk = 12;
|
||||
in_and_out("townsperson", town, scen);
|
||||
REQUIRE(town->creatures.size() >= 1);
|
||||
CHECK(town->creatures[0].number == 60);
|
||||
CHECK(town->creatures[0].start_attitude == eAttitude::DOCILE);
|
||||
CHECK(town->creatures[0].mobility == 1);
|
||||
CHECK(town->creatures[0].spec1 == 17);
|
||||
CHECK(town->creatures[0].spec2 == 4);
|
||||
CHECK(town->creatures[0].spec_enc_code == 3);
|
||||
CHECK(town->creatures[0].time_flag == eMonstTime::DISAPPEAR_WHEN_EVENT);
|
||||
CHECK(town->creatures[0].monster_time == 16);
|
||||
CHECK(town->creatures[0].time_code == 5);
|
||||
CHECK(town->creatures[0].facial_pic == 56);
|
||||
CHECK(town->creatures[0].personality == 8);
|
||||
CHECK(town->creatures[0].special_on_kill == 9);
|
||||
CHECK(town->creatures[0].special_on_talk == 12);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user