|
|
|
@ -12,8 +12,10 @@ namespace ArtifactTracker |
|
|
|
|
RE::BGSListForm* g_listStored; |
|
|
|
|
RE::BGSListForm* g_listFound; |
|
|
|
|
RE::BGSListForm* g_persistentStorage; |
|
|
|
|
RE::BGSKeyword* g_extraArtifactKeyword; |
|
|
|
|
RE::BGSKeyword* g_homeKeyword; |
|
|
|
|
std::unordered_map<RE::FormID, RE::TESForm*> g_artifactMap; |
|
|
|
|
std::unordered_set<RE::FormType> g_artifactFormTypes; |
|
|
|
|
std::unordered_map<RE::FormID, RE::TESObjectREFR*> g_persistentMap; |
|
|
|
|
RE::TESObjectREFR* g_cellStorage; |
|
|
|
|
|
|
|
|
@ -34,13 +36,14 @@ namespace ArtifactTracker |
|
|
|
|
g_listStored = dataHandler->LookupForm<RE::BGSListForm>(0x805, "Artifact Tracker.esp"); // ETR_ItemsStored
|
|
|
|
|
g_listFound = dataHandler->LookupForm<RE::BGSListForm>(0x806, "Artifact Tracker.esp"); // ETR_ItemsFound
|
|
|
|
|
g_persistentStorage = dataHandler->LookupForm<RE::BGSListForm>(0x807, "Artifact Tracker.esp"); // ETR_PersistentStorageList
|
|
|
|
|
g_extraArtifactKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0x80B, "Artifact Tracker.esp"); // ETR_ExtraArtifact
|
|
|
|
|
|
|
|
|
|
g_homeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xFC1A3, "Skyrim.esm"); // LocTypePlayerHouse
|
|
|
|
|
|
|
|
|
|
const auto recipeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xF5CB0, "Skyrim.esm"); // VendorItemRecipe
|
|
|
|
|
const auto excludeKeywords = dataHandler->LookupForm<RE::BGSListForm>(0x801, "Artifact Tracker.esp"); // ETR_ExcludeMiscKeywords
|
|
|
|
|
|
|
|
|
|
if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_homeKeyword || !recipeKeyword || !excludeKeywords) { |
|
|
|
|
if (!g_cellContainer || !g_listNew || !g_listStored || !g_listFound || !g_persistentStorage || !g_homeKeyword || !g_extraArtifactKeyword || !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; |
|
|
|
@ -48,52 +51,84 @@ namespace ArtifactTracker |
|
|
|
|
|
|
|
|
|
// Preloading item lists
|
|
|
|
|
|
|
|
|
|
g_artifactFormTypes.insert(RE::FormType::Weapon); |
|
|
|
|
for (const auto& form : dataHandler->GetFormArray(RE::FormType::Weapon)) { |
|
|
|
|
if (form->GetPlayable()) { |
|
|
|
|
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()) { |
|
|
|
|
g_artifactMap[form->formID] = form; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
g_artifactFormTypes.insert(RE::FormType::Book); |
|
|
|
|
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectBOOK>()) { |
|
|
|
|
if (form && !form->TeachesSpell() && (form->HasKeyword(recipeKeyword) || BookCheck::IsBook(form))) { |
|
|
|
|
g_artifactMap[form->formID] = form; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (const auto& form : dataHandler->GetFormArray(RE::FormType::Misc)) { |
|
|
|
|
if (form->GetPlayable() && !form->HasKeywordInList(excludeKeywords, false)) { |
|
|
|
|
OnGameLoad(); |
|
|
|
|
EventListener::Install(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void PreloadArtifactList() |
|
|
|
|
{ |
|
|
|
|
if (g_bLoaded) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const auto dataHandler = RE::TESDataHandler::GetSingleton(); |
|
|
|
|
const auto recipeKeyword = dataHandler->LookupForm<RE::BGSKeyword>(0xF5CB0, "Skyrim.esm"); // VendorItemRecipe
|
|
|
|
|
const auto excludeKeywords = dataHandler->LookupForm<RE::BGSListForm>(0x801, "Artifact Tracker.esp"); // ETR_ExcludeMiscKeywords
|
|
|
|
|
|
|
|
|
|
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectBOOK>()) { |
|
|
|
|
if (form->HasKeyword(g_extraArtifactKeyword)) { |
|
|
|
|
g_artifactMap[form->formID] = form; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
g_artifactFormTypes.insert(RE::FormType::Misc); |
|
|
|
|
for (const auto& form : dataHandler->GetFormArray<RE::TESObjectMISC>()) { |
|
|
|
|
if (form->GetPlayable() && (form->HasKeyword(g_extraArtifactKeyword) || !form->HasKeywordInList(excludeKeywords, false))) { |
|
|
|
|
g_artifactMap[form->formID] = form; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
g_artifactMap.erase(0xA); // Lockpick
|
|
|
|
|
g_artifactMap.erase(0xF); // Gold
|
|
|
|
|
|
|
|
|
|
for (const auto& form : dataHandler->GetFormArray(RE::FormType::Weapon)) { |
|
|
|
|
if (form->GetPlayable()) { |
|
|
|
|
|
|
|
|
|
for (const auto& form : dataHandler->GetFormArray<RE::AlchemyItem>()) { |
|
|
|
|
if (form->HasKeyword(g_extraArtifactKeyword)) { |
|
|
|
|
g_artifactMap[form->formID] = form; |
|
|
|
|
g_artifactFormTypes.insert(RE::FormType::AlchemyItem); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
g_artifactMap.erase(0x1F4); // Unarmed
|
|
|
|
|
|
|
|
|
|
for (const auto& form : dataHandler->GetFormArray(RE::FormType::Armor)) { |
|
|
|
|
if (form->GetPlayable()) { |
|
|
|
|
|
|
|
|
|
for (const auto& form : dataHandler->GetFormArray<RE::IngredientItem>()) { |
|
|
|
|
if (form->HasKeyword(g_extraArtifactKeyword)) { |
|
|
|
|
g_artifactMap[form->formID] = form; |
|
|
|
|
g_artifactFormTypes.insert(RE::FormType::Ingredient); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
OnGameLoad(); |
|
|
|
|
EventListener::Install(); |
|
|
|
|
for (const auto& form : dataHandler->GetFormArray<RE::TESSoulGem>()) { |
|
|
|
|
if (form->HasKeyword(g_extraArtifactKeyword)) { |
|
|
|
|
g_artifactMap[form->formID] = form; |
|
|
|
|
g_artifactFormTypes.insert(RE::FormType::SoulGem); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
g_bLoaded = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool IsArtifact(RE::TESForm* a_form) |
|
|
|
|
{ |
|
|
|
|
if (!a_form) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const auto formType = a_form->GetFormType(); |
|
|
|
|
|
|
|
|
|
if (formType == RE::FormType::Armor || formType == RE::FormType::Weapon || formType == RE::FormType::Book || formType == RE::FormType::Misc) { |
|
|
|
|
return g_artifactMap.contains(a_form->formID); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
return a_form && g_artifactFormTypes.contains(a_form->GetFormType()) && g_artifactMap.contains(a_form->formID); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
RE::TESForm* GetArtifactByID(RE::FormID a_formID) |
|
|
|
|