|
|
|
@ -178,42 +178,52 @@ inline void ReturnSupplies() |
|
|
|
|
} |
|
|
|
|
supplyCount.clear(); |
|
|
|
|
|
|
|
|
|
if (!GetSettings().at("StoreInventorySupplies")) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const auto kOreIngot = RE::TESForm::LookupByID(0x914EC)->As<RE::BGSKeyword>(); // VendorItemOreIngot
|
|
|
|
|
const auto kAnimalPart = RE::TESForm::LookupByID(0x914EB)->As<RE::BGSKeyword>(); // VendorItemAnimalPart
|
|
|
|
|
const auto kAnimalHide = RE::TESForm::LookupByID(0x914EA)->As<RE::BGSKeyword>(); // VendorItemAnimalHide
|
|
|
|
|
const auto kFirewood = RE::TESForm::LookupByID(0xBECD7)->As<RE::BGSKeyword>(); // VendorItemFireword
|
|
|
|
|
const auto kFoodRaw = RE::TESForm::LookupByID(0xA0E56)->As<RE::BGSKeyword>(); // VendorItemFoodRaw
|
|
|
|
|
|
|
|
|
|
const auto inv = playerRef->GetInventory([&](RE::TESBoundObject& a_form) { |
|
|
|
|
if (a_form.Is(RE::FormType::Ingredient)) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (a_form.Is(RE::FormType::Misc)) { |
|
|
|
|
const auto kform = a_form.As<RE::BGSKeywordForm>(); |
|
|
|
|
if (kform->GetNumKeywords() == 0) { |
|
|
|
|
return false; |
|
|
|
|
} else if (kform->HasKeyword(kOreIngot) || kform->HasKeyword(kAnimalPart) || kform->HasKeyword(kAnimalHide) || kform->HasKeyword(kFirewood)) { |
|
|
|
|
return true; |
|
|
|
|
if (GetSettings().at("StoreInventorySupplies")) { |
|
|
|
|
|
|
|
|
|
const auto kOreIngot = RE::TESForm::LookupByID(0x914EC)->As<RE::BGSKeyword>(); // VendorItemOreIngot
|
|
|
|
|
const auto kAnimalPart = RE::TESForm::LookupByID(0x914EB)->As<RE::BGSKeyword>(); // VendorItemAnimalPart
|
|
|
|
|
const auto kAnimalHide = RE::TESForm::LookupByID(0x914EA)->As<RE::BGSKeyword>(); // VendorItemAnimalHide
|
|
|
|
|
const auto kFirewood = RE::TESForm::LookupByID(0xBECD7)->As<RE::BGSKeyword>(); // VendorItemFireword
|
|
|
|
|
const auto kTool = RE::TESForm::LookupByID(0x914EE)->As<RE::BGSKeyword>(); // VendorItemTool
|
|
|
|
|
const auto kClutter = RE::TESForm::LookupByID(0x914E9)->As<RE::BGSKeyword>(); // VendorItemClutter
|
|
|
|
|
const auto kFoodRaw = RE::TESForm::LookupByID(0xA0E56)->As<RE::BGSKeyword>(); // VendorItemFoodRaw
|
|
|
|
|
|
|
|
|
|
std::unordered_set<RE::FormID> checkedItems; |
|
|
|
|
std::unordered_set<RE::TESForm*> suppliesToStore; |
|
|
|
|
|
|
|
|
|
for (const auto& recipe : RE::TESDataHandler::GetSingleton()->GetFormArray<RE::BGSConstructibleObject>()) { |
|
|
|
|
if (recipe->requiredItems.numContainerObjects > 0) { |
|
|
|
|
for (int i = 0; i < recipe->requiredItems.numContainerObjects; i++) { |
|
|
|
|
const auto component = recipe->requiredItems.GetContainerObjectAt(i).value(); |
|
|
|
|
const auto formID = (component && component->obj) ? component->obj->formID : NULL; |
|
|
|
|
if (formID && !checkedItems.contains(formID)) { |
|
|
|
|
checkedItems.insert(formID); |
|
|
|
|
|
|
|
|
|
const auto keywords = component->obj->As<RE::BGSKeywordForm>(); |
|
|
|
|
|
|
|
|
|
if (component->obj->Is(RE::FormType::Ingredient)) { |
|
|
|
|
suppliesToStore.insert(component->obj); |
|
|
|
|
} else if (component->obj->Is(RE::FormType::Misc) && !component->obj->IsGold() && !component->obj->IsLockpick()) { |
|
|
|
|
if (keywords->HasKeyword(kOreIngot) || keywords->HasKeyword(kAnimalPart) || keywords->HasKeyword(kAnimalHide) || keywords->HasKeyword(kFirewood) || keywords->HasKeyword(kTool) || keywords->HasKeyword(kClutter) || keywords->HasKeyword(kFoodRaw)) { |
|
|
|
|
suppliesToStore.insert(component->obj); |
|
|
|
|
} |
|
|
|
|
} else if (component->obj->Is(RE::FormType::AlchemyItem) && keywords->HasKeyword(kFoodRaw)) { |
|
|
|
|
suppliesToStore.insert(component->obj); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (a_form.Is(RE::FormType::AlchemyItem)) { |
|
|
|
|
return a_form.As<RE::BGSKeywordForm>()->HasKeyword(kFoodRaw); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
}); |
|
|
|
|
const auto inv = playerRef->GetInventory([&](RE::TESBoundObject& a_form) { |
|
|
|
|
return suppliesToStore.contains(&a_form); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
for (const auto& [item, data] : inv) { |
|
|
|
|
const auto& [count, entry] = data; |
|
|
|
|
if (count > 0 && !entry->IsFavorited() && !entry->IsQuestObject()) { |
|
|
|
|
playerRef->RemoveItem(item, count, iRemoveReason, nullptr, chest, 0, 0); |
|
|
|
|
for (const auto& [item, data] : inv) { |
|
|
|
|
const auto& [count, entry] = data; |
|
|
|
|
if (count > 0 && !entry->IsFavorited() && !entry->IsQuestObject()) { |
|
|
|
|
playerRef->RemoveItem(item, count, iRemoveReason, nullptr, chest, 0, 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -270,23 +280,21 @@ inline void FetchSupplies(RE::TESFurniture* a_furn) |
|
|
|
|
std::thread([a_furn]() { |
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(3)); |
|
|
|
|
SKSE::GetTaskInterface()->AddTask([a_furn]() { |
|
|
|
|
NotifyFetching("Fetching supplies..."); |
|
|
|
|
|
|
|
|
|
switch (a_furn->workBenchData.benchType.underlying()) { |
|
|
|
|
|
|
|
|
|
case (int)RE::TESFurniture::WorkBenchData::BenchType::kAlchemy: |
|
|
|
|
case (int)RE::TESFurniture::WorkBenchData::BenchType::kAlchemyExperiment: |
|
|
|
|
NotifyFetching("Fetching ingredients..."); |
|
|
|
|
FetchSuppliesByType(RE::FormType::Ingredient); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case (int)RE::TESFurniture::WorkBenchData::BenchType::kEnchanting: |
|
|
|
|
case (int)RE::TESFurniture::WorkBenchData::BenchType::kEnchantingExperiment: |
|
|
|
|
NotifyFetching("Fetching soul gems..."); |
|
|
|
|
FetchSuppliesByType(RE::FormType::SoulGem); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
NotifyFetching("Fetching supplies..."); |
|
|
|
|
FetchByWorkbench(a_furn); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
@ -301,7 +309,7 @@ inline bool GetSuppliesFetched() |
|
|
|
|
inline void FetchSpectralizingSupplies() |
|
|
|
|
{ |
|
|
|
|
if (GetSettings().at("ShowFetchingNotification")) { |
|
|
|
|
RE::DebugNotification("Fetching spectralizing supplies..."); |
|
|
|
|
RE::DebugNotification("Fetching supplies..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bSuppliesFetched = true; |
|
|
|
|