diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index e9e548c0ec..1d32a037a9 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -14,7 +14,7 @@ set(GAME_HEADER source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender - renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface + renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface ) add_openmw_dir (mwinput @@ -44,7 +44,7 @@ add_openmw_dir (mwsound add_openmw_dir (mwworld refdata world physicssystem scene environment globals class action nullaction actionteleport containerstore actiontalk actiontake containerstore manualref containerutil player cellfunctors - cells localscripts + cells localscripts customdata ) add_openmw_dir (mwclass diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index 30b308e70f..cc30c6955c 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" #include "containerutil.hpp" @@ -20,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index 4c8a2c0e2d..9a5a9b9558 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_APPARATUS_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index a8a431acf3..9a09360270 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" #include "containerutil.hpp" @@ -20,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index c5f9812b79..123713a38b 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_ARMOR_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 011fd2c320..8c5be4793b 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" #include "containerutil.hpp" @@ -20,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index f0e38cceba..6e38ea0d3d 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_BOOK_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 0214c72adf..3826c6c40a 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" #include "containerutil.hpp" @@ -20,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 76c2c4a3e4..353f7f606c 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_CLOTHING_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 4157ce17ad..13a6241d48 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -6,9 +6,41 @@ #include #include "../mwworld/ptr.hpp" +#include "../mwworld/containerstore.hpp" +#include "../mwworld/customdata.hpp" + +#include "../mwrender/objects.hpp" + +namespace +{ + struct CustomData : public MWWorld::CustomData + { + MWWorld::ContainerStore mContainerStore; + + virtual MWWorld::CustomData *clone() const; + }; + + MWWorld::CustomData *CustomData::clone() const + { + return new CustomData (*this); + } +} namespace MWClass { + void Container::ensureCustomData (const MWWorld::Ptr& ptr) const + { + if (!ptr.getRefData().getCustomData()) + { + std::auto_ptr data (new CustomData); + + // \todo add initial container content + + // store + ptr.getRefData().setCustomData (data.release()); + } + } + void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { ESMS::LiveCellRef *ref = @@ -16,7 +48,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); @@ -50,17 +82,9 @@ namespace MWClass MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr) const { - if (!ptr.getRefData().getContainerStore().get()) - { - boost::shared_ptr > store ( - new MWWorld::ContainerStore); + ensureCustomData (ptr); - // TODO add initial content - - ptr.getRefData().getContainerStore() = store; - } - - return *ptr.getRefData().getContainerStore(); + return dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore; } std::string Container::getScript (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index 01763870ad..78552ffe90 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -2,12 +2,13 @@ #define GAME_MWCLASS_CONTAINER_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { class Container : public MWWorld::Class { + void ensureCustomData (const MWWorld::Ptr& ptr) const; + public: virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 5aa203a49a..12a56e0ee6 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -4,16 +4,62 @@ #include #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/mechanicsmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" #include "../mwworld/environment.hpp" +#include "../mwworld/customdata.hpp" +#include "../mwworld/containerstore.hpp" +namespace +{ + struct CustomData : public MWWorld::CustomData + { + MWMechanics::CreatureStats mCreatureStats; + MWWorld::ContainerStore mContainerStore; -#include "../mwmechanics/mechanicsmanager.hpp" + virtual MWWorld::CustomData *clone() const; + }; + + MWWorld::CustomData *CustomData::clone() const + { + return new CustomData (*this); + } +} namespace MWClass { + void Creature::ensureCustomData (const MWWorld::Ptr& ptr) const + { + if (!ptr.getRefData().getCustomData()) + { + std::auto_ptr data (new CustomData); + + ESMS::LiveCellRef *ref = ptr.get(); + + // creature stats + data->mCreatureStats.mAttributes[0].set (ref->base->data.strength); + data->mCreatureStats.mAttributes[1].set (ref->base->data.intelligence); + data->mCreatureStats.mAttributes[2].set (ref->base->data.willpower); + data->mCreatureStats.mAttributes[3].set (ref->base->data.agility); + data->mCreatureStats.mAttributes[4].set (ref->base->data.speed); + data->mCreatureStats.mAttributes[5].set (ref->base->data.endurance); + data->mCreatureStats.mAttributes[6].set (ref->base->data.personality); + data->mCreatureStats.mAttributes[7].set (ref->base->data.luck); + data->mCreatureStats.mDynamic[0].set (ref->base->data.health); + data->mCreatureStats.mDynamic[1].set (ref->base->data.mana); + data->mCreatureStats.mDynamic[2].set (ref->base->data.fatigue); + + data->mCreatureStats.mLevel = ref->base->data.level; + + // \todo add initial container content + + // store + ptr.getRefData().setCustomData (data.release()); + } + } + std::string Creature::getId (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = @@ -24,18 +70,8 @@ namespace MWClass void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { - - /*ESMS::LiveCellRef *ref = - ptr.get(); - - assert (ref->base != NULL); - const std::string &model = ref->base->model; - - if (!model.empty()) - {*/ - MWRender::Actors& actors = renderingInterface.getActors(); - actors.insertCreature(ptr); - + MWRender::Actors& actors = renderingInterface.getActors(); + actors.insertCreature(ptr); } void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const @@ -49,7 +85,6 @@ namespace MWClass if(!model.empty()){ physics.insertActorPhysics(ptr, "meshes\\" + model); } - } void Creature::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const @@ -72,31 +107,9 @@ namespace MWClass MWMechanics::CreatureStats& Creature::getCreatureStats (const MWWorld::Ptr& ptr) const { - if (!ptr.getRefData().getCreatureStats().get()) - { - boost::shared_ptr stats ( - new MWMechanics::CreatureStats); + ensureCustomData (ptr); - ESMS::LiveCellRef *ref = ptr.get(); - - stats->mAttributes[0].set (ref->base->data.strength); - stats->mAttributes[1].set (ref->base->data.intelligence); - stats->mAttributes[2].set (ref->base->data.willpower); - stats->mAttributes[3].set (ref->base->data.agility); - stats->mAttributes[4].set (ref->base->data.speed); - stats->mAttributes[5].set (ref->base->data.endurance); - stats->mAttributes[6].set (ref->base->data.personality); - stats->mAttributes[7].set (ref->base->data.luck); - stats->mDynamic[0].set (ref->base->data.health); - stats->mDynamic[1].set (ref->base->data.mana); - stats->mDynamic[2].set (ref->base->data.fatigue); - - stats->mLevel = ref->base->data.level; - - ptr.getRefData().getCreatureStats() = stats; - } - - return *ptr.getRefData().getCreatureStats(); + return dynamic_cast (*ptr.getRefData().getCustomData()).mCreatureStats; } boost::shared_ptr Creature::activate (const MWWorld::Ptr& ptr, @@ -108,17 +121,9 @@ namespace MWClass MWWorld::ContainerStore& Creature::getContainerStore (const MWWorld::Ptr& ptr) const { - if (!ptr.getRefData().getContainerStore().get()) - { - boost::shared_ptr > store ( - new MWWorld::ContainerStore); + ensureCustomData (ptr); - // TODO add initial content - - ptr.getRefData().getContainerStore() = store; - } - - return *ptr.getRefData().getContainerStore(); + return dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore; } std::string Creature::getScript (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index b7b654bc01..9afeffea82 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -10,6 +10,8 @@ namespace MWClass { class Creature : public MWWorld::Class { + void ensureCustomData (const MWWorld::Ptr& ptr) const; + public: virtual std::string getId (const MWWorld::Ptr& ptr) const; diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 26436a0128..d0b3b11a2f 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -14,8 +14,6 @@ #include "../mwrender/objects.hpp" -#include - namespace MWClass { void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -25,7 +23,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); @@ -39,13 +37,11 @@ namespace MWClass ESMS::LiveCellRef *ref = ptr.get(); - const std::string &model = ref->base->model; assert (ref->base != NULL); if(!model.empty()){ physics.insertObjectPhysics(ptr, "meshes\\" + model); } - } std::string Door::getName (const MWWorld::Ptr& ptr) const @@ -86,7 +82,7 @@ namespace MWClass } else { - // another NPC or a create is using the door + // another NPC or a creature is using the door // TODO return action for teleporting other NPC/creature return boost::shared_ptr (new MWWorld::NullAction); } diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index c230cf3576..aecb4224cc 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_DOOR_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 5e55010ebf..ac1076cc1b 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" #include "containerutil.hpp" @@ -20,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); @@ -34,14 +35,11 @@ namespace MWClass ESMS::LiveCellRef *ref = ptr.get(); - - const std::string &model = ref->base->model; assert (ref->base != NULL); if(!model.empty()){ physics.insertObjectPhysics(ptr, "meshes\\" + model); } - } std::string Ingredient::getName (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index 47bd1a9e5c..6c74096659 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_INGREDIENT_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 3890899b0e..2c50472aca 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -12,6 +12,8 @@ #include "../mwsound/soundmanager.hpp" +#include "../mwrender/objects.hpp" + #include "containerutil.hpp" namespace MWClass @@ -23,7 +25,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 34421ff513..7df82ae5db 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_LIGHT_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 636a8f0be5..67756f23cf 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -8,6 +8,8 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" + #include "containerutil.hpp" namespace MWClass @@ -19,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index c5f1539b4c..074a07c936 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_LOCKPICK_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index a2642d8d5b..81e018d966 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -8,6 +8,8 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" + #include "containerutil.hpp" namespace MWClass @@ -19,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index 36ee2c1b26..cb18583156 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_MISC_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 2b98a3d604..d94920041f 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1,27 +1,88 @@ #include "npc.hpp" +#include + +#include + #include #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" +#include "../mwmechanics/movement.hpp" +#include "../mwmechanics/mechanicsmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" - -#include "../mwmechanics/mechanicsmanager.hpp" -#include +#include "../mwworld/containerstore.hpp" +#include "../mwworld/customdata.hpp" namespace { const Ogre::Radian kOgrePi (Ogre::Math::PI); const Ogre::Radian kOgrePiOverTwo (Ogre::Math::PI / Ogre::Real(2.0)); + + struct CustomData : public MWWorld::CustomData + { + MWMechanics::NpcStats mNpcStats; + MWMechanics::CreatureStats mCreatureStats; + MWMechanics::Movement mMovement; + MWWorld::ContainerStore mContainerStore; + + virtual MWWorld::CustomData *clone() const; + }; + + MWWorld::CustomData *CustomData::clone() const + { + return new CustomData (*this); + } } namespace MWClass { + void Npc::ensureCustomData (const MWWorld::Ptr& ptr) const + { + if (!ptr.getRefData().getCustomData()) + { + std::auto_ptr data (new CustomData); + + ESMS::LiveCellRef *ref = ptr.get(); + + // NPC stats + if (!ref->base->faction.empty()) + { + // TODO research how initial rank is stored. The information in loadnpc.hpp are at + // best very unclear. + data->mNpcStats.mFactionRank[ref->base->faction] = 0; + } + + for (int i=0; i<27; ++i) + data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); + + // creature stats + data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); + data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); + data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower); + data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility); + data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed); + data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance); + data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality); + data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck); + data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health); + data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana); + data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); + + data->mCreatureStats.mLevel = ref->base->npdt52.level; + + // \todo add initial container content + + // store + ptr.getRefData().setCustomData (data.release()); + } + } + std::string Npc::getId (const MWWorld::Ptr& ptr) const { ESMS::LiveCellRef *ref = @@ -77,56 +138,16 @@ namespace MWClass MWMechanics::CreatureStats& Npc::getCreatureStats (const MWWorld::Ptr& ptr) const { - if (!ptr.getRefData().getCreatureStats().get()) - { - boost::shared_ptr stats ( - new MWMechanics::CreatureStats); + ensureCustomData (ptr); - ESMS::LiveCellRef *ref = ptr.get(); - - stats->mAttributes[0].set (ref->base->npdt52.strength); - stats->mAttributes[1].set (ref->base->npdt52.intelligence); - stats->mAttributes[2].set (ref->base->npdt52.willpower); - stats->mAttributes[3].set (ref->base->npdt52.agility); - stats->mAttributes[4].set (ref->base->npdt52.speed); - stats->mAttributes[5].set (ref->base->npdt52.endurance); - stats->mAttributes[6].set (ref->base->npdt52.personality); - stats->mAttributes[7].set (ref->base->npdt52.luck); - stats->mDynamic[0].set (ref->base->npdt52.health); - stats->mDynamic[1].set (ref->base->npdt52.mana); - stats->mDynamic[2].set (ref->base->npdt52.fatigue); - - stats->mLevel = ref->base->npdt52.level; - - ptr.getRefData().getCreatureStats() = stats; - } - - return *ptr.getRefData().getCreatureStats(); + return dynamic_cast (*ptr.getRefData().getCustomData()).mCreatureStats; } MWMechanics::NpcStats& Npc::getNpcStats (const MWWorld::Ptr& ptr) const { - if (!ptr.getRefData().getNpcStats().get()) - { - boost::shared_ptr stats ( - new MWMechanics::NpcStats); + ensureCustomData (ptr); - ESMS::LiveCellRef *ref = ptr.get(); - - if (!ref->base->faction.empty()) - { - // TODO research how initial rank is stored. The information in loadnpc.hpp are at - // best very unclear. - stats->mFactionRank[ref->base->faction] = 0; - } - - for (int i=0; i<27; ++i) - stats->mSkill[i].setBase (ref->base->npdt52.skills[i]); - - ptr.getRefData().getNpcStats() = stats; - } - - return *ptr.getRefData().getNpcStats(); + return dynamic_cast (*ptr.getRefData().getCustomData()).mNpcStats; } boost::shared_ptr Npc::activate (const MWWorld::Ptr& ptr, @@ -138,17 +159,9 @@ namespace MWClass MWWorld::ContainerStore& Npc::getContainerStore (const MWWorld::Ptr& ptr) const { - if (!ptr.getRefData().getContainerStore().get()) - { - boost::shared_ptr > store ( - new MWWorld::ContainerStore); + ensureCustomData (ptr); - // TODO add initial content - - ptr.getRefData().getContainerStore() = store; - } - - return *ptr.getRefData().getContainerStore(); + return dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore; } std::string Npc::getScript (const MWWorld::Ptr& ptr) const @@ -239,29 +252,20 @@ namespace MWClass MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const { - if (!ptr.getRefData().getMovement().get()) - { - boost::shared_ptr movement ( - new MWMechanics::Movement); + ensureCustomData (ptr); - ptr.getRefData().getMovement() = movement; - } - - return *ptr.getRefData().getMovement(); + return dynamic_cast (*ptr.getRefData().getCustomData()).mMovement; } Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const { Ogre::Vector3 vector (0, 0, 0); - if (ptr.getRefData().getMovement().get()) - { - vector.x = - ptr.getRefData().getMovement()->mLeftRight * 200; - vector.y = ptr.getRefData().getMovement()->mForwardBackward * 200; + vector.x = - getMovementSettings (ptr).mLeftRight * 200; + vector.y = getMovementSettings (ptr).mForwardBackward * 200; - if (getStance (ptr, Run, false)) - vector *= 2; - } + if (getStance (ptr, Run, false)) + vector *= 2; return vector; } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index cc9dbef7fa..bb9b131c96 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -3,11 +3,12 @@ #include "../mwworld/class.hpp" - namespace MWClass { class Npc : public MWWorld::Class { + void ensureCustomData (const MWWorld::Ptr& ptr) const; + public: virtual std::string getId (const MWWorld::Ptr& ptr) const; diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index 86d1e2a985..08047a2e8e 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" #include "containerutil.hpp" @@ -20,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index 85678121fb..e1a54db3c7 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_POTION_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index d7b9df7385..287dd04755 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -3,7 +3,6 @@ #include "../mwworld/class.hpp" - namespace MWClass { class Probe : public MWWorld::Class diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index f8755b2ebc..79c18d4263 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -8,6 +8,8 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" + #include "containerutil.hpp" namespace MWClass @@ -19,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 1e0ea51785..174197d9a9 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_REPAIR_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index 946da311da..fbd96182f9 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -5,6 +5,7 @@ #include "../mwworld/ptr.hpp" +#include "../mwrender/objects.hpp" namespace MWClass { @@ -15,7 +16,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/static.hpp b/apps/openmw/mwclass/static.hpp index be3fdb1804..a4b1d8c547 100644 --- a/apps/openmw/mwclass/static.hpp +++ b/apps/openmw/mwclass/static.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_STATIC_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 1fbd21f7cf..f136aaccda 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -8,6 +8,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" +#include "../mwrender/objects.hpp" #include "containerutil.hpp" @@ -20,7 +21,7 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; - + if (!model.empty()) { MWRender::Objects& objects = renderingInterface.getObjects(); diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index 79bc4d4dec..84c633ab31 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -2,7 +2,6 @@ #define GAME_MWCLASS_WEAPON_H #include "../mwworld/class.hpp" -#include "../mwrender/objects.hpp" namespace MWClass { diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index ca82830d93..0e97a39cf4 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -10,6 +10,7 @@ #include "../mwworld/class.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" #include "interpretercontext.hpp" #include "ref.hpp" diff --git a/apps/openmw/mwworld/customdata.hpp b/apps/openmw/mwworld/customdata.hpp new file mode 100644 index 0000000000..588991fe40 --- /dev/null +++ b/apps/openmw/mwworld/customdata.hpp @@ -0,0 +1,17 @@ +#ifndef GAME_MWWORLD_CUSTOMDATA_H +#define GAME_MWWORLD_CUSTOMDATA_H + +namespace MWWorld +{ + /// \brief Base class for the MW-class-specific part of RefData + class CustomData + { + public: + + virtual ~CustomData() {} + + virtual CustomData *clone() const = 0; + }; +} + +#endif diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 4eb41ebf5c..5bfb82138c 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -3,6 +3,8 @@ #include "../mwrender/player.hpp" +#include "../mwmechanics/movement.hpp" + #include "world.hpp" #include "class.hpp" diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index 8bf75aa3cb..389c9349d5 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -5,6 +5,8 @@ #include +#include + #include #include "refdata.hpp" diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp new file mode 100644 index 0000000000..03d04a50ef --- /dev/null +++ b/apps/openmw/mwworld/refdata.cpp @@ -0,0 +1,144 @@ + +#include "refdata.hpp" + +#include + +#include "customdata.hpp" + +namespace MWWorld +{ + void RefData::copy (const RefData& refData) + { + mBaseNode = refData.mBaseNode; + mLocals = refData.mLocals; + mHasLocals = refData.mHasLocals; + mEnabled = refData.mEnabled; + mCount = refData.mCount; + mPosition = refData.mPosition; + + mCustomData = refData.mCustomData ? refData.mCustomData->clone() : 0; + } + + void RefData::cleanup() + { + mBaseNode = 0; + + delete mCustomData; + mCustomData = 0; + } + + RefData::RefData (const ESM::CellRef& cellRef) + : mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mPosition (cellRef.pos), + mCustomData (0) + {} + + RefData::RefData (const RefData& refData) + : mBaseNode(0), mCustomData (0) + { + try + { + copy (refData); + } + catch (...) + { + cleanup(); + throw; + } + } + + RefData::RefData& RefData::operator= (const RefData& refData) + { + try + { + cleanup(); + copy (refData); + } + catch (...) + { + cleanup(); + throw; + } + + return *this; + } + + RefData::~RefData() + { + try + { + cleanup(); + } + catch (...) + {} + } + + std::string RefData::getHandle() + { + return mBaseNode->getName(); + } + + Ogre::SceneNode* RefData::getBaseNode() + { + return mBaseNode; + } + + void RefData::setBaseNode(Ogre::SceneNode* base) + { + mBaseNode = base; + } + + int RefData::getCount() const + { + return mCount; + } + + void RefData::setLocals (const ESM::Script& script) + { + if (!mHasLocals) + { + mLocals.configure (script); + mHasLocals = true; + } + } + + void RefData::setCount (int count) + { + mCount = count; + } + + MWScript::Locals& RefData::getLocals() + { + return mLocals; + } + + bool RefData::isEnabled() const + { + return mEnabled; + } + + void RefData::enable() + { + mEnabled = true; + } + + void RefData::disable() + { + mEnabled = true; + } + + ESM::Position& RefData::getPosition() + { + return mPosition; + } + + void RefData::setCustomData (CustomData *data) + { + delete mCustomData; + mCustomData = data; + } + + CustomData *RefData::getCustomData() + { + return mCustomData; + } +} diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 9a91a27b56..30d676f130 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -3,24 +3,22 @@ #include -#include +#include + +#include #include "../mwscript/locals.hpp" -#include "../mwmechanics/creaturestats.hpp" -#include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/movement.hpp" - -#include "containerstore.hpp" -#include - namespace ESM { class Script; + class CellRef; } namespace MWWorld { + class CustomData; + class RefData { Ogre::SceneNode* mBaseNode; @@ -33,102 +31,58 @@ namespace MWWorld bool mEnabled; int mCount; // 0: deleted - // we are using shared pointer here to avoid having to create custom copy-constructor, - // assignment operator and destructor. As a consequence though copying a RefData object - // manually will probably give unexcepted results. This is not a problem since RefData - // are never copied outside of container operations. - boost::shared_ptr mCreatureStats; - boost::shared_ptr mNpcStats; - boost::shared_ptr mMovement; - - boost::shared_ptr > mContainerStore; - ESM::Position mPosition; + CustomData *mCustomData; + + void copy (const RefData& refData); + + void cleanup(); public: - /// @param cr Used to copy constant data such as position into this class where it can - /// be altered without effecting the original data. This makes it possible - /// to reset the position as the orignal data is still held in the CellRef - RefData(const ESMS::CellRef& cr) : mBaseNode(0), mHasLocals (false), mEnabled (true), - mCount (1), mPosition(cr.pos) {} + /// @param cellRef Used to copy constant data such as position into this class where it can + /// be altered without effecting the original data. This makes it possible + /// to reset the position as the orignal data is still held in the CellRef + RefData (const ESM::CellRef& cellRef); - std::string getHandle() - { - return mBaseNode->getName(); - } - Ogre::SceneNode* getBaseNode(){ - return mBaseNode; - } - void setBaseNode(Ogre::SceneNode* base){ - mBaseNode = base; - } + RefData (const RefData& refData); - int getCount() const - { - return mCount; - } + ~RefData(); - void setLocals (const ESM::Script& script) - { - if (!mHasLocals) - { - mLocals.configure (script); - mHasLocals = true; - } - } + RefData& operator= (const RefData& refData); + /// Return OGRE handle (may be empty). + std::string getHandle(); - void setCount (int count) - { - mCount = count; - } + /// Return OGRE base node (can be a null pointer). + Ogre::SceneNode* getBaseNode(); - MWScript::Locals& getLocals() - { - return mLocals; - } + /// Set OGRE base node (can be a null pointer). + void setBaseNode (Ogre::SceneNode* base); - bool isEnabled() const - { - return mEnabled; - } + int getCount() const; - void enable() - { - mEnabled = true; - } + void setLocals (const ESM::Script& script); - void disable() - { - mEnabled = true; - } + void setCount (int count); - boost::shared_ptr& getCreatureStats() - { - return mCreatureStats; - } + MWScript::Locals& getLocals(); - boost::shared_ptr& getNpcStats() - { - return mNpcStats; - } + bool isEnabled() const; - boost::shared_ptr& getMovement() - { - return mMovement; - } + void enable(); - boost::shared_ptr >& getContainerStore() - { - return mContainerStore; - } + void disable(); - ESM::Position& getPosition() - { - return mPosition; - } + ESM::Position& getPosition(); + + void setCustomData (CustomData *data); + ///< Set custom data (potentially replacing old custom data). The ownership of \æ data is + /// transferred to this. + + CustomData *getCustomData(); + ///< May return a 0-pointer. The ownership of the return data object is not transferred. }; } diff --git a/components/esm_store/cell_store.hpp b/components/esm_store/cell_store.hpp index d064312f10..c4bcf84d81 100644 --- a/components/esm_store/cell_store.hpp +++ b/components/esm_store/cell_store.hpp @@ -12,7 +12,6 @@ #include "store.hpp" #include "components/esm/records.hpp" -#include "components/esm/loadcell.hpp" #include #include @@ -36,7 +35,7 @@ namespace ESMS { LiveCellRef(const CellRef& cref, const X* b = NULL) : base(b), ref(cref), mData(ref) {} - + LiveCellRef(const X* b = NULL) : base(b), mData(ref) {} @@ -187,7 +186,7 @@ namespace ESMS ++iter) if (!functor (iter->ref, iter->mData)) return false; - + return true; }