From 7ee008e150bc5bcf76082d726f719ee0fdfda982 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Wed, 11 Feb 2026 02:37:39 -0600 Subject: Fluorine Manager: full Linux port of Mod Organizer 2 Complete native Linux port with FUSE-based virtual filesystem, Proton/umu-run integration, and Flatpak packaging. Key features: - FUSE VFS replacing Windows USVFS (in-process + standalone helper for Flatpak) - Proton/GE-Proton/umu-run launcher with env var forwarding - Flatpak support (sandbox-aware VFS, NXM handler, umu-run) - Wine prefix management UI - Case-insensitive path resolution for Linux filesystems - QSettings-safe INI handling (avoids Bethesda INI corruption) - Portable instance support with auto-generated launcher scripts Co-Authored-By: Claude Opus 4.6 --- .../src/games/oblivion/CMakeLists.txt | 21 ++ .../src/games/oblivion/game_oblivion_en.ts | 17 ++ .../src/games/oblivion/gameoblivion.cpp | 213 +++++++++++++++++++++ .../src/games/oblivion/gameoblivion.h | 51 +++++ .../src/games/oblivion/gameoblivion.json | 1 + .../src/games/oblivion/oblivionbsainvalidation.cpp | 16 ++ .../src/games/oblivion/oblivionbsainvalidation.h | 20 ++ .../src/games/oblivion/obliviondataarchives.cpp | 32 ++++ .../src/games/oblivion/obliviondataarchives.h | 23 +++ .../src/games/oblivion/oblivionmoddatachecker.cpp | 30 +++ .../src/games/oblivion/oblivionmoddatachecker.h | 35 ++++ .../src/games/oblivion/oblivionmoddatacontent.h | 22 +++ .../src/games/oblivion/oblivionsavegame.cpp | 74 +++++++ .../src/games/oblivion/oblivionsavegame.h | 21 ++ .../src/games/oblivion/oblivionscriptextender.cpp | 20 ++ .../src/games/oblivion/oblivionscriptextender.h | 18 ++ 16 files changed, 614 insertions(+) create mode 100644 libs/game_bethesda/src/games/oblivion/CMakeLists.txt create mode 100644 libs/game_bethesda/src/games/oblivion/game_oblivion_en.ts create mode 100644 libs/game_bethesda/src/games/oblivion/gameoblivion.cpp create mode 100644 libs/game_bethesda/src/games/oblivion/gameoblivion.h create mode 100644 libs/game_bethesda/src/games/oblivion/gameoblivion.json create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionbsainvalidation.cpp create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionbsainvalidation.h create mode 100644 libs/game_bethesda/src/games/oblivion/obliviondataarchives.cpp create mode 100644 libs/game_bethesda/src/games/oblivion/obliviondataarchives.h create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionmoddatachecker.cpp create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionmoddatachecker.h create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionmoddatacontent.h create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionsavegame.cpp create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionsavegame.h create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionscriptextender.cpp create mode 100644 libs/game_bethesda/src/games/oblivion/oblivionscriptextender.h (limited to 'libs/game_bethesda/src/games/oblivion') diff --git a/libs/game_bethesda/src/games/oblivion/CMakeLists.txt b/libs/game_bethesda/src/games/oblivion/CMakeLists.txt new file mode 100644 index 0000000..df5ff8c --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.16) + +add_library(game_oblivion SHARED + gameoblivion.cpp + gameoblivion.h + oblivionbsainvalidation.cpp + oblivionbsainvalidation.h + obliviondataarchives.cpp + obliviondataarchives.h + oblivionmoddatachecker.cpp + oblivionmoddatachecker.h + oblivionmoddatacontent.h + oblivionsavegame.cpp + oblivionsavegame.h + oblivionscriptextender.cpp + oblivionscriptextender.h +) +mo2_configure_plugin(game_oblivion NO_SOURCES WARNINGS 4) +mo2_default_source_group() +target_link_libraries(game_oblivion PRIVATE game_gamebryo) +mo2_install_plugin(game_oblivion) diff --git a/libs/game_bethesda/src/games/oblivion/game_oblivion_en.ts b/libs/game_bethesda/src/games/oblivion/game_oblivion_en.ts new file mode 100644 index 0000000..80b1dbb --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/game_oblivion_en.ts @@ -0,0 +1,17 @@ + + + + + GameOblivion + + + Oblivion Support Plugin + + + + + Adds support for the game Oblivion + + + + diff --git a/libs/game_bethesda/src/games/oblivion/gameoblivion.cpp b/libs/game_bethesda/src/games/oblivion/gameoblivion.cpp new file mode 100644 index 0000000..9f7a174 --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/gameoblivion.cpp @@ -0,0 +1,213 @@ +#include "gameoblivion.h" + +#include "oblivionbsainvalidation.h" +#include "obliviondataarchives.h" +#include "oblivionmoddatachecker.h" +#include "oblivionmoddatacontent.h" +#include "oblivionsavegame.h" +#include "oblivionscriptextender.h" + +#include "executableinfo.h" +#include "pluginsetting.h" +#include "steamutility.h" +#include +#include +#include +#include + +#include +#include +#include + +#include + +using namespace MOBase; + +GameOblivion::GameOblivion() {} + +bool GameOblivion::init(IOrganizer* moInfo) +{ + if (!GameGamebryo::init(moInfo)) { + return false; + } + + auto dataArchives = std::make_shared(this); + registerFeature(std::make_shared(this)); + registerFeature(dataArchives); + registerFeature(std::make_shared(dataArchives.get(), this)); + registerFeature(std::make_shared(this)); + registerFeature(std::make_shared(this, "oblivion.ini")); + registerFeature(std::make_shared(this)); + registerFeature( + std::make_shared(m_Organizer->gameFeatures())); + registerFeature(std::make_shared(moInfo)); + registerFeature(std::make_shared(this)); + return true; +} + +QString GameOblivion::gameName() const +{ + return "Oblivion"; +} + +QList GameOblivion::executables() const +{ + return QList() + << ExecutableInfo("Oblivion", findInGameFolder(binaryName())) + << ExecutableInfo("Oblivion Launcher", findInGameFolder(getLauncherName())) + << ExecutableInfo("Oblivion Mod Manager", + findInGameFolder("OblivionModManager.exe")) + << ExecutableInfo("BOSS", findInGameFolder("BOSS/BOSS.exe")) + << ExecutableInfo("LOOT", QFileInfo(getLootPath())) + .withArgument("--game=\"Oblivion\"") + << ExecutableInfo("Construction Set", + findInGameFolder("TESConstructionSet.exe")); +} + +QList GameOblivion::executableForcedLoads() const +{ + return QList() + << ExecutableForcedLoadSetting("Oblivion.exe", "obse_1_2_416.dll") + .withForced() + .withEnabled() + << ExecutableForcedLoadSetting("TESConstructionSet.exe", "obse_editor_1_2.dll") + .withForced() + .withEnabled(); +} + +QString GameOblivion::name() const +{ + return "Oblivion Support Plugin"; +} + +QString GameOblivion::localizedName() const +{ + return tr("Oblivion Support Plugin"); +} + +QString GameOblivion::author() const +{ + return "Tannin & MO2 Team"; +} + +QString GameOblivion::description() const +{ + return tr("Adds support for the game Oblivion"); +} + +MOBase::VersionInfo GameOblivion::version() const +{ + return VersionInfo(1, 6, 1, VersionInfo::RELEASE_FINAL); +} + +QList GameOblivion::settings() const +{ + return {PluginSetting("nehrim_downloads", "allow Nehrim downloads", QVariant(false))}; +} + +void GameOblivion::initializeProfile(const QDir& path, ProfileSettings settings) const +{ + if (settings.testFlag(IPluginGame::MODS)) { + copyToProfile(localAppFolder() + "/Oblivion", path, "plugins.txt"); + } + + if (settings.testFlag(IPluginGame::CONFIGURATION)) { + if (settings.testFlag(IPluginGame::PREFER_DEFAULTS) || + !QFileInfo(myGamesPath() + "/oblivion.ini").exists()) { + copyToProfile(gameDirectory().absolutePath(), path, "oblivion_default.ini", + "oblivion.ini"); + } else { + copyToProfile(myGamesPath(), path, "oblivion.ini"); + } + + copyToProfile(myGamesPath(), path, "oblivionprefs.ini"); + } +} + +QString GameOblivion::savegameExtension() const +{ + return "ess"; +} + +QString GameOblivion::savegameSEExtension() const +{ + return "obse"; +} + +std::shared_ptr +GameOblivion::makeSaveGame(QString filePath) const +{ + return std::make_shared(filePath, this); +} + +QString GameOblivion::steamAPPId() const +{ + return "22330"; +} + +QStringList GameOblivion::primaryPlugins() const +{ + return {"oblivion.esm", "update.esm"}; +} + +QString GameOblivion::gameShortName() const +{ + return "Oblivion"; +} + +QStringList GameOblivion::validShortNames() const +{ + QStringList shortNames; + if (m_Organizer->pluginSetting(name(), "nehrim_downloads").toBool()) { + shortNames.append("Nehrim"); + } + return shortNames; +} + +QString GameOblivion::gameNexusName() const +{ + return "Oblivion"; +} + +QStringList GameOblivion::iniFiles() const +{ + return {"oblivion.ini", "oblivionprefs.ini"}; +} + +QStringList GameOblivion::DLCPlugins() const +{ + return {"DLCBattlehornCastle.esp", "DLCShiveringIsles.esp", "Knights.esp", + "DLCFrostcrag.esp", "DLCSpellTomes.esp", "DLCMehrunesRazor.esp", + "DLCOrrery.esp", "DLCThievesDen.esp", "DLCVileLair.esp", + "DLCHorseArmor.esp"}; +} + +int GameOblivion::nexusModOrganizerID() const +{ + return 38277; +} + +int GameOblivion::nexusGameID() const +{ + return 101; +} + +QString GameOblivion::identifyGamePath() const +{ +#ifdef _WIN32 + return GameGamebryo::identifyGamePath(); +#else + // Prefer Steam app-id resolution to avoid matching Oblivion Remastered. + QString path = parseSteamLocation(steamAPPId(), "Oblivion"); + if (!path.isEmpty() && looksValid(QDir(path))) { + return path; + } + + path = MOBase::findSteamGame("Oblivion", "Oblivion.exe"); + if (!path.isEmpty() && looksValid(QDir(path))) { + return path; + } + + return GameGamebryo::identifyGamePath(); +#endif +} diff --git a/libs/game_bethesda/src/games/oblivion/gameoblivion.h b/libs/game_bethesda/src/games/oblivion/gameoblivion.h new file mode 100644 index 0000000..124aa7f --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/gameoblivion.h @@ -0,0 +1,51 @@ +#ifndef GAMEOBLIVION_H +#define GAMEOBLIVION_H + +#include "gamegamebryo.h" + +#include +#include + +class GameOblivion : public GameGamebryo +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.tannin.GameOblivion" FILE "gameoblivion.json") + +public: + GameOblivion(); + + virtual bool init(MOBase::IOrganizer* moInfo) override; + +public: // IPluginGame interface + virtual QString gameName() const override; + virtual QList executables() const override; + virtual QList + executableForcedLoads() const override; + virtual void initializeProfile(const QDir& path, + ProfileSettings settings) const override; + virtual QString steamAPPId() const override; + virtual QStringList primaryPlugins() const override; + virtual QString gameShortName() const override; + virtual QStringList validShortNames() const override; + virtual QString gameNexusName() const override; + virtual QStringList iniFiles() const override; + virtual QStringList DLCPlugins() const override; + virtual int nexusModOrganizerID() const override; + virtual int nexusGameID() const override; + +public: // IPlugin interface + virtual QString name() const override; + virtual QString localizedName() const override; + virtual QString author() const override; + virtual QString description() const override; + virtual MOBase::VersionInfo version() const override; + virtual QList settings() const override; + +protected: + QString identifyGamePath() const override; + std::shared_ptr makeSaveGame(QString filePath) const override; + QString savegameExtension() const override; + QString savegameSEExtension() const override; +}; + +#endif // GAMEOBLIVION_H diff --git a/libs/game_bethesda/src/games/oblivion/gameoblivion.json b/libs/game_bethesda/src/games/oblivion/gameoblivion.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/gameoblivion.json @@ -0,0 +1 @@ +{} diff --git a/libs/game_bethesda/src/games/oblivion/oblivionbsainvalidation.cpp b/libs/game_bethesda/src/games/oblivion/oblivionbsainvalidation.cpp new file mode 100644 index 0000000..864d37c --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionbsainvalidation.cpp @@ -0,0 +1,16 @@ +#include "oblivionbsainvalidation.h" + +OblivionBSAInvalidation::OblivionBSAInvalidation(MOBase::DataArchives* dataArchives, + MOBase::IPluginGame const* game) + : GamebryoBSAInvalidation(dataArchives, "oblivion.ini", game) +{} + +QString OblivionBSAInvalidation::invalidationBSAName() const +{ + return "Oblivion - Invalidation.bsa"; +} + +unsigned long OblivionBSAInvalidation::bsaVersion() const +{ + return 0x67; +} diff --git a/libs/game_bethesda/src/games/oblivion/oblivionbsainvalidation.h b/libs/game_bethesda/src/games/oblivion/oblivionbsainvalidation.h new file mode 100644 index 0000000..6804748 --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionbsainvalidation.h @@ -0,0 +1,20 @@ +#ifndef OBLIVIONBSAINVALIDATION_H +#define OBLIVIONBSAINVALIDATION_H + +#include "gamebryobsainvalidation.h" +#include "obliviondataarchives.h" + +#include + +class OblivionBSAInvalidation : public GamebryoBSAInvalidation +{ +public: + OblivionBSAInvalidation(MOBase::DataArchives* dataArchives, + MOBase::IPluginGame const* game); + +private: + virtual QString invalidationBSAName() const override; + virtual unsigned long bsaVersion() const override; +}; + +#endif // OBLIVIONBSAINVALIDATION_H diff --git a/libs/game_bethesda/src/games/oblivion/obliviondataarchives.cpp b/libs/game_bethesda/src/games/oblivion/obliviondataarchives.cpp new file mode 100644 index 0000000..47c3dd4 --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/obliviondataarchives.cpp @@ -0,0 +1,32 @@ +#include "obliviondataarchives.h" +#include + +QStringList OblivionDataArchives::vanillaArchives() const +{ + return {"Oblivion - Misc.bsa", "Oblivion - Textures - Compressed.bsa", + "Oblivion - Meshes.bsa", "Oblivion - Sounds.bsa", + "Oblivion - Voices1.bsa", "Oblivion - Voices2.bsa"}; +} + +QStringList OblivionDataArchives::archives(const MOBase::IProfile* profile) const +{ + QStringList result; + + QString iniFile = profile->localSettingsEnabled() + ? QDir(profile->absolutePath()).absoluteFilePath("oblivion.ini") + : localGameDirectory().absoluteFilePath("oblivion.ini"); + result.append(getArchivesFromKey(iniFile, "SArchiveList")); + + return result; +} + +void OblivionDataArchives::writeArchiveList(MOBase::IProfile* profile, + const QStringList& before) +{ + QString list = before.join(", "); + + QString iniFile = profile->localSettingsEnabled() + ? QDir(profile->absolutePath()).absoluteFilePath("oblivion.ini") + : localGameDirectory().absoluteFilePath("oblivion.ini"); + setArchivesToKey(iniFile, "SArchiveList", list); +} diff --git a/libs/game_bethesda/src/games/oblivion/obliviondataarchives.h b/libs/game_bethesda/src/games/oblivion/obliviondataarchives.h new file mode 100644 index 0000000..380f3ca --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/obliviondataarchives.h @@ -0,0 +1,23 @@ +#ifndef OBLIVIONDATAARCHIVES_H +#define OBLIVIONDATAARCHIVES_H + +#include +#include +#include +#include +#include + +class OblivionDataArchives : public GamebryoDataArchives +{ +public: + using GamebryoDataArchives::GamebryoDataArchives; + + virtual QStringList vanillaArchives() const override; + virtual QStringList archives(const MOBase::IProfile* profile) const override; + +private: + virtual void writeArchiveList(MOBase::IProfile* profile, + const QStringList& before) override; +}; + +#endif // OBLIVIONDATAARCHIVES_H diff --git a/libs/game_bethesda/src/games/oblivion/oblivionmoddatachecker.cpp b/libs/game_bethesda/src/games/oblivion/oblivionmoddatachecker.cpp new file mode 100644 index 0000000..30a74ee --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionmoddatachecker.cpp @@ -0,0 +1,30 @@ +#include "oblivionmoddatachecker.h" + +MOBase::ModDataChecker::CheckReturn OblivionModDataChecker::dataLooksValid( + std::shared_ptr fileTree) const +{ + // Check with Gamebryo stuff: + auto check = GamebryoModDataChecker::dataLooksValid(fileTree); + if (check == CheckReturn::VALID) { + return check; + } + + // Check for OBSE_ files: + for (auto const& entry : *fileTree) { + if (entry->isDir() || !entry->name().startsWith("OBSE", Qt::CaseInsensitive)) { + return CheckReturn::INVALID; + } + } + + return CheckReturn::FIXABLE; +} + +std::shared_ptr +OblivionModDataChecker::fix(std::shared_ptr fileTree) const +{ + // If we arrive here, it means all files starts with OBSE. + auto data = fileTree->createOrphanTree(); + auto obse = data->addDirectory("OBSE/Plugins"); + obse->merge(fileTree); + return data; +} diff --git a/libs/game_bethesda/src/games/oblivion/oblivionmoddatachecker.h b/libs/game_bethesda/src/games/oblivion/oblivionmoddatachecker.h new file mode 100644 index 0000000..f62d015 --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionmoddatachecker.h @@ -0,0 +1,35 @@ +#ifndef OBLIVION_MODATACHECKER_H +#define OBLIVION_MODATACHECKER_H + +#include + +class OblivionModDataChecker : public GamebryoModDataChecker +{ +public: + using GamebryoModDataChecker::GamebryoModDataChecker; + + CheckReturn + dataLooksValid(std::shared_ptr fileTree) const override; + std::shared_ptr + fix(std::shared_ptr fileTree) const override; + +protected: + virtual const FileNameSet& possibleFolderNames() const override + { + static FileNameSet result{"fonts", "interface", "menus", + "meshes", "music", "scripts", + "shaders", "sound", "strings", + "textures", "trees", "video", + "facegen", "obse", "distantlod", + "asi", "distantland", "mits", + "dllplugins", "CalienteTools", "NetScriptFramework"}; + return result; + } + virtual const FileNameSet& possibleFileExtensions() const override + { + static FileNameSet result{"esp", "esm", "bsa", "modgroups", "ini"}; + return result; + } +}; + +#endif // OBLIVION_MODATACHECKER_H diff --git a/libs/game_bethesda/src/games/oblivion/oblivionmoddatacontent.h b/libs/game_bethesda/src/games/oblivion/oblivionmoddatacontent.h new file mode 100644 index 0000000..4e412d0 --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionmoddatacontent.h @@ -0,0 +1,22 @@ +#ifndef OBLIVION_MODDATACONTENT_H +#define OBLIVION_MODDATACONTENT_H + +#include +#include + +class OblivionModDataContent : public GamebryoModDataContent +{ +public: + /** + * + */ + OblivionModDataContent(const MOBase::IGameFeatures* gameFeatures) + : GamebryoModDataContent(gameFeatures) + { + // Just need to disable some contents: + m_Enabled[CONTENT_MCM] = false; + m_Enabled[CONTENT_SKYPROC] = false; + } +}; + +#endif // OBLIVION_MODDATACONTENT_H diff --git a/libs/game_bethesda/src/games/oblivion/oblivionsavegame.cpp b/libs/game_bethesda/src/games/oblivion/oblivionsavegame.cpp new file mode 100644 index 0000000..2f26714 --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionsavegame.cpp @@ -0,0 +1,74 @@ +#include "oblivionsavegame.h" + +OblivionSaveGame::OblivionSaveGame(QString const& fileName, GameOblivion const* game) + : GamebryoSaveGame(fileName, game) +{ + FileWrapper file(getFilepath(), "TES4SAVEGAME"); + file.setPluginString(GamebryoSaveGame::StringType::TYPE_BSTRING); + + _SYSTEMTIME creationTime; + fetchInformationFields(file, m_SaveNumber, m_PCName, m_PCLevel, m_PCLocation, + creationTime); + setCreationTime(creationTime); +} + +void OblivionSaveGame::fetchInformationFields(FileWrapper& file, + uint32_t& saveNumber, + QString& playerName, + unsigned short& playerLevel, + QString& playerLocation, + _SYSTEMTIME& creationTime) const +{ + file.skip(); // Major version + file.skip(); // Minor version + + file.skip<_SYSTEMTIME>(); // exe last modified (!) + + file.skip(); // Header version + file.skip(); // Header size + + file.read(saveNumber); + + file.read(playerName); + file.read(playerLevel); + file.read(playerLocation); + + file.skip(); // game days + file.skip(); // game ticks + + // there is a save time stored here. So use it rather than the file time, which + // could have been copied. + // Note: This says it uses getlocaltime api to obtain it which is u/s - if so + // we should ignore this. + file.read(creationTime); +} + +std::unique_ptr OblivionSaveGame::fetchDataFields() const +{ + FileWrapper file(getFilepath(), "TES4SAVEGAME"); + file.setPluginString(GamebryoSaveGame::StringType::TYPE_BSTRING); + + std::unique_ptr fields = std::make_unique(); + + { + QString dummyName, dummyLocation; + unsigned short dummyLevel; + uint32_t dummySaveNumber; + _SYSTEMTIME dummyTime; + + fetchInformationFields(file, dummySaveNumber, dummyName, dummyLevel, dummyLocation, + dummyTime); + } + + // Note that screenshot size, width, height and data are apparently the same + // structure + uint32_t imageSize; + file.read(imageSize); // Screenshot size. + if (imageSize > 0) { + fields->Screenshot = file.readImage(); + } + + fields->Plugins = file.readPlugins(); + + return fields; +} diff --git a/libs/game_bethesda/src/games/oblivion/oblivionsavegame.h b/libs/game_bethesda/src/games/oblivion/oblivionsavegame.h new file mode 100644 index 0000000..3961214 --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionsavegame.h @@ -0,0 +1,21 @@ +#ifndef OBLIVIONSAVEGAME_H +#define OBLIVIONSAVEGAME_H + +#include "gamebryosavegame.h" +#include "gameoblivion.h" + +class OblivionSaveGame : public GamebryoSaveGame +{ +public: + OblivionSaveGame(QString const& fileName, GameOblivion const* game); + +protected: + // Fetch easy-to-access information. + void fetchInformationFields(FileWrapper& wrapper, uint32_t& saveNumber, + QString& playerName, unsigned short& playerLevel, + QString& playerLocation, _SYSTEMTIME& creationTime) const; + + std::unique_ptr fetchDataFields() const override; +}; + +#endif // OBLIVIONSAVEGAME_H diff --git a/libs/game_bethesda/src/games/oblivion/oblivionscriptextender.cpp b/libs/game_bethesda/src/games/oblivion/oblivionscriptextender.cpp new file mode 100644 index 0000000..f021a2e --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionscriptextender.cpp @@ -0,0 +1,20 @@ +#include "oblivionscriptextender.h" + +#include +#include + +OblivionScriptExtender::OblivionScriptExtender(GameGamebryo const* game) + : GamebryoScriptExtender(game) +{} + +OblivionScriptExtender::~OblivionScriptExtender() {} + +QString OblivionScriptExtender::BinaryName() const +{ + return "obse_loader.exe"; +} + +QString OblivionScriptExtender::PluginPath() const +{ + return "obse/plugins"; +} diff --git a/libs/game_bethesda/src/games/oblivion/oblivionscriptextender.h b/libs/game_bethesda/src/games/oblivion/oblivionscriptextender.h new file mode 100644 index 0000000..1044bfa --- /dev/null +++ b/libs/game_bethesda/src/games/oblivion/oblivionscriptextender.h @@ -0,0 +1,18 @@ +#ifndef OBLIVIONSCRIPTEXTENDER_H +#define OBLIVIONSCRIPTEXTENDER_H + +#include "gamebryoscriptextender.h" + +class GameGamebryo; + +class OblivionScriptExtender : public GamebryoScriptExtender +{ +public: + OblivionScriptExtender(const GameGamebryo* game); + ~OblivionScriptExtender(); + + virtual QString BinaryName() const override; + virtual QString PluginPath() const override; +}; + +#endif // OBLIVIONSCRIPTEXTENDER_H -- cgit v1.3.1