diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index c31a9d8fd..2342882e0 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -55,7 +55,7 @@ add_openmw_dir (mwclass ) add_openmw_dir (mwmechanics - mechanicsmanager stat creaturestats magiceffects movement + mechanicsmanager stat creaturestats magiceffects movement actors ) # Main executable diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a88588b9c..97aaf4090 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -160,7 +160,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) // update actors std::vector > movement; - mEnvironment.mMechanicsManager->update (movement); + mEnvironment.mMechanicsManager->update (movement, mEnvironment.mFrameDuration, + mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game); if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game) mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration); @@ -357,7 +358,7 @@ void OMW::Engine::go() // to find core.xml here. //addResourcesDirectory(mResDir); - + addResourcesDirectory(mResDir / "mygui"); addResourcesDirectory(mResDir / "water"); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp new file mode 100644 index 000000000..e68b99597 --- /dev/null +++ b/apps/openmw/mwmechanics/actors.cpp @@ -0,0 +1,77 @@ + +#include "actors.hpp" + +#include + +#include + +#include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" + +namespace MWMechanics +{ + void Actors::updateActor (const MWWorld::Ptr& ptr, float duration) + { + + } + + void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) + { + if (!paused) + MWWorld::Class::get (ptr).getInventoryStore (ptr).autoEquip ( + MWWorld::Class::get (ptr).getNpcStats (ptr)); + } + + Actors::Actors (MWWorld::Environment& environment) : mEnvironment (environment), mDuration (0) {} + + void Actors::addActor (const MWWorld::Ptr& ptr) + { + mActors.insert (ptr); + } + + void Actors::removeActor (const MWWorld::Ptr& ptr) + { + mActors.erase (ptr); + } + + void Actors::dropActors (const MWWorld::Ptr::CellStore *cellStore) + { + std::set::iterator iter = mActors.begin(); + + while (iter!=mActors.end()) + if (iter->getCell()==cellStore) + { + mActors.erase (iter++); + } + else + ++iter; + } + + void Actors::update (std::vector >& movement, float duration, + bool paused) + { + mDuration += duration; + + if (mDuration>=0.25) + { + for (std::set::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter) + { + updateActor (*iter, mDuration); + + if (iter->getTypeName()==typeid (ESM::NPC).name()) + updateNpc (*iter, mDuration, paused); + } + + mDuration = 0; + } + + for (std::set::iterator iter (mActors.begin()); iter!=mActors.end(); + ++iter) + { + Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter); + + if (vector!=Ogre::Vector3::ZERO) + movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector)); + } + } +} diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp new file mode 100644 index 000000000..7ff33b63b --- /dev/null +++ b/apps/openmw/mwmechanics/actors.hpp @@ -0,0 +1,51 @@ +#ifndef GAME_MWMECHANICS_ACTORS_H +#define GAME_MWMECHANICS_ACTORS_H + +#include +#include +#include + +#include "../mwworld/ptr.hpp" + +namespace Ogre +{ + class Vector3; +} + +namespace MWWorld +{ + class Environment; +} + +namespace MWMechanics +{ + class Actors + { + MWWorld::Environment& mEnvironment; + std::set mActors; + float mDuration; + + void updateActor (const MWWorld::Ptr& ptr, float duration); + + void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused); + + public: + + Actors (MWWorld::Environment& environment); + + void addActor (const MWWorld::Ptr& ptr); + ///< Register an actor for stats management + + void removeActor (const MWWorld::Ptr& ptr); + ///< Deregister an actor for stats management + + void dropActors (const MWWorld::Ptr::CellStore *cellStore); + ///< Deregister all actors in the given cell. + + void update (std::vector >& movement, + float duration, bool paused); + ///< Update actor stats and store desired velocity vectors in \a movement + }; +} + +#endif diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 7ed81f785..3c93857ef 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -222,14 +222,14 @@ namespace MWMechanics MechanicsManager::MechanicsManager (MWWorld::Environment& environment) : mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false), - mRaceSelected (false) + mRaceSelected (false), mActors (environment) { buildPlayer(); } void MechanicsManager::addActor (const MWWorld::Ptr& ptr) { - mActors.insert (ptr); + mActors.addActor (ptr); } void MechanicsManager::removeActor (const MWWorld::Ptr& ptr) @@ -237,7 +237,7 @@ namespace MWMechanics if (ptr==mWatched) mWatched = MWWorld::Ptr(); - mActors.erase (ptr); + mActors.removeActor (ptr); } void MechanicsManager::dropActors (const MWWorld::Ptr::CellStore *cellStore) @@ -245,16 +245,7 @@ namespace MWMechanics if (!mWatched.isEmpty() && mWatched.getCell()==cellStore) mWatched = MWWorld::Ptr(); - std::set::iterator iter = mActors.begin(); - - while (iter!=mActors.end()) - if (iter->getCell()==cellStore) - { - //std::cout << "Erasing an actor"; - mActors.erase (iter++); - } - else - ++iter; + mActors.dropActors (cellStore); } void MechanicsManager::watchActor (const MWWorld::Ptr& ptr) @@ -262,7 +253,8 @@ namespace MWMechanics mWatched = ptr; } - void MechanicsManager::update (std::vector >& movement) + void MechanicsManager::update (std::vector >& movement, + float duration, bool paused) { if (!mWatched.isEmpty()) { @@ -345,14 +337,7 @@ namespace MWMechanics mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills); } - for (std::set::iterator iter (mActors.begin()); iter!=mActors.end(); - ++iter) - { - Ogre::Vector3 vector = MWWorld::Class::get (*iter).getMovementVector (*iter); - - if (vector!=Ogre::Vector3::ZERO) - movement.push_back (std::make_pair (iter->getRefData().getHandle(), vector)); - } + mActors.update (movement, duration, paused); } void MechanicsManager::setPlayerName (const std::string& name) diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index 2e2192638..a7defe178 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -1,7 +1,6 @@ #ifndef GAME_MWMECHANICS_MECHANICSMANAGER_H #define GAME_MWMECHANICS_MECHANICSMANAGER_H -#include #include #include @@ -9,6 +8,7 @@ #include "creaturestats.hpp" #include "npcstats.hpp" +#include "actors.hpp" namespace Ogre { @@ -25,13 +25,13 @@ namespace MWMechanics class MechanicsManager { MWWorld::Environment& mEnvironment; - std::set mActors; MWWorld::Ptr mWatched; CreatureStats mWatchedCreature; NpcStats mWatchedNpc; bool mUpdatePlayer; bool mClassSelected; bool mRaceSelected; + Actors mActors; void buildPlayer(); ///< build player according to stored class/race/birthsign information. Will @@ -60,8 +60,12 @@ namespace MWMechanics ///< On each update look for changes in a previously registered actor and update the /// GUI accordingly. - void update (std::vector >& movement); + void update (std::vector >& movement, float duration, + bool paused); ///< Update actor stats and store desired velocity vectors in \a movement + /// + /// \param paused In game type does not currently advance (this usually means some GUI + /// component is up). void setPlayerName (const std::string& name); ///< Set player name. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index e64c9785f..aedd119c8 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -6,6 +6,8 @@ #include "class.hpp" +#include /// \todo remove after rendering is implemented + void MWWorld::InventoryStore::copySlots (const InventoryStore& store) { // some const-trickery, required because of a flaw in the handling of MW-references and the @@ -24,10 +26,15 @@ void MWWorld::InventoryStore::copySlots (const InventoryStore& store) } } -MWWorld::InventoryStore::InventoryStore() +void MWWorld::InventoryStore::initSlots (TSlots& slots) { for (int i=0; i, bool> itemsSlots = + MWWorld::Class::get (*iter).getEquipmentSlots (*iter); + + for (std::vector::const_iterator iter2 (itemsSlots.first.begin()); + iter2!=itemsSlots.first.end(); ++iter2) + { + /// \todo comapre item with item in slot + if (slots.at (*iter2)==end()) + { + /// \todo unstack, if reqquired (itemsSlots.second) + + slots[*iter2] = iter; + break; + } + } + } + + bool changed = false; + + for (std::size_t i=0; i mSlots; + typedef std::vector TSlots; + + mutable TSlots mSlots; void copySlots (const InventoryStore& store); + void initSlots (TSlots& slots); + public: InventoryStore(); @@ -52,6 +61,9 @@ namespace MWWorld ///< \note \a iteartor can be an end-iterator ContainerStoreIterator getSlot (int slot); + + void autoEquip (const MWMechanics::NpcStats& stats); + ///< Auto equip items according to stats and item value. }; } diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index c31c53122..d6e485f41 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -39,7 +39,7 @@ namespace MWWorld return mPtr.empty(); } - const std::type_info& getType() + const std::type_info& getType() const { assert (!mPtr.empty()); return mPtr.type();