mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 07:53:53 +00:00
Merge remote-tracking branch 'dteviot/Bug2076'
This commit is contained in:
commit
4e7f7baf8b
9 changed files with 45 additions and 17 deletions
|
@ -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,36 @@ 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);
|
||||
const float neckDeep = 1.85f;
|
||||
return isUnderwater(object, neckDeep);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
const float kneeDeep = 0.5f;
|
||||
return isUnderwater(object, kneeDeep);
|
||||
}
|
||||
|
||||
bool
|
||||
World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) 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 += heightRatio*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 heightRatio) 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…
Reference in a new issue