diff --git a/CMakeLists.txt b/CMakeLists.txt index 71f36fe3d..7b87e3544 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -346,7 +346,10 @@ if(WIN32) FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*") INSTALL(FILES ${files} DESTINATION ".") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") - INSTALL(FILES "${OpenMW_SOURCE_DIR}/readme.txt" DESTINATION ".") + INSTALL(FILES + "${OpenMW_SOURCE_DIR}/readme.txt" + "${OpenMW_BINARY_DIR}/settings-default.cfg" + DESTINATION ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") SET(CPACK_GENERATOR "NSIS") @@ -356,8 +359,12 @@ if(WIN32) SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO}) SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) - SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher") - set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'") + SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;omwlauncher;OpenMW Launcher") + SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'") + SET(CPACK_NSIS_DELETE_ICONS_EXTRA " + !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP + Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\" + ") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt") SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt") SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") 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 97215b5c0..259733600 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"); addResourcesDirectory(mResDir / "gbuffer"); diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index d27d0bc71..90db40b5a 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Apparatus::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Apparatus::registerSelf() { boost::shared_ptr instance (new Apparatus); diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index c0849e1fe..861610f6c 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 9956a56fb..8e1f81136 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -160,6 +160,14 @@ namespace MWClass return ESM::Skill::HeavyArmor; } + int Armor::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Armor::registerSelf() { boost::shared_ptr instance (new Armor); diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index 2b66ff828..de5ca3983 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -40,6 +40,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 76370dc5c..9069d9476 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -72,6 +72,14 @@ namespace MWClass return ref->base->script; } + int Book::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Book::registerSelf() { boost::shared_ptr instance (new Book); diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index ccbbfb4b2..4738187cd 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 2357851d7..1fbc11c63 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -123,6 +123,14 @@ namespace MWClass return -1; } + int Clothing::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Clothing::registerSelf() { boost::shared_ptr instance (new Clothing); diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 171b06246..97e09012d 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -34,6 +34,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index cbe153ba3..9707e79a8 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -68,6 +68,14 @@ namespace MWClass return ref->base->script; } + int Ingredient::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Ingredient::registerSelf() { boost::shared_ptr instance (new Ingredient); diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index 9463dcf8d..2d7717672 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 71e477591..f67dd4cf0 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -110,6 +110,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Light::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Light::registerSelf() { boost::shared_ptr instance (new Light); diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 46a4d60ba..bde252c28 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -34,6 +34,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 1eef0db8b..76bc3948f 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -81,6 +81,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Lockpick::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Lockpick::registerSelf() { boost::shared_ptr instance (new Lockpick); diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index 0c9189c54..1b56234af 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -29,6 +29,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index def1a90a8..84099caaa 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Miscellaneous::registerSelf() { boost::shared_ptr instance (new Miscellaneous); diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index b07964f99..fc002280c 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index ed1733e2d..642211df3 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Potion::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Potion::registerSelf() { boost::shared_ptr instance (new Potion); diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index be9e713fb..7d3017937 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 8013e2e80..923c29ee6 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -80,6 +80,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Probe::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Probe::registerSelf() { boost::shared_ptr instance (new Probe); diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index 1507d65aa..232b52364 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -29,6 +29,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index d49979861..d6433f5df 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Repair::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Repair::registerSelf() { boost::shared_ptr instance (new Repair); diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 17b606f4c..0a9d9c253 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index e36e9202f..7790e6a80 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -139,6 +139,14 @@ namespace MWClass return -1; } + int Weapon::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Weapon::registerSelf() { boost::shared_ptr instance (new Weapon); diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index f863c0bfe..505c45645 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -40,6 +40,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp new file mode 100644 index 000000000..7d9f748d4 --- /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 && ptr.getRefData().getHandle()!="player") + MWWorld::Class::get (ptr).getInventoryStore (ptr).autoEquip ( + MWWorld::Class::get (ptr).getNpcStats (ptr), mEnvironment); + } + + 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/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 9959bedc8..615def701 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -467,10 +467,15 @@ void OpenAL_Output::init(const std::string &devname) else fail("Failed to open \""+devname+"\""); } - if(alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT")) - std::cout << "Opened \""< #include +#include #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" @@ -49,11 +50,20 @@ namespace MWSound : mResourceMgr(Ogre::ResourceGroupManager::getSingleton()) , mEnvironment(environment) , mOutput(new DEFAULT_OUTPUT(*this)) - + , mMasterVolume(1.0f) + , mSFXVolume(1.0f) + , mMusicVolume(1.0f) { if(!useSound) return; + mMasterVolume = Settings::Manager::getFloat("master volume", "Sound"); + mMasterVolume = std::min(std::max(mMasterVolume, 0.0f), 1.0f); + mSFXVolume = Settings::Manager::getFloat("sfx volume", "Sound"); + mSFXVolume = std::min(std::max(mSFXVolume, 0.0f), 1.0f); + mMusicVolume = Settings::Manager::getFloat("music volume", "Sound"); + mMusicVolume = std::min(std::max(mMusicVolume, 0.0f), 1.0f); + std::cout << "Sound output: " << SOUND_OUT << std::endl; std::cout << "Sound decoder: " << SOUND_IN << std::endl; @@ -64,7 +74,19 @@ namespace MWSound for(size_t i = 0;i < names.size();i++) std::cout <<" "<init(); + std::string devname = Settings::Manager::getString("device", "Sound"); + try + { + mOutput->init(devname); + } + catch(std::exception &e) + { + if(devname.empty()) + throw; + std::cout <<"Failed to open device \""<init(); + Settings::Manager::setString("device", "Sound", ""); + } } catch(std::exception &e) { @@ -141,9 +163,10 @@ namespace MWSound std::cout <<"Playing "<streamSound(filename, 0.4f, 1.0f, Play_NoEnv); - mMusic->mBaseVolume = 0.4f; + mMusic = mOutput->streamSound(filename, basevol, 1.0f, Play_NoEnv); + mMusic->mBaseVolume = basevol; mMusic->mFlags = Play_NoEnv; } catch(std::exception &e) @@ -187,7 +210,7 @@ namespace MWSound try { // The range values are not tested - float basevol = 1.0f; /* TODO: volume settings */ + float basevol = mMasterVolume * mSFXVolume; std::string filePath = "Sound/"+filename; const ESM::Position &pos = ptr.getCellRef().pos; const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]); @@ -218,7 +241,7 @@ namespace MWSound return sound; try { - float basevol = 1.0f; /* TODO: volume settings */ + float basevol = mMasterVolume * mSFXVolume; float min, max; std::string file = lookup(soundId, basevol, min, max); @@ -248,7 +271,7 @@ namespace MWSound try { // Look up the sound in the ESM data - float basevol = 1.0f; /* TODO: volume settings */ + float basevol = mMasterVolume * mSFXVolume; float min, max; std::string file = lookup(soundId, basevol, min, max); const ESM::Position &pos = ptr.getCellRef().pos; diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index cad5f6187..d64db299b 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -56,6 +56,10 @@ namespace MWSound std::auto_ptr mOutput; + float mMasterVolume; + float mSFXVolume; + float mMusicVolume; + boost::shared_ptr mMusic; std::string mCurrentPlaylist; diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 9d766909f..d3a0a34ae 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -137,6 +137,11 @@ namespace MWWorld return -1; } + int Class::getValue (const Ptr& ptr) const + { + throw std::logic_error ("value not supported by this class"); + } + const Class& Class::get (const std::string& key) { std::map >::const_iterator iter = sClasses.find (key); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 67320b3e0..e474e9b92 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -155,6 +155,10 @@ namespace MWWorld /// no such skill. /// (default implementation: return -1) + virtual int getValue (const Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + /// (default implementation: throws an exception) + static const Class& get (const std::string& key); ///< If there is no class for this \a key, an exception is thrown. diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index e64c9785f..650418201 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -4,8 +4,12 @@ #include #include +#include "../mwmechanics/npcstats.hpp" + #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 +28,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) + { + bool use = false; + + if (slots.at (*iter2)==end()) + use = true; // slot was empty before -> skill all further checks + else + { + Ptr old = *slots.at (*iter2); + + if (!use) + { + // check skill + int oldSkill = + MWWorld::Class::get (old).getEquipmentSkill (old, environment); + + if (testSkill!=-1 || oldSkill!=-1 || testSkill!=oldSkill) + { + if (stats.mSkill[oldSkill].getModified()>stats.mSkill[testSkill].getModified()) + continue; // rejected, because old item better matched the NPC's skills. + + if (stats.mSkill[oldSkill].getModified()= + MWWorld::Class::get (test).getValue (test)) + { + continue; + } + + use = true; + } + } + + /// \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 +63,9 @@ namespace MWWorld ///< \note \a iteartor can be an end-iterator ContainerStoreIterator getSlot (int slot); + + void autoEquip (const MWMechanics::NpcStats& stats, const Environment& environment); + ///< 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(); diff --git a/files/settings-default.cfg b/files/settings-default.cfg index efe03972b..6b037c06a 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -70,3 +70,12 @@ reflect small statics = false reflect actors = true reflect misc = false + +[Sound] +# Device name. Blank means default +device = + +# Volumes. Sfx and music volumes are both affected by the master volume +master volume = 1.0 +sfx volume = 1.0 +music volume = 0.4