mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-01 05:45:33 +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;
|
virtual MWWorld::Ptr getFacedObject() = 0;
|
||||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
///< 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;
|
virtual void adjustPosition (const MWWorld::Ptr& ptr) = 0;
|
||||||
///< Adjust position after load to be on ground. Must be called after model load.
|
///< 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
|
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())
|
// Get the weapon used (if hand-to-hand, weapon = inv.end())
|
||||||
MWWorld::InventoryStore &inv = getInventoryStore(ptr);
|
MWWorld::InventoryStore &inv = getInventoryStore(ptr);
|
||||||
MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
|
||||||
if(weapon != inv.end() && weapon->getTypeName() != typeid(ESM::Weapon).name())
|
if(weapon != inv.end() && weapon->getTypeName() != typeid(ESM::Weapon).name())
|
||||||
weapon = inv.end();
|
weapon = inv.end();
|
||||||
|
|
||||||
// FIXME: Detect what was hit
|
float dist = 100.0f * ((weapon != inv.end()) ?
|
||||||
MWWorld::Ptr victim;
|
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
|
if(victim.isEmpty()) // Didn't hit anything
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -362,8 +367,6 @@ namespace MWClass
|
||||||
//damage *= weapon_current_health / weapon_max_health;
|
//damage *= weapon_current_health / weapon_max_health;
|
||||||
if(!othercls.hasDetected(victim, ptr))
|
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();
|
damage *= gmst.find("fCombatCriticalStrikeMult")->getFloat();
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -304,6 +304,19 @@ namespace MWWorld
|
||||||
return results;
|
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)
|
void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight)
|
||||||
{
|
{
|
||||||
// TODO: store and use
|
// TODO: store and use
|
||||||
|
|
|
@ -55,6 +55,9 @@ namespace MWWorld
|
||||||
Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr);
|
Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr);
|
||||||
|
|
||||||
std::pair<float, std::string> getFacedHandle (MWWorld::World& world, float queryDistance);
|
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 queryDistance);
|
||||||
std::vector < std::pair <float, std::string> > getFacedHandles (float mouseX, float mouseY, 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 "../mwmechanics/movement.hpp"
|
||||||
|
|
||||||
#include "../mwrender/sky.hpp"
|
#include "../mwrender/sky.hpp"
|
||||||
|
#include "../mwrender/animation.hpp"
|
||||||
|
|
||||||
#include "../mwclass/door.hpp"
|
#include "../mwclass/door.hpp"
|
||||||
|
|
||||||
|
@ -776,6 +777,28 @@ namespace MWWorld
|
||||||
return object;
|
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)
|
void World::deleteObject (const Ptr& ptr)
|
||||||
{
|
{
|
||||||
if (ptr.getRefData().getCount()>0)
|
if (ptr.getRefData().getCount()>0)
|
||||||
|
|
|
@ -252,6 +252,10 @@ namespace MWWorld
|
||||||
virtual MWWorld::Ptr getFacedObject();
|
virtual MWWorld::Ptr getFacedObject();
|
||||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
///< 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 deleteObject (const Ptr& ptr);
|
||||||
|
|
||||||
virtual void moveObject (const Ptr& ptr, float x, float y, float z);
|
virtual void moveObject (const Ptr& ptr, float x, float y, float z);
|
||||||
|
|
Loading…
Reference in a new issue