diff --git a/SKSE/Plugins/EnderalSEEasyCrafting.dll b/SKSE/Plugins/EnderalSEEasyCrafting.dll index ba0012b..c5b7d2f 100644 Binary files a/SKSE/Plugins/EnderalSEEasyCrafting.dll and b/SKSE/Plugins/EnderalSEEasyCrafting.dll differ diff --git a/src/src/Util.h b/src/src/Util.h index 0ef3675..c85d834 100644 --- a/src/src/Util.h +++ b/src/src/Util.h @@ -65,9 +65,21 @@ inline const std::map GetSettings(bool bInit = false) return settings; } +inline RE::TESObjectREFR* GetChest() +{ + return RE::TESForm::LookupByID(0x5C132); +} + +inline void NotifyFetching(const char* a_notification) +{ + if (GetSettings().at("ShowFetchingNotification")) { + RE::DebugNotification(a_notification); + } +} + inline void FetchSuppliesByType(RE::FormType formType) { - const auto chest = RE::TESForm::LookupByID(0x5C132)->As(); + const auto chest = GetChest(); const auto targetRef = RE::PlayerCharacter::GetSingleton(); const auto inv = chest->GetInventory([formType](RE::TESBoundObject& a_form) { @@ -93,6 +105,37 @@ inline void FetchSuppliesByType(RE::FormType formType) } } +inline void FetchByWorkbenchKeyword(RE::BGSKeyword* keyword) +{ + if (!keyword) { + logger::warn("Invalid keyword argument in FetchByWorkbenchKeyword"); + return; + } + + std::unordered_set checkedItems; + + const auto chest = GetChest(); + const auto playerRef = RE::PlayerCharacter::GetSingleton(); + const auto inv = chest->GetInventory(); + RE::ITEM_REMOVE_REASON iReason = RE::ITEM_REMOVE_REASON::kStoreInContainer; + + for (const auto& recipe : RE::TESDataHandler::GetSingleton()->GetFormArray()) { + if (recipe->benchKeyword == keyword && 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 it = inv.find(component->obj); + if (it != inv.end()) { + supplyCount.insert({ it->first, it->second.first }); + chest->RemoveItem(it->first, it->second.first, iReason, nullptr, playerRef, 0, 0); + } + } + } + } + } +} inline void FetchSuppliesByForm(RE::TESForm* a_form) { @@ -100,7 +143,7 @@ inline void FetchSuppliesByForm(RE::TESForm* a_form) return; } - const auto chest = RE::TESForm::LookupByID(0x5C132)->As(); + const auto chest = GetChest(); const auto targetRef = RE::PlayerCharacter::GetSingleton(); const auto inv = chest->GetInventory([&](RE::TESBoundObject& a_xform) { @@ -130,7 +173,7 @@ inline void ReturnSupplies() RE::DebugNotification("Returning supplies..."); } - const auto chest = RE::TESForm::LookupByID(0x5C132)->As(); + const auto chest = GetChest(); const auto playerRef = RE::PlayerCharacter::GetSingleton(); RE::ITEM_REMOVE_REASON iReason = RE::ITEM_REMOVE_REASON::kStoreInContainer; @@ -234,37 +277,51 @@ inline void FetchSupplies(RE::TESFurniture* a_furn) bool bNotify = GetSettings().at("ShowFetchingNotification"); switch (a_furn->workBenchData.benchType.underlying()) { + case (int)RE::TESFurniture::WorkBenchData::BenchType::kAlchemy: case (int)RE::TESFurniture::WorkBenchData::BenchType::kAlchemyExperiment: - if (bNotify) { - RE::DebugNotification("Fetching ingredients..."); - } + NotifyFetching("Fetching alchemy ingredients..."); FetchSuppliesByType(RE::FormType::Ingredient); break; + case (int)RE::TESFurniture::WorkBenchData::BenchType::kEnchanting: case (int)RE::TESFurniture::WorkBenchData::BenchType::kEnchantingExperiment: - if (bNotify) { - RE::DebugNotification("Fetching soul gems..."); - } + NotifyFetching("Fetching soul gems..."); FetchSuppliesByType(RE::FormType::SoulGem); break; + default: if (a_furn->As()->HasKeywordString("CraftingCookpot")) { - if (bNotify) { - RE::DebugNotification("Fetching cooking ingredients..."); - } - FetchSuppliesByType(RE::FormType::Ingredient); - FetchSuppliesByType(RE::FormType::AlchemyItem); + NotifyFetching("Fetching cooking ingredients..."); + FetchByWorkbenchKeyword(RE::TESForm::LookupByID(0xA5CB3)); // CraftingCookpot + + } else if (a_furn->As()->HasKeywordString("CraftingSmelter")) { + NotifyFetching("Fetching smelting supplies..."); + FetchByWorkbenchKeyword(RE::TESForm::LookupByID(0xA5CCE)); // CraftingSmelter + + } else if (a_furn->As()->HasKeywordString("CraftingTanningRack")) { + NotifyFetching("Fetching tanning supplies..."); + FetchByWorkbenchKeyword(RE::TESForm::LookupByID(0x7866A)); // CraftingTanningRack + + } else if (a_furn->As()->HasKeywordString("CraftingSmithingSharpeningWheel")) { + NotifyFetching("Fetching crafting supplies..."); + FetchByWorkbenchKeyword(RE::TESForm::LookupByID(0x88108)); // CraftingSmithingSharpeningWheel + + } else if (a_furn->As()->HasKeywordString("CraftingSmithingForge")) { + NotifyFetching("Fetching crafting supplies..."); + FetchByWorkbenchKeyword(RE::TESForm::LookupByID(0x88105)); // CraftingSmithingForge + + } else if (a_furn->As()->HasKeywordString("CraftingSmithingArmorTable")) { + NotifyFetching("Fetching crafting supplies..."); + FetchByWorkbenchKeyword(RE::TESForm::LookupByID(0xADB78)); // CraftingSmithingArmorTable + } else { - if (bNotify) { - RE::DebugNotification("Fetching crafting supplies..."); - } + NotifyFetching("Fetching crafting supplies..."); FetchSuppliesByType(RE::FormType::Misc); FetchSuppliesByType(RE::FormType::Ingredient); FetchSuppliesByType(RE::FormType::SoulGem); FetchSuppliesByType(RE::FormType::AlchemyItem); } - break; } }); }).detach();