Implement loading of scenarios

- This also tweaks the scenario schemas for consistency between schemas and code, adds some unique key restraints, and makes some attributes required.
This commit is contained in:
2015-02-11 13:25:20 -05:00
parent 1e0b093b78
commit 1894b31e20
24 changed files with 1777 additions and 229 deletions

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<items>
<items boes='2.0.0'>
<item id='0'>
<variety>shield</variety>
<level>3</level>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<monsters>
<monsters boes='2.0.0'>
<monster id="7">
<!-- The monster's name -->
<name>Cave Cow</name>

View File

@@ -10,14 +10,10 @@
<monster friendly="true">27</monster>
</wandering>
<signs>
<string id="0">This is a sample sign!</string>
</signs>
<sign id="0">This is a sample sign!</sign>
<!-- outdoor description rects -->
<descriptions>
<area top="32" left="32" bottom="36" right="36">This is an area description!</area>
</descriptions>
<area top="32" left="32" bottom="36" right="36">This is an area description!</area>
<strings/>
<string id="0">This is a special encounter string!</string>
</sector>

View File

@@ -128,7 +128,10 @@
<!-- Where in that outdoor section you start -->
<sector-start x="20" y="20"/>
<!-- Definitions of special items, if any -->
<specials/>
<special-item start-with='true'>
<name>My Special Item</name>
<description>It's so useful!</description>
</special-item>
<!-- Define quests here -->
<quest start-with='false'>
<!-- Quests can have a deadline, and an event that waives the deadline -->

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<terrains>
<terrains boes='2.0.0'>
<terrain id='2'>
<name>Grass</name>
<!-- The picture, and the automap picture -->
@@ -19,12 +19,12 @@
<type>0</type>
<!-- Can include flags here, if necessary -->
</special>
<!-- Base terrain type -->
<ground>2</ground>
<!-- Editor information -->
<editor>
<!-- Shortcut key -->
<shortcut>g</shortcut>
<!-- Base terrain type -->
<ground>2</ground>
</editor>
</terrain>
</terrains>

View File

@@ -2,6 +2,7 @@
<dialogue boes="1.0">
<!-- Basic personalities -->
<personality id="0">
<title>Bill</title>
<look>You see a small, strange creature.</look>
<name>"I'm Bill!"</name>
<job>"Job? What's that?"</job>

View File

@@ -24,7 +24,7 @@
<!-- Wandering monsters; optional -->
<wandering>
<monster group="0">21</monster>
<monster>21</monster>
</wandering>
<sign id="0">This is a sample sign!</sign>
@@ -45,6 +45,6 @@
</creature>
<!-- town description rects -->
<description top="32" left="32" bottom="36" right="36">This is an area description!</description>
<area top="32" left="32" bottom="36" right="36">This is an area description!</area>
</town>

View File

@@ -52,10 +52,7 @@
<xs:element name="text" minOccurs="1" maxOccurs="2" type="xs:string"/>
</xs:sequence>
<xs:attribute name="for" type="xs:integer" use="required"/>
</xs:complexType><!--
short personality,type;
char link1[4],link2[4];
short extras[4]; -->
</xs:complexType>
</xs:element>
<xs:element name="dialogue">
<xs:complexType>
@@ -63,7 +60,7 @@
<xs:element ref="personality" maxOccurs="10"/>
<xs:element ref="node" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="boes" type="xs:string"/>
<xs:attribute name="boes" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -120,6 +120,11 @@
<xs:sequence>
<xs:element ref="item" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="boes" type="xs:string" use="required"/>
</xs:complexType>
<xs:unique name='itemIds'>
<xs:selector xpath='item'/>
<xs:field xpath='@id'/>
</xs:unique>
</xs:element>
</xs:schema>

View File

@@ -192,6 +192,7 @@
<xs:sequence>
<xs:element ref="monster" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="boes" type="xs:string" use="required"/>
</xs:complexType>
<xs:unique name='monsterIds'>
<xs:selector xpath='monster'/>

View File

@@ -57,53 +57,43 @@
</xs:element>
<xs:element name="encounter" type="encounter" minOccurs="0" maxOccurs="4"/>
<xs:element name="wandering" type="encounter" minOccurs="0" maxOccurs="4"/>
<xs:element name="signs">
<xs:element name="sign" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="string" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="descriptions">
<xs:element name="area" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="area" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attributeGroup ref="rect"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attributeGroup ref="rect"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="strings">
<xs:element name="string" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="string" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="boes" type="xs:string"/>
<xs:attribute name="boes" type="xs:string" use="required"/>
</xs:complexType>
<xs:unique name='stringIds'>
<xs:selector xpath='string'/>
<xs:field xpath='@id'/>
</xs:unique>
<xs:unique name='signIds'>
<xs:selector xpath='sign'/>
<xs:field xpath='@id'/>
</xs:unique>
</xs:element>
</xs:schema>

View File

@@ -205,26 +205,20 @@
</xs:element>
<xs:element name="town-flag" minOccurs="0" maxOccurs="10">
<xs:complexType>
<xs:attribute name="town" type="xs:integer"/>
<xs:attribute name="add-x" type="xs:integer"/>
<xs:attribute name="add-y" type="xs:integer"/>
<xs:attribute name="town" type="xs:integer" use="required"/>
<xs:attribute name="add-x" type="xs:integer" use="required"/>
<xs:attribute name="add-y" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="specials">
<xs:element name="special-item" minOccurs="0" maxOccurs="50">
<xs:complexType>
<xs:sequence>
<xs:element name="item" minOccurs="0" maxOccurs="50">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="description" type="xs:string"/>
</xs:sequence>
<xs:attribute name="special" type="xs:integer"/>
<xs:attribute name="start-with" type="bool"/>
<xs:attribute name="useable" type="bool"/>
</xs:complexType>
</xs:element>
<xs:element name="name" type="xs:string"/>
<xs:element name="description" type="xs:string"/>
</xs:sequence>
<xs:attribute name="special" type="xs:integer"/>
<xs:attribute name="start-with" type="bool"/>
<xs:attribute name="useable" type="bool"/>
</xs:complexType>
</xs:element>
<xs:element name="quest" minOccurs='0' maxOccurs="unbounded">
@@ -288,13 +282,29 @@
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="time" type="xs:integer"/>
<xs:attribute name="freq" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="string" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="journal" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="journal" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
@@ -315,7 +325,7 @@
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="index" type="xs:integer"/>
<xs:attribute name="index" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
@@ -332,7 +342,7 @@
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="chance" type="xs:integer"/>
<xs:attribute name="chance" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
@@ -359,7 +369,7 @@
<xs:element ref="game"/>
<xs:element ref="editor"/>
</xs:sequence>
<xs:attribute name="boes" type="xs:string"/>
<xs:attribute name="boes" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -131,8 +131,6 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ground" minOccurs="0" type="xs:integer"/>
<xs:element name="trim-for" minOccurs="0" type="xs:integer"/>
</xs:all>
</xs:complexType>
</xs:element>
@@ -159,6 +157,8 @@
<xs:element name="step-sound" minOccurs="0" type="stepSound"/>
<xs:element name="trim" type="terTrim"/>
<xs:element name="arena" type="xs:integer"/>
<xs:element name="ground" minOccurs="0" type="xs:integer"/>
<xs:element name="trim-for" minOccurs="0" type="xs:integer"/>
<xs:element ref="editor" minOccurs="0"/>
</xs:all>
<xs:attribute name="id" type="xs:integer" use="required"/>
@@ -169,7 +169,11 @@
<xs:sequence>
<xs:element ref="terrain" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="boes" type="xs:string"/>
<xs:attribute name="boes" type="xs:string" use="required"/>
</xs:complexType>
<xs:unique name='terrainIds'>
<xs:selector xpath='terrain'/>
<xs:field xpath='@id'/>
</xs:unique>
</xs:element>
</xs:schema>

View File

@@ -116,33 +116,25 @@
<xs:element name="wandering" minOccurs="0" maxOccurs="4">
<xs:complexType>
<xs:sequence>
<xs:element name="monster" maxOccurs="4">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="group" type="xs:integer"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="monster" type="xs:integer" maxOccurs="4"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:choice maxOccurs="unbounded">
<xs:element name="sign">
<xs:element name="sign" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer"/>
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="string">
<xs:element name="string" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:integer"/>
<xs:attribute name="id" type="xs:integer" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
@@ -177,7 +169,7 @@
<xs:sequence>
<xs:element name="param" maxOccurs="2" type="xs:integer"/>
</xs:sequence>
<xs:attribute name="type">
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="always"/>
@@ -197,11 +189,12 @@
<xs:element name="face" type="xs:integer" minOccurs="0"/>
<xs:element name="personality" type="xs:integer" minOccurs="0"/>
<xs:element name="onkill" type="xs:integer" minOccurs="0"/>
<xs:element name="ontalk" type="xs:integer" minOccurs="0"/>
</xs:all>
<xs:attribute name="id" type="xs:integer"/>
</xs:complexType>
</xs:element>
<xs:element name="description">
<xs:element name="area">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
@@ -212,7 +205,7 @@
</xs:element>
</xs:choice>
</xs:sequence>
<xs:attribute name="boes" type="xs:string"/>
<xs:attribute name="boes" type="xs:string" use="required"/>
<xs:attribute name="type">
<xs:simpleType>
<xs:restriction base="xs:string">
@@ -222,5 +215,13 @@
</xs:simpleType>
</xs:attribute>
</xs:complexType>
<xs:unique name='stringIds'>
<xs:selector xpath='string'/>
<xs:field xpath='@id'/>
</xs:unique>
<xs:unique name='signIds'>
<xs:selector xpath='sign'/>
<xs:field xpath='@id'/>
</xs:unique>
</xs:element>
</xs:schema>

View File

@@ -173,26 +173,6 @@
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>.exr</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>boeresources</string>
<key>CFBundleTypeName</key>
<string>Resource File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.spidweb.bladesofexile.resources</string>
</array>
<key>LSTypeIsPackage</key>
<true/>
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>

View File

@@ -245,6 +245,7 @@
91C749B81A2D6670008E0E10 /* strings in Copy Strings */ = {isa = PBXBuildFile; fileRef = 91C749B71A2D6432008E0E10 /* strings */; };
91C749BA1A2D670D008E0E10 /* dialogs in Copy Dialog Definitions */ = {isa = PBXBuildFile; fileRef = 91C749B91A2D66F7008E0E10 /* dialogs */; };
91D634560F8FD77800674AB3 /* BoE.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2B8F435C0C0973680012E4A8 /* BoE.icns */; };
91DBE9A81A873D3900ED006C /* specials_parse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 915325181A2E37EE000A9A1C /* specials_parse.cpp */; };
91E30F2B1A74819C0057C54A /* fileio_party.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E30F2A1A74819B0057C54A /* fileio_party.cpp */; };
91E30F2C1A74819D0057C54A /* fileio_party.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E30F2A1A74819B0057C54A /* fileio_party.cpp */; };
91E30F2E1A7481C40057C54A /* fileio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E30F2D1A7481C20057C54A /* fileio.cpp */; };
@@ -1570,6 +1571,7 @@
91E30F2F1A7481C50057C54A /* fileio.cpp in Sources */,
91E30F311A748ABA0057C54A /* fileio_scen.cpp in Sources */,
9117A4111A7EC06700CD6EB4 /* living.cpp in Sources */,
91DBE9A81A873D3900ED006C /* specials_parse.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -1519,7 +1519,7 @@ std::istream& operator >> (std::istream& in, eItemUse& e){
if(i > 0 && i < 4)
e = (eItemUse) i;
} catch(boost::bad_lexical_cast) {
if(key == "help-on")
if(key == "help-one")
e = eItemUse::HELP_ONE;
else if(key == "harm-one")
e = eItemUse::HARM_ONE;

View File

@@ -179,17 +179,15 @@ static void writeScenarioToXml(ticpp::Printer&& data) {
data.CloseElement("town-flag");
}
}
data.OpenElement("specials");
for(int i = 0; i < scenario.special_items.size(); i++) {
data.OpenElement("item");
data.OpenElement("special-item");
data.PushAttribute("start-with", boolstr(scenario.special_items[i].flags / 10));
data.PushAttribute("useable", boolstr(scenario.special_items[i].flags % 10));
data.PushAttribute("special", scenario.special_items[i].special);
data.PushElement("name", scenario.special_items[i].name);
data.PushElement("description", scenario.special_items[i].descr);
data.CloseElement("item");
data.CloseElement("special-item");
}
data.CloseElement("specials");
for(size_t i = 0; i < scenario.quests.size(); i++) {
cQuest& quest = scenario.quests[i];
data.OpenElement("quest");
@@ -285,17 +283,27 @@ static void writeScenarioToXml(ticpp::Printer&& data) {
data.CloseElement("shop");
}
for(int i = 0; i < scenario.scenario_timers.size(); i++) {
if(scenario.scenario_timers[i].time > 0) {
if(scenario.scenario_timers[i].time >= 0) {
data.OpenElement("timer");
data.PushAttribute("time", scenario.scenario_timers[i].time);
data.PushAttribute("freq", scenario.scenario_timers[i].time);
data.PushText(scenario.scenario_timers[i].node);
data.CloseElement("timer");
}
}
for(size_t i = 0; i < scenario.spec_strs.size(); i++)
data.PushElement("string", scenario.spec_strs[i]);
for(size_t i = 0; i < scenario.journal_strs.size(); i++)
data.PushElement("journal", scenario.journal_strs[i]);
for(size_t i = 0; i < scenario.spec_strs.size(); i++) {
if(scenario.spec_strs[i].empty()) continue;
data.OpenElement("string");
data.PushAttribute("id", i);
data.PushText(scenario.spec_strs[i]);
data.CloseElement("string");
}
for(size_t i = 0; i < scenario.journal_strs.size(); i++) {
if(scenario.journal_strs[i].empty()) continue;
data.OpenElement("journal");
data.PushAttribute("id", i);
data.PushText(scenario.journal_strs[i]);
data.CloseElement("journal");
}
data.CloseElement("game");
data.OpenElement("editor");
data.PushElement("default-ground", scenario.default_ground);
@@ -335,6 +343,7 @@ static void writeScenarioToXml(ticpp::Printer&& data) {
static void writeTerrainToXml(ticpp::Printer&& data) {
data.OpenElement("terrains");
data.PushAttribute("boes", scenario.format_ed_version());
for(size_t i = 0; i < scenario.ter_types.size(); i++) {
data.OpenElement("terrain");
data.PushAttribute("id", i);
@@ -350,6 +359,8 @@ static void writeTerrainToXml(ticpp::Printer&& data) {
data.PushElement("light", ter.light_radius);
data.PushElement("step-sound", ter.step_sound);
data.PushElement("trim", ter.trim_type);
data.PushElement("ground", ter.ground_type);
data.PushElement("trim-for", ter.trim_ter);
data.PushElement("arena", ter.combat_arena);
data.OpenElement("special");
@@ -362,8 +373,6 @@ static void writeTerrainToXml(ticpp::Printer&& data) {
data.OpenElement("editor");
if(ter.shortcut_key > 0)
data.PushElement("shortcut", ter.shortcut_key);
data.PushElement("ground", ter.ground_type);
data.PushElement("trim-for", ter.trim_ter);
if(ter.obj_num > 0) {
data.OpenElement("object");
data.PushElement("num", ter.obj_num);
@@ -379,6 +388,7 @@ static void writeTerrainToXml(ticpp::Printer&& data) {
static void writeItemsToXml(ticpp::Printer&& data) {
data.OpenElement("items");
data.PushAttribute("boes", scenario.format_ed_version());
for(size_t i = 0; i < scenario.scen_items.size(); i++) {
data.OpenElement("item");
data.PushAttribute("id", i);
@@ -430,6 +440,7 @@ static void writeItemsToXml(ticpp::Printer&& data) {
static void writeMonstersToXml(ticpp::Printer&& data) {
std::ostringstream str;
data.OpenElement("monsters");
data.PushAttribute("boes", scenario.format_ed_version());
for(size_t i = 1; i < scenario.scen_monsters.size(); i++) {
data.OpenElement("monster");
data.PushAttribute("id", i);
@@ -587,20 +598,24 @@ static void writeOutdoorsToXml(ticpp::Printer&& data, cOutdoors& sector) {
data.PushElement("encounter", enc);
for(auto& enc : sector.wandering)
data.PushElement("wandering", enc);
data.OpenElement("signs");
for(auto& sign : sector.sign_locs)
data.PushElement("string", sign.text);
data.CloseElement("signs");
data.OpenElement("descriptions");
for(size_t i = 0; i < sector.sign_locs.size(); i++) {
if(sector.sign_locs[i].text.empty()) continue;
data.OpenElement("sign");
data.PushAttribute("id", i);
data.PushText(sector.sign_locs[i].text);
data.CloseElement("sign");
}
for(auto& area : sector.info_rect) {
if(!area.descr.empty() && area.top < area.bottom && area.left < area.right)
data.PushElement("area", area);
}
data.CloseElement("descriptions");
data.OpenElement("strings");
for(auto& str : sector.spec_strs)
data.PushElement("string", str);
data.CloseElement("strings");
for(size_t i = 0; i < sector.spec_strs.size(); i++) {
if(sector.spec_strs[i].empty()) continue;
data.OpenElement("string");
data.PushAttribute("id", i);
data.PushText(sector.spec_strs[i]);
data.CloseElement("string");
}
data.CloseElement("sector");
}
@@ -649,6 +664,7 @@ static void writeTownToXml(ticpp::Printer&& data, cTown& town) {
if(town.spec_on_hostile >= 0)
data.PushElement("onoffend", town.spec_on_hostile);
for(size_t i = 0; i < town.timers.size(); i++) {
if(town.timers[i].time < 0) continue;
data.OpenElement("timer");
data.PushAttribute("freq", town.timers[i].time);
data.PushText(town.timers[i].node);
@@ -686,6 +702,8 @@ static void writeTownToXml(ticpp::Printer&& data, cTown& town) {
data.PushElement("type", town.preset_items[i].code);
if(town.preset_items[i].charges > 0)
data.PushElement("charges", town.preset_items[i].charges);
if(town.preset_items[i].ability >= 0)
data.PushElement("mod", town.preset_items[i].ability);
if(town.preset_items[i].always_there)
data.PushElement("always", true);
if(town.preset_items[i].property)
@@ -709,6 +727,8 @@ static void writeTownToXml(ticpp::Printer&& data, cTown& town) {
data.PushElement("encounter", preset.spec_enc_code);
if(preset.special_on_kill >= 0)
data.PushElement("onkill", preset.special_on_kill);
if(preset.special_on_talk >= 0)
data.PushElement("ontalk", preset.special_on_talk);
if(preset.time_flag != eMonstTime::ALWAYS) {
data.OpenElement("time");
data.PushAttribute("type", preset.time_flag);
@@ -720,7 +740,7 @@ static void writeTownToXml(ticpp::Printer&& data, cTown& town) {
}
for(auto& area : town.room_rect) {
if(!area.descr.empty() && area.top < area.bottom && area.left < area.right)
data.PushElement("description", area);
data.PushElement("area", area);
}
for(size_t i = 0; i < town.sign_locs.size(); i++) {
if(town.sign_locs[i].text.empty()) continue;
@@ -739,13 +759,13 @@ static void writeTownToXml(ticpp::Printer&& data, cTown& town) {
data.CloseElement("town");
}
static void writeDialogueToXml(ticpp::Printer&& data, cSpeech& talk) {
static void writeDialogueToXml(ticpp::Printer&& data, cSpeech& talk, int town_num) {
data.OpenElement("dialogue");
data.PushAttribute("boes", scenario.format_ed_version());
for(size_t i = 0; i < 10; i++) {
cPersonality& who = talk.people[i];
data.OpenElement("personality");
data.PushAttribute("id", i);
data.PushAttribute("id", i + 10 * town_num);
data.PushElement("title", who.title);
data.PushElement("look", who.look);
data.PushElement("name", who.name);
@@ -811,14 +831,14 @@ static map_data buildOutMapData(location which) {
for(size_t i = 0; i < scenario.boats.size(); i++) {
if(scenario.boats[i].which_town == 200 && scenario.boats[i].sector == which) {
int j = i;
if(scenario.boats[i].property) j *= -1;
if(scenario.boats[i].property) j += 10000;
terrain.addFeature(scenario.boats[i].loc.x, scenario.boats[i].loc.y, eMapFeature::HORSE, j);
}
}
for(size_t i = 0; i < scenario.horses.size(); i++) {
if(scenario.horses[i].which_town == 200 && scenario.horses[i].sector == which) {
int j = i;
if(scenario.horses[i].property) j *= -1;
if(scenario.horses[i].property) j += 10000;
terrain.addFeature(scenario.horses[i].loc.x, scenario.horses[i].loc.y, eMapFeature::HORSE, j);
}
}
@@ -954,7 +974,7 @@ void save_scenario(fs::path toFile) {
// Don't forget the dialogue nodes.
std::ostream& town_talk = scen_file.newFile("scenario/towns/talk" + std::to_string(i) + ".xml");
writeDialogueToXml(ticpp::Printer("talk.xml", town_talk), scenario.towns[i]->talking);
writeDialogueToXml(ticpp::Printer("talk.xml", town_talk), scenario.towns[i]->talking, i);
}
// Now, custom graphics.
@@ -1031,7 +1051,7 @@ void save_scenario(fs::path toFile) {
std::string fname = toFile.filename().string();
size_t dot = fname.find_last_of('.');
if(dot == std::string::npos || fname.substr(dot) != ".boes") {
if(fname.substr(dot) == ".exs")
if(dot != std::string::npos && fname.substr(dot) == ".exs")
fname.replace(dot,4,".boes");
else fname += ".boes";
}

File diff suppressed because it is too large Load Diff

View File

@@ -15,15 +15,15 @@
using namespace std;
map_data load_map(fs::path path, bool isTown) {
map_data load_map(std::istream& fin, bool isTown) {
map_data data;
ifstream fin(path.string());
int row = 0;
while(!fin.eof()) {
std::string line;
getline(fin, line);
int n = 0, col = 0;
eMapFeature curFeature = eMapFeature::NONE;
// vehicle_owned = true means the party owns it
bool vehicle_owned;
for(char c : line) {
if(c == '#') break; // Found a comment
@@ -32,20 +32,20 @@ map_data load_map(fs::path path, bool isTown) {
n += c - '0';
} else if(isblank(c)) {
continue;
} else if(c == '^') {
} else if(c == '^' && isTown) {
data.addFeature(col, row, eMapFeature::ENTRANCE_NORTH);
} else if(c == '<') {
} else if(c == '<' && isTown) {
data.addFeature(col, row, eMapFeature::ENTRANCE_WEST);
} else if(c == 'v') {
} else if(c == 'v' && isTown) {
data.addFeature(col, row, eMapFeature::ENTRANCE_SOUTH);
} else if(c == '>') {
} else if(c == '>' && isTown) {
data.addFeature(col, row, eMapFeature::ENTRANCE_EAST);
} else {
if(curFeature == eMapFeature::NONE)
data.set(col, row, n);
else {
if((curFeature == eMapFeature::BOAT || curFeature == eMapFeature::HORSE) && !vehicle_owned)
n *= -1;
n += 10000;
data.addFeature(col, row, curFeature, n);
}
n = 0;

View File

@@ -12,11 +12,8 @@
#include <vector>
#include <map>
#include <iosfwd>
#include <boost/filesystem/path.hpp>
#include "location.h"
namespace fs = boost::filesystem;
enum class eMapFeature {
NONE, // Special value, won't appear in the map.
SPECIAL_NODE,
@@ -51,6 +48,6 @@ public:
void writeTo(std::ostream& out);
};
map_data load_map(fs::path path, bool isTown);
map_data load_map(std::istream& stream, bool isTown);
#endif

View File

@@ -175,18 +175,8 @@ namespace ResMgr {
/// @tparam type The type of resource the path applies to.
/// @return The removed path from the top of the stack.
template<typename type> fs::path popPath() {
fs::path path = resPool<type>::resPaths.top();
// std::map<std::string,std::string>::iterator mapiter;
// std::deque<std::string> toDestroy;
// std::deque<std::string>::iterator iter;
// for(mapiter = resPool<type>::pathFound().begin();
// mapiter != resPool<type>::pathFound().end();
// mapiter++)
// if(mapiter->second == path)
// toDestroy.push_back(mapiter->first);
// for(iter = toDestroy.begin(); iter != toDestroy.end(); iter++)
// resPool<type>::resources().erase(*iter);
resPool<type>::resPaths.pop();
fs::path path = resPool<type>::resPaths().top();
resPool<type>::resPaths().pop();
return path;
}