Skip to content

Commit

Permalink
Sfall: add support for loading mods / mod_order.txt
Browse files Browse the repository at this point in the history
  • Loading branch information
JanSimek committed Jun 4, 2024
1 parent 9fb917c commit 85150f0
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ target_sources(${EXECUTABLE_NAME} PUBLIC
"src/settings.h"
"src/sfall_config.cc"
"src/sfall_config.h"
"src/sfall_ext.h"
"src/sfall_ext.cc"
"src/sfall_global_vars.cc"
"src/sfall_global_vars.h"
"src/sfall_global_scripts.cc"
Expand Down
3 changes: 3 additions & 0 deletions src/game.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include "settings.h"
#include "sfall_arrays.h"
#include "sfall_config.h"
#include "sfall_ext.h"
#include "sfall_global_scripts.h"
#include "sfall_global_vars.h"
#include "sfall_ini.h"
Expand Down Expand Up @@ -1378,6 +1379,8 @@ static int gameDbInit()
}
}

sfall_load_mods();

if (compat_access("f2_res.dat", 0) == 0) {
dbOpen("f2_res.dat", 0, nullptr, 1);
}
Expand Down
81 changes: 81 additions & 0 deletions src/sfall_ext.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include "sfall_ext.h"

#include <algorithm>
#include <string>

#include "db.h"
#include "debug.h"
#include "platform_compat.h"

namespace fallout {

/**
* Load mods from the mod directory
*/
void sfall_load_mods()
{
// SFALL: additional mods from the mods directory / mods_order.txt
const char* mods_path = "mods";
const char* load_order_filename = "mods_order.txt";

char load_order_filepath[COMPAT_MAX_PATH];
compat_makepath(load_order_filepath, nullptr, mods_path, load_order_filename, nullptr);

// If the mods folder does not exist, create it.
compat_mkdir(mods_path);

// If load order file does not exist, initialize it automatically with mods already in the mods folder.
if (compat_access(load_order_filepath, 0) != 0) {
debugPrint("Generating Mods Order file based on the contents of Mods folder: %s\n", load_order_filepath);

File* stream = fileOpen(load_order_filepath, "wt");
if (stream != nullptr) {
char** fileList;
int fileListLength = fileNameListInit("mods\\*.dat", &fileList, 0, 0);

for (int index = 0; index < fileListLength; index++) {
fileWriteString(fileList[index], stream);
fileWriteString("\n", stream);
}
fileClose(stream);
fileNameListFree(&fileList, 0);
}
}

// Add mods from load order file.
File* stream = fileOpen(load_order_filepath, "r");
if (stream != nullptr) {
char mod[COMPAT_MAX_PATH];
while (fileReadString(mod, COMPAT_MAX_PATH, stream)) {
char mod_path[COMPAT_MAX_PATH];
compat_makepath(mod_path, nullptr, mods_path, mod, nullptr);
std::string normalized_mod_path { mod_path };

if (normalized_mod_path.find_first_of(";#") != std::string::npos)
continue; // skip comments

// ltrim
normalized_mod_path.erase(normalized_mod_path.begin(), std::find_if(normalized_mod_path.begin(), normalized_mod_path.end(), [](unsigned char ch) {
return !isspace(ch);
}));

// rtrim
normalized_mod_path.erase(std::find_if(normalized_mod_path.rbegin(), normalized_mod_path.rend(), [](unsigned char ch) {
return !isspace(ch);
}).base(),
normalized_mod_path.end());

if (compat_access(normalized_mod_path.c_str(), 0) == 0) {
debugPrint("Loading mod %s\n", normalized_mod_path.c_str());
dbOpen(normalized_mod_path.c_str(), 0, nullptr, 1);
} else {
debugPrint("Skipping invalid mod entry %s in %s\n", normalized_mod_path.c_str(), load_order_filepath);
}
}
fileClose(stream);
} else {
debugPrint("Error opening %s for read\n", load_order_filepath);
}
}

} // namespace fallout
10 changes: 10 additions & 0 deletions src/sfall_ext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef SFALL_EXT_H
#define SFALL_EXT_H

namespace fallout {

void sfall_load_mods();

} // namespace fallout

#endif /* SFALL_EXT_H */

0 comments on commit 85150f0

Please sign in to comment.