mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 18:59:57 +00:00
Merge branch 'esm4_achr' into 'master'
Load ESM4 actors (no rendering yet) See merge request OpenMW/openmw!3278
This commit is contained in:
commit
3e16ef7445
37 changed files with 363 additions and 317 deletions
|
@ -68,5 +68,7 @@ namespace MWClass
|
||||||
ESM4Tree::registerSelf();
|
ESM4Tree::registerSelf();
|
||||||
ESM4Named<ESM4::Weapon>::registerSelf();
|
ESM4Named<ESM4::Weapon>::registerSelf();
|
||||||
ESM4Light::registerSelf();
|
ESM4Light::registerSelf();
|
||||||
|
ESM4Actor<ESM4::Npc>::registerSelf();
|
||||||
|
ESM4Actor<ESM4::Creature>::registerSelf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,39 @@ namespace MWClass
|
||||||
return ptr.get<Record>()->mBase->mFullName;
|
return ptr.get<Record>()->mBase->mFullName;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Record>
|
||||||
|
class ESM4Actor : public MWWorld::RegisteredClass<ESM4Actor<Record>, ESM4Base<Record>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
friend MWWorld::RegisteredClass<ESM4Actor, ESM4Base<Record>>;
|
||||||
|
|
||||||
|
ESM4Actor()
|
||||||
|
: MWWorld::RegisteredClass<ESM4Actor, ESM4Base<Record>>(Record::sRecordId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertObjectPhysics(
|
||||||
|
const MWWorld::Ptr&, const std::string&, const osg::Quat&, MWPhysics::PhysicsSystem&) const override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasToolTip(const MWWorld::ConstPtr& ptr) const override { return true; }
|
||||||
|
|
||||||
|
MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override
|
||||||
|
{
|
||||||
|
return ESM4Impl::getToolTipInfo(ptr.get<Record>()->mBase->mEditorId, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getModel(const MWWorld::ConstPtr& ptr) const override
|
||||||
|
{
|
||||||
|
// TODO: Not clear where to get something renderable:
|
||||||
|
// ESM4::Npc::mModel is usually an empty string
|
||||||
|
// ESM4::Race::mModelMale is only a skeleton
|
||||||
|
// For now show error marker as a dummy model.
|
||||||
|
return "meshes/marker_error.nif";
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GAME_MWCLASS_ESM4BASE_H
|
#endif // GAME_MWCLASS_ESM4BASE_H
|
||||||
|
|
|
@ -25,10 +25,16 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CellRef::CellRef(const ESM4::ActorCharacter& ref)
|
||||||
|
: mCellRef(ESM::ReferenceVariant(ref))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
const ESM::RefNum& CellRef::getRefNum() const
|
const ESM::RefNum& CellRef::getRefNum() const
|
||||||
{
|
{
|
||||||
return std::visit(ESM::VisitOverload{
|
return std::visit(ESM::VisitOverload{
|
||||||
[&](const ESM4::Reference& ref) -> const ESM::RefNum& { return ref.mId; },
|
[&](const ESM4::Reference& ref) -> const ESM::RefNum& { return ref.mId; },
|
||||||
|
[&](const ESM4::ActorCharacter& ref) -> const ESM::RefNum& { return ref.mId; },
|
||||||
[&](const ESM::CellRef& ref) -> const ESM::RefNum& { return ref.mRefNum; },
|
[&](const ESM::CellRef& ref) -> const ESM::RefNum& { return ref.mRefNum; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -38,6 +44,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
ESM::RefNum& refNum = std::visit(ESM::VisitOverload{
|
ESM::RefNum& refNum = std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& ref) -> ESM::RefNum& { return ref.mId; },
|
[&](ESM4::Reference& ref) -> ESM::RefNum& { return ref.mId; },
|
||||||
|
[&](ESM4::ActorCharacter& ref) -> ESM::RefNum& { return ref.mId; },
|
||||||
[&](ESM::CellRef& ref) -> ESM::RefNum& { return ref.mRefNum; },
|
[&](ESM::CellRef& ref) -> ESM::RefNum& { return ref.mRefNum; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -63,6 +70,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& ref) { ref.mId = refNum; },
|
[&](ESM4::Reference& ref) { ref.mId = refNum; },
|
||||||
|
[&](ESM4::ActorCharacter& ref) { ref.mId = refNum; },
|
||||||
[&](ESM::CellRef& ref) { ref.mRefNum = refNum; },
|
[&](ESM::CellRef& ref) { ref.mRefNum = refNum; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -73,10 +81,12 @@ namespace MWWorld
|
||||||
ESM::Position CellRef::getDoorDest() const
|
ESM::Position CellRef::getDoorDest() const
|
||||||
{
|
{
|
||||||
|
|
||||||
return std::visit(ESM::VisitOverload{
|
return std::visit(
|
||||||
[&](const ESM4::Reference& ref) { return ref.mDoor.destPos; },
|
ESM::VisitOverload{
|
||||||
[&](const ESM::CellRef& ref) -> ESM::Position { return ref.mDoorDest; },
|
[&](const ESM4::Reference& ref) { return ref.mDoor.destPos; },
|
||||||
},
|
[&](const ESM::CellRef& ref) -> ESM::Position { return ref.mDoorDest; },
|
||||||
|
[&](const ESM4::ActorCharacter&) -> ESM::Position { throw std::logic_error("Not applicable"); },
|
||||||
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +112,10 @@ namespace MWWorld
|
||||||
return refDest->mParent;
|
return refDest->mParent;
|
||||||
return ESM::RefId();
|
return ESM::RefId();
|
||||||
};
|
};
|
||||||
|
auto actorDestCell
|
||||||
|
= [&](const ESM4::ActorCharacter&) -> ESM::RefId { throw std::logic_error("Not applicable"); };
|
||||||
|
|
||||||
return std::visit(ESM::VisitOverload{ esm3Visit, esm4Visit }, mCellRef.mVariant);
|
return std::visit(ESM::VisitOverload{ esm3Visit, esm4Visit, actorDestCell }, mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellRef::setScale(float scale)
|
void CellRef::setScale(float scale)
|
||||||
|
@ -126,6 +138,7 @@ namespace MWWorld
|
||||||
return std::visit(ESM::VisitOverload{
|
return std::visit(ESM::VisitOverload{
|
||||||
[&](const ESM4::Reference& /*ref*/) { return 0.f; },
|
[&](const ESM4::Reference& /*ref*/) { return 0.f; },
|
||||||
[&](const ESM::CellRef& ref) { return ref.mEnchantmentCharge; },
|
[&](const ESM::CellRef& ref) { return ref.mEnchantmentCharge; },
|
||||||
|
[&](const ESM4::ActorCharacter&) -> float { throw std::logic_error("Not applicable"); },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
@ -155,6 +168,7 @@ namespace MWWorld
|
||||||
|
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mEnchantmentCharge = charge; },
|
[&](ESM::CellRef& ref) { ref.mEnchantmentCharge = charge; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -165,6 +179,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mChargeInt = charge; },
|
[&](ESM::CellRef& ref) { ref.mChargeInt = charge; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -188,11 +203,11 @@ namespace MWWorld
|
||||||
cellRef3.mChargeIntRemainder = newChargeRemainder;
|
cellRef3.mChargeIntRemainder = newChargeRemainder;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::visit(
|
std::visit(ESM::VisitOverload{
|
||||||
ESM::VisitOverload{
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::ActorCharacter&) {},
|
||||||
esm3Visit,
|
esm3Visit,
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +215,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mChargeFloat = charge; },
|
[&](ESM::CellRef& ref) { ref.mChargeFloat = charge; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -209,6 +225,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
return std::visit(ESM::VisitOverload{
|
return std::visit(ESM::VisitOverload{
|
||||||
[&](const ESM4::Reference& /*ref*/) -> const std::string& { return emptyString; },
|
[&](const ESM4::Reference& /*ref*/) -> const std::string& { return emptyString; },
|
||||||
|
[&](const ESM4::ActorCharacter& /*ref*/) -> const std::string& { return emptyString; },
|
||||||
[&](const ESM::CellRef& ref) -> const std::string& { return ref.mGlobalVariable; },
|
[&](const ESM::CellRef& ref) -> const std::string& { return ref.mGlobalVariable; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -221,6 +238,7 @@ namespace MWWorld
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter& /*ref*/) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mGlobalVariable.erase(); },
|
[&](ESM::CellRef& ref) { ref.mGlobalVariable.erase(); },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -232,7 +250,9 @@ namespace MWWorld
|
||||||
if (factionRank != getFactionRank())
|
if (factionRank != getFactionRank())
|
||||||
{
|
{
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
std::visit([&](auto&& ref) { ref.mFactionRank = factionRank; }, mCellRef.mVariant);
|
std::visit(ESM::VisitOverload{
|
||||||
|
[&](ESM4::ActorCharacter&) {}, [&](auto&& ref) { ref.mFactionRank = factionRank; } },
|
||||||
|
mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +262,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mOwner = owner; },
|
[&](ESM::CellRef& ref) { ref.mOwner = owner; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -255,6 +276,7 @@ namespace MWWorld
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mSoul = soul; },
|
[&](ESM::CellRef& ref) { ref.mSoul = soul; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -268,6 +290,7 @@ namespace MWWorld
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mFaction = faction; },
|
[&](ESM::CellRef& ref) { ref.mFaction = faction; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -279,7 +302,12 @@ namespace MWWorld
|
||||||
if (lockLevel != getLockLevel())
|
if (lockLevel != getLockLevel())
|
||||||
{
|
{
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
std::visit([&](auto&& ref) { ref.mLockLevel = lockLevel; }, mCellRef.mVariant);
|
std::visit(ESM::VisitOverload{
|
||||||
|
[&](ESM4::Reference& ref) { ref.mLockLevel = lockLevel; },
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
|
[&](ESM::CellRef& ref) { ref.mLockLevel = lockLevel; },
|
||||||
|
},
|
||||||
|
mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,12 +325,23 @@ namespace MWWorld
|
||||||
|
|
||||||
bool CellRef::isLocked() const
|
bool CellRef::isLocked() const
|
||||||
{
|
{
|
||||||
return std::visit([](auto&& ref) { return ref.mIsLocked; }, mCellRef.mVariant);
|
struct Visitor
|
||||||
|
{
|
||||||
|
bool operator()(const ESM::CellRef& ref) { return ref.mIsLocked; }
|
||||||
|
bool operator()(const ESM4::Reference& ref) { return ref.mIsLocked; }
|
||||||
|
bool operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
|
};
|
||||||
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellRef::setLocked(bool locked)
|
void CellRef::setLocked(bool locked)
|
||||||
{
|
{
|
||||||
std::visit([=](auto&& ref) { ref.mIsLocked = locked; }, mCellRef.mVariant);
|
std::visit(ESM::VisitOverload{
|
||||||
|
[&](ESM4::Reference& ref) { ref.mIsLocked = locked; },
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
|
[&](ESM::CellRef& ref) { ref.mIsLocked = locked; },
|
||||||
|
},
|
||||||
|
mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellRef::setTrap(const ESM::RefId& trap)
|
void CellRef::setTrap(const ESM::RefId& trap)
|
||||||
|
@ -312,6 +351,7 @@ namespace MWWorld
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mTrap = trap; },
|
[&](ESM::CellRef& ref) { ref.mTrap = trap; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -325,6 +365,7 @@ namespace MWWorld
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mKey = key; },
|
[&](ESM::CellRef& ref) { ref.mKey = key; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -338,6 +379,7 @@ namespace MWWorld
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](ESM4::Reference& /*ref*/) {},
|
[&](ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](ESM4::ActorCharacter&) {},
|
||||||
[&](ESM::CellRef& ref) { ref.mGoldValue = value; },
|
[&](ESM::CellRef& ref) { ref.mGoldValue = value; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
@ -348,6 +390,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
std::visit(ESM::VisitOverload{
|
std::visit(ESM::VisitOverload{
|
||||||
[&](const ESM4::Reference& /*ref*/) {},
|
[&](const ESM4::Reference& /*ref*/) {},
|
||||||
|
[&](const ESM4::ActorCharacter&) {},
|
||||||
[&](const ESM::CellRef& ref) { state.mRef = ref; },
|
[&](const ESM::CellRef& ref) { state.mRef = ref; },
|
||||||
},
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace MWWorld
|
||||||
explicit CellRef(const ESM::CellRef& ref);
|
explicit CellRef(const ESM::CellRef& ref);
|
||||||
|
|
||||||
explicit CellRef(const ESM4::Reference& ref);
|
explicit CellRef(const ESM4::Reference& ref);
|
||||||
|
explicit CellRef(const ESM4::ActorCharacter& ref);
|
||||||
|
|
||||||
// Note: Currently unused for items in containers
|
// Note: Currently unused for items in containers
|
||||||
const ESM::RefNum& getRefNum() const;
|
const ESM::RefNum& getRefNum() const;
|
||||||
|
@ -47,6 +48,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mRefID; }
|
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mRefID; }
|
||||||
ESM::RefId operator()(const ESM4::Reference& ref) { return ref.mBaseObj; }
|
ESM::RefId operator()(const ESM4::Reference& ref) { return ref.mBaseObj; }
|
||||||
|
ESM::RefId operator()(const ESM4::ActorCharacter& ref) { return ref.mBaseObj; }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
@ -59,6 +61,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
bool operator()(const ESM::CellRef& ref) { return ref.mTeleport; }
|
bool operator()(const ESM::CellRef& ref) { return ref.mTeleport; }
|
||||||
bool operator()(const ESM4::Reference& ref) { return !ref.mDoor.destDoor.isZeroOrUnset(); }
|
bool operator()(const ESM4::Reference& ref) { return !ref.mDoor.destDoor.isZeroOrUnset(); }
|
||||||
|
bool operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
@ -101,6 +104,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
int operator()(const ESM::CellRef& ref) { return ref.mChargeInt; }
|
int operator()(const ESM::CellRef& ref) { return ref.mChargeInt; }
|
||||||
int operator()(const ESM4::Reference& /*ref*/) { return 0; }
|
int operator()(const ESM4::Reference& /*ref*/) { return 0; }
|
||||||
|
int operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
@ -110,6 +114,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
float operator()(const ESM::CellRef& ref) { return ref.mChargeFloat; }
|
float operator()(const ESM::CellRef& ref) { return ref.mChargeFloat; }
|
||||||
float operator()(const ESM4::Reference& /*ref*/) { return 0; }
|
float operator()(const ESM4::Reference& /*ref*/) { return 0; }
|
||||||
|
float operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
} // Implemented as union with int charge
|
} // Implemented as union with int charge
|
||||||
|
@ -123,7 +128,8 @@ namespace MWWorld
|
||||||
struct Visitor
|
struct Visitor
|
||||||
{
|
{
|
||||||
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mOwner; }
|
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mOwner; }
|
||||||
ESM::RefId operator()(const ESM4::Reference& /*ref*/) { return ESM::RefId(); }
|
ESM::RefId operator()(const ESM4::Reference& ref) { return ESM::RefId::formIdRefId(ref.mOwner); }
|
||||||
|
ESM::RefId operator()(const ESM4::ActorCharacter& ref) { return ESM::RefId::formIdRefId(ref.mOwner); }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
@ -143,6 +149,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mSoul; }
|
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mSoul; }
|
||||||
ESM::RefId operator()(const ESM4::Reference& /*ref*/) { return ESM::RefId(); }
|
ESM::RefId operator()(const ESM4::Reference& /*ref*/) { return ESM::RefId(); }
|
||||||
|
ESM::RefId operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
@ -156,6 +163,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mFaction; }
|
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mFaction; }
|
||||||
ESM::RefId operator()(const ESM4::Reference& /*ref*/) { return ESM::RefId(); }
|
ESM::RefId operator()(const ESM4::Reference& /*ref*/) { return ESM::RefId(); }
|
||||||
|
ESM::RefId operator()(const ESM4::ActorCharacter& /*ref*/) { return ESM::RefId(); }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +173,13 @@ namespace MWWorld
|
||||||
void setFactionRank(int factionRank);
|
void setFactionRank(int factionRank);
|
||||||
int getFactionRank() const
|
int getFactionRank() const
|
||||||
{
|
{
|
||||||
return std::visit([&](auto&& ref) { return ref.mFactionRank; }, mCellRef.mVariant);
|
struct Visitor
|
||||||
|
{
|
||||||
|
int operator()(const ESM::CellRef& ref) { return ref.mFactionRank; }
|
||||||
|
int operator()(const ESM4::Reference& ref) { return ref.mFactionRank; }
|
||||||
|
int operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
|
};
|
||||||
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock level for doors and containers
|
// Lock level for doors and containers
|
||||||
|
@ -173,7 +187,13 @@ namespace MWWorld
|
||||||
// For an unlocked door, it is set to -(previous locklevel)
|
// For an unlocked door, it is set to -(previous locklevel)
|
||||||
int getLockLevel() const
|
int getLockLevel() const
|
||||||
{
|
{
|
||||||
return std::visit([](auto&& ref) { return static_cast<int>(ref.mLockLevel); }, mCellRef.mVariant);
|
struct Visitor
|
||||||
|
{
|
||||||
|
int operator()(const ESM::CellRef& ref) { return ref.mLockLevel; }
|
||||||
|
int operator()(const ESM4::Reference& ref) { return ref.mLockLevel; }
|
||||||
|
int operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
|
};
|
||||||
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
void setLockLevel(int lockLevel);
|
void setLockLevel(int lockLevel);
|
||||||
void lock(int lockLevel);
|
void lock(int lockLevel);
|
||||||
|
@ -183,7 +203,13 @@ namespace MWWorld
|
||||||
// Key and trap ID names, if any
|
// Key and trap ID names, if any
|
||||||
ESM::RefId getKey() const
|
ESM::RefId getKey() const
|
||||||
{
|
{
|
||||||
return std::visit([](auto&& ref) -> const ESM::RefId& { return ref.mKey; }, mCellRef.mVariant);
|
struct Visitor
|
||||||
|
{
|
||||||
|
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mKey; }
|
||||||
|
ESM::RefId operator()(const ESM4::Reference& ref) { return ref.mKey; }
|
||||||
|
ESM::RefId operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
|
};
|
||||||
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
void setKey(const ESM::RefId& key);
|
void setKey(const ESM::RefId& key);
|
||||||
ESM::RefId getTrap() const
|
ESM::RefId getTrap() const
|
||||||
|
@ -192,6 +218,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mTrap; }
|
ESM::RefId operator()(const ESM::CellRef& ref) { return ref.mTrap; }
|
||||||
ESM::RefId operator()(const ESM4::Reference& /*ref*/) { return ESM::RefId(); }
|
ESM::RefId operator()(const ESM4::Reference& /*ref*/) { return ESM::RefId(); }
|
||||||
|
ESM::RefId operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
@ -204,6 +231,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
int operator()(const ESM::CellRef& ref) { return ref.mGoldValue; }
|
int operator()(const ESM::CellRef& ref) { return ref.mGoldValue; }
|
||||||
int operator()(const ESM4::Reference& /*ref*/) { return 0; }
|
int operator()(const ESM4::Reference& /*ref*/) { return 0; }
|
||||||
|
int operator()(const ESM4::ActorCharacter&) { throw std::logic_error("Not applicable"); }
|
||||||
};
|
};
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
return std::visit(Visitor(), mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace MWWorld
|
||||||
void load(ESM::CellRef& ref, bool deleted, const MWWorld::ESMStore& esmStore);
|
void load(ESM::CellRef& ref, bool deleted, const MWWorld::ESMStore& esmStore);
|
||||||
|
|
||||||
void load(const ESM4::Reference& ref, const MWWorld::ESMStore& esmStore);
|
void load(const ESM4::Reference& ref, const MWWorld::ESMStore& esmStore);
|
||||||
|
void load(const ESM4::ActorCharacter& ref, const MWWorld::ESMStore& esmStore);
|
||||||
|
|
||||||
LiveRef& insert(const LiveRef& item)
|
LiveRef& insert(const LiveRef& item)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <components/esm3/npcstate.hpp>
|
#include <components/esm3/npcstate.hpp>
|
||||||
#include <components/esm3/objectstate.hpp>
|
#include <components/esm3/objectstate.hpp>
|
||||||
#include <components/esm3/readerscache.hpp>
|
#include <components/esm3/readerscache.hpp>
|
||||||
|
#include <components/esm4/loadachr.hpp>
|
||||||
#include <components/esm4/loadligh.hpp>
|
#include <components/esm4/loadligh.hpp>
|
||||||
#include <components/esm4/loadrefr.hpp>
|
#include <components/esm4/loadrefr.hpp>
|
||||||
#include <components/esm4/loadstat.hpp>
|
#include <components/esm4/loadstat.hpp>
|
||||||
|
@ -384,24 +385,32 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr bool isESM4ActorRec(unsigned int rec)
|
||||||
|
{
|
||||||
|
return rec == ESM::REC_NPC_4 || rec == ESM::REC_CREA4 || rec == ESM::REC_LVLN4 || rec == ESM::REC_LVLC4;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename X, typename R>
|
||||||
|
static void loadImpl(const R& ref, const MWWorld::ESMStore& esmStore, auto& list)
|
||||||
|
{
|
||||||
|
const MWWorld::Store<X>& store = esmStore.get<X>();
|
||||||
|
if (const X* ptr = store.search(ref.mBaseObj))
|
||||||
|
list.emplace_back(ref, ptr);
|
||||||
|
else
|
||||||
|
Log(Debug::Warning) << "Warning: could not resolve cell reference " << ref.mId << " (dropping reference)";
|
||||||
|
}
|
||||||
|
|
||||||
template <typename X>
|
template <typename X>
|
||||||
void CellRefList<X>::load(const ESM4::Reference& ref, const MWWorld::ESMStore& esmStore)
|
void CellRefList<X>::load(const ESM4::Reference& ref, const MWWorld::ESMStore& esmStore)
|
||||||
{
|
{
|
||||||
|
if constexpr (ESM::isESM4Rec(X::sRecordId) && !isESM4ActorRec(X::sRecordId))
|
||||||
if constexpr (!ESM::isESM4Rec(X::sRecordId))
|
loadImpl<X>(ref, esmStore, mList);
|
||||||
return;
|
}
|
||||||
|
template <typename X>
|
||||||
const MWWorld::Store<X>& store = esmStore.get<X>();
|
void CellRefList<X>::load(const ESM4::ActorCharacter& ref, const MWWorld::ESMStore& esmStore)
|
||||||
|
{
|
||||||
if (const X* ptr = store.search(ref.mBaseObj))
|
if constexpr (isESM4ActorRec(X::sRecordId))
|
||||||
{
|
loadImpl<X>(ref, esmStore, mList);
|
||||||
LiveRef liveCellRef(ref, ptr);
|
|
||||||
mList.push_back(liveCellRef);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log(Debug::Warning) << "Warning: could not resolve cell reference " << ref.mId << " (dropping reference)";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename X>
|
template <typename X>
|
||||||
|
@ -769,9 +778,21 @@ namespace MWWorld
|
||||||
invocable(*ref);
|
invocable(*ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ReferenceInvocable>
|
||||||
|
static void visitCell4ActorReferences(
|
||||||
|
const ESM4::Cell& cell, const ESMStore& esmStore, ESM::ReadersCache& readers, ReferenceInvocable&& invocable)
|
||||||
|
{
|
||||||
|
for (const ESM4::ActorCharacter* ref : esmStore.get<ESM4::ActorCharacter>().getByCell(cell.mId))
|
||||||
|
invocable(*ref);
|
||||||
|
for (const ESM4::ActorCharacter* ref : esmStore.get<ESM4::ActorCreature>().getByCell(cell.mId))
|
||||||
|
invocable(*ref);
|
||||||
|
}
|
||||||
|
|
||||||
void CellStore::listRefs(const ESM4::Cell& cell)
|
void CellStore::listRefs(const ESM4::Cell& cell)
|
||||||
{
|
{
|
||||||
visitCell4References(cell, mStore, mReaders, [&](const ESM4::Reference& ref) { mIds.push_back(ref.mBaseObj); });
|
visitCell4References(cell, mStore, mReaders, [&](const ESM4::Reference& ref) { mIds.push_back(ref.mBaseObj); });
|
||||||
|
visitCell4ActorReferences(
|
||||||
|
cell, mStore, mReaders, [&](const ESM4::ActorCharacter& ref) { mIds.push_back(ref.mBaseObj); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellStore::listRefs()
|
void CellStore::listRefs()
|
||||||
|
@ -836,6 +857,7 @@ namespace MWWorld
|
||||||
void CellStore::loadRefs(const ESM4::Cell& cell, std::map<ESM::RefNum, ESM::RefId>& refNumToID)
|
void CellStore::loadRefs(const ESM4::Cell& cell, std::map<ESM::RefNum, ESM::RefId>& refNumToID)
|
||||||
{
|
{
|
||||||
visitCell4References(cell, mStore, mReaders, [&](const ESM4::Reference& ref) { loadRef(ref); });
|
visitCell4References(cell, mStore, mReaders, [&](const ESM4::Reference& ref) { loadRef(ref); });
|
||||||
|
visitCell4ActorReferences(cell, mStore, mReaders, [&](const ESM4::ActorCharacter& ref) { loadRef(ref); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CellStore::loadRefs()
|
void CellStore::loadRefs()
|
||||||
|
@ -888,6 +910,16 @@ namespace MWWorld
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CellStore::loadRef(const ESM4::ActorCharacter& ref)
|
||||||
|
{
|
||||||
|
const MWWorld::ESMStore& store = mStore;
|
||||||
|
ESM::RecNameInts foundType = static_cast<ESM::RecNameInts>(store.find(ref.mBaseObj));
|
||||||
|
|
||||||
|
Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&ref, &store, foundType](auto& x) {
|
||||||
|
recNameSwitcher(x, foundType, [&ref, &store](auto& storeIn) { storeIn.load(ref, store); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void CellStore::loadRef(ESM::CellRef& ref, bool deleted, std::map<ESM::RefNum, ESM::RefId>& refNumToID)
|
void CellStore::loadRef(ESM::CellRef& ref, bool deleted, std::map<ESM::RefNum, ESM::RefId>& refNumToID)
|
||||||
{
|
{
|
||||||
const MWWorld::ESMStore& store = mStore;
|
const MWWorld::ESMStore& store = mStore;
|
||||||
|
|
|
@ -58,6 +58,7 @@ namespace ESM4
|
||||||
class Reader;
|
class Reader;
|
||||||
struct Cell;
|
struct Cell;
|
||||||
struct Reference;
|
struct Reference;
|
||||||
|
struct ActorCharacter;
|
||||||
struct Static;
|
struct Static;
|
||||||
struct Light;
|
struct Light;
|
||||||
struct Activator;
|
struct Activator;
|
||||||
|
@ -73,6 +74,8 @@ namespace ESM4
|
||||||
struct MiscItem;
|
struct MiscItem;
|
||||||
struct Tree;
|
struct Tree;
|
||||||
struct Weapon;
|
struct Weapon;
|
||||||
|
struct Creature;
|
||||||
|
struct Npc;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
|
@ -90,7 +93,8 @@ namespace MWWorld
|
||||||
CellRefList<ESM4::Static>, CellRefList<ESM4::Light>, CellRefList<ESM4::Activator>, CellRefList<ESM4::Potion>,
|
CellRefList<ESM4::Static>, CellRefList<ESM4::Light>, CellRefList<ESM4::Activator>, CellRefList<ESM4::Potion>,
|
||||||
CellRefList<ESM4::Ammunition>, CellRefList<ESM4::Armor>, CellRefList<ESM4::Book>, CellRefList<ESM4::Clothing>,
|
CellRefList<ESM4::Ammunition>, CellRefList<ESM4::Armor>, CellRefList<ESM4::Book>, CellRefList<ESM4::Clothing>,
|
||||||
CellRefList<ESM4::Container>, CellRefList<ESM4::Door>, CellRefList<ESM4::Ingredient>, CellRefList<ESM4::Tree>,
|
CellRefList<ESM4::Container>, CellRefList<ESM4::Door>, CellRefList<ESM4::Ingredient>, CellRefList<ESM4::Tree>,
|
||||||
CellRefList<ESM4::MiscItem>, CellRefList<ESM4::Weapon>, CellRefList<ESM4::Furniture>>;
|
CellRefList<ESM4::MiscItem>, CellRefList<ESM4::Weapon>, CellRefList<ESM4::Furniture>,
|
||||||
|
CellRefList<ESM4::Creature>, CellRefList<ESM4::Npc>>;
|
||||||
|
|
||||||
/// \brief Mutable state of a cell
|
/// \brief Mutable state of a cell
|
||||||
class CellStore
|
class CellStore
|
||||||
|
@ -420,6 +424,7 @@ namespace MWWorld
|
||||||
void loadRefs();
|
void loadRefs();
|
||||||
|
|
||||||
void loadRef(const ESM4::Reference& ref);
|
void loadRef(const ESM4::Reference& ref);
|
||||||
|
void loadRef(const ESM4::ActorCharacter& ref);
|
||||||
void loadRef(ESM::CellRef& ref, bool deleted, std::map<ESM::RefNum, ESM::RefId>& refNumToID);
|
void loadRef(ESM::CellRef& ref, bool deleted, std::map<ESM::RefNum, ESM::RefId>& refNumToID);
|
||||||
///< Make case-adjustments to \a ref and insert it into the respective container.
|
///< Make case-adjustments to \a ref and insert it into the respective container.
|
||||||
///
|
///
|
||||||
|
|
|
@ -278,6 +278,8 @@ namespace MWWorld
|
||||||
case ESM::REC_STAT:
|
case ESM::REC_STAT:
|
||||||
case ESM::REC_WEAP:
|
case ESM::REC_WEAP:
|
||||||
case ESM::REC_BODY:
|
case ESM::REC_BODY:
|
||||||
|
case ESM::REC_ACHR4:
|
||||||
|
case ESM::REC_ACRE4:
|
||||||
case ESM::REC_STAT4:
|
case ESM::REC_STAT4:
|
||||||
case ESM::REC_LIGH4:
|
case ESM::REC_LIGH4:
|
||||||
case ESM::REC_ACTI4:
|
case ESM::REC_ACTI4:
|
||||||
|
@ -286,10 +288,15 @@ namespace MWWorld
|
||||||
case ESM::REC_ARMO4:
|
case ESM::REC_ARMO4:
|
||||||
case ESM::REC_BOOK4:
|
case ESM::REC_BOOK4:
|
||||||
case ESM::REC_CONT4:
|
case ESM::REC_CONT4:
|
||||||
|
case ESM::REC_CREA4:
|
||||||
case ESM::REC_DOOR4:
|
case ESM::REC_DOOR4:
|
||||||
case ESM::REC_FURN4:
|
case ESM::REC_FURN4:
|
||||||
case ESM::REC_INGR4:
|
case ESM::REC_INGR4:
|
||||||
|
case ESM::REC_LVLC4:
|
||||||
|
case ESM::REC_LVLN4:
|
||||||
case ESM::REC_MISC4:
|
case ESM::REC_MISC4:
|
||||||
|
case ESM::REC_NPC_4:
|
||||||
|
case ESM::REC_RACE4:
|
||||||
case ESM::REC_TREE4:
|
case ESM::REC_TREE4:
|
||||||
case ESM::REC_WEAP4:
|
case ESM::REC_WEAP4:
|
||||||
return true;
|
return true;
|
||||||
|
@ -439,6 +446,8 @@ namespace MWWorld
|
||||||
getWritable<ESM::Attribute>().setUp(get<ESM::GameSetting>());
|
getWritable<ESM::Attribute>().setUp(get<ESM::GameSetting>());
|
||||||
getWritable<ESM4::Land>().updateLandPositions(get<ESM4::Cell>());
|
getWritable<ESM4::Land>().updateLandPositions(get<ESM4::Cell>());
|
||||||
getWritable<ESM4::Reference>().preprocessReferences(get<ESM4::Cell>());
|
getWritable<ESM4::Reference>().preprocessReferences(get<ESM4::Cell>());
|
||||||
|
getWritable<ESM4::ActorCharacter>().preprocessReferences(get<ESM4::Cell>());
|
||||||
|
getWritable<ESM4::ActorCreature>().preprocessReferences(get<ESM4::Cell>());
|
||||||
|
|
||||||
rebuildIdsIndex();
|
rebuildIdsIndex();
|
||||||
mStoreImp->mStaticIds = mStoreImp->mIds;
|
mStoreImp->mStaticIds = mStoreImp->mIds;
|
||||||
|
|
|
@ -31,6 +31,8 @@ namespace ESM4
|
||||||
struct Cell;
|
struct Cell;
|
||||||
struct Light;
|
struct Light;
|
||||||
struct Reference;
|
struct Reference;
|
||||||
|
struct ActorCharacter;
|
||||||
|
struct ActorCreature;
|
||||||
struct Activator;
|
struct Activator;
|
||||||
struct Potion;
|
struct Potion;
|
||||||
struct Ammunition;
|
struct Ammunition;
|
||||||
|
@ -38,10 +40,15 @@ namespace ESM4
|
||||||
struct Book;
|
struct Book;
|
||||||
struct Clothing;
|
struct Clothing;
|
||||||
struct Container;
|
struct Container;
|
||||||
|
struct Creature;
|
||||||
struct Door;
|
struct Door;
|
||||||
struct Furniture;
|
struct Furniture;
|
||||||
struct Ingredient;
|
struct Ingredient;
|
||||||
|
struct LevelledCreature;
|
||||||
|
struct LevelledNpc;
|
||||||
struct MiscItem;
|
struct MiscItem;
|
||||||
|
struct Npc;
|
||||||
|
struct Race;
|
||||||
struct Tree;
|
struct Tree;
|
||||||
struct Weapon;
|
struct Weapon;
|
||||||
struct World;
|
struct World;
|
||||||
|
@ -124,7 +131,9 @@ namespace MWWorld
|
||||||
Store<ESM4::Static>, Store<ESM4::Cell>, Store<ESM4::Light>, Store<ESM4::Reference>, Store<ESM4::Activator>,
|
Store<ESM4::Static>, Store<ESM4::Cell>, Store<ESM4::Light>, Store<ESM4::Reference>, Store<ESM4::Activator>,
|
||||||
Store<ESM4::Potion>, Store<ESM4::Ammunition>, Store<ESM4::Armor>, Store<ESM4::Book>, Store<ESM4::Clothing>,
|
Store<ESM4::Potion>, Store<ESM4::Ammunition>, Store<ESM4::Armor>, Store<ESM4::Book>, Store<ESM4::Clothing>,
|
||||||
Store<ESM4::Container>, Store<ESM4::Door>, Store<ESM4::Ingredient>, Store<ESM4::MiscItem>,
|
Store<ESM4::Container>, Store<ESM4::Door>, Store<ESM4::Ingredient>, Store<ESM4::MiscItem>,
|
||||||
Store<ESM4::Tree>, Store<ESM4::Weapon>, Store<ESM4::World>, Store<ESM4::Furniture>, Store<ESM4::Land>>;
|
Store<ESM4::Tree>, Store<ESM4::Weapon>, Store<ESM4::World>, Store<ESM4::Furniture>, Store<ESM4::Land>,
|
||||||
|
Store<ESM4::ActorCharacter>, Store<ESM4::ActorCreature>, Store<ESM4::Race>, Store<ESM4::Creature>,
|
||||||
|
Store<ESM4::LevelledCreature>, Store<ESM4::Npc>, Store<ESM4::LevelledNpc>>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -28,6 +28,13 @@ MWWorld::LiveCellRefBase::LiveCellRefBase(unsigned int type, const ESM4::Referen
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWWorld::LiveCellRefBase::LiveCellRefBase(unsigned int type, const ESM4::ActorCharacter& cref)
|
||||||
|
: mClass(&Class::get(type))
|
||||||
|
, mRef(cref)
|
||||||
|
, mData(cref)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void MWWorld::LiveCellRefBase::loadImp(const ESM::ObjectState& state)
|
void MWWorld::LiveCellRefBase::loadImp(const ESM::ObjectState& state)
|
||||||
{
|
{
|
||||||
mRef = MWWorld::CellRef(state.mRef);
|
mRef = MWWorld::CellRef(state.mRef);
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace MWWorld
|
||||||
|
|
||||||
LiveCellRefBase(unsigned int type, const ESM::CellRef& cref = ESM::CellRef());
|
LiveCellRefBase(unsigned int type, const ESM::CellRef& cref = ESM::CellRef());
|
||||||
LiveCellRefBase(unsigned int type, const ESM4::Reference& cref);
|
LiveCellRefBase(unsigned int type, const ESM4::Reference& cref);
|
||||||
|
LiveCellRefBase(unsigned int type, const ESM4::ActorCharacter& cref);
|
||||||
/* Need this for the class to be recognized as polymorphic */
|
/* Need this for the class to be recognized as polymorphic */
|
||||||
virtual ~LiveCellRefBase() {}
|
virtual ~LiveCellRefBase() {}
|
||||||
|
|
||||||
|
@ -122,6 +123,12 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LiveCellRef(const ESM4::ActorCharacter& cref, const X* b = nullptr)
|
||||||
|
: LiveCellRefBase(X::sRecordId, cref)
|
||||||
|
, mBase(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
LiveCellRef(const X* b = nullptr)
|
LiveCellRef(const X* b = nullptr)
|
||||||
: LiveCellRefBase(X::sRecordId)
|
: LiveCellRefBase(X::sRecordId)
|
||||||
, mBase(b)
|
, mBase(b)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "refdata.hpp"
|
#include "refdata.hpp"
|
||||||
|
|
||||||
#include <components/esm3/objectstate.hpp>
|
#include <components/esm3/objectstate.hpp>
|
||||||
|
#include <components/esm4/loadachr.hpp>
|
||||||
|
#include <components/esm4/loadrefr.hpp>
|
||||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||||
|
|
||||||
#include "customdata.hpp"
|
#include "customdata.hpp"
|
||||||
|
@ -98,6 +100,19 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefData::RefData(const ESM4::ActorCharacter& ref)
|
||||||
|
: mBaseNode(nullptr)
|
||||||
|
, mDeletedByContentFile(ref.mFlags & ESM4::Rec_Deleted)
|
||||||
|
, mEnabled(!(ref.mFlags & ESM4::Rec_Disabled))
|
||||||
|
, mPhysicsPostponed(false)
|
||||||
|
, mCount(mDeletedByContentFile ? 0 : 1)
|
||||||
|
, mPosition(ref.mPos)
|
||||||
|
, mCustomData(nullptr)
|
||||||
|
, mChanged(false)
|
||||||
|
, mFlags(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
RefData::RefData(const ESM::ObjectState& objectState, bool deletedByContentFile)
|
RefData::RefData(const ESM::ObjectState& objectState, bool deletedByContentFile)
|
||||||
: mBaseNode(nullptr)
|
: mBaseNode(nullptr)
|
||||||
, mDeletedByContentFile(deletedByContentFile)
|
, mDeletedByContentFile(deletedByContentFile)
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace ESM
|
||||||
|
|
||||||
namespace ESM4
|
namespace ESM4
|
||||||
{
|
{
|
||||||
|
struct ActorCharacter;
|
||||||
struct Reference;
|
struct Reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ namespace MWWorld
|
||||||
/// to reset the position as the original data is still held in the CellRef
|
/// to reset the position as the original data is still held in the CellRef
|
||||||
RefData(const ESM::CellRef& cellRef);
|
RefData(const ESM::CellRef& cellRef);
|
||||||
RefData(const ESM4::Reference& cellRef);
|
RefData(const ESM4::Reference& cellRef);
|
||||||
|
RefData(const ESM4::ActorCharacter& cellRef);
|
||||||
|
|
||||||
RefData(const ESM::ObjectState& objectState, bool deletedByContentFile);
|
RefData(const ESM::ObjectState& objectState, bool deletedByContentFile);
|
||||||
///< Ignores local variables and custom data (not enough context available here to
|
///< Ignores local variables and custom data (not enough context available here to
|
||||||
|
|
|
@ -1326,33 +1326,6 @@ namespace MWWorld
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return foundLand->second;
|
return foundLand->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ESM4 Reference
|
|
||||||
//=========================================================================
|
|
||||||
|
|
||||||
void Store<ESM4::Reference>::preprocessReferences(const Store<ESM4::Cell>& cells)
|
|
||||||
{
|
|
||||||
for (auto& [_, ref] : mStatic)
|
|
||||||
{
|
|
||||||
const ESM4::Cell* cell = cells.find(ref.mParent);
|
|
||||||
if (cell->isExterior() && (cell->mFlags & ESM4::Rec_Persistent))
|
|
||||||
{
|
|
||||||
const ESM4::Cell* actualCell = cells.searchExterior(
|
|
||||||
positionToExteriorCellLocation(ref.mPos.pos[0], ref.mPos.pos[1], cell->mParent));
|
|
||||||
if (actualCell)
|
|
||||||
ref.mParent = actualCell->mId;
|
|
||||||
}
|
|
||||||
mPerCellReferences[ref.mParent].push_back(&ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::span<const ESM4::Reference* const> Store<ESM4::Reference>::getByCell(ESM::RefId cellId) const
|
|
||||||
{
|
|
||||||
auto it = mPerCellReferences.find(cellId);
|
|
||||||
if (it == mPerCellReferences.end())
|
|
||||||
return {};
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template class MWWorld::TypedDynamicStore<ESM::Activator>;
|
template class MWWorld::TypedDynamicStore<ESM::Activator>;
|
||||||
|
@ -1405,14 +1378,21 @@ template class MWWorld::TypedDynamicStore<ESM4::Armor>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Book>;
|
template class MWWorld::TypedDynamicStore<ESM4::Book>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Clothing>;
|
template class MWWorld::TypedDynamicStore<ESM4::Clothing>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Container>;
|
template class MWWorld::TypedDynamicStore<ESM4::Container>;
|
||||||
|
template class MWWorld::TypedDynamicStore<ESM4::Creature>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Door>;
|
template class MWWorld::TypedDynamicStore<ESM4::Door>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Furniture>;
|
template class MWWorld::TypedDynamicStore<ESM4::Furniture>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Ingredient>;
|
template class MWWorld::TypedDynamicStore<ESM4::Ingredient>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::MiscItem>;
|
template class MWWorld::TypedDynamicStore<ESM4::MiscItem>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Static>;
|
template class MWWorld::TypedDynamicStore<ESM4::Static>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Tree>;
|
template class MWWorld::TypedDynamicStore<ESM4::Tree>;
|
||||||
|
template class MWWorld::TypedDynamicStore<ESM4::LevelledCreature>;
|
||||||
|
template class MWWorld::TypedDynamicStore<ESM4::LevelledNpc>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Light>;
|
template class MWWorld::TypedDynamicStore<ESM4::Light>;
|
||||||
|
template class MWWorld::TypedDynamicStore<ESM4::Npc>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Reference, ESM::FormId>;
|
template class MWWorld::TypedDynamicStore<ESM4::Reference, ESM::FormId>;
|
||||||
|
template class MWWorld::TypedDynamicStore<ESM4::ActorCharacter, ESM::FormId>;
|
||||||
|
template class MWWorld::TypedDynamicStore<ESM4::ActorCreature, ESM::FormId>;
|
||||||
|
template class MWWorld::TypedDynamicStore<ESM4::Race>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Cell>;
|
template class MWWorld::TypedDynamicStore<ESM4::Cell>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::Weapon>;
|
template class MWWorld::TypedDynamicStore<ESM4::Weapon>;
|
||||||
template class MWWorld::TypedDynamicStore<ESM4::World>;
|
template class MWWorld::TypedDynamicStore<ESM4::World>;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <components/esm3/loadland.hpp>
|
#include <components/esm3/loadland.hpp>
|
||||||
#include <components/esm3/loadpgrd.hpp>
|
#include <components/esm3/loadpgrd.hpp>
|
||||||
#include <components/esm3/loadskil.hpp>
|
#include <components/esm3/loadskil.hpp>
|
||||||
|
#include <components/esm4/loadachr.hpp>
|
||||||
#include <components/esm4/loadcell.hpp>
|
#include <components/esm4/loadcell.hpp>
|
||||||
#include <components/esm4/loadland.hpp>
|
#include <components/esm4/loadland.hpp>
|
||||||
#include <components/esm4/loadrefr.hpp>
|
#include <components/esm4/loadrefr.hpp>
|
||||||
|
@ -581,16 +582,51 @@ namespace MWWorld
|
||||||
const MWDialogue::KeywordSearch<int>& getDialogIdKeywordSearch() const;
|
const MWDialogue::KeywordSearch<int>& getDialogIdKeywordSearch() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <typename T>
|
||||||
class Store<ESM4::Reference> : public TypedDynamicStore<ESM4::Reference, ESM::FormId>
|
class ESM4RefsStore : public TypedDynamicStore<T, ESM::FormId>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void preprocessReferences(const Store<ESM4::Cell>& cells);
|
void preprocessReferences(const Store<ESM4::Cell>& cells)
|
||||||
|
{
|
||||||
|
for (auto& [_, ref] : this->mStatic)
|
||||||
|
{
|
||||||
|
const ESM4::Cell* cell = cells.find(ref.mParent);
|
||||||
|
if (cell->isExterior() && (cell->mFlags & ESM4::Rec_Persistent))
|
||||||
|
{
|
||||||
|
const ESM4::Cell* actualCell = cells.searchExterior(
|
||||||
|
positionToExteriorCellLocation(ref.mPos.pos[0], ref.mPos.pos[1], cell->mParent));
|
||||||
|
if (actualCell)
|
||||||
|
ref.mParent = actualCell->mId;
|
||||||
|
}
|
||||||
|
mPerCellReferences[ref.mParent].push_back(&ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::span<const ESM4::Reference* const> getByCell(ESM::RefId cellId) const;
|
std::span<const T* const> getByCell(ESM::RefId cellId) const
|
||||||
|
{
|
||||||
|
auto it = mPerCellReferences.find(cellId);
|
||||||
|
if (it == mPerCellReferences.end())
|
||||||
|
return {};
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<ESM::RefId, std::vector<ESM4::Reference*>> mPerCellReferences;
|
std::unordered_map<ESM::RefId, std::vector<T*>> mPerCellReferences;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class Store<ESM4::Reference> : public ESM4RefsStore<ESM4::Reference>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class Store<ESM4::ActorCharacter> : public ESM4RefsStore<ESM4::ActorCharacter>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class Store<ESM4::ActorCreature> : public ESM4RefsStore<ESM4::ActorCreature>
|
||||||
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <components/esm4/inventory.hpp>
|
#include <components/esm4/inventory.hpp>
|
||||||
#include <components/esm4/lighting.hpp>
|
#include <components/esm4/lighting.hpp>
|
||||||
#include <components/esm4/loadachr.hpp>
|
#include <components/esm4/loadachr.hpp>
|
||||||
#include <components/esm4/loadacre.hpp>
|
|
||||||
#include <components/esm4/loadacti.hpp>
|
#include <components/esm4/loadacti.hpp>
|
||||||
#include <components/esm4/loadalch.hpp>
|
#include <components/esm4/loadalch.hpp>
|
||||||
#include <components/esm4/loadaloc.hpp>
|
#include <components/esm4/loadaloc.hpp>
|
||||||
|
|
|
@ -161,7 +161,6 @@ add_component_dir (esm4
|
||||||
inventory
|
inventory
|
||||||
lighting
|
lighting
|
||||||
loadachr
|
loadachr
|
||||||
loadacre
|
|
||||||
loadacti
|
loadacti
|
||||||
loadalch
|
loadalch
|
||||||
loadaloc
|
loadaloc
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#ifndef COMPONENTS_ESM_ESMBRIDGE
|
#ifndef COMPONENTS_ESM_ESMBRIDGE
|
||||||
#define COMPONENTS_ESM_ESMBRIDGE
|
#define COMPONENTS_ESM_ESMBRIDGE
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include <components/esm3/cellref.hpp>
|
#include <components/esm3/cellref.hpp>
|
||||||
|
#include <components/esm4/loadachr.hpp>
|
||||||
#include <components/esm4/loadrefr.hpp>
|
#include <components/esm4/loadrefr.hpp>
|
||||||
|
|
||||||
namespace ESM4
|
namespace ESM4
|
||||||
|
@ -52,25 +54,22 @@ namespace ESM
|
||||||
|
|
||||||
struct ReferenceVariant
|
struct ReferenceVariant
|
||||||
{
|
{
|
||||||
std::variant<ESM::CellRef, ESM4::Reference> mVariant;
|
std::variant<ESM::CellRef, ESM4::Reference, ESM4::ActorCharacter> mVariant;
|
||||||
|
|
||||||
explicit ReferenceVariant(const ESM4::Reference& ref)
|
explicit ReferenceVariant(const ESM4::Reference& ref)
|
||||||
: mVariant(ref)
|
: mVariant(ref)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit ReferenceVariant(const ESM4::ActorCharacter& ref)
|
||||||
|
: mVariant(ref)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
explicit ReferenceVariant(const ESM::CellRef& ref)
|
explicit ReferenceVariant(const ESM::CellRef& ref)
|
||||||
: mVariant(ref)
|
: mVariant(ref)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isESM4() const { return std::holds_alternative<ESM4::Reference>(mVariant); }
|
|
||||||
|
|
||||||
const ESM::CellRef& getEsm3() const { return std::get<ESM::CellRef>(mVariant); }
|
|
||||||
const ESM4::Reference& getEsm4() const { return std::get<ESM4::Reference>(mVariant); }
|
|
||||||
|
|
||||||
ESM::CellRef& getEsm3() { return std::get<ESM::CellRef>(mVariant); }
|
|
||||||
ESM4::Reference& getEsm4() { return std::get<ESM4::Reference>(mVariant); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class F, class... T>
|
template <class F, class... T>
|
||||||
|
|
|
@ -51,11 +51,16 @@
|
||||||
#include <components/esm4/loadcell.hpp>
|
#include <components/esm4/loadcell.hpp>
|
||||||
#include <components/esm4/loadclot.hpp>
|
#include <components/esm4/loadclot.hpp>
|
||||||
#include <components/esm4/loadcont.hpp>
|
#include <components/esm4/loadcont.hpp>
|
||||||
|
#include <components/esm4/loadcrea.hpp>
|
||||||
#include <components/esm4/loaddoor.hpp>
|
#include <components/esm4/loaddoor.hpp>
|
||||||
#include <components/esm4/loadfurn.hpp>
|
#include <components/esm4/loadfurn.hpp>
|
||||||
#include <components/esm4/loadingr.hpp>
|
#include <components/esm4/loadingr.hpp>
|
||||||
#include <components/esm4/loadligh.hpp>
|
#include <components/esm4/loadligh.hpp>
|
||||||
|
#include <components/esm4/loadlvlc.hpp>
|
||||||
|
#include <components/esm4/loadlvln.hpp>
|
||||||
#include <components/esm4/loadmisc.hpp>
|
#include <components/esm4/loadmisc.hpp>
|
||||||
|
#include <components/esm4/loadnpc.hpp>
|
||||||
|
#include <components/esm4/loadrace.hpp>
|
||||||
#include <components/esm4/loadrefr.hpp>
|
#include <components/esm4/loadrefr.hpp>
|
||||||
#include <components/esm4/loadstat.hpp>
|
#include <components/esm4/loadstat.hpp>
|
||||||
#include <components/esm4/loadtree.hpp>
|
#include <components/esm4/loadtree.hpp>
|
||||||
|
|
|
@ -33,10 +33,10 @@
|
||||||
|
|
||||||
void ESM4::ActorCharacter::load(ESM4::Reader& reader)
|
void ESM4::ActorCharacter::load(ESM4::Reader& reader)
|
||||||
{
|
{
|
||||||
mFormId = reader.hdr().record.getFormId();
|
mId = reader.hdr().record.getFormId();
|
||||||
reader.adjustFormId(mFormId);
|
reader.adjustFormId(mId);
|
||||||
mFlags = reader.hdr().record.flags;
|
mFlags = reader.hdr().record.flags;
|
||||||
mParent = reader.currCell(); // NOTE: only for persistent achr? (aren't they all persistent?)
|
mParent = ESM::RefId::formIdRefId(reader.currCell());
|
||||||
|
|
||||||
while (reader.getSubRecordHeader())
|
while (reader.getSubRecordHeader())
|
||||||
{
|
{
|
||||||
|
@ -50,10 +50,14 @@ void ESM4::ActorCharacter::load(ESM4::Reader& reader)
|
||||||
reader.getZString(mFullName);
|
reader.getZString(mFullName);
|
||||||
break;
|
break;
|
||||||
case ESM4::SUB_NAME:
|
case ESM4::SUB_NAME:
|
||||||
reader.getFormId(mBaseObj);
|
{
|
||||||
|
FormId baseId;
|
||||||
|
reader.getFormId(baseId);
|
||||||
|
mBaseObj = ESM::RefId::formIdRefId(baseId);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ESM4::SUB_DATA:
|
case ESM4::SUB_DATA:
|
||||||
reader.get(mPlacement);
|
reader.get(mPos);
|
||||||
break;
|
break;
|
||||||
case ESM4::SUB_XSCL:
|
case ESM4::SUB_XSCL:
|
||||||
reader.get(mScale);
|
reader.get(mScale);
|
||||||
|
@ -97,7 +101,7 @@ void ESM4::ActorCharacter::load(ESM4::Reader& reader)
|
||||||
reader.skipSubRecordData();
|
reader.skipSubRecordData();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("ESM4::ACHR::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
|
throw std::runtime_error("ESM4 ACHR/ACRE load - Unknown subrecord " + ESM::printName(subHdr.typeId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
#include "reference.hpp" // FormId, Placement, EnableParent
|
#include "reference.hpp" // FormId, Placement, EnableParent
|
||||||
|
|
||||||
namespace ESM4
|
namespace ESM4
|
||||||
|
@ -38,22 +41,19 @@ namespace ESM4
|
||||||
|
|
||||||
struct ActorCharacter
|
struct ActorCharacter
|
||||||
{
|
{
|
||||||
FormId mParent; // cell formId, from the loading sequence
|
ESM::FormId mId; // from the header
|
||||||
// NOTE: for exterior cells it will be the dummy cell FormId
|
ESM::RefId mParent; // cell FormId , from the loading sequence
|
||||||
|
// NOTE: for exterior cells it will be the dummy cell FormId
|
||||||
FormId mFormId; // from the header
|
|
||||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||||
|
|
||||||
std::string mEditorId;
|
std::string mEditorId;
|
||||||
std::string mFullName;
|
std::string mFullName;
|
||||||
FormId mBaseObj;
|
ESM::RefId mBaseObj;
|
||||||
|
|
||||||
Placement mPlacement;
|
ESM::Position mPos;
|
||||||
float mScale = 1.0f;
|
float mScale = 1.0f;
|
||||||
FormId mOwner;
|
ESM::FormId mOwner;
|
||||||
FormId mGlobal;
|
ESM::FormId mGlobal;
|
||||||
|
|
||||||
bool mInitiallyDisabled; // TODO may need to check mFlags & 0x800 (initially disabled)
|
|
||||||
|
|
||||||
EnableParent mEsp;
|
EnableParent mEsp;
|
||||||
|
|
||||||
|
@ -61,6 +61,12 @@ namespace ESM4
|
||||||
// void save(ESM4::Writer& writer) const;
|
// void save(ESM4::Writer& writer) const;
|
||||||
|
|
||||||
// void blank();
|
// void blank();
|
||||||
|
static constexpr ESM::RecNameInts sRecordId = ESM::REC_ACHR4;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ActorCreature : public ActorCharacter
|
||||||
|
{
|
||||||
|
static constexpr ESM::RecNameInts sRecordId = ESM::REC_ACRE4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2016, 2018, 2020 cc9cii
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
|
|
||||||
cc9cii cc9c@iinet.net.au
|
|
||||||
|
|
||||||
Much of the information on the data structures are based on the information
|
|
||||||
from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
|
|
||||||
trial & error. See http://en.uesp.net/wiki for details.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include "loadacre.hpp"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include "reader.hpp"
|
|
||||||
//#include "writer.hpp"
|
|
||||||
|
|
||||||
void ESM4::ActorCreature::load(ESM4::Reader& reader)
|
|
||||||
{
|
|
||||||
mFormId = reader.hdr().record.getFormId();
|
|
||||||
reader.adjustFormId(mFormId);
|
|
||||||
mFlags = reader.hdr().record.flags;
|
|
||||||
|
|
||||||
while (reader.getSubRecordHeader())
|
|
||||||
{
|
|
||||||
const ESM4::SubRecordHeader& subHdr = reader.subRecordHeader();
|
|
||||||
switch (subHdr.typeId)
|
|
||||||
{
|
|
||||||
case ESM4::SUB_EDID:
|
|
||||||
reader.getZString(mEditorId);
|
|
||||||
break;
|
|
||||||
case ESM4::SUB_NAME:
|
|
||||||
reader.getFormId(mBaseObj);
|
|
||||||
break;
|
|
||||||
case ESM4::SUB_DATA:
|
|
||||||
reader.get(mPlacement);
|
|
||||||
break;
|
|
||||||
case ESM4::SUB_XSCL:
|
|
||||||
reader.get(mScale);
|
|
||||||
break;
|
|
||||||
case ESM4::SUB_XESP:
|
|
||||||
reader.getFormId(mEsp.parent);
|
|
||||||
reader.get(mEsp.flags);
|
|
||||||
break;
|
|
||||||
case ESM4::SUB_XOWN:
|
|
||||||
reader.getFormId(mOwner);
|
|
||||||
break;
|
|
||||||
case ESM4::SUB_XGLB:
|
|
||||||
reader.getFormId(mGlobal);
|
|
||||||
break;
|
|
||||||
case ESM4::SUB_XRNK:
|
|
||||||
reader.get(mFactionRank);
|
|
||||||
break;
|
|
||||||
case ESM4::SUB_XLKR: // FO3
|
|
||||||
case ESM4::SUB_XLCM: // FO3
|
|
||||||
case ESM4::SUB_XEZN: // FO3
|
|
||||||
case ESM4::SUB_XMRC: // FO3
|
|
||||||
case ESM4::SUB_XAPD: // FO3
|
|
||||||
case ESM4::SUB_XAPR: // FO3
|
|
||||||
case ESM4::SUB_XRDS: // FO3
|
|
||||||
case ESM4::SUB_XPRD: // FO3
|
|
||||||
case ESM4::SUB_XATO: // FONV
|
|
||||||
// seems to occur only for dead bodies, e.g. DeadMuffy, DeadDogVicious
|
|
||||||
case ESM4::SUB_XRGD: // ragdoll
|
|
||||||
case ESM4::SUB_XRGB: // ragdoll biped
|
|
||||||
reader.skipSubRecordData();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("ESM4::ACRE::load - Unknown subrecord " + ESM::printName(subHdr.typeId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// void ESM4::ActorCreature::save(ESM4::Writer& writer) const
|
|
||||||
//{
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void ESM4::ActorCreature::blank()
|
|
||||||
//{
|
|
||||||
// }
|
|
|
@ -1,64 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2016, 2018, 2020 cc9cii
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
|
|
||||||
cc9cii cc9c@iinet.net.au
|
|
||||||
|
|
||||||
Much of the information on the data structures are based on the information
|
|
||||||
from Tes4Mod:Mod_File_Format and Tes5Mod:File_Formats but also refined by
|
|
||||||
trial & error. See http://en.uesp.net/wiki for details.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef ESM4_ACRE_H
|
|
||||||
#define ESM4_ACRE_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "reference.hpp" // FormId, Placement, EnableParent
|
|
||||||
|
|
||||||
namespace ESM4
|
|
||||||
{
|
|
||||||
class Reader;
|
|
||||||
class Writer;
|
|
||||||
|
|
||||||
struct ActorCreature
|
|
||||||
{
|
|
||||||
FormId mFormId; // from the header
|
|
||||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
|
||||||
|
|
||||||
std::string mEditorId;
|
|
||||||
FormId mBaseObj;
|
|
||||||
|
|
||||||
Placement mPlacement;
|
|
||||||
float mScale = 1.0f;
|
|
||||||
FormId mOwner;
|
|
||||||
FormId mGlobal;
|
|
||||||
std::uint32_t mFactionRank;
|
|
||||||
|
|
||||||
bool mInitiallyDisabled; // TODO may need to check mFlags & 0x800 (initially disabled)
|
|
||||||
|
|
||||||
EnableParent mEsp;
|
|
||||||
|
|
||||||
void load(ESM4::Reader& reader);
|
|
||||||
// void save(ESM4::Writer& writer) const;
|
|
||||||
|
|
||||||
// void blank();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ESM4_ACRE_H
|
|
|
@ -37,8 +37,7 @@
|
||||||
|
|
||||||
void ESM4::Creature::load(ESM4::Reader& reader)
|
void ESM4::Creature::load(ESM4::Reader& reader)
|
||||||
{
|
{
|
||||||
mFormId = reader.hdr().record.getFormId();
|
mId = reader.getRefIdFromHeader();
|
||||||
reader.adjustFormId(mFormId);
|
|
||||||
mFlags = reader.hdr().record.flags;
|
mFlags = reader.hdr().record.flags;
|
||||||
|
|
||||||
while (reader.getSubRecordHeader())
|
while (reader.getSubRecordHeader())
|
||||||
|
@ -153,7 +152,7 @@ void ESM4::Creature::load(ESM4::Reader& reader)
|
||||||
std::uint32_t nift;
|
std::uint32_t nift;
|
||||||
reader.get(nift);
|
reader.get(nift);
|
||||||
if (nift)
|
if (nift)
|
||||||
Log(Debug::Verbose) << "CREA NIFT " << mFormId << ", non-zero " << nift;
|
Log(Debug::Verbose) << "CREA NIFT " << mId << ", non-zero " << nift;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESM4::SUB_KFFZ:
|
case ESM4::SUB_KFFZ:
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
#include "actor.hpp"
|
#include "actor.hpp"
|
||||||
#include "inventory.hpp"
|
#include "inventory.hpp"
|
||||||
|
|
||||||
|
@ -103,7 +106,7 @@ namespace ESM4
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
FormId mFormId; // from the header
|
ESM::RefId mId; // from the header
|
||||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||||
|
|
||||||
std::string mEditorId;
|
std::string mEditorId;
|
||||||
|
@ -142,6 +145,7 @@ namespace ESM4
|
||||||
// void save(ESM4::Writer& writer) const;
|
// void save(ESM4::Writer& writer) const;
|
||||||
|
|
||||||
// void blank();
|
// void blank();
|
||||||
|
static constexpr ESM::RecNameInts sRecordId = ESM::RecNameInts::REC_CREA4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,7 @@
|
||||||
|
|
||||||
void ESM4::LevelledCreature::load(ESM4::Reader& reader)
|
void ESM4::LevelledCreature::load(ESM4::Reader& reader)
|
||||||
{
|
{
|
||||||
mFormId = reader.hdr().record.getFormId();
|
mId = reader.getRefIdFromHeader();
|
||||||
reader.adjustFormId(mFormId);
|
|
||||||
mFlags = reader.hdr().record.flags;
|
mFlags = reader.hdr().record.flags;
|
||||||
|
|
||||||
while (reader.getSubRecordHeader())
|
while (reader.getSubRecordHeader())
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
#include "formid.hpp"
|
#include "formid.hpp"
|
||||||
#include "inventory.hpp"
|
#include "inventory.hpp"
|
||||||
|
|
||||||
|
@ -40,7 +43,7 @@ namespace ESM4
|
||||||
|
|
||||||
struct LevelledCreature
|
struct LevelledCreature
|
||||||
{
|
{
|
||||||
FormId mFormId; // from the header
|
ESM::RefId mId; // from the header
|
||||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||||
|
|
||||||
std::string mEditorId;
|
std::string mEditorId;
|
||||||
|
@ -62,6 +65,7 @@ namespace ESM4
|
||||||
// void save(ESM4::Writer& writer) const;
|
// void save(ESM4::Writer& writer) const;
|
||||||
|
|
||||||
// void blank();
|
// void blank();
|
||||||
|
static constexpr ESM::RecNameInts sRecordId = ESM::RecNameInts::REC_LVLC4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,7 @@
|
||||||
|
|
||||||
void ESM4::LevelledNpc::load(ESM4::Reader& reader)
|
void ESM4::LevelledNpc::load(ESM4::Reader& reader)
|
||||||
{
|
{
|
||||||
mFormId = reader.hdr().record.getFormId();
|
mId = reader.getRefIdFromHeader();
|
||||||
reader.adjustFormId(mFormId);
|
|
||||||
mFlags = reader.hdr().record.flags;
|
mFlags = reader.hdr().record.flags;
|
||||||
// std::uint32_t esmVer = reader.esmVersion(); // currently unused
|
// std::uint32_t esmVer = reader.esmVersion(); // currently unused
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
#include "formid.hpp"
|
#include "formid.hpp"
|
||||||
#include "inventory.hpp" // LVLO
|
#include "inventory.hpp" // LVLO
|
||||||
|
|
||||||
|
@ -41,7 +44,7 @@ namespace ESM4
|
||||||
|
|
||||||
struct LevelledNpc
|
struct LevelledNpc
|
||||||
{
|
{
|
||||||
FormId mFormId; // from the header
|
ESM::RefId mId; // from the header
|
||||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||||
|
|
||||||
std::string mEditorId;
|
std::string mEditorId;
|
||||||
|
@ -61,6 +64,7 @@ namespace ESM4
|
||||||
// void save(ESM4::Writer& writer) const;
|
// void save(ESM4::Writer& writer) const;
|
||||||
|
|
||||||
// void blank();
|
// void blank();
|
||||||
|
static constexpr ESM::RecNameInts sRecordId = ESM::RecNameInts::REC_LVLN4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,7 @@
|
||||||
|
|
||||||
void ESM4::Npc::load(ESM4::Reader& reader)
|
void ESM4::Npc::load(ESM4::Reader& reader)
|
||||||
{
|
{
|
||||||
mFormId = reader.hdr().record.getFormId();
|
mId = reader.getRefIdFromHeader();
|
||||||
reader.adjustFormId(mFormId);
|
|
||||||
mFlags = reader.hdr().record.flags;
|
mFlags = reader.hdr().record.flags;
|
||||||
|
|
||||||
std::uint32_t esmVer = reader.esmVersion();
|
std::uint32_t esmVer = reader.esmVersion();
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
#include "actor.hpp"
|
#include "actor.hpp"
|
||||||
#include "inventory.hpp"
|
#include "inventory.hpp"
|
||||||
|
|
||||||
|
@ -164,7 +167,7 @@ namespace ESM4
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
FormId mFormId; // from the header
|
ESM::RefId mId; // from the header
|
||||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||||
|
|
||||||
bool mIsTES4;
|
bool mIsTES4;
|
||||||
|
@ -221,6 +224,7 @@ namespace ESM4
|
||||||
// void save(ESM4::Writer& writer) const;
|
// void save(ESM4::Writer& writer) const;
|
||||||
|
|
||||||
// void blank();
|
// void blank();
|
||||||
|
static constexpr ESM::RecNameInts sRecordId = ESM::RecNameInts::REC_NPC_4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,7 @@
|
||||||
|
|
||||||
void ESM4::Race::load(ESM4::Reader& reader)
|
void ESM4::Race::load(ESM4::Reader& reader)
|
||||||
{
|
{
|
||||||
mFormId = reader.hdr().record.getFormId();
|
mId = reader.getRefIdFromHeader();
|
||||||
reader.adjustFormId(mFormId);
|
|
||||||
mFlags = reader.hdr().record.flags;
|
mFlags = reader.hdr().record.flags;
|
||||||
|
|
||||||
std::uint32_t esmVer = reader.esmVersion();
|
std::uint32_t esmVer = reader.esmVersion();
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/esm/refid.hpp>
|
||||||
|
|
||||||
#include "actor.hpp" // AttributeValues, BodyTemplate
|
#include "actor.hpp" // AttributeValues, BodyTemplate
|
||||||
#include "formid.hpp"
|
#include "formid.hpp"
|
||||||
|
|
||||||
|
@ -106,7 +109,7 @@ namespace ESM4
|
||||||
std::string texture; // can be empty e.g. eye left, eye right
|
std::string texture; // can be empty e.g. eye left, eye right
|
||||||
};
|
};
|
||||||
|
|
||||||
FormId mFormId; // from the header
|
ESM::RefId mId; // from the header
|
||||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||||
|
|
||||||
bool mIsTES5;
|
bool mIsTES5;
|
||||||
|
@ -165,6 +168,7 @@ namespace ESM4
|
||||||
// void save(ESM4::Writer& writer) const;
|
// void save(ESM4::Writer& writer) const;
|
||||||
|
|
||||||
// void blank();
|
// void blank();
|
||||||
|
static constexpr ESM::RecNameInts sRecordId = ESM::RecNameInts::REC_RACE4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,11 +36,8 @@ void ESM4::Reference::load(ESM4::Reader& reader)
|
||||||
mId = reader.hdr().record.getFormId();
|
mId = reader.hdr().record.getFormId();
|
||||||
reader.adjustFormId(mId);
|
reader.adjustFormId(mId);
|
||||||
mFlags = reader.hdr().record.flags;
|
mFlags = reader.hdr().record.flags;
|
||||||
mParentFormId = reader.currCell(); // NOTE: only for persistent refs?
|
mParent = ESM::RefId::formIdRefId(reader.currCell());
|
||||||
mParent = ESM::RefId::formIdRefId(mParentFormId);
|
|
||||||
|
|
||||||
// TODO: Let the engine apply this? Saved games?
|
|
||||||
// mInitiallyDisabled = ((mFlags & ESM4::Rec_Disabled) != 0) ? true : false;
|
|
||||||
std::uint32_t esmVer = reader.esmVersion();
|
std::uint32_t esmVer = reader.esmVersion();
|
||||||
bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
|
bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134;
|
||||||
|
|
||||||
|
@ -63,15 +60,6 @@ void ESM4::Reference::load(ESM4::Reader& reader)
|
||||||
FormId BaseId;
|
FormId BaseId;
|
||||||
reader.getFormId(BaseId);
|
reader.getFormId(BaseId);
|
||||||
mBaseObj = ESM::RefId::formIdRefId(BaseId);
|
mBaseObj = ESM::RefId::formIdRefId(BaseId);
|
||||||
#if 0
|
|
||||||
if (mFlags & ESM4::Rec_Disabled)
|
|
||||||
std::cout << "REFR disable at start " << formIdToString(mFormId) <<
|
|
||||||
" baseobj " << formIdToString(mBaseObj) <<
|
|
||||||
" " << (mEditorId.empty() ? "" : mEditorId) << std::endl; // FIXME
|
|
||||||
#endif
|
|
||||||
// if (mBaseObj == 0x20) // e.g. FO3 mFormId == 0x0007E90F
|
|
||||||
// if (mBaseObj == 0x17)
|
|
||||||
// std::cout << mEditorId << std::endl;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ESM4::SUB_DATA:
|
case ESM4::SUB_DATA:
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "reference.hpp" // FormId, Placement, EnableParent
|
#include "reference.hpp" // EnableParent
|
||||||
|
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/defs.hpp>
|
||||||
#include <components/esm/refid.hpp>
|
#include <components/esm/refid.hpp>
|
||||||
|
@ -58,7 +58,7 @@ namespace ESM4
|
||||||
|
|
||||||
struct TeleportDest
|
struct TeleportDest
|
||||||
{
|
{
|
||||||
FormId destDoor;
|
ESM::FormId destDoor;
|
||||||
ESM::Position destPos;
|
ESM::Position destPos;
|
||||||
std::uint32_t flags = 0; // 0x01 no alarm (only in TES5)
|
std::uint32_t flags = 0; // 0x01 no alarm (only in TES5)
|
||||||
};
|
};
|
||||||
|
@ -69,16 +69,15 @@ namespace ESM4
|
||||||
// 0 radius, 1 everywhere, 2 worldspace and linked int, 3 linked int, 4 current cell only
|
// 0 radius, 1 everywhere, 2 worldspace and linked int, 3 linked int, 4 current cell only
|
||||||
std::uint32_t broadcastRange;
|
std::uint32_t broadcastRange;
|
||||||
float staticPercentage;
|
float staticPercentage;
|
||||||
FormId posReference; // only used if broadcastRange == 0
|
ESM::FormId posReference; // only used if broadcastRange == 0
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Reference
|
struct Reference
|
||||||
{
|
{
|
||||||
FormId mId; // from the header
|
ESM::FormId mId; // from the header
|
||||||
|
|
||||||
FormId mParentFormId; // cell FormId (currently persistent refs only), from the loading sequence
|
ESM::RefId mParent; // cell FormId, from the loading sequence
|
||||||
// NOTE: for exterior cells it will be the dummy cell FormId
|
// NOTE: for exterior cells it will be the dummy cell FormId
|
||||||
ESM::RefId mParent;
|
|
||||||
|
|
||||||
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
std::uint32_t mFlags; // from the header, see enum type RecordFlag for details
|
||||||
|
|
||||||
|
@ -88,19 +87,18 @@ namespace ESM4
|
||||||
|
|
||||||
ESM::Position mPos;
|
ESM::Position mPos;
|
||||||
float mScale = 1.0f;
|
float mScale = 1.0f;
|
||||||
FormId mOwner;
|
ESM::FormId mOwner;
|
||||||
FormId mGlobal;
|
ESM::FormId mGlobal;
|
||||||
std::int32_t mFactionRank = -1;
|
std::int32_t mFactionRank = -1;
|
||||||
|
|
||||||
bool mInitiallyDisabled; // TODO may need to check mFlags & 0x800 (initially disabled)
|
bool mIsMapMarker = false;
|
||||||
bool mIsMapMarker;
|
|
||||||
std::uint16_t mMapMarker;
|
std::uint16_t mMapMarker;
|
||||||
|
|
||||||
EnableParent mEsp;
|
EnableParent mEsp;
|
||||||
|
|
||||||
std::uint32_t mCount = 1; // only if > 1
|
std::uint32_t mCount = 1; // only if > 1
|
||||||
|
|
||||||
FormId mAudioLocation;
|
ESM::FormId mAudioLocation;
|
||||||
|
|
||||||
RadioStationData mRadio;
|
RadioStationData mRadio;
|
||||||
|
|
||||||
|
@ -109,7 +107,7 @@ namespace ESM4
|
||||||
std::int8_t mLockLevel;
|
std::int8_t mLockLevel;
|
||||||
ESM::RefId mKey;
|
ESM::RefId mKey;
|
||||||
|
|
||||||
FormId mTargetRef;
|
ESM::FormId mTargetRef;
|
||||||
|
|
||||||
void load(ESM4::Reader& reader);
|
void load(ESM4::Reader& reader);
|
||||||
// void save(ESM4::Writer& writer) const;
|
// void save(ESM4::Writer& writer) const;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define COMPONENTS_ESM4_RECORDS_H
|
#define COMPONENTS_ESM4_RECORDS_H
|
||||||
|
|
||||||
#include <components/esm4/loadachr.hpp>
|
#include <components/esm4/loadachr.hpp>
|
||||||
#include <components/esm4/loadacre.hpp>
|
|
||||||
#include <components/esm4/loadacti.hpp>
|
#include <components/esm4/loadacti.hpp>
|
||||||
#include <components/esm4/loadalch.hpp>
|
#include <components/esm4/loadalch.hpp>
|
||||||
#include <components/esm4/loadaloc.hpp>
|
#include <components/esm4/loadaloc.hpp>
|
||||||
|
|
|
@ -30,37 +30,22 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "formid.hpp"
|
#include <components/esm/defs.hpp>
|
||||||
|
#include <components/esm/formid.hpp>
|
||||||
|
|
||||||
namespace ESM4
|
namespace ESM4
|
||||||
{
|
{
|
||||||
#pragma pack(push, 1)
|
|
||||||
struct Vector3
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
};
|
|
||||||
|
|
||||||
// REFR, ACHR, ACRE
|
|
||||||
struct Placement
|
|
||||||
{
|
|
||||||
Vector3 pos;
|
|
||||||
Vector3 rot; // angles are in radian, rz applied first and rx applied last
|
|
||||||
};
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
// REFR, ACHR, ACRE
|
// REFR, ACHR, ACRE
|
||||||
struct EnableParent
|
struct EnableParent
|
||||||
{
|
{
|
||||||
FormId parent;
|
ESM::FormId parent;
|
||||||
std::uint32_t flags; // 0x0001 = Set Enable State Opposite Parent, 0x0002 = Pop In
|
std::uint32_t flags; // 0x0001 = Set Enable State Opposite Parent, 0x0002 = Pop In
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LODReference
|
struct LODReference
|
||||||
{
|
{
|
||||||
FormId baseObj;
|
ESM::FormId baseObj;
|
||||||
Placement placement;
|
ESM::Position placement;
|
||||||
float scale;
|
float scale;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue