Slaughter fish attacks when player only knee deep in water (Fixes #2076)

openmw-35
dteviot 10 years ago
parent 9d6efcecff
commit 7fe2f86d06

@ -392,6 +392,7 @@ namespace MWBase
virtual bool isFlying(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 isWading(const MWWorld::Ptr &object) const = 0;
///Is the head of the creature underwater?
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
virtual bool isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const = 0;

@ -348,9 +348,9 @@ namespace MWClass
// Self defense
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)
&& !attacker.isEmpty())
// No retaliation for totally static creatures (they have no movement or attacks anyway)
if (isMobile(ptr) && !attacker.isEmpty())
{
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
// except that creature is already hostile
if ((againstPlayer || !creatureStats.getAiSequence().isInCombat())
&& ((actor1.getClass().canSwim(actor1) && !actor1.getClass().canWalk(actor1) // pure water creature
&& !MWBase::Environment::get().getWorld()->isSwimming(actor2))
&& ((actor1.getClass().isPureWaterCreature(actor1)
&& !MWBase::Environment::get().getWorld()->isWading(actor2))
|| (!actor1.getClass().canSwim(actor1) && MWBase::Environment::get().getWorld()->isSwimming(actor2)))) // creature can't swim to target
return;

@ -209,7 +209,7 @@ namespace MWMechanics
if (!actorClass.isNpc() &&
// 1. pure water creature and Player moved out of water
((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
|| (!actorClass.canSwim(actor) && world->isSwimming(target))))
{

@ -383,6 +383,16 @@ namespace MWWorld
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
{
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 canSwim(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;

@ -281,7 +281,7 @@ namespace MWWorld
// Early-out for totally static creatures
// (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;
OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
@ -434,7 +434,7 @@ namespace MWWorld
if(result)
{
// 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 = oldPosition;
}

@ -1978,25 +1978,34 @@ namespace MWWorld
bool World::isSubmerged(const MWWorld::Ptr &object) const
{
const float *fpos = object.getRefData().getPosition().pos;
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);
return isUnderwater(object, 1.85f);
}
bool
World::isSwimming(const MWWorld::Ptr &object) const
{
/// \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;
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
/// \fixme 3/4ths submerged?
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);
}

@ -139,6 +139,9 @@ namespace MWWorld
void loadContentFiles(const Files::Collections& fileCollections,
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 mLevitationEnabled;
bool mGoToJail;
@ -454,6 +457,7 @@ namespace MWWorld
virtual bool isSubmerged(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 isWading(const MWWorld::Ptr &object) const;
virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
virtual void togglePOV() {

Loading…
Cancel
Save