Files
Commonwealth-Online-Public/plugin/lib/commonlibf4/include/RE/T/TESDataHandler.h
T
2026-05-30 18:33:24 +12:00

201 lines
7.1 KiB
C++

#pragma once
#include "RE/B/BSPointerHandle.h"
#include "RE/B/BSSimpleList.h"
#include "RE/B/BSTArray.h"
#include "RE/B/BSTEvent.h"
#include "RE/B/BSTSingleton.h"
#include "RE/E/ENUM_FORM_ID.h"
#include "RE/N/NiTArray.h"
#include "RE/N/NiTList.h"
#include "RE/T/TESFileCollection.h"
#include "RE/T/TESForm.h"
namespace RE
{
class BGSHotloadCompletedEvent;
class NEW_REFR_DATA;
class TESFile;
class TESObjectList;
class TESRegionDataManager;
class TESRegionList;
class TESDataHandler :
public BSTEventSource<BGSHotloadCompletedEvent>, // 0000
public BSTSingletonSDM<TESDataHandler> // 0058
{
public:
[[nodiscard]] static TESDataHandler* GetSingleton()
{
static REL::Relocation<TESDataHandler**> singleton{ ID::TESDataHandler::Singleton };
return *singleton;
}
[[nodiscard]] bool AddFormToDataHandler(TESForm* a_form)
{
using func_t = decltype(&TESDataHandler::AddFormToDataHandler);
static REL::Relocation<func_t> func{ ID::TESDataHandler::AddFormToDataHandler };
return func(this, a_form);
}
[[nodiscard]] bool CheckModsLoaded(bool a_everModded)
{
using func_t = decltype(&TESDataHandler::CheckModsLoaded);
static REL::Relocation<func_t> func{ ID::TESDataHandler::CheckModsLoaded };
return func(this, a_everModded);
}
[[nodiscard]] ObjectRefHandle CreateReferenceAtLocation(NEW_REFR_DATA& a_data)
{
using func_t = decltype(&TESDataHandler::CreateReferenceAtLocation);
static REL::Relocation<func_t> func{ ID::TESDataHandler::CreateReferenceAtLocation };
return func(this, a_data);
}
template <class T>
[[nodiscard]] BSTArray<T*>& GetFormArray() noexcept //
requires(std::derived_from<T, TESForm> &&
!std::is_pointer_v<T> &&
!std::is_reference_v<T>)
{
assert(T::FORM_ID < ENUM_FORM_ID::kTotal);
return reinterpret_cast<BSTArray<T*>&>(formArrays[std::to_underlying(T::FORM_ID)]);
}
TESFormID LookupFormID(TESFormID a_rawFormID, std::string_view a_modName)
{
auto file = LookupModByName(a_modName);
if (!file || file->compileIndex == 0xFF) {
return 0;
}
TESFormID formID = file->compileIndex << 24;
formID += file->smallFileCompileIndex << 12;
formID += a_rawFormID;
return formID;
}
TESForm* LookupForm(TESFormID a_rawFormID, std::string_view a_modName)
{
auto formID = LookupFormID(a_rawFormID, a_modName);
return formID != 0 ? TESForm::GetFormByID(formID) : nullptr;
}
template <class T>
T* LookupForm(TESFormID a_rawFormID, std::string_view a_modName)
{
auto form = LookupForm(a_rawFormID, a_modName);
if (!form) {
return nullptr;
}
return form->Is(T::FORM_ID) ? form->As<T>() : nullptr;
}
const TESFile* LookupModByName(std::string_view a_modName)
{
for (auto& file : files) {
if (a_modName.size() == strlen(file->filename) &&
_strnicmp(file->filename, a_modName.data(), a_modName.size()) == 0) {
return file;
}
}
return nullptr;
}
std::optional<std::uint8_t> GetModIndex(std::string_view a_modName)
{
auto mod = LookupModByName(a_modName);
return mod ? std::make_optional(mod->compileIndex) : std::nullopt;
}
const TESFile* LookupLoadedModByName(std::string_view a_modName)
{
for (auto& file : compiledFileCollection.files) {
if (a_modName.size() == strlen(file->filename) &&
_strnicmp(file->filename, a_modName.data(), a_modName.size()) == 0) {
return file;
}
}
return nullptr;
}
const TESFile* LookupLoadedModByIndex(std::uint8_t a_index)
{
for (auto& file : compiledFileCollection.files) {
if (file->compileIndex == a_index) {
return file;
}
}
return nullptr;
}
std::optional<std::uint8_t> GetLoadedModIndex(std::string_view a_modName)
{
auto mod = LookupLoadedModByName(a_modName);
return mod ? std::make_optional(mod->compileIndex) : std::nullopt;
}
const TESFile* LookupLoadedLightModByName(std::string_view a_modName)
{
for (auto& smallFile : compiledFileCollection.smallFiles) {
if (a_modName.size() == strlen(smallFile->filename) &&
_strnicmp(smallFile->filename, a_modName.data(), a_modName.size()) == 0) {
return smallFile;
}
}
return nullptr;
}
const TESFile* LookupLoadedLightModByIndex(std::uint16_t a_index)
{
for (auto& smallFile : compiledFileCollection.smallFiles) {
if (smallFile->smallFileCompileIndex == a_index) {
return smallFile;
}
}
return nullptr;
}
std::optional<std::uint16_t> GetLoadedLightModIndex(std::string_view a_modName)
{
auto mod = LookupLoadedLightModByName(a_modName);
return mod ? std::make_optional(mod->smallFileCompileIndex) : std::nullopt;
}
bool IsFormIDInuse(TESFormID a_formID)
{
using func_t = decltype(&TESDataHandler::IsFormIDInuse);
static REL::Relocation<func_t> func{ ID::TESDataHandler::IsFormIDInuse };
return func(this, a_formID);
}
// members
TESObjectList* objectList; // 0060
BSTArray<TESForm*> formArrays[std::to_underlying(ENUM_FORM_ID::kTotal)]; // 0068
TESRegionList* regionList; // 0F50
NiTPrimitiveArray<TESObjectCELL*> interiorCells; // 0F58
NiTPrimitiveArray<BGSAddonNode*> addonNodes; // 0F70
NiTList<TESForm*> badForms; // 0F88
std::uint32_t nextID; // 0FA0
TESFile* activeFile; // 0FA8
BSSimpleList<TESFile*> files; // 0FB0
TESFileCollection compiledFileCollection; // 0FC0
BSTArray<std::uint32_t> releasedFormIDArray; // 0FF0
bool masterSave; // 1008
bool blockSave; // 1009
bool saveLoadGame; // 100A
bool autoSaving; // 100B
bool exportingPlugin; // 100C
bool clearingData; // 100D
bool hasDesiredFiles; // 100E
bool checkingModels; // 100F
bool loadingFiles; // 1010
bool dontRemoveIDs; // 1011
char gameSettingsLoadState; // 1012
TESRegionDataManager* regionDataManager; // 1018
};
static_assert(sizeof(TESDataHandler) == 0x1020);
}