mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Try to figure out what gets hit
This isn't the greatest. The distance multiplier is a guess, and a sphere cast may be better.
This commit is contained in:
parent
b3a057d679
commit
6195062d72
6 changed files with 54 additions and 4 deletions
|
@ -218,6 +218,10 @@ namespace MWBase
|
|||
virtual MWWorld::Ptr getFacedObject() = 0;
|
||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
||||
|
||||
/// Returns a pointer to the object the provided object is facing (if within the
|
||||
/// specified distance). This will attempt to use the "Bip01 Head" node as a basis.
|
||||
virtual MWWorld::Ptr getFacedObject(const MWWorld::Ptr &ptr, float distance) = 0;
|
||||
|
||||
virtual void adjustPosition (const MWWorld::Ptr& ptr) = 0;
|
||||
///< Adjust position after load to be on ground. Must be called after model load.
|
||||
|
||||
|
|
|
@ -305,14 +305,19 @@ namespace MWClass
|
|||
|
||||
void Npc::hit(const MWWorld::Ptr& ptr, int type) const
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
|
||||
// Get the weapon used (if hand-to-hand, weapon = inv.end())
|
||||
MWWorld::InventoryStore &inv = getInventoryStore(ptr);
|
||||
MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
if(weapon != inv.end() && weapon->getTypeName() != typeid(ESM::Weapon).name())
|
||||
weapon = inv.end();
|
||||
|
||||
// FIXME: Detect what was hit
|
||||
MWWorld::Ptr victim;
|
||||
float dist = 100.0f * ((weapon != inv.end()) ?
|
||||
weapon->get<ESM::Weapon>()->mBase->mData.mReach :
|
||||
gmst.find("fHandToHandReach")->getFloat());
|
||||
MWWorld::Ptr victim = world->getFacedObject(ptr, dist);
|
||||
if(victim.isEmpty()) // Didn't hit anything
|
||||
return;
|
||||
|
||||
|
@ -362,8 +367,6 @@ namespace MWClass
|
|||
//damage *= weapon_current_health / weapon_max_health;
|
||||
if(!othercls.hasDetected(victim, ptr))
|
||||
{
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat();
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||
}
|
||||
|
|
|
@ -304,6 +304,19 @@ namespace MWWorld
|
|||
return results;
|
||||
}
|
||||
|
||||
std::pair<std::string,float> PhysicsSystem::getFacedHandle(const Ogre::Vector3 &origin_, const Ogre::Quaternion &orient_, float queryDistance)
|
||||
{
|
||||
Ogre::Vector3 dest_ = origin_ + orient_.yAxis()*queryDistance;
|
||||
|
||||
btVector3 origin(origin_.x, origin_.y, origin_.z);
|
||||
btVector3 dest(dest_.x, dest_.y, dest_.z);
|
||||
|
||||
std::pair<std::string,float> result = mEngine->rayTest(origin, dest);
|
||||
result.second *= queryDistance;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight)
|
||||
{
|
||||
// TODO: store and use
|
||||
|
|
|
@ -55,6 +55,9 @@ namespace MWWorld
|
|||
Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr);
|
||||
|
||||
std::pair<float, std::string> getFacedHandle (MWWorld::World& world, float queryDistance);
|
||||
std::pair<std::string,float> getFacedHandle(const Ogre::Vector3 &origin,
|
||||
const Ogre::Quaternion &orientation,
|
||||
float queryDistance);
|
||||
std::vector < std::pair <float, std::string> > getFacedHandles (float queryDistance);
|
||||
std::vector < std::pair <float, std::string> > getFacedHandles (float mouseX, float mouseY, float queryDistance);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "../mwmechanics/movement.hpp"
|
||||
|
||||
#include "../mwrender/sky.hpp"
|
||||
#include "../mwrender/animation.hpp"
|
||||
|
||||
#include "../mwclass/door.hpp"
|
||||
|
||||
|
@ -776,6 +777,28 @@ namespace MWWorld
|
|||
return object;
|
||||
}
|
||||
|
||||
MWWorld::Ptr World::getFacedObject(const MWWorld::Ptr &ptr, float distance)
|
||||
{
|
||||
const ESM::Position &posdata = ptr.getRefData().getPosition();
|
||||
Ogre::Vector3 pos(posdata.pos);
|
||||
Ogre::Quaternion rot = Ogre::Quaternion(Ogre::Radian(posdata.rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
|
||||
Ogre::Quaternion(Ogre::Radian(posdata.rot[0]), Ogre::Vector3::UNIT_X);
|
||||
|
||||
MWRender::Animation *anim = mRendering->getAnimation(ptr);
|
||||
if(anim != NULL)
|
||||
{
|
||||
Ogre::Node *node = anim->getNode("Head");
|
||||
if(node != NULL)
|
||||
pos += node->_getDerivedPosition();
|
||||
}
|
||||
|
||||
std::pair<std::string,float> result = mPhysics->getFacedHandle(pos, rot, distance);
|
||||
if(result.first.empty())
|
||||
return MWWorld::Ptr();
|
||||
|
||||
return searchPtrViaHandle(result.first);
|
||||
}
|
||||
|
||||
void World::deleteObject (const Ptr& ptr)
|
||||
{
|
||||
if (ptr.getRefData().getCount()>0)
|
||||
|
|
|
@ -252,6 +252,10 @@ namespace MWWorld
|
|||
virtual MWWorld::Ptr getFacedObject();
|
||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
||||
|
||||
/// Returns a pointer to the object the provided object is facing (if within the
|
||||
/// specified distance). This will attempt to use the "Bip01 Head" node as a basis.
|
||||
virtual MWWorld::Ptr getFacedObject(const MWWorld::Ptr &ptr, float distance);
|
||||
|
||||
virtual void deleteObject (const Ptr& ptr);
|
||||
|
||||
virtual void moveObject (const Ptr& ptr, float x, float y, float z);
|
||||
|
|
Loading…
Reference in a new issue