mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Implement support for OpenMW
Most of the complexity is handled by libloadorder, but it's worth noting that: - The game path is OpenMW's install path, not Morrowind's - OpenMW doesn't force master-flagged plugins to load before others - OpenMW doesn't provide a way to record the load order of inactive plugins - .omwgame and .omwaddon plugins are equivalent to .esm and .esp respectively, while .omwscripts plugins have a completely different format with none of the metadata that libloot uses. - OpenMW effectively relies on additional data paths to load Morrowind's (and mods') files, and the last directory listed that contains a given filename is used to load a file with that filename, with the main data path effectively being the first listed. - I've disabled support for ghosted plugins for OpenMW because it makes the multi-path stuff more confusing and may not provide any benefit.
This commit is contained in:
+7
-5
@@ -98,11 +98,13 @@ LOOT_API bool IsCompatible(const unsigned int major,
|
||||
* The relative or absolute path to the directory containing the
|
||||
* game's executable.
|
||||
* @param game_local_path
|
||||
* The relative or absolute path to the game's folder in
|
||||
* `%%LOCALAPPDATA%` or an empty path. If an empty path, the API will
|
||||
* attempt to look up the path that `%%LOCALAPPDATA%` corresponds to.
|
||||
* This parameter is provided so that systems lacking that environmental
|
||||
* variable (eg. Linux) can still use the API.
|
||||
* The relative or absolute path to the game's local data folder, or an
|
||||
* empty path. The local data folder is usually in `%%LOCALAPPDATA%`, but
|
||||
* Morrowind has no local data folder and OpenMW's is in the user's
|
||||
* My Games folder on Windows and in `$HOME/.config` on Linux. If an
|
||||
* empty path is provided, the API will attempt to look up the relevant
|
||||
* local data path, which may fail in some situations (e.g. when running
|
||||
* libloot natively on Linux for a game other than Morrowind or OpenMW).
|
||||
* @returns The new game handle.
|
||||
*/
|
||||
LOOT_API std::unique_ptr<GameInterface> CreateGameHandle(
|
||||
|
||||
@@ -50,7 +50,9 @@ enum struct GameType : unsigned int {
|
||||
/** The Elder Scrolls III: Morrowind */
|
||||
tes3,
|
||||
/** Starfield */
|
||||
starfield
|
||||
starfield,
|
||||
/** OpenMW */
|
||||
openmw
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,11 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Gets the currently-set additional data paths.
|
||||
* @details Only Fallout 4 installed from the Microsoft Store is configured
|
||||
* with any additional data paths by default, as its DLC directories
|
||||
* are installed outside of the Fallout 4 install path.
|
||||
* @details The following games are configured with additional data paths by
|
||||
* default:
|
||||
* - Fallout 4, when installed from the Microsoft Store
|
||||
* - Starfield
|
||||
* - OpenMW
|
||||
*/
|
||||
virtual std::vector<std::filesystem::path> GetAdditionalDataPaths() const = 0;
|
||||
|
||||
@@ -52,8 +54,9 @@ public:
|
||||
* @details The additional data paths are used when interacting with the load
|
||||
* order, evaluating conditions and scanning for archives (BSA/BA2
|
||||
* depending on the game). Additional data paths are used in the
|
||||
* order they are given, and take precedence over the game's main
|
||||
* data path.
|
||||
* order they are given (except with OpenMW, which checks them in
|
||||
* reverse order), and take precedence over the game's main data
|
||||
* path.
|
||||
*/
|
||||
virtual void SetAdditionalDataPaths(
|
||||
const std::vector<std::filesystem::path>& additionalDataPaths) = 0;
|
||||
@@ -87,9 +90,9 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Check if a file is a valid plugin.
|
||||
* @details The validity check is not exhaustive: it checks that the file
|
||||
* extension is ``.esm`` or ``.esp`` (after trimming any ``.ghost``
|
||||
* extension), and that the ``TES4`` header can be parsed.
|
||||
* @details The validity check is not exhaustive: it generally checks that the
|
||||
* file is a valid plugin file extension for the game and that its
|
||||
* header (if applicable) can be parsed.
|
||||
* @param pluginPath
|
||||
* The path to the file to check. Relative paths are resolved relative
|
||||
* to the game's plugins directory, while absolute paths are used
|
||||
@@ -107,10 +110,9 @@ public:
|
||||
* the game's plugins directory, while absolute paths are used as
|
||||
* given. Each plugin filename must be unique within the vector.
|
||||
* @param loadHeadersOnly
|
||||
* If true, only the plugins' ``TES4`` headers are loaded. If false,
|
||||
* all records in the plugins are parsed, apart from the main master
|
||||
* file if it has been identified by a previous call to
|
||||
* ``IdentifyMainMasterFile()``.
|
||||
* If true, only the plugins' headers are loaded. If false, all records
|
||||
* in the plugins are parsed, apart from the main master file if it has
|
||||
* been identified by a previous call to ``IdentifyMainMasterFile()``.
|
||||
*/
|
||||
virtual void LoadPlugins(
|
||||
const std::vector<std::filesystem::path>& pluginPaths,
|
||||
@@ -219,6 +221,9 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Set the game's load order.
|
||||
* @details There is no way to persist the load order of inactive OpenMW
|
||||
* plugins, so setting an OpenMW load order will have no effect if
|
||||
* the relative order of active plugins is unchanged.
|
||||
* @param loadOrder
|
||||
* A vector of plugin filenames sorted in the load order to set.
|
||||
*/
|
||||
|
||||
@@ -44,7 +44,8 @@ public:
|
||||
/**
|
||||
* Get the plugin's filename.
|
||||
* @return The plugin filename. If the plugin was ghosted when it was loaded,
|
||||
* this filename will be without the .ghost suffix.
|
||||
* this filename will be without the .ghost suffix, unless the game is
|
||||
* OpenMW, in which case ghosted plugins are not supported.
|
||||
*/
|
||||
virtual std::string GetName() const = 0;
|
||||
|
||||
@@ -88,8 +89,19 @@ public:
|
||||
virtual std::optional<uint32_t> GetCRC() const = 0;
|
||||
|
||||
/**
|
||||
* Check if the plugin's master flag is set.
|
||||
* @return True if the master flag is set, false otherwise.
|
||||
* Check if the plugin is a master plugin.
|
||||
*
|
||||
* What causes a plugin to be a master plugin varies by game, but is usually
|
||||
* indicated by the plugin having its master flag set and/or by its file
|
||||
* extension. However, OpenMW uses neither for determining plugins' load order
|
||||
* so all OpenMW plugins are treated as non-masters.
|
||||
*
|
||||
* The term "master" is potentially confusing: a plugin A may not be a *master
|
||||
* plugin*, but may still be a *master of* another plugin by being listed as
|
||||
* such in that plugin's header record. Master plugins are sometimes referred
|
||||
* to as *master files* or simply *masters*, while the other meaning is always
|
||||
* referenced in relation to another plugin.
|
||||
* @return True if the plugin is a master plugin, false otherwise.
|
||||
*/
|
||||
virtual bool IsMaster() const = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user