Add Fallout 4 support

Still need to update docs, this assumes that FO4 will not need "Redate
Plugins" functionality, and that it only loads BSAs if they match a
plugin's basename.
This commit is contained in:
Oliver Hamlet
2015-11-26 19:19:29 +00:00
parent 15102d3d13
commit 547106bc55
9 changed files with 38 additions and 7 deletions
+1
View File
@@ -246,6 +246,7 @@ extern "C"
LOOT_API extern const unsigned int loot_game_tes5; /**< Game code for The Elder Scrolls V: Skyrim. */
LOOT_API extern const unsigned int loot_game_fo3; /**< Game code for Fallout 3. */
LOOT_API extern const unsigned int loot_game_fonv; /**< Game code for Fallout: New Vegas. */
LOOT_API extern const unsigned int loot_game_fo4; /**< Game code for Fallout: New Vegas. */
/**@}*/
/**********************************************************************//**
+7 -1
View File
@@ -63,6 +63,7 @@ const unsigned int loot_game_tes4 = loot::Game::tes4;
const unsigned int loot_game_tes5 = loot::Game::tes5;
const unsigned int loot_game_fo3 = loot::Game::fo3;
const unsigned int loot_game_fonv = loot::Game::fonv;
const unsigned int loot_game_fo4 = loot::Game::fo4;
// LOOT message types.
const unsigned int loot_message_say = loot::Message::say;
@@ -243,7 +244,12 @@ LOOT_API unsigned int loot_create_db(loot_db * const db,
const unsigned int clientGame,
const char * const gamePath,
const char * const gameLocalPath) {
if (db == nullptr || (clientGame != loot_game_tes4 && clientGame != loot_game_tes5 && clientGame != loot_game_fo3 && clientGame != loot_game_fonv))
if (db == nullptr
|| (clientGame != loot_game_tes4
&& clientGame != loot_game_tes5
&& clientGame != loot_game_fo3
&& clientGame != loot_game_fonv
&& clientGame != loot_game_fo4))
return c_error(loot_error_invalid_args, "Null pointer passed.");
//Set the locale to get encoding conversions working correctly.
+1 -1
View File
@@ -54,7 +54,7 @@ namespace loot {
Game::Game(const unsigned int gameCode, const std::string& folder) : GameSettings(gameCode, folder), _pluginsFullyLoaded(false) {}
void Game::Init(bool createFolder, const boost::filesystem::path& gameLocalAppData) {
if (Id() != Game::tes4 && Id() != Game::tes5 && Id() != Game::fo3 && Id() != Game::fonv) {
if (Id() != Game::tes4 && Id() != Game::tes5 && Id() != Game::fo3 && Id() != Game::fonv && Id() != Game::fo4) {
throw error(error::invalid_args, lc::translate("Invalid game ID supplied.").str());
}
+15 -1
View File
@@ -42,6 +42,7 @@ namespace loot {
const unsigned int GameSettings::tes5 = 2;
const unsigned int GameSettings::fo3 = 3;
const unsigned int GameSettings::fonv = 4;
const unsigned int GameSettings::fo4 = 5;
GameSettings::GameSettings() : _id(GameSettings::autodetect) {}
@@ -78,6 +79,14 @@ namespace loot {
_repositoryURL = "https://github.com/loot/falloutnv.git";
_repositoryBranch = "v0.8";
}
else if (Id() == GameSettings::fo4) {
_name = "Fallout 4";
_registryKey = "Software\\Bethesda Softworks\\Fallout4\\Installed Path";
_lootFolderName = "Fallout4";
_masterFile = "Fallout4.esm";
_repositoryURL = "https://github.com/loot/fallout4.git";
_repositoryBranch = "v0.8";
}
if (!folder.empty())
_lootFolderName = folder;
@@ -127,8 +136,10 @@ namespace loot {
return libespm::GameId::SKYRIM;
else if (_id == GameSettings::fo3)
return libespm::GameId::FALLOUT3;
else
else if (_id == GameSettings::fonv)
return libespm::GameId::FALLOUTNV;
else
return libespm::GameId::FALLOUT4;
}
string GameSettings::Name() const {
@@ -234,6 +245,9 @@ namespace loot {
if (find(games.begin(), games.end(), GameSettings(GameSettings::fonv)) == games.end())
games.push_back(GameSettings(GameSettings::fonv));
if (find(games.begin(), games.end(), GameSettings(GameSettings::fo4)) == games.end())
games.push_back(GameSettings(GameSettings::fo4));
// If there were any missing defaults, make sure they're in settings now.
settings["games"] = games;
+3
View File
@@ -71,6 +71,7 @@ namespace loot {
static const unsigned int tes5;
static const unsigned int fo3;
static const unsigned int fonv;
static const unsigned int fo4;
private:
unsigned int _id;
std::string _name;
@@ -122,6 +123,8 @@ namespace YAML {
rhs = loot::GameSettings(loot::GameSettings::fo3, node["folder"].as<std::string>());
else if (node["type"].as<std::string>() == loot::GameSettings(loot::GameSettings::fonv).FolderName())
rhs = loot::GameSettings(loot::GameSettings::fonv, node["folder"].as<std::string>());
else if (node["type"].as<std::string>() == loot::GameSettings(loot::GameSettings::fo4).FolderName())
rhs = loot::GameSettings(loot::GameSettings::fo4, node["folder"].as<std::string>());
else
throw RepresentationException(node.Mark(), "bad conversion: invalid value for 'type' key in 'game settings' object");
+4 -1
View File
@@ -45,7 +45,8 @@ namespace loot {
if (game.Id() != GameSettings::tes4
&& game.Id() != GameSettings::tes5
&& game.Id() != GameSettings::fo3
&& game.Id() != GameSettings::fonv) {
&& game.Id() != GameSettings::fonv
&& game.Id() != GameSettings::fo4) {
throw error(error::invalid_args, lc::translate("Unsupported game ID supplied.").str());
}
@@ -74,6 +75,8 @@ namespace loot {
ret = lo_create_handle(&_gh, LIBLO_GAME_FO3, game.GamePath().string().c_str(), gameLocalDataPath);
else if (game.Id() == GameSettings::fonv)
ret = lo_create_handle(&_gh, LIBLO_GAME_FNV, game.GamePath().string().c_str(), gameLocalDataPath);
else if (game.Id() == GameSettings::fo4)
ret = lo_create_handle(&_gh, LIBLO_GAME_FO4, game.GamePath().string().c_str(), gameLocalDataPath);
else
ret = LIBLO_ERROR_INVALID_ARGS;
+1 -1
View File
@@ -296,7 +296,7 @@ namespace loot {
bool Plugin::LoadsBSA(const Game& game) const {
if (IsRegexPlugin())
return false;
if (game.Id() == Game::tes5) {
if (game.Id() == Game::tes5 || game.Id() == Game::fo4) {
// Skyrim plugins only load BSAs that exactly match their basename.
return boost::filesystem::exists(game.DataPath() / (name.substr(0, name.length() - 3) + "bsa"));
}
+1
View File
@@ -612,6 +612,7 @@ namespace loot {
temp.push_back(Game(Game::tes5).FolderName());
temp.push_back(Game(Game::fo3).FolderName());
temp.push_back(Game(Game::fonv).FolderName());
temp.push_back(Game(Game::fo4).FolderName());
return JSON::stringify(temp);
}
+5 -2
View File
@@ -259,7 +259,8 @@ TEST(GetGameSettings, AllMissing) {
loot::GameSettings(loot::GameSettings::tes4),
loot::GameSettings(loot::GameSettings::tes5),
loot::GameSettings(loot::GameSettings::fo3),
loot::GameSettings(loot::GameSettings::fonv)
loot::GameSettings(loot::GameSettings::fonv),
loot::GameSettings(loot::GameSettings::fo4)
};
EXPECT_FALSE(settings["games"]);
@@ -271,7 +272,8 @@ TEST(GetGameSettings, MissingFallout3) {
std::list<loot::GameSettings> initial({
loot::GameSettings(loot::GameSettings::tes4, "folder1"),
loot::GameSettings(loot::GameSettings::tes5, "folder2"),
loot::GameSettings(loot::GameSettings::fonv, "folder3")
loot::GameSettings(loot::GameSettings::fonv, "folder3"),
loot::GameSettings(loot::GameSettings::fo4, "folder4")
});
YAML::Node settings;
@@ -281,6 +283,7 @@ TEST(GetGameSettings, MissingFallout3) {
loot::GameSettings(loot::GameSettings::tes4, "folder1"),
loot::GameSettings(loot::GameSettings::tes5, "folder2"),
loot::GameSettings(loot::GameSettings::fonv, "folder3"),
loot::GameSettings(loot::GameSettings::fo4, "folder4"),
loot::GameSettings(loot::GameSettings::fo3)
};