diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 675287af9..09891652a 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -7,6 +7,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/failedaction.hpp" @@ -136,7 +137,8 @@ namespace MWClass MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWWorld::InventoryStore& invStore = player.getClass().getInventoryStore(player); - bool needKey = ptr.getCellRef().getLockLevel() > 0; + bool isLocked = ptr.getCellRef().getLockLevel() > 0; + bool isTrapped = !ptr.getCellRef().getTrap().empty(); bool hasKey = false; std::string keyName; @@ -154,18 +156,26 @@ namespace MWClass } } - if (needKey && hasKey) + if ((isLocked || isTrapped) && hasKey) { MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}"); - unlock(ptr); + if(isLocked) + unlock(ptr); // using a key disarms the trap - ptr.getCellRef().setTrap(""); + if(isTrapped) + { + ptr.getCellRef().setTrap(""); + MWBase::Environment::get().getSoundManager()->playSound3D(ptr, + "Disarm Trap", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, + MWBase::SoundManager::Play_Normal); + isTrapped = false; + } } - if (!needKey || hasKey) + if (!isLocked || hasKey) { - if(ptr.getCellRef().getTrap().empty()) + if(!isTrapped) { boost::shared_ptr action (new MWWorld::ActionOpen(ptr)); return action; @@ -173,7 +183,7 @@ namespace MWClass else { // Activate trap - boost::shared_ptr action(new MWWorld::ActionTrap(actor, ptr.getCellRef().getTrap(), ptr)); + boost::shared_ptr action(new MWWorld::ActionTrap(ptr.getCellRef().getTrap(), ptr)); action->setSound(trapActivationSound); return action; } diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index d8a9efba5..a54b64897 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -107,7 +107,8 @@ namespace MWClass MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); - bool needKey = ptr.getCellRef().getLockLevel() > 0; + bool isLocked = ptr.getCellRef().getLockLevel() > 0; + bool isTrapped = !ptr.getCellRef().getTrap().empty(); bool hasKey = false; std::string keyName; @@ -125,21 +126,29 @@ namespace MWClass } } - if (needKey && hasKey) + if ((isLocked || isTrapped) && hasKey) { if(actor == MWMechanics::getPlayer()) MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}"); - unlock(ptr); //Call the function here. because that makes sense. + if(isLocked) + unlock(ptr); //Call the function here. because that makes sense. // using a key disarms the trap - ptr.getCellRef().setTrap(""); + if(isTrapped) + { + ptr.getCellRef().setTrap(""); + MWBase::Environment::get().getSoundManager()->playSound3D(ptr, + "Disarm Trap", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, + MWBase::SoundManager::Play_Normal); + isTrapped = false; + } } - if (!needKey || hasKey) + if (!isLocked || hasKey) { - if(!ptr.getCellRef().getTrap().empty()) + if(isTrapped) { // Trap activation - boost::shared_ptr action(new MWWorld::ActionTrap(actor, ptr.getCellRef().getTrap(), ptr)); + boost::shared_ptr action(new MWWorld::ActionTrap(ptr.getCellRef().getTrap(), ptr)); action->setSound(trapActivationSound); return action; } diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 2d7b8b9f6..f655fee85 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -68,7 +68,6 @@ namespace MWMechanics if (mRemainingDuration <= 0) { mRemainingDuration = mDuration; - mStarted = false; // Reset to false so this package will build path again when repeating return true; } } @@ -100,7 +99,6 @@ namespace MWMechanics if(pathTo(actor,point,duration)) //Returns true on path complete { mRemainingDuration = mDuration; - mStarted = false; // Reset to false so this package will build path again when repeating return true; } mMaxDist = 450; diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 5345035f0..90fe8c21b 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -23,7 +23,6 @@ MWMechanics::AiPackage::~AiPackage() {} MWMechanics::AiPackage::AiPackage() : mTimer(AI_REACTION_TIME + 1.0f), // to force initial pathbuild - mStarted(false), mIsShortcutting(false), mShortcutProhibited(false), mShortcutFailPos() { @@ -90,8 +89,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const ESM::Pathgr if (!mIsShortcutting) { - if (!mStarted // If repeating an AI package (mStarted = false), build a new path so package doesn't immediately end - || wasShortcutting || doesPathNeedRecalc(dest)) // if need to rebuild path + if (wasShortcutting || doesPathNeedRecalc(dest)) // if need to rebuild path { mPathFinder.buildSyncedPath(start, dest, actor.getCell()); @@ -122,7 +120,6 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const ESM::Pathgr } mTimer = 0; - mStarted = true; } if (isDestReached || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1])) // if path is finished @@ -250,9 +247,7 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const ESM::Pathgrid::Point& bool MWMechanics::AiPackage::doesPathNeedRecalc(const ESM::Pathgrid::Point& newDest) { - if (mPathFinder.getPath().empty()) return true; - - return (distance(mPathFinder.getPath().back(), newDest) > 10); + return mPathFinder.getPath().empty() || (distance(mPathFinder.getPath().back(), newDest) > 10); } bool MWMechanics::AiPackage::isTargetMagicallyHidden(const MWWorld::Ptr& target) diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 8a4cf6b90..d30ed89ca 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -124,11 +124,6 @@ namespace MWMechanics bool mShortcutProhibited; // shortcutting may be prohibited after unsuccessful attempt ESM::Pathgrid::Point mShortcutFailPos; // position of last shortcut fail - // Set to true once package starts actually being executed - bool mStarted; - - ESM::Pathgrid::Point mPrevDest; - private: bool isNearInactiveCell(const ESM::Position& actorPos); }; diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index 5375644be..1585a3007 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -58,13 +58,9 @@ namespace MWMechanics if (!isWithinMaxRange(osg::Vec3f(mX, mY, mZ), pos.asVec3())) return false; - if (!mStarted) - mStarted = true; - if (pathTo(actor, ESM::Pathgrid::Point(static_cast(mX), static_cast(mY), static_cast(mZ)), duration)) { actor.getClass().getMovementSettings(actor).mPosition[1] = 0; - mStarted = false; // Reset to false so this package will build path again when repeating return true; } return false; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 24f004588..081f288d5 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1305,7 +1305,9 @@ bool CharacterController::updateWeaponState() if(!resultMessage.empty()) MWBase::Environment::get().getWindowManager()->messageBox(resultMessage); if(!resultSound.empty()) - MWBase::Environment::get().getSoundManager()->playSound(resultSound, 1.0f, 1.0f); + MWBase::Environment::get().getSoundManager()->playSound3D(target, + resultSound, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, + MWBase::SoundManager::Play_Normal); } else if (ammunition) { diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index 4c2f4139f..5ff91613f 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -18,10 +18,9 @@ namespace MWWorld public: /// @param spellId - /// @param actor Actor that activated the trap /// @param trapSource - ActionTrap (const Ptr& actor, const std::string& spellId, const Ptr& trapSource) - : Action(false, actor), mSpellId(spellId), mTrapSource(trapSource) {} + ActionTrap (const std::string& spellId, const Ptr& trapSource) + : Action(false, trapSource), mSpellId(spellId), mTrapSource(trapSource) {} }; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index cb5756c93..b178e6e52 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1722,7 +1722,8 @@ namespace MWWorld MWWorld::Ptr World::getFacedObject(float maxDistance, bool ignorePlayer) { - maxDistance += mRendering->getCameraDistance(); + const float camDist = mRendering->getCameraDistance(); + maxDistance += camDist; MWWorld::Ptr facedObject; MWRender::RenderingManager::RayResult rayToObject; @@ -1737,7 +1738,7 @@ namespace MWWorld facedObject = rayToObject.mHitObject; if (rayToObject.mHit) - mDistanceToFacedObject = rayToObject.mRatio * maxDistance; + mDistanceToFacedObject = (rayToObject.mRatio * maxDistance) - camDist; else mDistanceToFacedObject = -1; return facedObject; diff --git a/components/nif/niffile.hpp b/components/nif/niffile.hpp index 900c360bb..9a2acbb9f 100644 --- a/components/nif/niffile.hpp +++ b/components/nif/niffile.hpp @@ -48,14 +48,14 @@ class NIFFile public: /// Used if file parsing fails - void fail(const std::string &msg) + void fail(const std::string &msg) const { std::string err = " NIFFile Error: " + msg; err += "\nFile: " + filename; throw std::runtime_error(err); } /// Used when something goes wrong, but not catastrophically so - void warn(const std::string &msg) + void warn(const std::string &msg) const { std::cerr << " NIFFile Warning: " << msg < NIFFilePtr; +typedef boost::shared_ptr NIFFilePtr; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 172d92abe..b71701f55 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -321,8 +321,8 @@ namespace NifOsg continue; } - if (!(ctrl->flags & Nif::NiNode::ControllerFlag_Active)) - continue; + // Vanilla seems to ignore the "active" flag for NiKeyframeController, + // so we don't want to skip inactive controllers here. const Nif::NiStringExtraData *strdata = static_cast(extra.getPtr()); const Nif::NiKeyframeController *key = static_cast(ctrl.getPtr()); @@ -918,9 +918,9 @@ namespace NifOsg emitter->setShooter(shooter); osgParticle::BoxPlacer* placer = new osgParticle::BoxPlacer; - placer->setXRange(-partctrl->offsetRandom.x(), partctrl->offsetRandom.x()); - placer->setYRange(-partctrl->offsetRandom.y(), partctrl->offsetRandom.y()); - placer->setZRange(-partctrl->offsetRandom.z(), partctrl->offsetRandom.z()); + placer->setXRange(-partctrl->offsetRandom.x() / 2.f, partctrl->offsetRandom.x() / 2.f); + placer->setYRange(-partctrl->offsetRandom.y() / 2.f, partctrl->offsetRandom.y() / 2.f); + placer->setZRange(-partctrl->offsetRandom.z() / 2.f, partctrl->offsetRandom.z() / 2.f); emitter->setPlacer(placer); return emitter;