From d717b7b9dd3a73631a811bd243983bbd63860f7b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 30 Mar 2012 16:18:58 +0200 Subject: [PATCH 1/4] factored out actor related game mechanics code into a separate class --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwmechanics/actors.cpp | 44 +++++++++++++++++++ apps/openmw/mwmechanics/actors.hpp | 45 ++++++++++++++++++++ apps/openmw/mwmechanics/mechanicsmanager.cpp | 26 +++-------- apps/openmw/mwmechanics/mechanicsmanager.hpp | 4 +- 5 files changed, 97 insertions(+), 24 deletions(-) create mode 100644 apps/openmw/mwmechanics/actors.cpp create mode 100644 apps/openmw/mwmechanics/actors.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2d49a414c..e16bd181d 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -54,7 +54,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/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp new file mode 100644 index 000000000..e4fba8a9c --- /dev/null +++ b/apps/openmw/mwmechanics/actors.cpp @@ -0,0 +1,44 @@ + +#include "actors.hpp" + +#include "../mwworld/class.hpp" + +namespace MWMechanics +{ + Actors::Actors (MWWorld::Environment& environment) : mEnvironment (environment) {} + + 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) + { + 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..d3a372472 --- /dev/null +++ b/apps/openmw/mwmechanics/actors.hpp @@ -0,0 +1,45 @@ +#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; + + 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); + ///< 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..f669ea65c 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) @@ -345,14 +336,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); } void MechanicsManager::setPlayerName (const std::string& name) diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index 2e2192638..bf0a6215a 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 From a1d3516e0a23c049eca4e787d8dc5e06193f1af9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 30 Mar 2012 17:01:23 +0200 Subject: [PATCH 2/4] constness fix --- apps/openmw/mwworld/ptr.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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(); From 0892df0ad38ca0eddf0da8b0c46ba7676f4dc0a1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 30 Mar 2012 17:01:55 +0200 Subject: [PATCH 3/4] framework for gamemechanics-realted actor updated --- apps/openmw/engine.cpp | 5 +-- apps/openmw/mwmechanics/actors.cpp | 34 ++++++++++++++++++-- apps/openmw/mwmechanics/actors.hpp | 12 +++++-- apps/openmw/mwmechanics/mechanicsmanager.cpp | 5 +-- apps/openmw/mwmechanics/mechanicsmanager.hpp | 6 +++- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 441c22769..45ed0abd4 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -148,7 +148,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); @@ -317,7 +318,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 index e4fba8a9c..d532c6f09 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1,11 +1,25 @@ #include "actors.hpp" +#include + +#include + #include "../mwworld/class.hpp" namespace MWMechanics { - Actors::Actors (MWWorld::Environment& environment) : mEnvironment (environment) {} + void Actors::updateActor (const MWWorld::Ptr& ptr, float duration) + { + + } + + void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused) + { + + } + + Actors::Actors (MWWorld::Environment& environment) : mEnvironment (environment), mDuration (0) {} void Actors::addActor (const MWWorld::Ptr& ptr) { @@ -30,8 +44,24 @@ namespace MWMechanics ++iter; } - void Actors::update (std::vector >& movement) + 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) { diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index d3a372472..7ff33b63b 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -21,8 +21,13 @@ namespace MWMechanics { class Actors { - MWWorld::Environment& mEnvironment; - std::set mActors; + 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: @@ -37,7 +42,8 @@ namespace MWMechanics void dropActors (const MWWorld::Ptr::CellStore *cellStore); ///< Deregister all actors in the given cell. - 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 }; } diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index f669ea65c..3c93857ef 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -253,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()) { @@ -336,7 +337,7 @@ namespace MWMechanics mEnvironment.mWindowManager->configureSkills (majorSkills, minorSkills); } - mActors.update (movement); + 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 bf0a6215a..a7defe178 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -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. From 751e7d2199d595b2024d8172aef1e03670d0eaa9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 31 Mar 2012 17:26:15 +0200 Subject: [PATCH 4/4] basic auto-equipping (picks the first matching item --- apps/openmw/mwmechanics/actors.cpp | 5 ++- apps/openmw/mwworld/inventorystore.cpp | 58 +++++++++++++++++++++++++- apps/openmw/mwworld/inventorystore.hpp | 14 ++++++- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index d532c6f09..e68b99597 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -6,6 +6,7 @@ #include #include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" namespace MWMechanics { @@ -16,7 +17,9 @@ namespace MWMechanics 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) {} 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. }; }