forked from teamnwah/openmw-tes3coop
Slaughter fish attacks when player only knee deep in water (Fixes #2076)
This commit is contained in:
parent
9d6efcecff
commit
7fe2f86d06
9 changed files with 43 additions and 17 deletions
|
@ -392,6 +392,7 @@ namespace MWBase
|
||||||
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
|
virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0;
|
||||||
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
|
virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0;
|
||||||
virtual bool isSwimming(const MWWorld::Ptr &object) const = 0;
|
virtual bool isSwimming(const MWWorld::Ptr &object) const = 0;
|
||||||
|
virtual bool isWading(const MWWorld::Ptr &object) const = 0;
|
||||||
///Is the head of the creature underwater?
|
///Is the head of the creature underwater?
|
||||||
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
|
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
|
||||||
virtual bool isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const = 0;
|
virtual bool isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const = 0;
|
||||||
|
|
|
@ -348,9 +348,9 @@ namespace MWClass
|
||||||
|
|
||||||
// Self defense
|
// Self defense
|
||||||
bool setOnPcHitMe = true; // Note OnPcHitMe is not set for friendly hits.
|
bool setOnPcHitMe = true; // Note OnPcHitMe is not set for friendly hits.
|
||||||
if ((canWalk(ptr) || canFly(ptr) || canSwim(ptr)) // No retaliation for totally static creatures
|
|
||||||
// (they have no movement or attacks anyway)
|
// No retaliation for totally static creatures (they have no movement or attacks anyway)
|
||||||
&& !attacker.isEmpty())
|
if (isMobile(ptr) && !attacker.isEmpty())
|
||||||
{
|
{
|
||||||
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,8 +309,8 @@ namespace MWMechanics
|
||||||
// pure water creatures won't try to fight with the target on the ground
|
// pure water creatures won't try to fight with the target on the ground
|
||||||
// except that creature is already hostile
|
// except that creature is already hostile
|
||||||
if ((againstPlayer || !creatureStats.getAiSequence().isInCombat())
|
if ((againstPlayer || !creatureStats.getAiSequence().isInCombat())
|
||||||
&& ((actor1.getClass().canSwim(actor1) && !actor1.getClass().canWalk(actor1) // pure water creature
|
&& ((actor1.getClass().isPureWaterCreature(actor1)
|
||||||
&& !MWBase::Environment::get().getWorld()->isSwimming(actor2))
|
&& !MWBase::Environment::get().getWorld()->isWading(actor2))
|
||||||
|| (!actor1.getClass().canSwim(actor1) && MWBase::Environment::get().getWorld()->isSwimming(actor2)))) // creature can't swim to target
|
|| (!actor1.getClass().canSwim(actor1) && MWBase::Environment::get().getWorld()->isSwimming(actor2)))) // creature can't swim to target
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ namespace MWMechanics
|
||||||
if (!actorClass.isNpc() &&
|
if (!actorClass.isNpc() &&
|
||||||
// 1. pure water creature and Player moved out of water
|
// 1. pure water creature and Player moved out of water
|
||||||
((target == world->getPlayerPtr() &&
|
((target == world->getPlayerPtr() &&
|
||||||
actorClass.canSwim(actor) && !actor.getClass().canWalk(actor) && !world->isSwimming(target))
|
actorClass.isPureWaterCreature(actor) && !world->isWading(target))
|
||||||
// 2. creature can't swim to target
|
// 2. creature can't swim to target
|
||||||
|| (!actorClass.canSwim(actor) && world->isSwimming(target))))
|
|| (!actorClass.canSwim(actor) && world->isSwimming(target))))
|
||||||
{
|
{
|
||||||
|
|
|
@ -383,6 +383,16 @@ namespace MWWorld
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Class::isPureWaterCreature(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return canSwim(ptr) && !canWalk(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Class::isMobile(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
return canSwim(ptr) || canWalk(ptr) || canFly(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
int Class::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
int Class::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
||||||
{
|
{
|
||||||
throw std::runtime_error("class does not support skills");
|
throw std::runtime_error("class does not support skills");
|
||||||
|
|
|
@ -308,6 +308,8 @@ namespace MWWorld
|
||||||
virtual bool canFly(const MWWorld::Ptr& ptr) const;
|
virtual bool canFly(const MWWorld::Ptr& ptr) const;
|
||||||
virtual bool canSwim(const MWWorld::Ptr& ptr) const;
|
virtual bool canSwim(const MWWorld::Ptr& ptr) const;
|
||||||
virtual bool canWalk(const MWWorld::Ptr& ptr) const;
|
virtual bool canWalk(const MWWorld::Ptr& ptr) const;
|
||||||
|
bool isPureWaterCreature(const MWWorld::Ptr& ptr) const;
|
||||||
|
bool isMobile(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
|
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ namespace MWWorld
|
||||||
|
|
||||||
// Early-out for totally static creatures
|
// Early-out for totally static creatures
|
||||||
// (Not sure if gravity should still apply?)
|
// (Not sure if gravity should still apply?)
|
||||||
if (!ptr.getClass().canWalk(ptr) && !ptr.getClass().canFly(ptr) && !ptr.getClass().canSwim(ptr))
|
if (!ptr.getClass().isMobile(ptr))
|
||||||
return position;
|
return position;
|
||||||
|
|
||||||
OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
|
OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
|
||||||
|
@ -434,7 +434,7 @@ namespace MWWorld
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
// don't let pure water creatures move out of water after stepMove
|
// don't let pure water creatures move out of water after stepMove
|
||||||
if((ptr.getClass().canSwim(ptr) && !ptr.getClass().canWalk(ptr))
|
if (ptr.getClass().isPureWaterCreature(ptr)
|
||||||
&& newPosition.z > (waterlevel - halfExtents.z * 0.5))
|
&& newPosition.z > (waterlevel - halfExtents.z * 0.5))
|
||||||
newPosition = oldPosition;
|
newPosition = oldPosition;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1978,25 +1978,34 @@ namespace MWWorld
|
||||||
|
|
||||||
bool World::isSubmerged(const MWWorld::Ptr &object) const
|
bool World::isSubmerged(const MWWorld::Ptr &object) const
|
||||||
{
|
{
|
||||||
const float *fpos = object.getRefData().getPosition().pos;
|
return isUnderwater(object, 1.85f);
|
||||||
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
|
|
||||||
|
|
||||||
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(object.getRefData().getHandle());
|
|
||||||
if(actor) pos.z += 1.85*actor->getHalfExtents().z;
|
|
||||||
|
|
||||||
return isUnderwater(object.getCell(), pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
World::isSwimming(const MWWorld::Ptr &object) const
|
World::isSwimming(const MWWorld::Ptr &object) const
|
||||||
{
|
{
|
||||||
/// \todo add check ifActor() - only actors can swim
|
/// \todo add check ifActor() - only actors can swim
|
||||||
|
/// \fixme 3/4ths submerged?
|
||||||
|
return isUnderwater(object, 1.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
World::isWading(const MWWorld::Ptr &object) const
|
||||||
|
{
|
||||||
|
return isUnderwater(object, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
World::isUnderwater(const MWWorld::Ptr &object, const float hightRatio) const
|
||||||
|
{
|
||||||
const float *fpos = object.getRefData().getPosition().pos;
|
const float *fpos = object.getRefData().getPosition().pos;
|
||||||
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
|
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
|
||||||
|
|
||||||
/// \fixme 3/4ths submerged?
|
|
||||||
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(object.getRefData().getHandle());
|
const OEngine::Physic::PhysicActor *actor = mPhysEngine->getCharacter(object.getRefData().getHandle());
|
||||||
if(actor) pos.z += actor->getHalfExtents().z * 1.5;
|
if (actor)
|
||||||
|
{
|
||||||
|
pos.z += hightRatio*actor->getHalfExtents().z;
|
||||||
|
}
|
||||||
|
|
||||||
return isUnderwater(object.getCell(), pos);
|
return isUnderwater(object.getCell(), pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,9 @@ namespace MWWorld
|
||||||
void loadContentFiles(const Files::Collections& fileCollections,
|
void loadContentFiles(const Files::Collections& fileCollections,
|
||||||
const std::vector<std::string>& content, ContentLoader& contentLoader);
|
const std::vector<std::string>& content, ContentLoader& contentLoader);
|
||||||
|
|
||||||
|
bool isUnderwater(const MWWorld::Ptr &object, const float hightRatio) const;
|
||||||
|
///< helper function for implementing isSwimming(), isSubmerged(), isWading()
|
||||||
|
|
||||||
bool mTeleportEnabled;
|
bool mTeleportEnabled;
|
||||||
bool mLevitationEnabled;
|
bool mLevitationEnabled;
|
||||||
bool mGoToJail;
|
bool mGoToJail;
|
||||||
|
@ -454,6 +457,7 @@ namespace MWWorld
|
||||||
virtual bool isSubmerged(const MWWorld::Ptr &object) const;
|
virtual bool isSubmerged(const MWWorld::Ptr &object) const;
|
||||||
virtual bool isSwimming(const MWWorld::Ptr &object) const;
|
virtual bool isSwimming(const MWWorld::Ptr &object) const;
|
||||||
virtual bool isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const;
|
virtual bool isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const;
|
||||||
|
virtual bool isWading(const MWWorld::Ptr &object) const;
|
||||||
virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
|
virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
virtual void togglePOV() {
|
virtual void togglePOV() {
|
||||||
|
|
Loading…
Reference in a new issue