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 28c3908
Show file tree
Hide file tree
Showing 4 changed files with 100 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.cc"
"src/sfall_ext.h"
"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()
}
}

sfallLoadMods();

if (compat_access("f2_res.dat", 0) == 0) {
dbOpen("f2_res.dat", 0, nullptr, 1);
}
Expand Down
85 changes: 85 additions & 0 deletions src/sfall_ext.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#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 sfallLoadMods()
{
// SFALL: additional mods from the mods directory / mods_order.txt
const char* modsPath = "mods";
const char* loadOrderFilename = "mods_order.txt";

char loadOrderFilepath[COMPAT_MAX_PATH];
compat_makepath(loadOrderFilepath, nullptr, modsPath, loadOrderFilename, nullptr);

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

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

File* stream = fileOpen(loadOrderFilepath, "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(loadOrderFilepath, "r");
if (stream != nullptr) {
char mod[COMPAT_MAX_PATH];
while (fileReadString(mod, COMPAT_MAX_PATH, stream)) {
std::string modPath { mod };

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

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

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

if (modPath.empty())
continue; // skip empty lines

char normalizedModPath[COMPAT_MAX_PATH];
compat_makepath(normalizedModPath, nullptr, modsPath, modPath.c_str(), nullptr);

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

} // 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 sfallLoadMods();

} // namespace fallout

#endif /* SFALL_EXT_H */

0 comments on commit 28c3908

Please sign in to comment.