Implement recursive search for scenarios, allowing you to organize your scenarios directory

This commit is contained in:
2015-06-26 14:12:29 -04:00
parent 2bb89f127c
commit 95b3d7e30e
4 changed files with 49 additions and 6 deletions

View File

@@ -460,15 +460,48 @@ void start_data_dump() {
}
}
fs::path locate_scenario(std::string scen_name) {
std::transform(scen_name.begin(), scen_name.end(), scen_name.begin(), tolower);
fs::path scenDir = progDir/"Blades of Exile Scenarios", scenPath;
for(fs::recursive_directory_iterator iter(scenDir); iter != fs::recursive_directory_iterator(); iter++) {
fs::file_status stat = iter->status();
std::string fname = iter->path().filename().string().c_str();
std::transform(fname.begin(), fname.end(), fname.begin(), tolower);
if(fname == "header.exs") {
if(scen_name != "header.exs") continue;
// We want to support a scenario whose main filename is header.exs, just in case.
// However, any unpacked scenarios would have a header.exs.
// So, skip them if they're in a .boes folder.
fname = iter->path().parent_path().filename().string().c_str();
std::transform(fname.begin(), fname.end(), fname.begin(), tolower);
size_t dot = fname.find_first_of('.');
if(dot != std::string::npos && fname.substr(dot) == ".boes")
continue;
}
if(fname != scen_name) continue;
size_t dot = fname.find_first_of('.');
if(dot == std::string::npos) continue;
if(fname.substr(dot) == ".exs" && stat.type() == fs::regular_file) {
scenPath = iter->path();
break;
}
if(fname.substr(dot) == ".boes" && (stat.type() == fs::regular_file || stat.type() == fs::directory_file)) {
scenPath = iter->path();
break;
}
}
return scenPath;
}
void build_scen_headers() {
fs::path scenDir = progDir;
scenDir /= "Blades of Exile Scenarios";
std::cout << progDir << '\n' << scenDir << std::endl;
scen_headers.clear();
fs::directory_iterator iter(scenDir);
fs::recursive_directory_iterator iter(scenDir);
make_cursor_watch();
while(iter != fs::directory_iterator()) {
while(iter != fs::recursive_directory_iterator()) {
fs::file_status stat = iter->status();
if(stat.type() == fs::regular_file)
load_scenario_header(iter->path());

View File

@@ -29,6 +29,7 @@ void end_data_dump();
short onm(char x_sector,char y_sector);
void build_scen_headers();
bool load_scenario_header(fs::path filename/*,short header_entry*/);
fs::path locate_scenario(std::string scen_name);
void alter_rect(rectangle *r);

View File

@@ -262,10 +262,11 @@ void put_party_in_scen(std::string scen_name) {
univ.party.m_killed[i] = 0;
univ.party.party_event_timers.clear();
fs::path path;
path = progDir/"Blades of Exile Scenarios";
path /= scen_name;
std::cout<<"Searching for scenario at:\n"<<path<<'\n';
fs::path path = locate_scenario(scen_name);
if(path.empty()) {
giveError("Could not find scenario!");
return;
}
if(!load_scenario(path, univ.scenario))
return;

View File

@@ -1787,11 +1787,19 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head
bool is_packed = true;
tarball pack;
std::ifstream fin;
if(!fs::exists(file_to_load)) {
giveError("The scenario could not be found.");
return false;
}
if(fs::is_directory(file_to_load)) { // Unpacked
is_packed = false;
} else { // Packed
igzstream gzin(file_to_load.string().c_str());
pack.readFrom(gzin);
if(gzin.bad()) {
giveError("There was an error loading the scenario.");
return false;
}
}
auto getFile = [&](std::string relpath) -> std::istream& {
if(is_packed) return pack.getFile(relpath);