1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-30 20:45:35 +00:00

Fix headtracking while invisible

This commit is contained in:
Jacob Turnbull 2021-04-18 10:54:56 +00:00 committed by Petr Mikheev
parent c83b6ff445
commit f49b9e3806
3 changed files with 18 additions and 18 deletions

View file

@ -90,6 +90,7 @@ Programmers
Internecine Internecine
Jackerty Jackerty
Jacob Essex (Yacoby) Jacob Essex (Yacoby)
Jacob Turnbull (Tankinfrank)
Jake Westrip (16bitint) Jake Westrip (16bitint)
James Carty (MrTopCat) James Carty (MrTopCat)
James Moore (moore.work) James Moore (moore.work)

View file

@ -432,7 +432,8 @@ namespace MWMechanics
} }
void Actors::updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor, void Actors::updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor,
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance) MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance,
bool inCombatOrPursue)
{ {
if (!actor.getRefData().getBaseNode()) if (!actor.getRefData().getBaseNode())
return; return;
@ -453,7 +454,7 @@ namespace MWMechanics
const osg::Vec3f actor2Pos(targetActor.getRefData().getPosition().asVec3()); const osg::Vec3f actor2Pos(targetActor.getRefData().getPosition().asVec3());
float sqrDist = (actor1Pos - actor2Pos).length2(); float sqrDist = (actor1Pos - actor2Pos).length2();
if (sqrDist > std::min(maxDistance * maxDistance, sqrHeadTrackDistance)) if (sqrDist > std::min(maxDistance * maxDistance, sqrHeadTrackDistance) && !inCombatOrPursue)
return; return;
// stop tracking when target is behind the actor // stop tracking when target is behind the actor
@ -461,7 +462,7 @@ namespace MWMechanics
osg::Vec3f targetDirection(actor2Pos - actor1Pos); osg::Vec3f targetDirection(actor2Pos - actor1Pos);
actorDirection.z() = 0; actorDirection.z() = 0;
targetDirection.z() = 0; targetDirection.z() = 0;
if (actorDirection * targetDirection > 0 if ((actorDirection * targetDirection > 0 || inCombatOrPursue)
&& MWBase::Environment::get().getWorld()->getLOS(actor, targetActor) // check LOS and awareness last as it's the most expensive function && MWBase::Environment::get().getWorld()->getLOS(actor, targetActor) // check LOS and awareness last as it's the most expensive function
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(targetActor, actor)) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(targetActor, actor))
{ {
@ -2012,28 +2013,25 @@ namespace MWMechanics
MWMechanics::CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first); MWMechanics::CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first);
bool firstPersonPlayer = isPlayer && world->isFirstPerson(); bool firstPersonPlayer = isPlayer && world->isFirstPerson();
bool inCombatOrPursue = stats.getAiSequence().isInCombat() || stats.getAiSequence().hasPackage(AiPackageTypeId::Pursue); bool inCombatOrPursue = stats.getAiSequence().isInCombat() || stats.getAiSequence().hasPackage(AiPackageTypeId::Pursue);
MWWorld::Ptr activePackageTarget;
// 1. Unconsious actor can not track target // 1. Unconsious actor can not track target
// 2. Actors in combat and pursue mode do not bother to headtrack // 2. Actors in combat and pursue mode do not bother to headtrack anyone except their target
// 3. Player character does not use headtracking in the 1st-person view // 3. Player character does not use headtracking in the 1st-person view
if (!stats.getKnockedDown() && !firstPersonPlayer && !inCombatOrPursue) if (!stats.getKnockedDown() && !firstPersonPlayer)
{ {
if (inCombatOrPursue)
activePackageTarget = stats.getAiSequence().getActivePackage().getTarget();
for (PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it) for (PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it)
{ {
if (it->first == iter->first) if (it->first == iter->first)
continue; continue;
updateHeadTracking(iter->first, it->first, headTrackTarget, sqrHeadTrackDistance);
}
}
if (!stats.getKnockedDown() && !isPlayer && inCombatOrPursue) if (inCombatOrPursue && it->first != activePackageTarget)
{ continue;
// Actors in combat and pursue mode always look at their target.
for (const auto& package : stats.getAiSequence()) updateHeadTracking(iter->first, it->first, headTrackTarget, sqrHeadTrackDistance, inCombatOrPursue);
{
headTrackTarget = package->getTarget();
if (!headTrackTarget.isEmpty())
break;
} }
} }

View file

@ -131,7 +131,8 @@ namespace MWMechanics
void turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir); void turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir);
void updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor, void updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor,
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance); MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance,
bool inCombatOrPursue);
void rest(double hours, bool sleep); void rest(double hours, bool sleep);
///< Update actors while the player is waiting or sleeping. ///< Update actors while the player is waiting or sleeping.