From b29e9e9c77a73755f420b0eb89361998a4ed6657 Mon Sep 17 00:00:00 2001 From: Allofich Date: Fri, 1 Jul 2016 02:27:20 +0900 Subject: [PATCH 01/23] Don't allow telekinesis on actors or teleport doors --- apps/openmw/mwworld/worldimp.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 313fe73b1..5bc38005d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1025,6 +1025,10 @@ namespace MWWorld float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; facedObject = getFacedObject(activationDistance); + if (!facedObject.isEmpty() && !facedObject.getClass().isActor() && !facedObject.getCellRef().getTeleport()) + return facedObject; + else + facedObject = getFacedObject(getMaxActivationDistance()); } return facedObject; From 574e40db5e34ebd0827b21be52c4f35f24ca0aaa Mon Sep 17 00:00:00 2001 From: Allofich Date: Mon, 4 Jul 2016 01:50:47 +0900 Subject: [PATCH 02/23] Don't allow telekinesis on activators --- apps/openmw/mwworld/worldimp.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 5bc38005d..6915a389c 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1025,7 +1025,10 @@ namespace MWWorld float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; facedObject = getFacedObject(activationDistance); - if (!facedObject.isEmpty() && !facedObject.getClass().isActor() && !facedObject.getCellRef().getTeleport()) + + // Not allowing telekinesis on actors, on doors that teleport to other cells, or on activators + // Original engine doesn't allow telekinesis on books or lights, either + if (!facedObject.isEmpty() && !facedObject.getClass().isActor() && !facedObject.getCellRef().getTeleport() && facedObject.getClass().getTypeName() != "struct ESM::Activator") return facedObject; else facedObject = getFacedObject(getMaxActivationDistance()); From 64d53a2314976f87165102aa79c811e444269354 Mon Sep 17 00:00:00 2001 From: Allofich Date: Mon, 4 Jul 2016 02:11:30 +0900 Subject: [PATCH 03/23] Avoid double raycasts when using getFacedObject --- apps/openmw/mwrender/renderingmanager.cpp | 4 ++- apps/openmw/mwrender/renderingmanager.hpp | 1 + apps/openmw/mwworld/worldimp.cpp | 37 ++++++++++++++++++++--- apps/openmw/mwworld/worldimp.hpp | 6 ++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ea3e7b7ee..c9be3bdcb 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -738,7 +738,9 @@ namespace MWRender mViewer->getCamera()->accept(*createIntersectionVisitor(intersector, ignorePlayer, ignoreActors)); - return getIntersectionResult(intersector); + RayResult result = getIntersectionResult(intersector); + result.mDistanceToFirstIntersection = maxDistance * intersector->getFirstIntersection().ratio; + return result; } void RenderingManager::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index ebe75d39b..3345d121f 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -120,6 +120,7 @@ namespace MWRender osg::Vec3f mHitNormalWorld; osg::Vec3f mHitPointWorld; MWWorld::Ptr mHitObject; + float mDistanceToFirstIntersection; }; RayResult castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors=false); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6915a389c..5b156cba0 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1,4 +1,5 @@ #include "worldimp.hpp" +#include #include #include @@ -1023,15 +1024,16 @@ namespace MWWorld telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus); float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; + float distanceToObject; - facedObject = getFacedObject(activationDistance); + facedObject = getFacedObject(activationDistance, distanceToObject, true); // Not allowing telekinesis on actors, on doors that teleport to other cells, or on activators // Original engine doesn't allow telekinesis on books or lights, either - if (!facedObject.isEmpty() && !facedObject.getClass().isActor() && !facedObject.getCellRef().getTeleport() && facedObject.getClass().getTypeName() != "struct ESM::Activator") - return facedObject; - else - facedObject = getFacedObject(getMaxActivationDistance()); + if (!facedObject.isEmpty() && (facedObject.getClass().isActor() + || facedObject.getCellRef().getTeleport() || facedObject.getClass().getTypeName() == "struct ESM::Activator") + && (distanceToObject > getMaxActivationDistance())) + return 0; } return facedObject; @@ -1731,6 +1733,31 @@ namespace MWWorld return mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer).mHitObject; } } + + MWWorld::Ptr World::getFacedObject(float maxDistance, float& distance, bool ignorePlayer) + { + maxDistance += mRendering->getCameraDistance(); + MWWorld::Ptr facedObject; + + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + float x, y; + MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); + MWRender::RenderingManager::RayResult rayToObject = mRendering->castCameraToViewportRay(x, y, maxDistance, ignorePlayer); + facedObject = rayToObject.mHitObject; + if (!facedObject.isEmpty()) + distance = rayToObject.mDistanceToFirstIntersection; + return facedObject; + } + else + { + MWRender::RenderingManager::RayResult rayToObject = mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer); + facedObject = rayToObject.mHitObject; + if (!facedObject.isEmpty()) + distance = rayToObject.mDistanceToFirstIntersection; + return facedObject; + } + } bool World::isCellExterior() const { diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 7af632d23..d5c3c7815 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -127,7 +127,13 @@ namespace MWWorld void updateSoundListener(); void updateWindowManager (); void updatePlayer(bool paused); + + /// Return faced object MWWorld::Ptr getFacedObject(float maxDistance, bool ignorePlayer=true); + + /// Return faced object and distance from player to it + MWWorld::Ptr getFacedObject(float maxDistance, float& distanceToObject, bool ignorePlayer=true); + public: // FIXME void removeContainerScripts(const Ptr& reference); private: From 64d298d2b54fe6e13ab9dc4e4c171ebe21a287b2 Mon Sep 17 00:00:00 2001 From: Allofich Date: Mon, 4 Jul 2016 02:23:04 +0900 Subject: [PATCH 04/23] Use raycast distance when player activates trapped object --- apps/openmw/mwworld/action.cpp | 30 +++++++++++++++++++++++++++++- apps/openmw/mwworld/action.hpp | 5 ++++- apps/openmw/mwworld/actiontrap.cpp | 6 +++--- apps/openmw/mwworld/actiontrap.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 15 ++++++++++++++- 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index c29377ecb..35cd99de7 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -42,7 +42,35 @@ void MWWorld::Action::execute (const Ptr& actor) } } - executeImp (actor); + executeImp(actor); +} + +void MWWorld::Action::execute (const Ptr& actor, float distanceToObject) +{ + if(!mSoundId.empty()) + { + if(mKeepSound && actor == MWMechanics::getPlayer()) + MWBase::Environment::get().getSoundManager()->playSound(mSoundId, 1.0, 1.0, + MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Normal, mSoundOffset + ); + else + { + bool local = mTarget.isEmpty() || !mTarget.isInCell(); // no usable target + if(mKeepSound) + MWBase::Environment::get().getSoundManager()->playSound3D( + (local ? actor : mTarget).getRefData().getPosition().asVec3(), + mSoundId, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, + MWBase::SoundManager::Play_Normal, mSoundOffset + ); + else + MWBase::Environment::get().getSoundManager()->playSound3D(local ? actor : mTarget, + mSoundId, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, + MWBase::SoundManager::Play_Normal, mSoundOffset + ); + } + } + + executeImp(actor, distanceToObject); } void MWWorld::Action::setSound (const std::string& id) diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index 38907cf44..867c1e27c 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -19,7 +19,9 @@ namespace MWWorld Action (const Action& action); Action& operator= (const Action& action); - virtual void executeImp (const Ptr& actor) = 0; + virtual void executeImp (const Ptr& actor) { return; } + virtual void executeImp (const Ptr& actor, float distanceToObject) { return; } + protected: @@ -36,6 +38,7 @@ namespace MWWorld ///< Is running this action a no-op? (default false) void execute (const Ptr& actor); + void execute (const Ptr& actor, float distanceToObject); void setSound (const std::string& id); void setSoundOffset(float offset); diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index 68d7c69e9..0279eea3e 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -7,20 +7,20 @@ namespace MWWorld { - void ActionTrap::executeImp(const Ptr &actor) + void ActionTrap::executeImp(const Ptr &actor, float distance) { osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); // GUI calcs if object in activation distance include object and player geometry - const float fudgeFactor = 1.25f; + //const float fudgeFactor = 1.25f; // Hack: if actor is beyond activation range, then assume actor is using telekinesis // to open door/container. // Note, can't just detonate the trap at the trapped object's location and use the blast // radius, because for most trap spells this is 1 foot, much less than the activation distance. - if ((trapPosition - actorPosition).length() < (activationDistance * fudgeFactor)) + if (distance < activationDistance) { // assume actor touched trap MWMechanics::CastSpell cast(mTrapSource, actor); diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index 4c2f4139f..7fd6f2bcc 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -13,7 +13,7 @@ namespace MWWorld std::string mSpellId; MWWorld::Ptr mTrapSource; - virtual void executeImp (const Ptr& actor); + virtual void executeImp (const Ptr& actor, float distance); public: diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 5b156cba0..f3ed54eaf 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3228,7 +3228,20 @@ namespace MWWorld if (object.getRefData().activate()) { boost::shared_ptr action = (object.getClass().activate(object, actor)); - action->execute (actor); + if (object.getCellRef().getTrap() != "") // If the object is trapped, do a distance check to account for opening with telekinesis + { + float distanceToObject; + if (actor == getPlayerPtr()) // If the actor doing the activation is the player, get distance using the raycast in getFacedObject() + MWWorld::Ptr result = getFacedObject(1.0f, distanceToObject, true); + else // Otherwise do a position-based distance check + { + osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); + osg::Vec3f objectPosition(object.getRefData().getPosition().asVec3()); + distanceToObject = (objectPosition - actorPosition).length(); + } + action->execute (actor, distanceToObject); + } + action->execute (actor); } } From 199607423b3f06391598fae265ca4c7773fa84e5 Mon Sep 17 00:00:00 2001 From: Allofich Date: Mon, 4 Jul 2016 02:24:45 +0900 Subject: [PATCH 05/23] Use iMaxActivateDist for AI actors that use Activate packages --- apps/openmw/mwmechanics/aiactivate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index 3c5504228..a79adbc8b 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -39,7 +39,7 @@ namespace MWMechanics //Set the target desition from the actor ESM::Pathgrid::Point dest = target.getRefData().getPosition().pos; - if(distance(dest, pos.pos[0], pos.pos[1], pos.pos[2]) < 200) { //Stop when you get close + if(distance(dest, pos.pos[0], pos.pos[1], pos.pos[2]) < MWBase::Environment::get().getWorld()->getMaxActivationDistance()) { //Stop when you get in activation range actor.getClass().getMovementSettings(actor).mPosition[1] = 0; MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr(mObjectId,false); From c02695e56d3d5298407f6cdb9e5854b0aa695492 Mon Sep 17 00:00:00 2001 From: Allofich Date: Mon, 4 Jul 2016 14:39:44 +0900 Subject: [PATCH 06/23] Cleanups and fixes --- apps/openmw/mwworld/action.cpp | 36 ++++--------------------- apps/openmw/mwworld/action.hpp | 3 +-- apps/openmw/mwworld/actiontrap.cpp | 16 +++++------ apps/openmw/mwworld/worldimp.cpp | 43 ++++++++++-------------------- apps/openmw/mwworld/worldimp.hpp | 8 +++--- 5 files changed, 30 insertions(+), 76 deletions(-) diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index 35cd99de7..028080d7a 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -17,7 +17,7 @@ MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSo MWWorld::Action::~Action() {} -void MWWorld::Action::execute (const Ptr& actor) +void MWWorld::Action::execute (const Ptr& actor, float distanceToObject, bool useDistance) { if(!mSoundId.empty()) { @@ -41,36 +41,10 @@ void MWWorld::Action::execute (const Ptr& actor) ); } } - - executeImp(actor); -} - -void MWWorld::Action::execute (const Ptr& actor, float distanceToObject) -{ - if(!mSoundId.empty()) - { - if(mKeepSound && actor == MWMechanics::getPlayer()) - MWBase::Environment::get().getSoundManager()->playSound(mSoundId, 1.0, 1.0, - MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Normal, mSoundOffset - ); - else - { - bool local = mTarget.isEmpty() || !mTarget.isInCell(); // no usable target - if(mKeepSound) - MWBase::Environment::get().getSoundManager()->playSound3D( - (local ? actor : mTarget).getRefData().getPosition().asVec3(), - mSoundId, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, - MWBase::SoundManager::Play_Normal, mSoundOffset - ); - else - MWBase::Environment::get().getSoundManager()->playSound3D(local ? actor : mTarget, - mSoundId, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, - MWBase::SoundManager::Play_Normal, mSoundOffset - ); - } - } - - executeImp(actor, distanceToObject); + if (useDistance) + executeImp(actor, distanceToObject); + else + executeImp(actor); } void MWWorld::Action::setSound (const std::string& id) diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index 867c1e27c..39df539cd 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -37,8 +37,7 @@ namespace MWWorld virtual bool isNullAction() { return false; } ///< Is running this action a no-op? (default false) - void execute (const Ptr& actor); - void execute (const Ptr& actor, float distanceToObject); + void execute (const Ptr& actor, float distanceToObject = 0, bool useDistance = false); void setSound (const std::string& id); void setSoundOffset(float offset); diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index 0279eea3e..a8b937c0a 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -1,40 +1,36 @@ #include "actiontrap.hpp" #include "../mwmechanics/spellcasting.hpp" + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" namespace MWWorld { - void ActionTrap::executeImp(const Ptr &actor, float distance) { osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); - // GUI calcs if object in activation distance include object and player geometry - //const float fudgeFactor = 1.25f; - - // Hack: if actor is beyond activation range, then assume actor is using telekinesis - // to open door/container. - // Note, can't just detonate the trap at the trapped object's location and use the blast + // Note: can't just detonate the trap at the trapped object's location and use the blast // radius, because for most trap spells this is 1 foot, much less than the activation distance. + // Using the activation distance as the trap range. + if (distance < activationDistance) { - // assume actor touched trap + // actor activated object within range of trap MWMechanics::CastSpell cast(mTrapSource, actor); cast.mHitPosition = actorPosition; cast.cast(mSpellId); } else { - // assume telekinesis used + // actor activated object outside range of trap MWMechanics::CastSpell cast(mTrapSource, mTrapSource); cast.mHitPosition = trapPosition; cast.cast(mSpellId); } mTrapSource.getCellRef().setTrap(""); } - } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f3ed54eaf..e54c75afe 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1,5 +1,4 @@ #include "worldimp.hpp" -#include #include #include @@ -151,7 +150,7 @@ namespace MWWorld mSky (true), mCells (mStore, mEsm), mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), mActivationDistanceOverride (activationDistanceOverride), mStartupScript(startupScript), - mStartCell (startCell), mTeleportEnabled(true), + mStartCell (startCell), mDistanceToFacedObject(0), mTeleportEnabled(true), mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0) { mPhysics = new MWPhysics::PhysicsSystem(resourceSystem, rootNode); @@ -1012,10 +1011,11 @@ namespace MWWorld MWWorld::Ptr World::getFacedObject() { MWWorld::Ptr facedObject; + float distanceToObject; if (MWBase::Environment::get().getWindowManager()->isGuiMode() && MWBase::Environment::get().getWindowManager()->isConsoleMode()) - facedObject = getFacedObject(getMaxActivationDistance() * 50, false); + facedObject = getFacedObject(getMaxActivationDistance() * 50, distanceToObject, false); else { float telekinesisRangeBonus = @@ -1024,7 +1024,6 @@ namespace MWWorld telekinesisRangeBonus = feetToGameUnits(telekinesisRangeBonus); float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; - float distanceToObject; facedObject = getFacedObject(activationDistance, distanceToObject, true); @@ -1036,6 +1035,8 @@ namespace MWWorld return 0; } + mDistanceToFacedObject = distanceToObject; + mFacedObject = facedObject; return facedObject; } @@ -1718,22 +1719,6 @@ namespace MWWorld } } - MWWorld::Ptr World::getFacedObject(float maxDistance, bool ignorePlayer) - { - maxDistance += mRendering->getCameraDistance(); - - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - float x, y; - MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); - return mRendering->castCameraToViewportRay(x, y, maxDistance, ignorePlayer).mHitObject; - } - else - { - return mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer).mHitObject; - } - } - MWWorld::Ptr World::getFacedObject(float maxDistance, float& distance, bool ignorePlayer) { maxDistance += mRendering->getCameraDistance(); @@ -3228,20 +3213,20 @@ namespace MWWorld if (object.getRefData().activate()) { boost::shared_ptr action = (object.getClass().activate(object, actor)); - if (object.getCellRef().getTrap() != "") // If the object is trapped, do a distance check to account for opening with telekinesis + if (object.getCellRef().getTrap() != "") { - float distanceToObject; - if (actor == getPlayerPtr()) // If the actor doing the activation is the player, get distance using the raycast in getFacedObject() - MWWorld::Ptr result = getFacedObject(1.0f, distanceToObject, true); - else // Otherwise do a position-based distance check + // For the distance check to a trapped object, use the raycast-derived distance if we have it + if (actor == getPlayerPtr() && (object == mFacedObject)) + action->execute (actor, mDistanceToFacedObject, true); + else // Otherwise use a position comparison { osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); osg::Vec3f objectPosition(object.getRefData().getPosition().asVec3()); - distanceToObject = (objectPosition - actorPosition).length(); - } - action->execute (actor, distanceToObject); + action->execute (actor, (objectPosition - actorPosition).length(), true); + } } - action->execute (actor); + else + action->execute (actor); } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d5c3c7815..b1cc08120 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -128,10 +128,6 @@ namespace MWWorld void updateWindowManager (); void updatePlayer(bool paused); - /// Return faced object - MWWorld::Ptr getFacedObject(float maxDistance, bool ignorePlayer=true); - - /// Return faced object and distance from player to it MWWorld::Ptr getFacedObject(float maxDistance, float& distanceToObject, bool ignorePlayer=true); public: // FIXME @@ -160,6 +156,10 @@ namespace MWWorld const std::vector& content, ContentLoader& contentLoader); float mSwimHeightScale; + + float mDistanceToFacedObject; + MWWorld::Ptr mFacedObject; + bool isUnderwater(const MWWorld::ConstPtr &object, const float heightRatio) const; ///< helper function for implementing isSwimming(), isSubmerged(), isWading() From c1236f4113ae3a395ce1f9738533bbbc42219d29 Mon Sep 17 00:00:00 2001 From: Allofich Date: Mon, 4 Jul 2016 19:09:12 +0900 Subject: [PATCH 07/23] Simplified code --- apps/openmw/mwworld/action.cpp | 4 ++-- apps/openmw/mwworld/action.hpp | 2 +- apps/openmw/mwworld/actiontrap.cpp | 32 ++++++++++++++++++------------ apps/openmw/mwworld/actiontrap.hpp | 6 +++++- apps/openmw/mwworld/worldimp.cpp | 19 +++++------------- apps/openmw/mwworld/worldimp.hpp | 1 - 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index 028080d7a..748e30ceb 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -17,7 +17,7 @@ MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSo MWWorld::Action::~Action() {} -void MWWorld::Action::execute (const Ptr& actor, float distanceToObject, bool useDistance) +void MWWorld::Action::execute (const Ptr& actor, float distanceToObject) { if(!mSoundId.empty()) { @@ -41,7 +41,7 @@ void MWWorld::Action::execute (const Ptr& actor, float distanceToObject, bool us ); } } - if (useDistance) + if (distanceToObject != 0) executeImp(actor, distanceToObject); else executeImp(actor); diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index 39df539cd..e363927ff 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -37,7 +37,7 @@ namespace MWWorld virtual bool isNullAction() { return false; } ///< Is running this action a no-op? (default false) - void execute (const Ptr& actor, float distanceToObject = 0, bool useDistance = false); + void execute (const Ptr& actor, float distanceToObject = 0); void setSound (const std::string& id); void setSoundOffset(float offset); diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index a8b937c0a..86e232302 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -7,30 +7,36 @@ namespace MWWorld { - void ActionTrap::executeImp(const Ptr &actor, float distance) + // actor activated object without telekinesis, so trap will hit + void ActionTrap::executeImp(const Ptr &actor) { osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); + + MWMechanics::CastSpell cast(mTrapSource, actor); + cast.mHitPosition = actorPosition; + cast.cast(mSpellId); + + mTrapSource.getCellRef().setTrap(""); + } + + // actor activated object with telekinesis, so trap may or may not hit + void ActionTrap::executeImp(const Ptr &actor, float distance) + { osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); // Note: can't just detonate the trap at the trapped object's location and use the blast // radius, because for most trap spells this is 1 foot, much less than the activation distance. - // Using the activation distance as the trap range. + // Using activation distance as the trap range. - if (distance < activationDistance) + if (distance < activationDistance) // actor activated object within range of trap + executeImp(actor); + else // actor activated object outside range of trap { - // actor activated object within range of trap - MWMechanics::CastSpell cast(mTrapSource, actor); - cast.mHitPosition = actorPosition; - cast.cast(mSpellId); - } - else - { - // actor activated object outside range of trap MWMechanics::CastSpell cast(mTrapSource, mTrapSource); cast.mHitPosition = trapPosition; cast.cast(mSpellId); - } - mTrapSource.getCellRef().setTrap(""); + mTrapSource.getCellRef().setTrap(""); + } } } diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index 7fd6f2bcc..73a43b354 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -13,7 +13,11 @@ namespace MWWorld std::string mSpellId; MWWorld::Ptr mTrapSource; - virtual void executeImp (const Ptr& actor, float distance); + /// Activating trapped object without telekinesis active or within trap range + virtual void executeImp (const Ptr& actor); + + /// Activating trapped object with telekinesis active + virtual void executeImp (const Ptr& actor, float distanceToObject); public: diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index e54c75afe..a6ea308e8 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1036,7 +1036,6 @@ namespace MWWorld } mDistanceToFacedObject = distanceToObject; - mFacedObject = facedObject; return facedObject; } @@ -3213,19 +3212,11 @@ namespace MWWorld if (object.getRefData().activate()) { boost::shared_ptr action = (object.getClass().activate(object, actor)); - if (object.getCellRef().getTrap() != "") - { - // For the distance check to a trapped object, use the raycast-derived distance if we have it - if (actor == getPlayerPtr() && (object == mFacedObject)) - action->execute (actor, mDistanceToFacedObject, true); - else // Otherwise use a position comparison - { - osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); - osg::Vec3f objectPosition(object.getRefData().getPosition().asVec3()); - action->execute (actor, (objectPosition - actorPosition).length(), true); - } - } - else + // If the player is opening a trap with telekinesis on, use the raycast-derived distance to check if the trap should hit + if (object.getCellRef().getTrap() != "" && actor == getPlayerPtr() && mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects() + .get(ESM::MagicEffect::Telekinesis).getMagnitude() > 0) + action->execute (actor, mDistanceToFacedObject); + else // Otherwise just activate, and if it's trapped it will always hit action->execute (actor); } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index b1cc08120..64160018f 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -158,7 +158,6 @@ namespace MWWorld float mSwimHeightScale; float mDistanceToFacedObject; - MWWorld::Ptr mFacedObject; bool isUnderwater(const MWWorld::ConstPtr &object, const float heightRatio) const; ///< helper function for implementing isSwimming(), isSubmerged(), isWading() From bf0ec550dacb8dab63cbe21b493c87e24c3ec9b0 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Thu, 7 Jul 2016 01:09:59 +0200 Subject: [PATCH 08/23] OS X: specify minimum CMake version & remove redundant argument from CI script --- CI/before_script.osx.sh | 1 - CMakeLists.txt | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CI/before_script.osx.sh b/CI/before_script.osx.sh index bf38186f6..164208f49 100755 --- a/CI/before_script.osx.sh +++ b/CI/before_script.osx.sh @@ -10,7 +10,6 @@ mkdir build cd build cmake \ --D PKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON \ -D CMAKE_EXE_LINKER_FLAGS="-lz" \ -D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="10.8" \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 14a1c15c8..133d9f7e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,7 +140,10 @@ if (USE_QT) endif() endif() -if (USE_QT AND DESIRED_QT_VERSION MATCHES 5) +if (APPLE) + # OS X build process relies on this fix: https://github.com/Kitware/CMake/commit/3df5147043d83aa09acd5c9ce31d5c602efb99db + cmake_minimum_required(VERSION 3.1.0) +elseif (USE_QT AND DESIRED_QT_VERSION MATCHES 5) # 2.8.11+ is required to make Qt5 happy and allow linking QtMain on Windows. cmake_minimum_required(VERSION 2.8.11) else() From e25e6989781cfe03ce989acb0e907787fde86f10 Mon Sep 17 00:00:00 2001 From: Allofich Date: Mon, 4 Jul 2016 23:27:02 +0900 Subject: [PATCH 09/23] Fix telekinesis check for activators --- apps/openmw/mwworld/worldimp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a6ea308e8..f1cee80f1 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1030,7 +1030,7 @@ namespace MWWorld // Not allowing telekinesis on actors, on doors that teleport to other cells, or on activators // Original engine doesn't allow telekinesis on books or lights, either if (!facedObject.isEmpty() && (facedObject.getClass().isActor() - || facedObject.getCellRef().getTeleport() || facedObject.getClass().getTypeName() == "struct ESM::Activator") + || facedObject.getCellRef().getTeleport() || facedObject.getClass().getTypeName() == typeid(ESM::Activator).name()) && (distanceToObject > getMaxActivationDistance())) return 0; } From 538209b0a240cc8b113c1280c599d814c9ee6e89 Mon Sep 17 00:00:00 2001 From: Allofich Date: Wed, 6 Jul 2016 22:03:37 +0900 Subject: [PATCH 10/23] Change variable to mRatio and initialize it --- apps/openmw/mwrender/renderingmanager.cpp | 6 +++--- apps/openmw/mwrender/renderingmanager.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index c9be3bdcb..c18fa9dd2 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -668,6 +668,7 @@ namespace MWRender { RenderingManager::RayResult result; result.mHit = false; + result.mRatio = 0; if (intersector->containsIntersections()) { result.mHit = true; @@ -675,6 +676,7 @@ namespace MWRender result.mHitPointWorld = intersection.getWorldIntersectPoint(); result.mHitNormalWorld = intersection.getWorldIntersectNormal(); + result.mRatio = intersection.ratio; PtrHolder* ptrHolder = NULL; for (osg::NodePath::const_iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) @@ -738,9 +740,7 @@ namespace MWRender mViewer->getCamera()->accept(*createIntersectionVisitor(intersector, ignorePlayer, ignoreActors)); - RayResult result = getIntersectionResult(intersector); - result.mDistanceToFirstIntersection = maxDistance * intersector->getFirstIntersection().ratio; - return result; + return getIntersectionResult(intersector); } void RenderingManager::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 3345d121f..d2adbd31f 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -120,7 +120,7 @@ namespace MWRender osg::Vec3f mHitNormalWorld; osg::Vec3f mHitPointWorld; MWWorld::Ptr mHitObject; - float mDistanceToFirstIntersection; + float mRatio; }; RayResult castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors=false); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f1cee80f1..35749049d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1730,7 +1730,7 @@ namespace MWWorld MWRender::RenderingManager::RayResult rayToObject = mRendering->castCameraToViewportRay(x, y, maxDistance, ignorePlayer); facedObject = rayToObject.mHitObject; if (!facedObject.isEmpty()) - distance = rayToObject.mDistanceToFirstIntersection; + distance = rayToObject.mRatio * maxDistance; return facedObject; } else @@ -1738,7 +1738,7 @@ namespace MWWorld MWRender::RenderingManager::RayResult rayToObject = mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer); facedObject = rayToObject.mHitObject; if (!facedObject.isEmpty()) - distance = rayToObject.mDistanceToFirstIntersection; + distance = rayToObject.mRatio * maxDistance; return facedObject; } } From 8014f37879e1de82a443cd684fd9c1085a0adc55 Mon Sep 17 00:00:00 2001 From: Allofich Date: Wed, 6 Jul 2016 22:09:39 +0900 Subject: [PATCH 11/23] Avoid duplicate code --- apps/openmw/mwworld/worldimp.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 35749049d..c2d27e60e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1722,25 +1722,21 @@ namespace MWWorld { maxDistance += mRendering->getCameraDistance(); MWWorld::Ptr facedObject; + MWRender::RenderingManager::RayResult rayToObject; if (MWBase::Environment::get().getWindowManager()->isGuiMode()) { float x, y; MWBase::Environment::get().getWindowManager()->getMousePosition(x, y); - MWRender::RenderingManager::RayResult rayToObject = mRendering->castCameraToViewportRay(x, y, maxDistance, ignorePlayer); - facedObject = rayToObject.mHitObject; - if (!facedObject.isEmpty()) - distance = rayToObject.mRatio * maxDistance; - return facedObject; + rayToObject = mRendering->castCameraToViewportRay(x, y, maxDistance, ignorePlayer); } else - { - MWRender::RenderingManager::RayResult rayToObject = mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer); - facedObject = rayToObject.mHitObject; - if (!facedObject.isEmpty()) - distance = rayToObject.mRatio * maxDistance; - return facedObject; - } + rayToObject = mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer); + + facedObject = rayToObject.mHitObject; + if (!facedObject.isEmpty()) + distance = rayToObject.mRatio * maxDistance; + return facedObject; } bool World::isCellExterior() const From 35a23c3b49b7986a8d288e0af625d4041a8be626 Mon Sep 17 00:00:00 2001 From: Allofich Date: Thu, 7 Jul 2016 00:03:14 +0900 Subject: [PATCH 12/23] Implement and use new method allowTelekinesis() --- apps/openmw/mwclass/activator.cpp | 4 ++++ apps/openmw/mwclass/activator.hpp | 3 +++ apps/openmw/mwclass/actor.cpp | 4 ++++ apps/openmw/mwclass/actor.hpp | 3 +++ apps/openmw/mwclass/door.cpp | 8 ++++++++ apps/openmw/mwclass/door.hpp | 3 +++ apps/openmw/mwworld/class.hpp | 3 +++ apps/openmw/mwworld/worldimp.cpp | 7 ++----- 8 files changed, 30 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index 9785eef1e..b3747f916 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -81,6 +81,10 @@ namespace MWClass return (ref->mBase->mName != ""); } + bool Activator::allowTelekinesis(const MWWorld::ConstPtr &ptr) const { + return false; + } + MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const { const MWWorld::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/activator.hpp b/apps/openmw/mwclass/activator.hpp index 15dbf5767..e90620cea 100644 --- a/apps/openmw/mwclass/activator.hpp +++ b/apps/openmw/mwclass/activator.hpp @@ -24,6 +24,9 @@ namespace MWClass virtual bool hasToolTip (const MWWorld::ConstPtr& ptr) const; ///< @return true if this object has a tooltip when focused (default implementation: false) + virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const; + ///< Return whether this class of object can be activated with telekinesis + virtual MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const; ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index 4e89c7282..56de5e3f8 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -79,4 +79,8 @@ namespace MWClass weight += effects.get(MWMechanics::EffectKey(ESM::MagicEffect::Burden)).getMagnitude(); return (weight < 0) ? 0.0f : weight; } + + bool Actor::allowTelekinesis(const MWWorld::ConstPtr &ptr) const { + return false; + } } diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp index 88a3f1a32..1aca5e660 100644 --- a/apps/openmw/mwclass/actor.hpp +++ b/apps/openmw/mwclass/actor.hpp @@ -35,6 +35,9 @@ namespace MWClass ///< Returns total weight of objects inside this object (including modifications from magic /// effects). Throws an exception, if the object can't hold other objects. + virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const; + ///< Return whether this class of object can be activated with telekinesis + // not implemented Actor(const Actor&); Actor& operator= (const Actor&); diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 8d54dff5d..81188fe10 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -213,6 +213,14 @@ namespace MWClass return true; } + bool Door::allowTelekinesis(const MWWorld::ConstPtr &ptr) const + { + if (ptr.getCellRef().getTeleport()) + return false; + else + return true; + } + std::string Door::getScript (const MWWorld::ConstPtr& ptr) const { const MWWorld::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index 42aa6d64d..906b18511 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -45,6 +45,9 @@ namespace MWClass virtual bool canLock(const MWWorld::ConstPtr &ptr) const; + virtual bool allowTelekinesis(const MWWorld::ConstPtr &ptr) const; + ///< Return whether this class of object can be activated with telekinesis + virtual std::string getScript (const MWWorld::ConstPtr& ptr) const; ///< Return name of the script attached to ptr diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 0bb3edbee..23128ea9d 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -279,6 +279,9 @@ namespace MWWorld virtual bool isKey (const MWWorld::ConstPtr& ptr) const { return false; } virtual bool isGold(const MWWorld::ConstPtr& ptr) const { return false; } + + virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const { return true; } + ///< Return whether this class of object can be activated with telekinesis /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c2d27e60e..869ccdfe5 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1027,11 +1027,8 @@ namespace MWWorld facedObject = getFacedObject(activationDistance, distanceToObject, true); - // Not allowing telekinesis on actors, on doors that teleport to other cells, or on activators - // Original engine doesn't allow telekinesis on books or lights, either - if (!facedObject.isEmpty() && (facedObject.getClass().isActor() - || facedObject.getCellRef().getTeleport() || facedObject.getClass().getTypeName() == typeid(ESM::Activator).name()) - && (distanceToObject > getMaxActivationDistance())) + if (!facedObject.isEmpty() && !facedObject.getClass().allowTelekinesis(facedObject) + && distanceToObject > getMaxActivationDistance()) return 0; } From cb621939fdbb9c54390deb7ec6b8713fb274ae33 Mon Sep 17 00:00:00 2001 From: Allofich Date: Thu, 7 Jul 2016 04:03:56 +0900 Subject: [PATCH 13/23] Streamline trap code --- apps/openmw/mwworld/action.cpp | 6 +++--- apps/openmw/mwworld/action.hpp | 2 +- apps/openmw/mwworld/actiontrap.cpp | 28 ++++++++++------------------ apps/openmw/mwworld/actiontrap.hpp | 8 ++------ apps/openmw/mwworld/worldimp.cpp | 7 +------ 5 files changed, 17 insertions(+), 34 deletions(-) diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index 748e30ceb..e76ff8105 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -17,7 +17,7 @@ MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSo MWWorld::Action::~Action() {} -void MWWorld::Action::execute (const Ptr& actor, float distanceToObject) +void MWWorld::Action::execute (const Ptr& actor, float distanceToFacedObject) { if(!mSoundId.empty()) { @@ -41,8 +41,8 @@ void MWWorld::Action::execute (const Ptr& actor, float distanceToObject) ); } } - if (distanceToObject != 0) - executeImp(actor, distanceToObject); + if (mTarget.getCellRef().getTrap() != "") + executeImp(actor, distanceToFacedObject); else executeImp(actor); } diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index e363927ff..d61e72551 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -37,7 +37,7 @@ namespace MWWorld virtual bool isNullAction() { return false; } ///< Is running this action a no-op? (default false) - void execute (const Ptr& actor, float distanceToObject = 0); + void execute (const Ptr& actor, float distanceToObject = -1); void setSound (const std::string& id); void setSoundOffset(float offset); diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index 86e232302..991e05313 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -7,36 +7,28 @@ namespace MWWorld { - // actor activated object without telekinesis, so trap will hit - void ActionTrap::executeImp(const Ptr &actor) - { - osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); - - MWMechanics::CastSpell cast(mTrapSource, actor); - cast.mHitPosition = actorPosition; - cast.cast(mSpellId); - - mTrapSource.getCellRef().setTrap(""); - } - - // actor activated object with telekinesis, so trap may or may not hit void ActionTrap::executeImp(const Ptr &actor, float distance) { + osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); - float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); + float trapRange = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); // Note: can't just detonate the trap at the trapped object's location and use the blast // radius, because for most trap spells this is 1 foot, much less than the activation distance. // Using activation distance as the trap range. - if (distance < activationDistance) // actor activated object within range of trap - executeImp(actor); - else // actor activated object outside range of trap + if (distance > trapRange) // actor activated object outside range of trap { MWMechanics::CastSpell cast(mTrapSource, mTrapSource); cast.mHitPosition = trapPosition; + cast.cast(mSpellId); + } + else // actor activated object within range of trap + { + MWMechanics::CastSpell cast(mTrapSource, actor); + cast.mHitPosition = actorPosition; cast.cast(mSpellId); - mTrapSource.getCellRef().setTrap(""); } + mTrapSource.getCellRef().setTrap(""); } } diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index 73a43b354..5fb76eb5d 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -13,11 +13,7 @@ namespace MWWorld std::string mSpellId; MWWorld::Ptr mTrapSource; - /// Activating trapped object without telekinesis active or within trap range - virtual void executeImp (const Ptr& actor); - - /// Activating trapped object with telekinesis active - virtual void executeImp (const Ptr& actor, float distanceToObject); + virtual void executeImp (const Ptr& actor, float distanceToObject = -1); public: @@ -25,7 +21,7 @@ namespace MWWorld /// @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) {} + : Action(false, trapSource), mSpellId(spellId), mTrapSource(trapSource) {} }; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 869ccdfe5..3b53e8cac 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3205,12 +3205,7 @@ namespace MWWorld if (object.getRefData().activate()) { boost::shared_ptr action = (object.getClass().activate(object, actor)); - // If the player is opening a trap with telekinesis on, use the raycast-derived distance to check if the trap should hit - if (object.getCellRef().getTrap() != "" && actor == getPlayerPtr() && mPlayer->getPlayer().getClass().getCreatureStats(mPlayer->getPlayer()).getMagicEffects() - .get(ESM::MagicEffect::Telekinesis).getMagnitude() > 0) - action->execute (actor, mDistanceToFacedObject); - else // Otherwise just activate, and if it's trapped it will always hit - action->execute (actor); + action->execute (actor, mDistanceToFacedObject); } } From 7de3afaa7d29502a653ab8a8f230e9fcf98f8cb6 Mon Sep 17 00:00:00 2001 From: Allofich Date: Thu, 7 Jul 2016 21:46:58 +0900 Subject: [PATCH 14/23] Cleanups --- apps/openmw/mwworld/actiontrap.cpp | 2 +- apps/openmw/mwworld/actiontrap.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 13 ++++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index 991e05313..e9ec5fa5e 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -21,7 +21,7 @@ namespace MWWorld { MWMechanics::CastSpell cast(mTrapSource, mTrapSource); cast.mHitPosition = trapPosition; - cast.cast(mSpellId); + cast.cast(mSpellId); } else // actor activated object within range of trap { diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index 5fb76eb5d..6a0820381 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -13,7 +13,7 @@ namespace MWWorld std::string mSpellId; MWWorld::Ptr mTrapSource; - virtual void executeImp (const Ptr& actor, float distanceToObject = -1); + virtual void executeImp (const Ptr& actor, float distanceToObject); public: diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 3b53e8cac..05b060bce 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -150,7 +150,7 @@ namespace MWWorld mSky (true), mCells (mStore, mEsm), mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), mActivationDistanceOverride (activationDistanceOverride), mStartupScript(startupScript), - mStartCell (startCell), mDistanceToFacedObject(0), mTeleportEnabled(true), + mStartCell (startCell), mDistanceToFacedObject(-1), mTeleportEnabled(true), mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0) { mPhysics = new MWPhysics::PhysicsSystem(resourceSystem, rootNode); @@ -1011,11 +1011,10 @@ namespace MWWorld MWWorld::Ptr World::getFacedObject() { MWWorld::Ptr facedObject; - float distanceToObject; if (MWBase::Environment::get().getWindowManager()->isGuiMode() && MWBase::Environment::get().getWindowManager()->isConsoleMode()) - facedObject = getFacedObject(getMaxActivationDistance() * 50, distanceToObject, false); + facedObject = getFacedObject(getMaxActivationDistance() * 50, mDistanceToFacedObject, false); else { float telekinesisRangeBonus = @@ -1025,14 +1024,12 @@ namespace MWWorld float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; - facedObject = getFacedObject(activationDistance, distanceToObject, true); + facedObject = getFacedObject(activationDistance, mDistanceToFacedObject, true); if (!facedObject.isEmpty() && !facedObject.getClass().allowTelekinesis(facedObject) - && distanceToObject > getMaxActivationDistance()) + && mDistanceToFacedObject > getMaxActivationDistance()) return 0; } - - mDistanceToFacedObject = distanceToObject; return facedObject; } @@ -1733,6 +1730,8 @@ namespace MWWorld facedObject = rayToObject.mHitObject; if (!facedObject.isEmpty()) distance = rayToObject.mRatio * maxDistance; + else + distance = -1; return facedObject; } From 0e5c3f781fe1419163f52936f49b466f0d1f4bbc Mon Sep 17 00:00:00 2001 From: Allofich Date: Thu, 7 Jul 2016 22:10:38 +0900 Subject: [PATCH 15/23] Only allow trap distance check to apply to player --- apps/openmw/mwworld/actiontrap.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index e9ec5fa5e..1ddf86bf6 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -1,6 +1,7 @@ #include "actiontrap.hpp" #include "../mwmechanics/spellcasting.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -17,13 +18,13 @@ namespace MWWorld // radius, because for most trap spells this is 1 foot, much less than the activation distance. // Using activation distance as the trap range. - if (distance > trapRange) // actor activated object outside range of trap + if (distance > trapRange && actor == MWMechanics::getPlayer()) // player activated object outside range of trap { MWMechanics::CastSpell cast(mTrapSource, mTrapSource); cast.mHitPosition = trapPosition; cast.cast(mSpellId); } - else // actor activated object within range of trap + else // player activated object within range of trap, or NPC activated trap { MWMechanics::CastSpell cast(mTrapSource, actor); cast.mHitPosition = actorPosition; From ff3b7de0e78f30a9d78d862f0f98dc3018a5e1fb Mon Sep 17 00:00:00 2001 From: Alexander Kurtz Date: Thu, 7 Jul 2016 18:31:49 +0200 Subject: [PATCH 16/23] Update gamecontrollerdb.txt from upstream. --- files/gamecontrollerdb.txt | 53 +++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/files/gamecontrollerdb.txt b/files/gamecontrollerdb.txt index bd8d9c5fc..a69a7c7dd 100644 --- a/files/gamecontrollerdb.txt +++ b/files/gamecontrollerdb.txt @@ -24,6 +24,7 @@ 341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, 6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, 4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, @@ -39,6 +40,22 @@ ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0 8f0e0300000000000000504944564944,Piranha xtreme,platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2, 8f0e0d31000000000000504944564944,Multilaser JS071 USB,platform:Windows,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, 10080300000000000000504944564944,PS2 USB,platform:Windows,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5, +79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows, +4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,platform:Windows, +d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows, +4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,platform:Windows,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Windows, +10080100000000000000504944564944,PS1 USB,platform:Windows,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,platform:Windows, +4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Windows, +0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +9000318000000000000504944564944,Mayflash Wiimote PC Adapter,platform:Windows,a:b2,b:h0.4,x:b0,y:b1,back:b4,start:b5,guide:b11,leftshoulder:b6,rightshoulder:b3,leftx:a0,lefty:a1, +79004318000000000000504944564944,Mayflash GameCube Controller Adapter,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows, +300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,platform:Windows, # OS X 0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, @@ -53,6 +70,16 @@ ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0 4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Mac OS X, 8f0e0000000000000300000000000000,Piranha xtreme,platform:Mac OS X,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2, 0d0f0000000000004d00000000000000,HORI Gem Pad 3,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, +79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, +4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,platform:Mac OS X,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, +050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,y:b9,x:b10,start:b6,guide:b8,back:b7,dpup:b2,dpleft:b0,dpdown:b3,dpright:b1,leftx:a0,lefty:a1,lefttrigger:b12,righttrigger:,leftshoulder:b11,platform:Mac OS X, +83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X, +5e04000000000000dd02000000000000,Xbox One Wired Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4, +050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,x:b18,y:b17,back:b7,guide:b8,start:b6,leftstick:b23,rightstick:b24,leftshoulder:b19,rightshoulder:b20,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b21,righttrigger:b22,platform:Mac OS X, +79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,x:b0,y:b12,back:b32,start:b36,leftstick:b40,rightstick:b44,leftshoulder:b16,rightshoulder:b20,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a8,righty:a12,lefttrigger:b24,righttrigger:b28,platform:Mac OS X, +2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X, +351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X, # Linux 0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, @@ -64,6 +91,7 @@ ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0 030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000006f0e00003001000001010000,EA Sports PS3 Controller,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7, 03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -94,8 +122,31 @@ ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0 03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux, 050000004c050000c405000000010000,PS4 Controller (Bluetooth),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux, +050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux, 03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4, 03000000666600000488000000010000,Super Joy Box 5 Pro,platform:Linux,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13, 05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2, 05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2, -030000008916000001fd000024010000,Razer Onza Classic Edition,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8tart:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000008916000001fd000024010000,Razer Onza Classic Edition,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000005e040000d102000001010000,Microsoft X-Box One pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000005e040000dd02000003020000,Microsoft X-Box One pad v2,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux, +03000000790000001100000010010000,RetroLink Saturn Classic Controller,platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1, +050000007e0500003003000001000000,Nintendo Wii U Pro Controller,platform:Linux,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16, +030000005e0400008e02000004010000,Microsoft X-Box 360 pad,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2, +030000000d0f00002200000011010000,HORI CO.,LTD. REAL ARCADE Pro.V3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1, +030000000d0f00001000000011010000,HORI CO.,LTD. FIGHTING STICK 3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7 +03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3, +0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3, +03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux, +030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000006f0e00001304000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:a0,rightstick:a3,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux, +03000000c9110000f055000011010000,HJC Game GAMEPAD,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b2,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:b7,b:b1,platform:Linux, +03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux, +03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:,leftstick:,rightstick:,leftshoulder:,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,rightshoulder:b7,dpup:b12,platform:Linux, +030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,platform:Linux,x:b0,a:b2,b:b3,y:b1,back:b10,guide:b12,start:b11,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3, +030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,platform:Linux,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4, +03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4, +030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux, +030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,platform:Linux,a:b0,b:b2,x:b1,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7, From 4e54338ce083d91ded1145341c3cc44a9456cd0d Mon Sep 17 00:00:00 2001 From: Allofich Date: Fri, 8 Jul 2016 23:07:07 +0900 Subject: [PATCH 17/23] Implement and use getDistanceToFacedObject() --- apps/openmw/mwbase/world.hpp | 2 ++ apps/openmw/mwworld/action.cpp | 8 +++----- apps/openmw/mwworld/action.hpp | 6 ++---- apps/openmw/mwworld/actiontrap.cpp | 5 ++--- apps/openmw/mwworld/actiontrap.hpp | 4 ++-- apps/openmw/mwworld/worldimp.cpp | 7 ++++++- apps/openmw/mwworld/worldimp.hpp | 2 ++ 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 7376e6b51..82d5ddd5e 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -250,6 +250,8 @@ namespace MWBase virtual MWWorld::Ptr getFacedObject() = 0; ///< Return pointer to the object the player is looking at, if it is within activation range + virtual float getDistanceToFacedObject() = 0; + virtual float getMaxActivationDistance() = 0; /// Returns a pointer to the object the provided object would hit (if within the diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index e76ff8105..c29377ecb 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -17,7 +17,7 @@ MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSo MWWorld::Action::~Action() {} -void MWWorld::Action::execute (const Ptr& actor, float distanceToFacedObject) +void MWWorld::Action::execute (const Ptr& actor) { if(!mSoundId.empty()) { @@ -41,10 +41,8 @@ void MWWorld::Action::execute (const Ptr& actor, float distanceToFacedObject) ); } } - if (mTarget.getCellRef().getTrap() != "") - executeImp(actor, distanceToFacedObject); - else - executeImp(actor); + + executeImp (actor); } void MWWorld::Action::setSound (const std::string& id) diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index d61e72551..38907cf44 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -19,9 +19,7 @@ namespace MWWorld Action (const Action& action); Action& operator= (const Action& action); - virtual void executeImp (const Ptr& actor) { return; } - virtual void executeImp (const Ptr& actor, float distanceToObject) { return; } - + virtual void executeImp (const Ptr& actor) = 0; protected: @@ -37,7 +35,7 @@ namespace MWWorld virtual bool isNullAction() { return false; } ///< Is running this action a no-op? (default false) - void execute (const Ptr& actor, float distanceToObject = -1); + void execute (const Ptr& actor); void setSound (const std::string& id); void setSoundOffset(float offset); diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index 1ddf86bf6..cdabaf8c8 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -1,14 +1,13 @@ #include "actiontrap.hpp" #include "../mwmechanics/spellcasting.hpp" -#include "../mwmechanics/actorutil.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" namespace MWWorld { - void ActionTrap::executeImp(const Ptr &actor, float distance) + void ActionTrap::executeImp(const Ptr &actor) { osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); @@ -18,7 +17,7 @@ namespace MWWorld // radius, because for most trap spells this is 1 foot, much less than the activation distance. // Using activation distance as the trap range. - if (distance > trapRange && actor == MWMechanics::getPlayer()) // player activated object outside range of trap + if (actor == MWBase::Environment::get().getWorld()->getPlayerPtr() && MWBase::Environment::get().getWorld()->getDistanceToFacedObject() > trapRange) // player activated object outside range of trap { MWMechanics::CastSpell cast(mTrapSource, mTrapSource); cast.mHitPosition = trapPosition; diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index 6a0820381..4c2f4139f 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -13,7 +13,7 @@ namespace MWWorld std::string mSpellId; MWWorld::Ptr mTrapSource; - virtual void executeImp (const Ptr& actor, float distanceToObject); + virtual void executeImp (const Ptr& actor); public: @@ -21,7 +21,7 @@ namespace MWWorld /// @param actor Actor that activated the trap /// @param trapSource ActionTrap (const Ptr& actor, const std::string& spellId, const Ptr& trapSource) - : Action(false, trapSource), mSpellId(spellId), mTrapSource(trapSource) {} + : Action(false, actor), mSpellId(spellId), mTrapSource(trapSource) {} }; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 05b060bce..4aa249a6d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1033,6 +1033,11 @@ namespace MWWorld return facedObject; } + float World::getDistanceToFacedObject() + { + return mDistanceToFacedObject; + } + osg::Matrixf World::getActorHeadTransform(const MWWorld::ConstPtr& actor) const { const MWRender::Animation *anim = mRendering->getAnimation(actor); @@ -3204,7 +3209,7 @@ namespace MWWorld if (object.getRefData().activate()) { boost::shared_ptr action = (object.getClass().activate(object, actor)); - action->execute (actor, mDistanceToFacedObject); + action->execute (actor); } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 64160018f..411dbc103 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -348,6 +348,8 @@ namespace MWWorld virtual MWWorld::Ptr getFacedObject(); ///< Return pointer to the object the player is looking at, if it is within activation range + virtual float getDistanceToFacedObject(); + /// Returns a pointer to the object the provided object would hit (if within the /// specified distance), and the point where the hit occurs. This will attempt to /// use the "Head" node as a basis. From 53ceefa46adc01bda639949615a41cd8e316e75c Mon Sep 17 00:00:00 2001 From: Allofich Date: Sat, 9 Jul 2016 00:31:39 +0900 Subject: [PATCH 18/23] Allow some telekinesis on teleport doors --- apps/openmw/mwclass/door.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 81188fe10..d8a9efba5 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -146,11 +146,18 @@ namespace MWClass if (ptr.getCellRef().getTeleport()) { - boost::shared_ptr action(new MWWorld::ActionTeleport (ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest(), true)); - - action->setSound(openSound); - - return action; + if (actor == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getDistanceToFacedObject() > MWBase::Environment::get().getWorld()->getMaxActivationDistance()) + { + // player activated teleport door with telekinesis + boost::shared_ptr action(new MWWorld::FailedAction); + return action; + } + else + { + boost::shared_ptr action(new MWWorld::ActionTeleport (ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest(), true)); + action->setSound(openSound); + return action; + } } else { @@ -215,7 +222,7 @@ namespace MWClass bool Door::allowTelekinesis(const MWWorld::ConstPtr &ptr) const { - if (ptr.getCellRef().getTeleport()) + if (ptr.getCellRef().getTeleport() && ptr.getCellRef().getLockLevel() <= 0 && ptr.getCellRef().getTrap().empty()) return false; else return true; From 7a0f9a79898fc17a48e700baf14a308c0fa03113 Mon Sep 17 00:00:00 2001 From: Allofich Date: Sat, 9 Jul 2016 02:12:58 +0900 Subject: [PATCH 19/23] Clean up, remove unnecessary code changes --- apps/openmw/mwworld/worldimp.cpp | 12 ++++++------ apps/openmw/mwworld/worldimp.hpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 4aa249a6d..abae3a3ae 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1014,7 +1014,7 @@ namespace MWWorld if (MWBase::Environment::get().getWindowManager()->isGuiMode() && MWBase::Environment::get().getWindowManager()->isConsoleMode()) - facedObject = getFacedObject(getMaxActivationDistance() * 50, mDistanceToFacedObject, false); + facedObject = getFacedObject(getMaxActivationDistance() * 50, false); else { float telekinesisRangeBonus = @@ -1024,7 +1024,7 @@ namespace MWWorld float activationDistance = getMaxActivationDistance() + telekinesisRangeBonus; - facedObject = getFacedObject(activationDistance, mDistanceToFacedObject, true); + facedObject = getFacedObject(activationDistance, true); if (!facedObject.isEmpty() && !facedObject.getClass().allowTelekinesis(facedObject) && mDistanceToFacedObject > getMaxActivationDistance()) @@ -1717,7 +1717,7 @@ namespace MWWorld } } - MWWorld::Ptr World::getFacedObject(float maxDistance, float& distance, bool ignorePlayer) + MWWorld::Ptr World::getFacedObject(float maxDistance, bool ignorePlayer) { maxDistance += mRendering->getCameraDistance(); MWWorld::Ptr facedObject; @@ -1733,10 +1733,10 @@ namespace MWWorld rayToObject = mRendering->castCameraToViewportRay(0.5f, 0.5f, maxDistance, ignorePlayer); facedObject = rayToObject.mHitObject; - if (!facedObject.isEmpty()) - distance = rayToObject.mRatio * maxDistance; + if (rayToObject.mHit) + mDistanceToFacedObject = rayToObject.mRatio * maxDistance; else - distance = -1; + mDistanceToFacedObject = -1; return facedObject; } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 411dbc103..aa67c9ea8 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -128,7 +128,7 @@ namespace MWWorld void updateWindowManager (); void updatePlayer(bool paused); - MWWorld::Ptr getFacedObject(float maxDistance, float& distanceToObject, bool ignorePlayer=true); + MWWorld::Ptr getFacedObject(float maxDistance, bool ignorePlayer=true); public: // FIXME void removeContainerScripts(const Ptr& reference); From dc0bc5b68c474e40aeeb4a73ef4d0b4c48d3f3c9 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 9 Jul 2016 02:16:47 +0200 Subject: [PATCH 20/23] Implement Face instruction (Feature #1424) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwmechanics/aiface.cpp | 31 ++++++++++++++++++++++++++ apps/openmw/mwmechanics/aiface.hpp | 29 ++++++++++++++++++++++++ apps/openmw/mwmechanics/aipackage.hpp | 5 +++-- apps/openmw/mwmechanics/aisequence.cpp | 3 ++- apps/openmw/mwscript/aiextensions.cpp | 12 +++++++++- components/compiler/extensions0.cpp | 2 +- 7 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 apps/openmw/mwmechanics/aiface.cpp create mode 100644 apps/openmw/mwmechanics/aiface.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index f7a9fea3c..73f88bdb5 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -84,7 +84,7 @@ add_openmw_dir (mwmechanics drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction actor summoning - character actors objects aistate coordinateconverter trading + character actors objects aistate coordinateconverter trading aiface ) add_openmw_dir (mwstate diff --git a/apps/openmw/mwmechanics/aiface.cpp b/apps/openmw/mwmechanics/aiface.cpp new file mode 100644 index 000000000..7d15cabf2 --- /dev/null +++ b/apps/openmw/mwmechanics/aiface.cpp @@ -0,0 +1,31 @@ +#include "aiface.hpp" + +#include "../mwbase/world.hpp" + +#include "steering.hpp" + +MWMechanics::AiFace::AiFace(float targetX, float targetY) + : mTargetX(targetX), mTargetY(targetY) +{ +} + +MWMechanics::AiPackage *MWMechanics::AiFace::clone() const +{ + return new AiFace(*this); +} + +bool MWMechanics::AiFace::execute(const MWWorld::Ptr& actor, MWMechanics::CharacterController& /*characterController*/, MWMechanics::AiState& /*state*/, float /*duration*/) +{ + osg::Vec3f dir = osg::Vec3f(mTargetX, mTargetY, 0) - actor.getRefData().getPosition().asVec3(); + return zTurn(actor, std::atan2(dir.x(), dir.y()), osg::DegreesToRadians(3.f)); +} + +int MWMechanics::AiFace::getTypeId() const +{ + return AiPackage::TypeIdFace; +} + +unsigned int MWMechanics::AiFace::getPriority() const +{ + return 2; +} diff --git a/apps/openmw/mwmechanics/aiface.hpp b/apps/openmw/mwmechanics/aiface.hpp new file mode 100644 index 000000000..099e5d237 --- /dev/null +++ b/apps/openmw/mwmechanics/aiface.hpp @@ -0,0 +1,29 @@ +#ifndef GAME_MWMECHANICS_AIFACE_H +#define GAME_MWMECHANICS_AIFACE_H + +#include "aipackage.hpp" + +namespace MWMechanics +{ + /// AiPackage which makes an actor face a certain direction. + class AiFace : public AiPackage { + public: + AiFace(float targetX, float targetY); + + virtual AiPackage *clone() const; + + virtual bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration); + + virtual int getTypeId() const; + + virtual unsigned int getPriority() const; + + virtual bool canCancel() const { return false; } + virtual bool shouldCancelPreviousAi() const { return false; } + + private: + float mTargetX, mTargetY; + }; +} + +#endif diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 8f6ddb111..277629770 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -40,11 +40,12 @@ namespace MWMechanics TypeIdFollow = 3, TypeIdActivate = 4, - // These 3 are not really handled as Ai Packages in the MW engine + // These 4 are not really handled as Ai Packages in the MW engine // For compatibility do *not* return these in the getCurrentAiPackage script function.. TypeIdCombat = 5, TypeIdPursue = 6, - TypeIdAvoidDoor = 7 + TypeIdAvoidDoor = 7, + TypeIdFace = 8 }; ///Default constructor diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index ed9db102f..f05725cc2 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -159,7 +159,8 @@ bool isActualAiPackage(int packageTypeId) { return (packageTypeId != AiPackage::TypeIdCombat && packageTypeId != AiPackage::TypeIdPursue - && packageTypeId != AiPackage::TypeIdAvoidDoor); + && packageTypeId != AiPackage::TypeIdAvoidDoor + && packageTypeId != AiPackage::TypeIdFace); } void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 12e323272..76130be24 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -19,6 +19,7 @@ #include "../mwmechanics/aifollow.hpp" #include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/aiwander.hpp" +#include "../mwmechanics/aiface.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -483,7 +484,16 @@ namespace MWScript public: virtual void execute(Interpreter::Runtime& runtime) { - /// \todo implement + MWWorld::Ptr actor = R()(runtime); + + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + + MWMechanics::AiFace facePackage(x, y); + actor.getClass().getCreatureStats(actor).getAiSequence().stack(facePackage, actor); } }; diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index f67e70522..353c35a0d 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -70,7 +70,7 @@ namespace Compiler extensions.registerFunction ("getlineofsight", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit); extensions.registerFunction ("getlos", 'l', "c", opcodeGetLineOfSight, opcodeGetLineOfSightExplicit); extensions.registerFunction("gettarget", 'l', "c", opcodeGetTarget, opcodeGetTargetExplicit); - extensions.registerInstruction("face", "llX", opcodeFace, opcodeFaceExplicit); + extensions.registerInstruction("face", "ffX", opcodeFace, opcodeFaceExplicit); } } From f6f3f71db54637fdcaee1aa18ea6c7aae653269e Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 9 Jul 2016 03:18:45 +0200 Subject: [PATCH 21/23] Improve format specifiers for message boxes --- components/CMakeLists.txt | 2 +- components/compiler/lineparser.cpp | 46 +++++---- components/compiler/lineparser.hpp | 20 ++++ components/interpreter/miscopcodes.hpp | 120 ++++++++++++++---------- components/misc/messageformatparser.cpp | 68 ++++++++++++++ components/misc/messageformatparser.hpp | 26 +++++ 6 files changed, 208 insertions(+), 74 deletions(-) create mode 100644 components/misc/messageformatparser.cpp create mode 100644 components/misc/messageformatparser.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 7a07cd59e..6d2436824 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -85,7 +85,7 @@ add_component_dir (esmterrain ) add_component_dir (misc - utf8stream stringops resourcehelpers rng + utf8stream stringops resourcehelpers rng messageformatparser ) IF(NOT WIN32 AND NOT APPLE) diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index ce1e1e463..a5b67f58b 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -140,30 +140,9 @@ namespace Compiler if (mState==MessageState || mState==MessageCommaState) { - std::string arguments; - - for (std::size_t i=0; i +#include #include +#include #include "parser.hpp" #include "exprparser.hpp" @@ -74,6 +76,24 @@ namespace Compiler void reset(); ///< Reset parser to clean state. }; + + class GetArgumentsFromMessageFormat : public ::Misc::MessageFormatParser + { + private: + std::string mArguments; + + protected: + virtual void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision); + virtual void visitedCharacter(char c) {} + + public: + virtual void process(const std::string& message) + { + mArguments.clear(); + ::Misc::MessageFormatParser::process(message); + } + std::string getArguments() const { return mArguments; } + }; } #endif diff --git a/components/interpreter/miscopcodes.hpp b/components/interpreter/miscopcodes.hpp index c49bbeb01..9d62b60aa 100644 --- a/components/interpreter/miscopcodes.hpp +++ b/components/interpreter/miscopcodes.hpp @@ -13,67 +13,89 @@ #include "defines.hpp" #include +#include namespace Interpreter { - inline std::string formatMessage (const std::string& message, Runtime& runtime) + class RuntimeMessageFormatter : public Misc::MessageFormatParser { - std::string formattedMessage; - - for (std::size_t i=0; i= '0' && m[i] <= '9') + { + width = width * 10 + (m[i] - '0'); + widthSet = true; + ++i; + } + + if (i < m.size()) + { + int precision = 0; + bool precisionSet = false; + if (m[i] == '.') + { + while (++i < m.size() && m[i] >= '0' && m[i] <= '9') + { + precision = precision * 10 + (m[i] - '0'); + precisionSet = true; + } + } + + if (i < m.size()) + { + width = (widthSet) ? width : -1; + precision = (precisionSet) ? precision : -1; + + if (m[i] == 'S' || m[i] == 's') + visitedPlaceholder(StringPlaceholder, pad, width, precision); + else if (m[i] == 'g' || m[i] == 'G') + visitedPlaceholder(IntegerPlaceholder, pad, width, precision); + else if (m[i] == 'f' || m[i] == 'F') + visitedPlaceholder(FloatPlaceholder, pad, width, precision); + } + } + } + } + } + else + { + visitedCharacter(m[i]); + } + } + } +} diff --git a/components/misc/messageformatparser.hpp b/components/misc/messageformatparser.hpp new file mode 100644 index 000000000..48faff714 --- /dev/null +++ b/components/misc/messageformatparser.hpp @@ -0,0 +1,26 @@ +#ifndef OPENMW_COMPONENTS_MISC_MESSAGEFORMATPARSER_H +#define OPENMW_COMPONENTS_MISC_MESSAGEFORMATPARSER_H + +#include + +namespace Misc +{ + class MessageFormatParser + { + protected: + enum Placeholder + { + StringPlaceholder, + IntegerPlaceholder, + FloatPlaceholder + }; + + virtual void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision) = 0; + virtual void visitedCharacter(char c) = 0; + + public: + virtual void process(const std::string& message); + }; +} + +#endif From 75a66ced2085de8c99b7ef0180bd77de7887f97a Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 10 Jul 2016 01:48:54 +0200 Subject: [PATCH 22/23] Fix actors lacking turning animations while in first person mode --- apps/openmw/mwmechanics/character.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 0b1c96186..24f004588 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1805,7 +1805,7 @@ void CharacterController::update(float duration) : (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack))); } - else if(rot.z() != 0.0f && !inwater && !sneak && !MWBase::Environment::get().getWorld()->isFirstPerson()) + else if(rot.z() != 0.0f && !inwater && !sneak && !(mPtr == getPlayer() && MWBase::Environment::get().getWorld()->isFirstPerson())) { if(rot.z() > 0.0f) movestate = CharState_TurnRight; From b0fcad4cb88b5f9af6fe85f58286c96593dfe75e Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sun, 10 Jul 2016 03:49:09 +0200 Subject: [PATCH 23/23] Don't stack effects for scrolls of the same type (Fixes #3466) --- apps/openmw/mwmechanics/spellcasting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 4059702d3..52815816e 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -696,7 +696,7 @@ namespace MWMechanics const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find(enchantmentName); - mStack = (enchantment->mData.mType == ESM::Enchantment::CastOnce); + mStack = false; // Check if there's enough charge left if (enchantment->mData.mType == ESM::Enchantment::WhenUsed || enchantment->mData.mType == ESM::Enchantment::WhenStrikes)