diff --git a/AUTHORS.md b/AUTHORS.md index cfe88ca6b..5591489b7 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -90,6 +90,7 @@ Programmers Internecine Jackerty Jacob Essex (Yacoby) + Jacob Turnbull (Tankinfrank) Jake Westrip (16bitint) James Carty (MrTopCat) James Moore (moore.work) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 72d5d96a2..e9467a679 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -432,7 +432,8 @@ namespace MWMechanics } 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()) return; @@ -453,7 +454,7 @@ namespace MWMechanics const osg::Vec3f actor2Pos(targetActor.getRefData().getPosition().asVec3()); float sqrDist = (actor1Pos - actor2Pos).length2(); - if (sqrDist > std::min(maxDistance * maxDistance, sqrHeadTrackDistance)) + if (sqrDist > std::min(maxDistance * maxDistance, sqrHeadTrackDistance) && !inCombatOrPursue) return; // stop tracking when target is behind the actor @@ -461,7 +462,7 @@ namespace MWMechanics osg::Vec3f targetDirection(actor2Pos - actor1Pos); actorDirection.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().getMechanicsManager()->awarenessCheck(targetActor, actor)) { @@ -2012,28 +2013,25 @@ namespace MWMechanics MWMechanics::CreatureStats& stats = iter->first.getClass().getCreatureStats(iter->first); bool firstPersonPlayer = isPlayer && world->isFirstPerson(); bool inCombatOrPursue = stats.getAiSequence().isInCombat() || stats.getAiSequence().hasPackage(AiPackageTypeId::Pursue); + MWWorld::Ptr activePackageTarget; // 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 - if (!stats.getKnockedDown() && !firstPersonPlayer && !inCombatOrPursue) + if (!stats.getKnockedDown() && !firstPersonPlayer) { - for(PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it) + if (inCombatOrPursue) + activePackageTarget = stats.getAiSequence().getActivePackage().getTarget(); + + for (PtrActorMap::iterator it(mActors.begin()); it != mActors.end(); ++it) { if (it->first == iter->first) continue; - updateHeadTracking(iter->first, it->first, headTrackTarget, sqrHeadTrackDistance); - } - } - if (!stats.getKnockedDown() && !isPlayer && inCombatOrPursue) - { - // Actors in combat and pursue mode always look at their target. - for (const auto& package : stats.getAiSequence()) - { - headTrackTarget = package->getTarget(); - if (!headTrackTarget.isEmpty()) - break; + if (inCombatOrPursue && it->first != activePackageTarget) + continue; + + updateHeadTracking(iter->first, it->first, headTrackTarget, sqrHeadTrackDistance, inCombatOrPursue); } } diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 59814bcc2..2de0728d5 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -131,7 +131,8 @@ namespace MWMechanics void turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir); 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); ///< Update actors while the player is waiting or sleeping.