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:
@@ -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>
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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;
|
||||
|
@@ -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
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user