mirror of
https://github.com/ModOrganizer2/modorganizer-game_enderalse.git
synced 2026-07-27 14:08:06 -07:00
Initial commit.
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
edit
|
||||||
|
CMakeLists.txt.user
|
||||||
|
/msbuild.log
|
||||||
|
/*std*.log
|
||||||
|
/*build
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(game_enderalse)
|
||||||
|
set(project_type plugin)
|
||||||
|
set(enable_warnings OFF)
|
||||||
|
|
||||||
|
if(DEFINED DEPENDENCIES_DIR)
|
||||||
|
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/project.cmake)
|
||||||
|
else()
|
||||||
|
include(../cmake_common/project.cmake)
|
||||||
|
endif()
|
||||||
|
add_subdirectory(src)
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
version: 1.0.{build}
|
||||||
|
skip_branch_with_pr: true
|
||||||
|
image: Visual Studio 2019
|
||||||
|
environment:
|
||||||
|
WEBHOOK_URL:
|
||||||
|
secure: gOKbXaZM9ImtMD5XrYITvdyZUW/az082G9OIN1EC1Vbg57wBaeLhi49uGjxPw5GVujHku6kxN6ab89zhbS5GVeluR76GM83IbKV4Sh7udXzoYZZdg6YudtYHzdhCgUeiedpswbuczTq9ceIkkfSEWZuh/lMAAVVwvcGsJAnoPFw=
|
||||||
|
build_script:
|
||||||
|
- pwsh: >-
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
git clone --depth=1 --no-single-branch https://github.com/ModOrganizer2/modorganizer-umbrella.git c:\projects\modorganizer-umbrella
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Path c:\projects\modorganizer-build
|
||||||
|
|
||||||
|
cd c:\projects\modorganizer-umbrella
|
||||||
|
|
||||||
|
($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH -eq $null) ? ($branch = $env:APPVEYOR_REPO_BRANCH) : ($branch = $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH)
|
||||||
|
|
||||||
|
git checkout $(git show-ref --verify --quiet refs/remotes/origin/${branch} || echo '-b') ${branch}
|
||||||
|
|
||||||
|
C:\Python37-x64\python.exe unimake.py -d c:\projects\modorganizer-build -s Appveyor_Build=True ${env:APPVEYOR_PROJECT_NAME}
|
||||||
|
|
||||||
|
if($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode ) }
|
||||||
|
artifacts:
|
||||||
|
- path: vsbuild\src\RelWithDebInfo\game_skyrimse.dll
|
||||||
|
name: game_skyrimse_dll
|
||||||
|
- path: vsbuild\src\RelWithDebInfo\game_skyrimse.pdb
|
||||||
|
name: game_skyrimse_pdb
|
||||||
|
- path: vsbuild\src\RelWithDebInfo\game_skyrimse.lib
|
||||||
|
name: game_skyrimse_lib
|
||||||
|
on_success:
|
||||||
|
- ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
|
||||||
|
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
|
||||||
|
- ps: ./send.ps1 success $env:WEBHOOK_URL
|
||||||
|
on_failure:
|
||||||
|
- ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER
|
||||||
|
- ps: Push-AppveyorArtifact ${env:APPVEYOR_BUILD_FOLDER}\stdout.log
|
||||||
|
- ps: Push-AppveyorArtifact ${env:APPVEYOR_BUILD_FOLDER}\stderr.log
|
||||||
|
- ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1
|
||||||
|
- ps: ./send.ps1 failure $env:WEBHOOK_URL
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
if(DEFINED DEPENDENCIES_DIR)
|
||||||
|
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/src.cmake)
|
||||||
|
else()
|
||||||
|
include(../../cmake_common/src.cmake)
|
||||||
|
endif()
|
||||||
|
requires_project(game_gamebryo game_features)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#include "enderalsebsainvalidation.h"
|
||||||
|
|
||||||
|
EnderalSEBSAInvalidation::EnderalSEBSAInvalidation(DataArchives* dataArchives, MOBase::IPluginGame const* game)
|
||||||
|
: GamebryoBSAInvalidation(dataArchives, "skyrim.ini", game)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EnderalSEBSAInvalidation::invalidationBSAName() const
|
||||||
|
{
|
||||||
|
return "Enderal - Invalidation.bsa";
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long EnderalSEBSAInvalidation::bsaVersion() const
|
||||||
|
{
|
||||||
|
return 0x69;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef ENDERALSEBSAINVALIDATION_H
|
||||||
|
#define ENDERALSEBSAINVALIDATION_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "gamebryobsainvalidation.h"
|
||||||
|
#include "enderalsedataarchives.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class EnderalSEBSAInvalidation : public GamebryoBSAInvalidation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
EnderalSEBSAInvalidation(DataArchives* dataArchives, MOBase::IPluginGame const* game);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual QString invalidationBSAName() const override;
|
||||||
|
virtual unsigned long bsaVersion() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ENDERALSEBSAINVALIDATION_H
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include "enderalSEdataarchives.h"
|
||||||
|
|
||||||
|
#include "iprofile.h"
|
||||||
|
#include <utility.h>
|
||||||
|
|
||||||
|
EnderalSEDataArchives::EnderalSEDataArchives(const QDir &myGamesDir) :
|
||||||
|
GamebryoDataArchives(myGamesDir)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QStringList EnderalSEDataArchives::vanillaArchives() const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"Skyrim - Textures0.bsa",
|
||||||
|
"Skyrim - Textures1.bsa",
|
||||||
|
"Skyrim - Textures2.bsa",
|
||||||
|
"Skyrim - Textures3.bsa",
|
||||||
|
"Skyrim - Textures4.bsa",
|
||||||
|
"Skyrim - Textures5.bsa",
|
||||||
|
"Skyrim - Textures6.bsa",
|
||||||
|
"Skyrim - Textures7.bsa",
|
||||||
|
"Skyrim - Textures8.bsa",
|
||||||
|
"Skyrim - Meshes0.bsa",
|
||||||
|
"Skyrim - Meshes1.bsa",
|
||||||
|
"Skyrim - Voices_en0.bsa",
|
||||||
|
"Skyrim - Sounds.bsa",
|
||||||
|
"Skyrim - Interface.bsa",
|
||||||
|
"Skyrim - Animations.bsa",
|
||||||
|
"Skyrim - Shaders.bsa",
|
||||||
|
"Skyrim - Misc.bsa",
|
||||||
|
"E - Meshes.bsa",
|
||||||
|
"E - SE.bsa",
|
||||||
|
"E - Scripts.bsa",
|
||||||
|
"E - Sounds.bsa",
|
||||||
|
"E - Textures1.bsa",
|
||||||
|
"E - Textures2.bsa",
|
||||||
|
"E - Textures3.bsa",
|
||||||
|
"L - Textures.bsa",
|
||||||
|
"L - Voices.bsa"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QStringList EnderalSEDataArchives::archives(const MOBase::IProfile *profile) const
|
||||||
|
{
|
||||||
|
QStringList result;
|
||||||
|
|
||||||
|
QString iniFile = profile->localSettingsEnabled() ? QDir(profile->absolutePath()).absoluteFilePath("skyrim.ini") : m_LocalGameDir.absoluteFilePath("skyrim.ini");
|
||||||
|
result.append(getArchivesFromKey(iniFile, "SResourceArchiveList"));
|
||||||
|
result.append(getArchivesFromKey(iniFile, "SResourceArchiveList2"));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnderalSEDataArchives::writeArchiveList(MOBase::IProfile *profile, const QStringList &before)
|
||||||
|
{
|
||||||
|
QString list = before.join(", ");
|
||||||
|
|
||||||
|
QString iniFile = profile->localSettingsEnabled() ? QDir(profile->absolutePath()).absoluteFilePath("skyrim.ini") : m_LocalGameDir.absoluteFilePath("skyrim.ini");
|
||||||
|
if (list.length() > 255) {
|
||||||
|
int splitIdx = list.lastIndexOf(",", 256);
|
||||||
|
setArchivesToKey(iniFile, "SResourceArchiveList", list.mid(0, splitIdx));
|
||||||
|
setArchivesToKey(iniFile, "SResourceArchiveList2", list.mid(splitIdx + 2));
|
||||||
|
} else {
|
||||||
|
setArchivesToKey(iniFile, "SResourceArchiveList", list);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef ENDERALSEDATAARCHIVES_H
|
||||||
|
#define ENDERALSEDATAARCHIVES_H
|
||||||
|
|
||||||
|
#include "gamebryodataarchives.h"
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
namespace MOBase { class IProfile; }
|
||||||
|
|
||||||
|
|
||||||
|
class EnderalSEDataArchives : public GamebryoDataArchives
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EnderalSEDataArchives(const QDir &myGamesDir);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
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 // _SKYRIMSEDATAARCHIVES_H
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef ENDERALSE_MODATACHECKER_H
|
||||||
|
#define ENDERALSE_MODATACHECKER_H
|
||||||
|
|
||||||
|
#include <gamebryomoddatachecker.h>
|
||||||
|
|
||||||
|
class EnderalSEModDataChecker : public GamebryoModDataChecker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using GamebryoModDataChecker::GamebryoModDataChecker;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const FileNameSet& possibleFolderNames() const override {
|
||||||
|
static FileNameSet result{
|
||||||
|
"fonts", "interface", "menus", "meshes", "music", "scripts", "shaders",
|
||||||
|
"sound", "strings", "textures", "trees", "video", "facegen", "materials",
|
||||||
|
"skse", "distantlod", "asi", "Tools", "MCM", "distantland", "mits",
|
||||||
|
"dllplugins", "CalienteTools", "NetScriptFramework", "shadersfx",
|
||||||
|
"Nemesis_Engine"
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
virtual const FileNameSet& possibleFileExtensions() const override {
|
||||||
|
static FileNameSet result{
|
||||||
|
"esp", "esm", "esl", "bsa", "modgroups"
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SKYRIMSE_MODATACHECKER_H
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef ENDERALSE_MODDATACONTENT_H
|
||||||
|
#define ENDERALSE_MODDATACONTENT_H
|
||||||
|
|
||||||
|
#include <gamebryomoddatacontent.h>
|
||||||
|
#include <ifiletree.h>
|
||||||
|
|
||||||
|
class EnderalSEModDataContent : public GamebryoModDataContent {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EnderalSEModDataContent(GameGamebryo const* gamePlugin) : GamebryoModDataContent(gamePlugin) {
|
||||||
|
// Just need to disable some contents:
|
||||||
|
m_Enabled[CONTENT_SKYPROC] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SKYRIMSE_MODDATACONTENT_H
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
#include "enderalsesavegame.h"
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
EnderalSESaveGame::EnderalSESaveGame(QString const &fileName, GameEnderalSE const *game) :
|
||||||
|
GamebryoSaveGame(fileName, game, true)
|
||||||
|
{
|
||||||
|
FileWrapper file(fileName, "TESV_SAVEGAME"); //10bytes
|
||||||
|
|
||||||
|
unsigned long version;
|
||||||
|
FILETIME ftime;
|
||||||
|
fetchInformationFields(file, version, m_PCName, m_PCLevel, m_PCLocation, m_SaveNumber, ftime);
|
||||||
|
|
||||||
|
//A file time is a 64-bit value that represents the number of 100-nanosecond
|
||||||
|
//intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC).
|
||||||
|
//So we need to convert that to something useful
|
||||||
|
|
||||||
|
//For some reason, the file time is off by about 6 hours.
|
||||||
|
//So we need to subtract those 6 hours from the filetime.
|
||||||
|
_ULARGE_INTEGER time;
|
||||||
|
time.LowPart = ftime.dwLowDateTime;
|
||||||
|
time.HighPart = ftime.dwHighDateTime;
|
||||||
|
time.QuadPart -= 2.16e11;
|
||||||
|
ftime.dwHighDateTime = time.HighPart;
|
||||||
|
ftime.dwLowDateTime = time.LowPart;
|
||||||
|
|
||||||
|
SYSTEMTIME ctime;
|
||||||
|
::FileTimeToSystemTime(&ftime, &ctime);
|
||||||
|
|
||||||
|
setCreationTime(ctime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnderalSESaveGame::fetchInformationFields(
|
||||||
|
FileWrapper& file,
|
||||||
|
unsigned long& version,
|
||||||
|
QString& playerName,
|
||||||
|
unsigned short& playerLevel,
|
||||||
|
QString& playerLocation,
|
||||||
|
unsigned long& saveNumber,
|
||||||
|
FILETIME& creationTime) const
|
||||||
|
{
|
||||||
|
unsigned long headerSize;
|
||||||
|
file.read(headerSize); // header size "TESV_SAVEGAME"
|
||||||
|
file.read(version);
|
||||||
|
file.read(saveNumber);
|
||||||
|
file.read(playerName);
|
||||||
|
|
||||||
|
unsigned long temp;
|
||||||
|
file.read(temp);
|
||||||
|
playerLevel = static_cast<unsigned short>(temp);
|
||||||
|
file.read(playerLocation);
|
||||||
|
|
||||||
|
QString timeOfDay;
|
||||||
|
file.read(timeOfDay);
|
||||||
|
|
||||||
|
QString race;
|
||||||
|
file.read(race); // race name (i.e. BretonRace)
|
||||||
|
|
||||||
|
file.skip<unsigned short>(); // Player gender (0 = male)
|
||||||
|
file.skip<float>(2); // experience gathered, experience required
|
||||||
|
|
||||||
|
file.read(creationTime); //filetime
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<GamebryoSaveGame::DataFields> EnderalSESaveGame::fetchDataFields() const
|
||||||
|
{
|
||||||
|
FileWrapper file(getFilepath(), "TESV_SAVEGAME"); //10bytes
|
||||||
|
|
||||||
|
unsigned long version = 0;
|
||||||
|
{
|
||||||
|
QString dummyName, dummyLocation;
|
||||||
|
unsigned short dummyLevel;
|
||||||
|
unsigned long dummySaveNumber;
|
||||||
|
FILETIME dummyTime;
|
||||||
|
|
||||||
|
fetchInformationFields(file, version, dummyName, dummyLevel,
|
||||||
|
dummyLocation, dummySaveNumber, dummyTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<DataFields> fields = std::make_unique<DataFields>();
|
||||||
|
|
||||||
|
unsigned long width;
|
||||||
|
unsigned long height;
|
||||||
|
file.read(width);
|
||||||
|
file.read(height);
|
||||||
|
|
||||||
|
bool alpha = false;
|
||||||
|
|
||||||
|
// compatibility between LE and SE:
|
||||||
|
// SE has an additional uin16_t for compression
|
||||||
|
// SE uses an alpha channel, whereas LE does not
|
||||||
|
if (version == 12) {
|
||||||
|
uint16_t compressionType;
|
||||||
|
file.read(compressionType);
|
||||||
|
file.setCompressionType(compressionType);
|
||||||
|
alpha = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fields->Screenshot = file.readImage(width, height, 320, alpha);
|
||||||
|
|
||||||
|
file.openCompressedData();
|
||||||
|
|
||||||
|
uint8_t saveGameVersion = file.readChar();
|
||||||
|
uint8_t pluginInfoSize = file.readChar();
|
||||||
|
uint16_t other = file.readShort(); //Unknown
|
||||||
|
|
||||||
|
fields->Plugins = file.readPlugins(1); // Just empty data
|
||||||
|
|
||||||
|
if (saveGameVersion >= 78) {
|
||||||
|
fields->LightPlugins = file.readLightPlugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
file.closeCompressedData();
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef ENDERALSESAVEGAME_H
|
||||||
|
#define ENDERALSESAVEGAME_H
|
||||||
|
|
||||||
|
#include "gamebryosavegame.h"
|
||||||
|
#include "gameenderalse.h"
|
||||||
|
|
||||||
|
namespace MOBase { class IPluginGame; }
|
||||||
|
|
||||||
|
class EnderalSESaveGame : public GamebryoSaveGame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EnderalSESaveGame(QString const &fileName, GameEnderalSE const *game);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Fetch easy-to-access information.
|
||||||
|
void fetchInformationFields(FileWrapper& wrapper,
|
||||||
|
unsigned long& version,
|
||||||
|
QString& playerName,
|
||||||
|
unsigned short& playerLevel,
|
||||||
|
QString& playerLocation,
|
||||||
|
unsigned long& saveNumber,
|
||||||
|
FILETIME& creationTime) const;
|
||||||
|
|
||||||
|
std::unique_ptr<DataFields> fetchDataFields() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _SKYRIMSESAVEGAME_H
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include "enderalsescriptextender.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
EnderalSEScriptExtender::EnderalSEScriptExtender(GameGamebryo const *game) :
|
||||||
|
GamebryoScriptExtender(game)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EnderalSEScriptExtender::BinaryName() const
|
||||||
|
{
|
||||||
|
return "skse64_loader.exe";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EnderalSEScriptExtender::PluginPath() const
|
||||||
|
{
|
||||||
|
return "skse/plugins";
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef ENDERALSESCRIPTEXTENDER_H
|
||||||
|
#define ENDERALESCRIPTEXTENDER_H
|
||||||
|
|
||||||
|
#include "gamebryoscriptextender.h"
|
||||||
|
|
||||||
|
class GameGamebryo;
|
||||||
|
|
||||||
|
class EnderalSEScriptExtender : public GamebryoScriptExtender
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EnderalSEScriptExtender(GameGamebryo const *game);
|
||||||
|
|
||||||
|
virtual QString BinaryName() const override;
|
||||||
|
virtual QString PluginPath() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _SKYRIMSESCRIPTEXTENDER_H
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#include "enderalseunmanagedmods.h"
|
||||||
|
|
||||||
|
|
||||||
|
EnderalSEUnmangedMods::EnderalSEUnmangedMods(const GameGamebryo *game)
|
||||||
|
: GamebryoUnmangedMods(game)
|
||||||
|
{}
|
||||||
|
|
||||||
|
EnderalSEUnmangedMods::~EnderalSEUnmangedMods()
|
||||||
|
{}
|
||||||
|
|
||||||
|
QStringList EnderalSEUnmangedMods::mods(bool onlyOfficial) const {
|
||||||
|
QStringList result;
|
||||||
|
|
||||||
|
QStringList pluginList = game()->primaryPlugins();
|
||||||
|
QStringList otherPlugins = game()->DLCPlugins();
|
||||||
|
otherPlugins.append(game()->CCPlugins());
|
||||||
|
for (QString plugin : otherPlugins) {
|
||||||
|
pluginList.removeAll(plugin);
|
||||||
|
}
|
||||||
|
QDir dataDir(game()->dataDirectory());
|
||||||
|
for (const QString &fileName : dataDir.entryList({ "*.esp", "*.esl", "*.esm" })) {
|
||||||
|
if (!pluginList.contains(fileName, Qt::CaseInsensitive)) {
|
||||||
|
if (!onlyOfficial || pluginList.contains(fileName, Qt::CaseInsensitive)) {
|
||||||
|
QFileInfo file(fileName);
|
||||||
|
result.append(file.baseName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef ENDERALSEUNMANAGEDMODS_H
|
||||||
|
#define ENDERALSEUNMANAGEDMODS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "gamebryounmanagedmods.h"
|
||||||
|
#include <gamegamebryo.h>
|
||||||
|
|
||||||
|
|
||||||
|
class EnderalSEUnmangedMods : public GamebryoUnmangedMods {
|
||||||
|
public:
|
||||||
|
EnderalSEUnmangedMods(const GameGamebryo *game);
|
||||||
|
~EnderalSEUnmangedMods();
|
||||||
|
|
||||||
|
virtual QStringList mods(bool onlyOfficial) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _SKYRIMSEUNMANAGEDMODS_H
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="en_US">
|
||||||
|
<context>
|
||||||
|
<name>GameEnderalSE</name>
|
||||||
|
<message>
|
||||||
|
<location filename="gameenderalse.cpp" line="135"/>
|
||||||
|
<source>Enderal Special Edition Support Plugin</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="gameenderalse.cpp" line="145"/>
|
||||||
|
<source>Adds support for the game Enderal Special Edition.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
@@ -0,0 +1,281 @@
|
|||||||
|
#include "gameenderalse.h"
|
||||||
|
|
||||||
|
#include "enderalsebsainvalidation.h"
|
||||||
|
#include "enderalsedataarchives.h"
|
||||||
|
#include "enderalsescriptextender.h"
|
||||||
|
#include "enderalseunmanagedmods.h"
|
||||||
|
#include "enderalsemoddatachecker.h"
|
||||||
|
#include "enderalsemoddatacontent.h"
|
||||||
|
#include "enderalsesavegame.h"
|
||||||
|
|
||||||
|
#include <pluginsetting.h>
|
||||||
|
#include <executableinfo.h>
|
||||||
|
#include <gamebryosavegameinfo.h>
|
||||||
|
#include <gamebryolocalsavegames.h>
|
||||||
|
#include <creationgameplugins.h>
|
||||||
|
#include "versioninfo.h"
|
||||||
|
#include <utility.h>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QList>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "scopeguard.h"
|
||||||
|
|
||||||
|
using namespace MOBase;
|
||||||
|
|
||||||
|
GameEnderalSE::GameEnderalSE()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameEnderalSE::setGamePath(const QString &path)
|
||||||
|
{
|
||||||
|
m_GamePath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir GameEnderalSE::documentsDirectory() const
|
||||||
|
{
|
||||||
|
return m_MyGamesPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::identifyGamePath() const
|
||||||
|
{
|
||||||
|
QString path = "Software\\Bethesda Softworks\\Skyrim Special Edition";
|
||||||
|
return findInRegistry(HKEY_LOCAL_MACHINE, path.toStdWString().c_str(), L"Installed Path");
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir GameEnderalSE::savesDirectory() const
|
||||||
|
{
|
||||||
|
return QDir(m_MyGamesPath + "/Saves");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::myGamesPath() const
|
||||||
|
{
|
||||||
|
return m_MyGamesPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameEnderalSE::isInstalled() const
|
||||||
|
{
|
||||||
|
return !m_GamePath.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameEnderalSE::detectGame()
|
||||||
|
{
|
||||||
|
m_GamePath = identifyGamePath();
|
||||||
|
m_MyGamesPath = determineMyGamesPath("Skyrim Special Edition");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GameEnderalSE::init(IOrganizer *moInfo)
|
||||||
|
{
|
||||||
|
if (!GameGamebryo::init(moInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerFeature<ScriptExtender>(new EnderalSEScriptExtender(this));
|
||||||
|
registerFeature<DataArchives>(new EnderalSEDataArchives(myGamesPath()));
|
||||||
|
registerFeature<BSAInvalidation>(new EnderalSEBSAInvalidation(feature<DataArchives>(), this));
|
||||||
|
registerFeature<LocalSavegames>(new GamebryoLocalSavegames(myGamesPath(), "skyrimcustom.ini"));
|
||||||
|
registerFeature<ModDataChecker>(new EnderalSEModDataChecker(this));
|
||||||
|
registerFeature<ModDataContent>(new EnderalSEModDataContent(this));
|
||||||
|
registerFeature<SaveGameInfo>(new GamebryoSaveGameInfo(this));
|
||||||
|
registerFeature<GamePlugins>(new CreationGamePlugins(moInfo));
|
||||||
|
registerFeature<UnmanagedMods>(new EnderalSEUnmangedMods(this));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::gameName() const
|
||||||
|
{
|
||||||
|
return "Enderal Special Edition";
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ExecutableInfo> GameEnderalSE::executables() const
|
||||||
|
{
|
||||||
|
return QList<ExecutableInfo>()
|
||||||
|
<< ExecutableInfo("Enderal Special Edition (SKSE)", findInGameFolder(feature<ScriptExtender>()->loaderName()))
|
||||||
|
// << ExecutableInfo("Enderal Special Edition Launcher", findInGameFolder(getLauncherName()))
|
||||||
|
// << ExecutableInfo("LOOT", getLootPath()).withArgument("--game=\"Skyrim Special Edition\"")
|
||||||
|
<< ExecutableInfo("Creation Kit", findInGameFolder("CreationKit.exe"))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ExecutableForcedLoadSetting> GameEnderalSE::executableForcedLoads() const
|
||||||
|
{
|
||||||
|
return QList<ExecutableForcedLoadSetting>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::binaryName() const
|
||||||
|
{
|
||||||
|
return "skse64_loader.exe";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::getLauncherName() const
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QFileInfo GameEnderalSE::findInGameFolder(const QString &relativePath) const
|
||||||
|
{
|
||||||
|
return QFileInfo(m_GamePath + "/" + relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::name() const
|
||||||
|
{
|
||||||
|
return "Enderal Special Edition Support Plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::localizedName() const
|
||||||
|
{
|
||||||
|
return tr("Enderal Special Edition Support Plugin");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::author() const
|
||||||
|
{
|
||||||
|
return "Holt59 & Archost & ZachHaber";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::description() const
|
||||||
|
{
|
||||||
|
return tr("Adds support for the game Enderal Special Edition.");
|
||||||
|
}
|
||||||
|
|
||||||
|
MOBase::VersionInfo GameEnderalSE::version() const
|
||||||
|
{
|
||||||
|
return VersionInfo(1, 0, 0, VersionInfo::RELEASE_BETA);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PluginSetting> GameEnderalSE::settings() const
|
||||||
|
{
|
||||||
|
return QList<PluginSetting>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameEnderalSE::initializeProfile(const QDir &path, ProfileSettings settings) const
|
||||||
|
{
|
||||||
|
if (settings.testFlag(IPluginGame::MODS)) {
|
||||||
|
copyToProfile(localAppFolder() + "/Enderal Special Edition", path, "plugins.txt");
|
||||||
|
copyToProfile(localAppFolder() + "/Enderal Special Edition", path, "loadorder.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.testFlag(IPluginGame::CONFIGURATION)) {
|
||||||
|
if (settings.testFlag(IPluginGame::PREFER_DEFAULTS)
|
||||||
|
|| !QFileInfo(myGamesPath() + "/skyrim.ini").exists()) {
|
||||||
|
copyToProfile(gameDirectory().absolutePath(), path, "skyrim_default.ini", "skyrim.ini");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
copyToProfile(myGamesPath(), path, "skyrim.ini");
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToProfile(myGamesPath(), path, "skyrimprefs.ini");
|
||||||
|
copyToProfile(myGamesPath(), path, "skyrimcustom.ini");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::savegameExtension() const
|
||||||
|
{
|
||||||
|
return "ess";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::savegameSEExtension() const
|
||||||
|
{
|
||||||
|
return "skse";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<const GamebryoSaveGame> GameEnderalSE::makeSaveGame(QString filePath) const
|
||||||
|
{
|
||||||
|
return std::make_shared<const EnderalSESaveGame>(filePath, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::steamAPPId() const
|
||||||
|
{
|
||||||
|
return "976620";
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList GameEnderalSE::primaryPlugins() const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
"skyrim.esm",
|
||||||
|
"Enderal - Forgotten Stories.esm",
|
||||||
|
"update.esm"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList GameEnderalSE::gameVariants() const
|
||||||
|
{
|
||||||
|
return{ "Regular" };
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::gameShortName() const
|
||||||
|
{
|
||||||
|
return "EnderalSE";
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList GameEnderalSE::validShortNames() const
|
||||||
|
{
|
||||||
|
return { "Skyrim", "SkyrimSE", "Enderal" };
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GameEnderalSE::gameNexusName() const
|
||||||
|
{
|
||||||
|
return "enderalspecialedition";
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList GameEnderalSE::iniFiles() const
|
||||||
|
{
|
||||||
|
return{ "skyrim.ini", "skyrimprefs.ini", "skyrimcustom.ini" };
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList GameEnderalSE::DLCPlugins() const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList GameEnderalSE::CCPlugins() const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
MOBase::IPluginGame::SortMechanism GameEnderalSE::sortMechanism() const
|
||||||
|
{
|
||||||
|
return SortMechanism::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPluginGame::LoadOrderMechanism GameEnderalSE::loadOrderMechanism() const
|
||||||
|
{
|
||||||
|
return IPluginGame::LoadOrderMechanism::PluginsTxt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameEnderalSE::nexusModOrganizerID() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameEnderalSE::nexusGameID() const
|
||||||
|
{
|
||||||
|
return 3685;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir GameEnderalSE::gameDirectory() const
|
||||||
|
{
|
||||||
|
return QDir(m_GamePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not to delete all the spaces...
|
||||||
|
MappingType GameEnderalSE::mappings() const
|
||||||
|
{
|
||||||
|
MappingType result;
|
||||||
|
|
||||||
|
for (const QString &profileFile : { "plugins.txt", "loadorder.txt" }) {
|
||||||
|
result.push_back({ m_Organizer->profilePath() + "/" + profileFile,
|
||||||
|
localAppFolder() + "/" + gameName() + "/" + profileFile,
|
||||||
|
false });
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#ifndef GAMEENDERALSE_H
|
||||||
|
#define GAMEENDERALSE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "gamegamebryo.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
class GameEnderalSE : public GameGamebryo
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PLUGIN_METADATA(IID "com.soundcontactstudio.GameEnderalSE" FILE "gameenderalse.json")
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
GameEnderalSE();
|
||||||
|
|
||||||
|
virtual bool init(MOBase::IOrganizer *moInfo) override;
|
||||||
|
|
||||||
|
public: // IPluginGame interface
|
||||||
|
|
||||||
|
virtual void detectGame() override;
|
||||||
|
virtual QString gameName() const override;
|
||||||
|
virtual QList<MOBase::ExecutableInfo> executables() const override;
|
||||||
|
virtual QList<MOBase::ExecutableForcedLoadSetting> executableForcedLoads() const override;
|
||||||
|
virtual void initializeProfile(const QDir &path, ProfileSettings settings) const override;
|
||||||
|
virtual QString steamAPPId() const override;
|
||||||
|
virtual QStringList primaryPlugins() const override;
|
||||||
|
virtual QStringList gameVariants() const override;
|
||||||
|
virtual QString binaryName() const override;
|
||||||
|
virtual QString getLauncherName() const override;
|
||||||
|
virtual QString gameShortName() const override;
|
||||||
|
virtual QString gameNexusName() const override;
|
||||||
|
virtual QStringList validShortNames() const override;
|
||||||
|
virtual QStringList iniFiles() const override;
|
||||||
|
virtual QStringList DLCPlugins() const override;
|
||||||
|
virtual QStringList CCPlugins() const override;
|
||||||
|
SortMechanism sortMechanism() const override;
|
||||||
|
virtual LoadOrderMechanism loadOrderMechanism() const override;
|
||||||
|
virtual int nexusModOrganizerID() const override;
|
||||||
|
virtual int nexusGameID() const override;
|
||||||
|
|
||||||
|
virtual bool isInstalled() const override;
|
||||||
|
virtual void setGamePath(const QString &path) override;
|
||||||
|
virtual QDir gameDirectory() 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<MOBase::PluginSetting> settings() const override;
|
||||||
|
virtual MappingType mappings() const override;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::shared_ptr<const GamebryoSaveGame> makeSaveGame(QString filePath) const override;
|
||||||
|
QString savegameExtension() const override;
|
||||||
|
QString savegameSEExtension() const override;
|
||||||
|
|
||||||
|
QDir documentsDirectory() const;
|
||||||
|
QDir savesDirectory() const;
|
||||||
|
QFileInfo findInGameFolder(const QString &relativePath) const;
|
||||||
|
QString myGamesPath() const;
|
||||||
|
|
||||||
|
virtual QString identifyGamePath() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _GAMESKYRIMSE_H
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
Reference in New Issue
Block a user