diff --git a/apps/openmw/mwclass/classes.cpp b/apps/openmw/mwclass/classes.cpp index e96350294e..076e9670b7 100644 --- a/apps/openmw/mwclass/classes.cpp +++ b/apps/openmw/mwclass/classes.cpp @@ -49,5 +49,6 @@ namespace MWClass BodyPart::registerSelf(); ESM4Static::registerSelf(); + ESM4Light::registerSelf(); } } diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 04d9a758c5..4fc03c7a76 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "../mwbase/environment.hpp" @@ -242,4 +243,53 @@ namespace MWClass { return ptr.get()->mBase->mSound; } + + ESM4Light::ESM4Light() + : MWWorld::RegisteredClass(ESM4::Light::sRecordId) + { + } + + void ESM4Light ::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + { + MWWorld::LiveCellRef* ref = ptr.get(); + + // Insert even if model is empty, so that the light is added + renderingInterface.getObjects().insertModel(ptr, model, !(ref->mBase->mData.flags & ESM4::Light::OffDefault)); + } + + void ESM4Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const + { + insertObjectPhysics(ptr, model, rotation, physics); + } + + void ESM4Light::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const + { + physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World); + } + + std::string ESM4Light::getModel(const MWWorld::ConstPtr& ptr) const + { + return getClassModel(ptr); + } + + std::string_view ESM4Light ::getName(const MWWorld::ConstPtr& ptr) const + { + return {}; + } + + bool ESM4Light::hasToolTip(const MWWorld::ConstPtr& ptr) const + { + return false; + } + + MWWorld::Ptr ESM4Light::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const + { + const MWWorld::LiveCellRef* ref = ptr.get(); + + return MWWorld::Ptr(cell.insert(ref), &cell); + } + } diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 612d6f9e5e..b76b72735f 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -78,6 +78,33 @@ namespace MWClass const ESM::RefId& getSound(const MWWorld::ConstPtr& ptr) const override; }; + + class ESM4Light : public MWWorld::RegisteredClass + { + friend MWWorld::RegisteredClass; + + ESM4Light(); + + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; + + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering + + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; + + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. + + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) + + std::string getModel(const MWWorld::ConstPtr& ptr) const override; + }; } #endif diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index 6078feba4c..72eab8c4fc 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "../mwbase/environment.hpp" diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 9843c8a06a..eab25c21b8 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -59,6 +59,7 @@ namespace ESM4 struct Cell; struct Reference; struct Static; + struct Light; } namespace MWWorld @@ -73,7 +74,7 @@ namespace MWWorld CellRefList, CellRefList, CellRefList, CellRefList, CellRefList, CellRefList, CellRefList, CellRefList, - CellRefList>; + CellRefList, CellRefList>; /// \brief Mutable state of a cell class CellStore diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 7d9fda7273..0227d6ede3 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -279,6 +280,7 @@ namespace MWWorld case ESM::REC_WEAP: case ESM::REC_BODY: case ESM::REC_STAT4: + case ESM::REC_LIGH4: return true; break; } diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 9d737c3f53..3f153d45c0 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -30,6 +30,7 @@ namespace ESM4 struct Static; struct Cell; struct Reference; + struct Light; } namespace ESM @@ -105,7 +106,7 @@ namespace MWWorld // Special entry which is hardcoded and not loaded from an ESM Store, - Store, Store, Store>; + Store, Store, Store, Store>; private: template diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 19b07c0725..a8c49e9252 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -1250,5 +1251,6 @@ template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; +template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; template class MWWorld::TypedDynamicStore; diff --git a/components/esm4/loadligh.cpp b/components/esm4/loadligh.cpp index eb82224d66..6c222a6f60 100644 --- a/components/esm4/loadligh.cpp +++ b/components/esm4/loadligh.cpp @@ -33,8 +33,9 @@ void ESM4::Light::load(ESM4::Reader& reader) { - mFormId = reader.hdr().record.id; - reader.adjustFormId(mFormId); + FormId formId = reader.hdr().record.id; + reader.adjustFormId(formId); + mId = ESM::RefId::formIdRefId(formId); mFlags = reader.hdr().record.flags; std::uint32_t esmVer = reader.esmVersion(); bool isFONV = esmVer == ESM::VER_132 || esmVer == ESM::VER_133 || esmVer == ESM::VER_134; diff --git a/components/esm4/loadligh.hpp b/components/esm4/loadligh.hpp index fe5129f8b0..b6447853b8 100644 --- a/components/esm4/loadligh.hpp +++ b/components/esm4/loadligh.hpp @@ -32,6 +32,9 @@ #include "formid.hpp" +#include +#include + namespace ESM4 { class Reader; @@ -39,6 +42,20 @@ namespace ESM4 struct Light { + enum Flag + { + Dynamic = 0x01, + Carryable = 0x02, + Negative = 0x04, + Flicker = 0x08, + OffDefault = 0x020, + FlickerSlow = 0x040, + Pulse = 0x080, + PulseSlow = 0x100, + SpotLight = 0x200, + SpotShadow = 0x400, + }; + struct Data { std::uint32_t time; // FO/FONV only @@ -67,7 +84,7 @@ namespace ESM4 float weight; }; - 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::string mEditorId; @@ -87,6 +104,8 @@ namespace ESM4 void load(ESM4::Reader& reader); // void save(ESM4::Writer& writer) const; + static constexpr ESM::RecNameInts sRecordId = ESM::REC_LIGH4; + // void blank(); }; }