Added the exclusion keyword ETR_NotArtifact, improved artifact filtering
This commit is contained in:
parent
0c22f0b8bd
commit
81b174e028
Binary file not shown.
@ -3,3 +3,6 @@ Keyword = ETR_ExtraArtifact|Misc Item|0x1F6D4,0x200B6,0x200BA,0x20949,0x59654,0x
|
||||
|
||||
; Treasure Maps
|
||||
Keyword = ETR_ExtraArtifact|Book|0xEF07A,0xF33CD,0xF33CE,0xF33CF,0xF33D0,0xF33D1,0xF33D2,0xF33D3,0xF33D4,0xF33D5,0xF33E0
|
||||
|
||||
; Soul Gem Fragments
|
||||
Keyword = ETR_NotArtifact|Misc Item|0x67181,0x67182,0x67183,0x67184,0x67185
|
||||
|
Binary file not shown.
Binary file not shown.
@ -60,7 +60,7 @@ DisableFormat: 'false'
|
||||
FixNamespaceComments: 'false'
|
||||
IncludeBlocks: Preserve
|
||||
IndentCaseBlocks: 'true'
|
||||
IndentCaseLabels: 'false'
|
||||
IndentCaseLabels: 'true'
|
||||
IndentExternBlock: Indent
|
||||
IndentGotoLabels: 'false'
|
||||
IndentPPDirectives: AfterHash
|
||||
|
@ -18,15 +18,18 @@ namespace ArtifactTracker
|
||||
std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap;
|
||||
RE::TESObjectREFR* g_cellStorage;
|
||||
|
||||
void Init()
|
||||
bool Init()
|
||||
{
|
||||
g_bLoaded = false;
|
||||
if (g_bLoaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto dataHandler = RE::TESDataHandler::GetSingleton();
|
||||
|
||||
if (!dataHandler) {
|
||||
SKSE::log::error("Failed to call RE::TESDataHandler::GetSingleton()");
|
||||
return;
|
||||
SKSE::log::error("Unable to call RE::TESDataHandler::GetSingleton()");
|
||||
RE::DebugMessageBox("Unable to initialize Artifact Tracker.");
|
||||
return false;
|
||||
}
|
||||
|
||||
g_cellContainer = dataHandler->LookupForm(0x800, "Artifact Tracker.esp")->As<RE::TESBoundObject>(); // ETR_CellStorageContainer
|
||||
@ -40,47 +43,74 @@ namespace ArtifactTracker
|
||||
|
||||
const auto recipeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xF5CB0, "Skyrim.esm"); // VendorItemRecipe
|
||||
const auto excludeKeywords = dataHandler->LookupForm<RE::BGSListForm>(0x801, "Artifact Tracker.esp"); // ETR_ExcludeMiscKeywords
|
||||
const auto dummyKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xF3E6C, "Skyrim.esm"); // Dummy
|
||||
const auto extraArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xDE3FD3, "Update.esm"); // ETR_ExtraArtifact
|
||||
const auto notArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xDE3FD4, "Update.esm"); // ETR_NotArtifact
|
||||
|
||||
if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_homeKeyword || !recipeKeyword || !excludeKeywords) {
|
||||
SKSE::log::warn("Failed to load data from Artifact Tracker.esp");
|
||||
RE::DebugMessageBox("Failed to load data from Artifact Tracker.esp, the mod is disabled.");
|
||||
return;
|
||||
if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_homeKeyword || !recipeKeyword || !excludeKeywords || !dummyKeyword || !extraArtifactKeyword || !notArtifactKeyword) {
|
||||
SKSE::log::warn("Unable to load data from Artifact Tracker.esp");
|
||||
RE::DebugMessageBox("Unable to load data from Artifact Tracker.esp, the mod is disabled.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preloading item lists
|
||||
|
||||
g_artifactFormTypes.insert(RE::FormType::Weapon);
|
||||
for (const auto& form : dataHandler->GetFormArray(RE::FormType::Weapon)) {
|
||||
if (form->GetPlayable()) {
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectWEAP>()) {
|
||||
if (form->GetPlayable() && !form->IsBound() && !form->weaponData.flags.all(RE::TESObjectWEAP::Data::Flag::kCantDrop) && !form->IsDeleted() && !form->HasKeyword(dummyKeyword) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
g_artifactMap.erase(0x1F4); // Unarmed
|
||||
|
||||
g_artifactFormTypes.insert(RE::FormType::Armor);
|
||||
for (const auto& form : dataHandler->GetFormArray(RE::FormType::Armor)) {
|
||||
if (form->GetPlayable()) {
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectARMO>()) {
|
||||
if (form->GetPlayable() && !form->IsDeleted() && !form->HasKeyword(dummyKeyword) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
g_artifactMap.erase(0xD64); // SkinNaked
|
||||
g_artifactMap.erase(0x69CE3); // SkinNakedBeast
|
||||
g_artifactMap.erase(0xCDD86); // SkinNakedWerewolfBeast
|
||||
|
||||
g_artifactFormTypes.insert(RE::FormType::Book);
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectBOOK>()) {
|
||||
if (form && !form->TeachesSpell() && (form->HasKeyword(recipeKeyword) || BookCheck::IsBook(form))) {
|
||||
if (!form->TeachesSpell() && !form->IsDeleted() && (form->HasKeyword(recipeKeyword) || form->HasKeyword(extraArtifactKeyword) || BookCheck::IsBook(form)) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
|
||||
g_artifactFormTypes.insert(RE::FormType::Misc);
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectMISC>()) {
|
||||
if (form->GetPlayable() && !form->HasKeywordInList(excludeKeywords, false)) {
|
||||
if (form->GetPlayable() && !form->IsDeleted() && (form->HasKeyword(extraArtifactKeyword) || !form->HasKeywordInList(excludeKeywords, false)) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
g_artifactMap.erase(0xA); // Lockpick
|
||||
g_artifactMap.erase(0xF); // Gold
|
||||
|
||||
// Fishing CC
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::AlchemyItem>()) {
|
||||
if (!form->IsDeleted() && form->HasKeyword(extraArtifactKeyword) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
g_artifactFormTypes.insert(RE::FormType::AlchemyItem);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::IngredientItem>()) {
|
||||
if (!form->IsDeleted() && form->HasKeyword(extraArtifactKeyword) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
g_artifactFormTypes.insert(RE::FormType::Ingredient);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESSoulGem>()) {
|
||||
if (!form->IsDeleted() && form->HasKeyword(extraArtifactKeyword) && !form->HasKeyword(notArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
g_artifactFormTypes.insert(RE::FormType::SoulGem);
|
||||
}
|
||||
}
|
||||
|
||||
// Fishing CC (remove, when KID adds formlist support)
|
||||
const auto plaqueFish = dataHandler->LookupForm<RE::BGSListForm>(0xF4B, "ccBGSSSE001-Fish.esm"); // ccBGSSSE001_FishPlaqueGiftFilterList
|
||||
if (plaqueFish) {
|
||||
plaqueFish->ForEachForm([&](RE::TESForm& a_form) {
|
||||
@ -93,58 +123,15 @@ namespace ArtifactTracker
|
||||
EventListener::Install();
|
||||
|
||||
g_bLoaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnKeywordDistribution()
|
||||
{
|
||||
const auto dataHandler = RE::TESDataHandler::GetSingleton();
|
||||
const auto extraArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xDE3FD3, "Update.esm"); // ETR_ExtraArtifact
|
||||
|
||||
if (!dataHandler || !extraArtifactKeyword) {
|
||||
SKSE::log::error("Unable to load ETR_ExtraArtifact in OnKeywordDistribution");
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectBOOK>()) {
|
||||
if (form->HasKeyword(extraArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectMISC>()) {
|
||||
if (form->GetPlayable() && form->HasKeyword(extraArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::AlchemyItem>()) {
|
||||
if (form->HasKeyword(extraArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
g_artifactFormTypes.insert(RE::FormType::AlchemyItem);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::IngredientItem>()) {
|
||||
if (form->HasKeyword(extraArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
g_artifactFormTypes.insert(RE::FormType::Ingredient);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& form : dataHandler->GetFormArray<RE::TESSoulGem>()) {
|
||||
if (form->HasKeyword(extraArtifactKeyword)) {
|
||||
g_artifactMap[form->formID] = form;
|
||||
g_artifactFormTypes.insert(RE::FormType::SoulGem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsArtifact(RE::TESForm* a_form)
|
||||
bool IsArtifact(const RE::TESForm* a_form)
|
||||
{
|
||||
return a_form && g_artifactFormTypes.contains(a_form->GetFormType()) && g_artifactMap.contains(a_form->formID);
|
||||
}
|
||||
|
||||
RE::TESForm* GetArtifactByID(RE::FormID a_formID)
|
||||
RE::TESForm* GetArtifactByID(const RE::FormID a_formID)
|
||||
{
|
||||
if (!a_formID) {
|
||||
return nullptr;
|
||||
@ -169,7 +156,7 @@ namespace ArtifactTracker
|
||||
});
|
||||
}
|
||||
|
||||
void SetContainerMode(bool bOpening)
|
||||
void SetContainerMode(const bool bOpening)
|
||||
{
|
||||
if (bOpening) {
|
||||
|
||||
@ -229,7 +216,7 @@ namespace ArtifactTracker
|
||||
return baseObj->formType == RE::FormType::Container || (baseObj->formType == RE::FormType::NPC && !a_ref->IsDisabled() && baseObj->As<RE::TESNPC>()->GetRace()->formID == 0x0010760A);
|
||||
}
|
||||
|
||||
void OnCellEnter(RE::FormID a_formID)
|
||||
void OnCellEnter(const RE::FormID a_formID)
|
||||
{
|
||||
RE::TESObjectCELL* cell = RE::TESForm::LookupByID<RE::TESObjectCELL>(a_formID);
|
||||
RE::BGSLocation* location = cell ? cell->GetLocation() : nullptr;
|
||||
@ -260,7 +247,7 @@ namespace ArtifactTracker
|
||||
}
|
||||
}
|
||||
|
||||
void OnCellEnter(RE::BGSLocation* location, RE::TESObjectCELL* cell)
|
||||
void OnCellEnter(const RE::BGSLocation* location, const RE::TESObjectCELL* cell)
|
||||
{
|
||||
if (!location || !cell->IsInteriorCell() || cell != RE::PlayerCharacter::GetSingleton()->GetParentCell() || !location->HasKeyword(g_homeKeyword)) {
|
||||
ToggleHomeMode(nullptr);
|
||||
@ -303,7 +290,7 @@ namespace ArtifactTracker
|
||||
}
|
||||
}
|
||||
|
||||
void SyncCellStorage(RE::FormID a_ignoreRef)
|
||||
void SyncCellStorage(const RE::TESObjectREFR* a_ignoreRef)
|
||||
{
|
||||
if (!IsHome()) {
|
||||
#ifdef _DEBUG
|
||||
@ -322,7 +309,7 @@ namespace ArtifactTracker
|
||||
const auto inv = g_cellStorage->GetInventory();
|
||||
|
||||
for (const auto& a_ref : cell->references) {
|
||||
if (a_ignoreRef == a_ref->formID) {
|
||||
if (a_ignoreRef && a_ignoreRef->formID == a_ref->formID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -428,7 +415,7 @@ namespace ArtifactTracker
|
||||
if (!g_bHomeContainer) {
|
||||
const auto container = RE::TESForm::LookupByID<RE::TESObjectREFR>(a_event->oldContainer);
|
||||
if (container && !GetItemCount(container, form)) {
|
||||
SyncCellStorage(container->formID);
|
||||
SyncCellStorage(container);
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,7 +562,7 @@ namespace ArtifactTracker
|
||||
if (g_cellStorage && IsInSameCell(container)) { // deleted from container at home
|
||||
|
||||
if (!GetItemCount(container, form)) {
|
||||
SyncCellStorage(container->formID);
|
||||
SyncCellStorage(container);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,25 +15,23 @@ namespace ArtifactTracker
|
||||
extern std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap;
|
||||
extern RE::TESObjectREFR* g_cellStorage;
|
||||
|
||||
void Init();
|
||||
bool Init();
|
||||
|
||||
void OnKeywordDistribution();
|
||||
bool IsArtifact(const RE::TESForm* a_item);
|
||||
|
||||
bool IsArtifact(RE::TESForm* a_item);
|
||||
|
||||
RE::TESForm* GetArtifactByID(RE::FormID a_formID);
|
||||
RE::TESForm* GetArtifactByID(const RE::FormID a_formID);
|
||||
|
||||
bool IsHome();
|
||||
|
||||
void OnGameLoad();
|
||||
|
||||
void SetContainerMode(bool bOpening);
|
||||
void SetContainerMode(const bool bOpening);
|
||||
|
||||
void OnCellEnter(RE::FormID a_formID);
|
||||
void OnCellEnter(const RE::FormID a_formID);
|
||||
|
||||
void OnCellEnter(RE::BGSLocation* location, RE::TESObjectCELL* cell);
|
||||
void OnCellEnter(const RE::BGSLocation* location, const RE::TESObjectCELL* cell);
|
||||
|
||||
void SyncCellStorage(RE::FormID a_ignoreRef = NULL);
|
||||
void SyncCellStorage(const RE::TESObjectREFR* a_ignoreRef = nullptr);
|
||||
|
||||
void OnContainerChanged(const RE::TESContainerChangedEvent* a_event, RE::TESForm* form);
|
||||
|
||||
|
@ -20,7 +20,7 @@ auto EventListener::ProcessEvent(
|
||||
{
|
||||
if (a_event->eventName == "KID_KeywordDistributionDone") {
|
||||
SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton());
|
||||
ArtifactTracker::OnKeywordDistribution();
|
||||
ArtifactTracker::Init();
|
||||
}
|
||||
|
||||
return RE::BSEventNotifyControl::kContinue;
|
||||
|
@ -29,14 +29,13 @@ namespace {
|
||||
void InitializeMessaging()
|
||||
{
|
||||
GetMessagingInterface()->RegisterListener([](MessagingInterface::Message* message) {
|
||||
|
||||
if (message->type == MessagingInterface::kPostPostLoad) {
|
||||
if (message->type == MessagingInterface::kPostLoad) {
|
||||
SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton());
|
||||
} else if (message->type == MessagingInterface::kDataLoaded) {
|
||||
ArtifactTracker::Init();
|
||||
} else if (message->type == MessagingInterface::kPostLoadGame) {
|
||||
} else if (message->type == MessagingInterface::kNewGame || message->type == MessagingInterface::kPreLoadGame) {
|
||||
SKSE::GetModCallbackEventSource()->RemoveEventSink(EventListener::GetSingleton());
|
||||
ArtifactTracker::OnGameLoad();
|
||||
ArtifactTracker::Init(); // if KID is not installed
|
||||
} else if (message->type == MessagingInterface::kPostLoadGame) {
|
||||
ArtifactTracker::OnGameLoad(); // refresh g_persistentMap from savegame
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -5,9 +5,9 @@
|
||||
|
||||
namespace Papyrus::PapyrusFunctions
|
||||
{
|
||||
constexpr bool IsLoaded(RE::StaticFunctionTag*)
|
||||
inline bool Load(RE::StaticFunctionTag*)
|
||||
{
|
||||
return ArtifactTracker::g_bLoaded;
|
||||
return ArtifactTracker::Init();
|
||||
}
|
||||
|
||||
inline RE::TESObjectREFR* GetCellStorage(RE::StaticFunctionTag*)
|
||||
@ -75,8 +75,8 @@ namespace Papyrus::PapyrusFunctions
|
||||
|
||||
inline void Bind(VM& a_vm)
|
||||
{
|
||||
BIND(IsLoaded);
|
||||
logger::info("Registered IsLoaded"sv);
|
||||
BIND(Load);
|
||||
logger::info("Registered Load"sv);
|
||||
BIND(GetArtifactCount);
|
||||
logger::info("Registered GetArtifactCount"sv);
|
||||
BIND(RescanStoredArtifacts);
|
||||
|
@ -22,7 +22,7 @@ endevent
|
||||
|
||||
Event OnPlayerLoadGame()
|
||||
|
||||
if ! IsLoaded()
|
||||
if ! Load()
|
||||
ETR_ItemsNew.Revert()
|
||||
ETR_ItemsFound.Revert()
|
||||
ETR_ItemsStored.Revert()
|
||||
@ -166,7 +166,7 @@ endstate
|
||||
|
||||
; NATIVE FUNCTIONS
|
||||
|
||||
bool function IsLoaded() native global
|
||||
bool function Load() native global
|
||||
|
||||
int function GetArtifactCount() native global
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user