diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index e9e548c0e..1d32a037a 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 30b308e70..cc30c6955 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 4c8a2c0e2..9a5a9b955 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 a8a431acf..9a0936027 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 c5f9812b7..123713a38 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 011fd2c32..8c5be4793 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 f0e38cceb..6e38ea0d3 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 0214c72ad..3826c6c40 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 76c2c4a3e..353f7f606 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 4157ce17a..13a6241d4 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); - - // TODO add initial content - - ptr.getRefData().getContainerStore() = store; - } + ensureCustomData (ptr); - 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 01763870a..78552ffe9 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 5aa203a49..12a56e0ee 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); - - // TODO add initial content - - ptr.getRefData().getContainerStore() = store; - } + ensureCustomData (ptr); - 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 b7b654bc0..9afeffea8 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 26436a012..d0b3b11a2 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 c230cf357..aecb4224c 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 5e55010eb..ac1076cc1 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 47bd1a9e5..6c7409665 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 3890899b0..2c50472ac 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 34421ff51..7df82ae5d 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 636a8f0be..67756f23c 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 c5f1539b4..074a07c93 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 a2642d8d5..81e018d96 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 36ee2c1b2..cb1858315 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 2b98a3d60..d94920041 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); - - ESMS::LiveCellRef *ref = ptr.get(); + ensureCustomData (ptr); - 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); - - 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; - } + ensureCustomData (ptr); - 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); - - // TODO add initial content + ensureCustomData (ptr); - 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); - - ptr.getRefData().getMovement() = movement; - } + ensureCustomData (ptr); - 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 cc9dbef7f..bb9b131c9 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 86d1e2a98..08047a2e8 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 85678121f..e1a54db3c 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 d7b9df738..287dd0475 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 f8755b2eb..79c18d426 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 1e0ea5178..174197d9a 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 946da311d..fbd96182f 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 be3fdb180..a4b1d8c54 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 1fbd21f7c..f136aaccd 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 79bc4d4de..84c633ab3 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 ca82830d9..0e97a39cf 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 000000000..588991fe4 --- /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 4eb41ebf5..5bfb82138 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 8bf75aa3c..389c9349d 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 000000000..03d04a50e --- /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 9a91a27b5..30d676f13 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -3,24 +3,22 @@ #include -#include - -#include "../mwscript/locals.hpp" +#include -#include "../mwmechanics/creaturestats.hpp" -#include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/movement.hpp" +#include -#include "containerstore.hpp" -#include +#include "../mwscript/locals.hpp" 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; + ESM::Position mPosition; - boost::shared_ptr > mContainerStore; + CustomData *mCustomData; - ESM::Position mPosition; + 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) {} - - - std::string getHandle() - { - return mBaseNode->getName(); - } - Ogre::SceneNode* getBaseNode(){ - return mBaseNode; - } - void setBaseNode(Ogre::SceneNode* base){ - mBaseNode = base; - } - - int getCount() const - { - return mCount; - } - - void setLocals (const ESM::Script& script) - { - if (!mHasLocals) - { - mLocals.configure (script); - mHasLocals = true; - } - } - - - void setCount (int count) - { - mCount = count; - } - - MWScript::Locals& getLocals() - { - return mLocals; - } - - bool isEnabled() const - { - return mEnabled; - } - - void enable() - { - mEnabled = true; - } - - void disable() - { - mEnabled = true; - } - - boost::shared_ptr& getCreatureStats() - { - return mCreatureStats; - } - - boost::shared_ptr& getNpcStats() - { - return mNpcStats; - } - - boost::shared_ptr& getMovement() - { - return mMovement; - } - - boost::shared_ptr >& getContainerStore() - { - return mContainerStore; - } - - ESM::Position& getPosition() - { - return mPosition; - } + + /// @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); + + RefData (const RefData& refData); + + ~RefData(); + + RefData& operator= (const RefData& refData); + + /// Return OGRE handle (may be empty). + std::string getHandle(); + + /// Return OGRE base node (can be a null pointer). + Ogre::SceneNode* getBaseNode(); + + /// Set OGRE base node (can be a null pointer). + void setBaseNode (Ogre::SceneNode* base); + + int getCount() const; + + void setLocals (const ESM::Script& script); + + void setCount (int count); + + MWScript::Locals& getLocals(); + + bool isEnabled() const; + + void enable(); + + void disable(); + + 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 d064312f1..c4bcf84d8 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; }