Compare commits
2 Commits
946e05d1ed
...
29f7c4e566
Author | SHA1 | Date | |
---|---|---|---|
29f7c4e566 | |||
3a52cb85b1 |
Binary file not shown.
@ -6,7 +6,7 @@ message("Using toolchain file ${CMAKE_TOOLCHAIN_FILE}.")
|
||||
########################################################################################################################
|
||||
project(
|
||||
ArtifactTracker
|
||||
VERSION 1.0.3
|
||||
VERSION 1.0.4
|
||||
DESCRIPTION "Artifact Tracker"
|
||||
LANGUAGES CXX)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
|
@ -9,6 +9,7 @@ using namespace SKSE::log;
|
||||
namespace ArtifactTracker
|
||||
{
|
||||
bool g_bLoaded = false;
|
||||
bool g_bSaveLoaded = true;
|
||||
bool g_bHomeContainer = false;
|
||||
bool g_bBookShelf = false;
|
||||
bool g_bTakeAll = false;
|
||||
@ -316,7 +317,7 @@ namespace ArtifactTracker
|
||||
|
||||
bool IsValidContainer(RE::TESObjectREFR* a_ref)
|
||||
{
|
||||
if (!a_ref) {
|
||||
if (!a_ref || a_ref->IsMarkedForDeletion()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -327,6 +328,11 @@ namespace ArtifactTracker
|
||||
|
||||
void OnCellEnter(const RE::FormID a_formID)
|
||||
{
|
||||
if (!g_bSaveLoaded) {
|
||||
// Cell load events fire before formlists are loaded from savegame
|
||||
return;
|
||||
}
|
||||
|
||||
RE::TESObjectCELL* cell = RE::TESForm::LookupByID<RE::TESObjectCELL>(a_formID);
|
||||
RE::BGSLocation* location = cell ? cell->GetLocation() : nullptr;
|
||||
|
||||
@ -339,40 +345,75 @@ namespace ArtifactTracker
|
||||
}
|
||||
|
||||
RE::TESObjectREFR* cellStorage = nullptr;
|
||||
bool bHasDupes = false;
|
||||
|
||||
g_persistentStorage->ForEachForm([&](RE::TESForm& a_form) {
|
||||
const auto refr = a_form.As<RE::TESObjectREFR>();
|
||||
if (refr && refr->GetBaseObject() == g_cellContainer && refr->GetParentCell()->formID == a_formID) {
|
||||
cellStorage = refr;
|
||||
return false;
|
||||
if (refr && refr->GetParentCell()->formID == a_formID && refr->GetBaseObject() == g_cellContainer) {
|
||||
if (cellStorage) {
|
||||
log::warn("Multiple cell storages detected in {}", cell->GetName());
|
||||
bHasDupes = true;
|
||||
} else {
|
||||
cellStorage = refr;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (cellStorage) {
|
||||
log::info("Found cell storage in {} (first pass)", cell->GetName());
|
||||
}
|
||||
#endif
|
||||
|
||||
ToggleHomeMode(cellStorage);
|
||||
|
||||
if (!cellStorage) {
|
||||
if (!cellStorage || bHasDupes) {
|
||||
RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESCellFullyLoadedEvent>(EventListener::GetSingleton());
|
||||
}
|
||||
}
|
||||
|
||||
void OnCellEnter(const RE::BGSLocation* location, const RE::TESObjectCELL* cell)
|
||||
{
|
||||
RE::ScriptEventSourceHolder::GetSingleton()->RemoveEventSink<RE::TESCellFullyLoadedEvent>(EventListener::GetSingleton());
|
||||
|
||||
if (!g_bSaveLoaded) {
|
||||
// Cell load events fire before formlists are loaded from savegame, duh!
|
||||
return;
|
||||
}
|
||||
|
||||
if (!location || !cell->IsInteriorCell() || cell != RE::PlayerCharacter::GetSingleton()->GetParentCell() || !location->HasKeyword(g_homeKeyword)) {
|
||||
ToggleHomeMode(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
RE::TESObjectREFR* cellStorage = nullptr;
|
||||
std::vector<RE::TESObjectREFR*> dupes;
|
||||
|
||||
for (const auto& a_ref : cell->references) {
|
||||
if (a_ref.get()->GetBaseObject() == g_cellContainer) {
|
||||
cellStorage = a_ref.get();
|
||||
break;
|
||||
cell->ForEachReference([&cellStorage, &dupes](RE::TESObjectREFR& a_ref) {
|
||||
if (a_ref.GetBaseObject() == g_cellContainer && !a_ref.IsMarkedForDeletion()) {
|
||||
if (cellStorage) {
|
||||
dupes.push_back(&a_ref);
|
||||
} else {
|
||||
cellStorage = &a_ref;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (int i = 0; i < dupes.size(); i++) {
|
||||
log::warn("Removing duplicate storage {:08X}", dupes[i]->formID);
|
||||
g_persistentMap.erase(dupes[i]->formID);
|
||||
ListRemoveItem(g_persistentStorage, dupes[i]);
|
||||
dupes[i]->Disable();
|
||||
dupes[i]->SetDelete(true);
|
||||
}
|
||||
dupes.clear();
|
||||
|
||||
if (cellStorage) {
|
||||
#ifdef _DEBUG
|
||||
log::info("Found cell storage in {} (second pass)", cell->GetName());
|
||||
#endif
|
||||
if (!g_persistentMap.contains(cellStorage->formID)) {
|
||||
g_persistentStorage->AddForm(cellStorage);
|
||||
g_persistentMap[cellStorage->formID] = cellStorage;
|
||||
@ -390,6 +431,9 @@ namespace ArtifactTracker
|
||||
const auto cellStorage = RE::PlayerCharacter::GetSingleton()->PlaceObjectAtMe(g_cellContainer, true).get();
|
||||
|
||||
if (cellStorage) {
|
||||
#ifdef _DEBUG
|
||||
log::info("Created storage {:08X}", cellStorage->formID);
|
||||
#endif
|
||||
cellStorage->Disable();
|
||||
g_persistentStorage->AddForm(cellStorage);
|
||||
g_persistentMap[cellStorage->formID] = cellStorage;
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace ArtifactTracker
|
||||
{
|
||||
extern bool g_bLoaded;
|
||||
extern bool g_bSaveLoaded;
|
||||
extern bool g_bHomeContainer;
|
||||
extern bool g_bBookShelf;
|
||||
extern bool g_bTakeAll;
|
||||
|
@ -117,7 +117,7 @@ auto EventListener::ProcessEvent(
|
||||
// This listener is expected to be unregistered outside of home.
|
||||
if (ArtifactTracker::IsHome() && a_event->actionRef->IsPlayerRef() && a_event->objectActivated) {
|
||||
const auto ref = a_event->objectActivated.get();
|
||||
if (ref && ArtifactTracker::IsArtifact(ref->GetBaseObject())) {
|
||||
if (ref && ArtifactTracker::g_artifactAllFormTypes.contains(ref->GetBaseObject()->GetFormType())) {
|
||||
std::thread([]() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
ArtifactTracker::SyncCellStorage();
|
||||
|
@ -34,8 +34,15 @@ namespace {
|
||||
if (const auto pluginInfo = ArtifactTracker::g_loadInterface->GetPluginInfo("po3_KeywordItemDistributor"); !pluginInfo) {
|
||||
ArtifactTracker::Init(); // if KID is not installed
|
||||
}
|
||||
} else if (message->type == MessagingInterface::kPreLoadGame) {
|
||||
ArtifactTracker::g_bSaveLoaded = false; // block cell load events
|
||||
} else if (message->type == MessagingInterface::kPostLoadGame) {
|
||||
ArtifactTracker::OnGameLoad(); // save-specific updates
|
||||
SKSE::GetTaskInterface()->AddTask([]() {
|
||||
ArtifactTracker::OnGameLoad(); // save-specific updates
|
||||
ArtifactTracker::g_bSaveLoaded = true;
|
||||
const auto cell = RE::PlayerCharacter::GetSingleton()->GetParentCell();
|
||||
ArtifactTracker::OnCellEnter(cell->GetLocation(), cell);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
|
||||
"name": "artifact-tracker",
|
||||
"version-string": "1.0.3",
|
||||
"version-string": "1.0.4",
|
||||
"port-version": 0,
|
||||
"description": "Artifact Tracker",
|
||||
"homepage": "https://eddoursul.win/mods/artifact-tracker/",
|
||||
|
Loading…
Reference in New Issue
Block a user