diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index c7d0ae3165..bad2181a06 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -406,10 +406,31 @@ namespace MWWorld static void loadImpl(const R& ref, const MWWorld::ESMStore& esmStore, auto& list) { const MWWorld::Store& store = esmStore.get(); - if (const X* ptr = store.search(ref.mBaseObj)) - list.emplace_back(ref, ptr); - else + const X* ptr = store.search(ref.mBaseObj); + if (!ptr) + { Log(Debug::Warning) << "Warning: could not resolve cell reference " << ref.mId << " (dropping reference)"; + return; + } + LiveCellRef liveCellRef(ref, ptr); + if (!ref.mEsp.parent.isZeroOrUnset()) + { + // Disable objects that are linked to an initially disabled parent. + // Actually when we will start working on Oblivion/Skyrim scripting we will need to: + // - use the current state of the parent instead of initial state of the parent + // - every time when the parent is enabled/disabled we should also enable/disable + // all objects that are linked to it. + // But for now we assume that the parent remains in its initial state. + const ESM4::Reference* parentRef = esmStore.get().searchStatic(ref.mEsp.parent); + if (parentRef) + { + bool parentDisabled = parentRef->mFlags & ESM4::Rec_Disabled; + bool inversed = ref.mEsp.flags & ESM4::EnableParent::Flag_Inversed; + if (parentDisabled != inversed) + liveCellRef.mData.disable(); + } + } + list.push_back(liveCellRef); } template diff --git a/components/esm4/reference.hpp b/components/esm4/reference.hpp index debb39f839..9d6efdfd82 100644 --- a/components/esm4/reference.hpp +++ b/components/esm4/reference.hpp @@ -39,7 +39,13 @@ namespace ESM4 struct EnableParent { ESM::FormId parent; - std::uint32_t flags; // 0x0001 = Set Enable State Opposite Parent, 0x0002 = Pop In + std::uint32_t flags; + + enum Flags + { + Flag_Inversed = 0x1, // Set enable state opposite to the parent + Flag_PopIn = 0x2, + }; }; struct LODReference