Use raycast distance when player activates trapped object

coverity_scan^2
Allofich 9 years ago
parent 64d53a2314
commit 64d298d2b5

@ -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) void MWWorld::Action::setSound (const std::string& id)

@ -19,7 +19,9 @@ namespace MWWorld
Action (const Action& action); Action (const Action& action);
Action& operator= (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: protected:
@ -36,6 +38,7 @@ namespace MWWorld
///< Is running this action a no-op? (default false) ///< Is running this action a no-op? (default false)
void execute (const Ptr& actor); void execute (const Ptr& actor);
void execute (const Ptr& actor, float distanceToObject);
void setSound (const std::string& id); void setSound (const std::string& id);
void setSoundOffset(float offset); void setSoundOffset(float offset);

@ -7,20 +7,20 @@
namespace MWWorld 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 actorPosition(actor.getRefData().getPosition().asVec3());
osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3());
float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance();
// GUI calcs if object in activation distance include object and player geometry // 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 // Hack: if actor is beyond activation range, then assume actor is using telekinesis
// to open door/container. // 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. // 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 // assume actor touched trap
MWMechanics::CastSpell cast(mTrapSource, actor); MWMechanics::CastSpell cast(mTrapSource, actor);

@ -13,7 +13,7 @@ namespace MWWorld
std::string mSpellId; std::string mSpellId;
MWWorld::Ptr mTrapSource; MWWorld::Ptr mTrapSource;
virtual void executeImp (const Ptr& actor); virtual void executeImp (const Ptr& actor, float distance);
public: public:

@ -3228,7 +3228,20 @@ namespace MWWorld
if (object.getRefData().activate()) if (object.getRefData().activate())
{ {
boost::shared_ptr<MWWorld::Action> action = (object.getClass().activate(object, actor)); boost::shared_ptr<MWWorld::Action> 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);
} }
} }

Loading…
Cancel
Save