diff --git a/CHANGELOG.md b/CHANGELOG.md index ad6a78761..19337301b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -180,6 +180,7 @@ Bug #5209: Spellcasting ignores race height Bug #5210: AiActivate allows actors to open dialogue and inventory windows Bug #5211: Screen fades in if the first loaded save is in interior cell + Bug #5212: AiTravel does not work for actors outside of AI processing range Bug #5213: SameFaction script function is broken Bug #5218: Crash when disabling ToggleBorders Bug #5220: GetLOS crashes when actor isn't loaded diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 35a48710d..cbe058a00 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1695,6 +1695,11 @@ namespace MWMechanics } } } + else if (aiActive && iter->first != player && isConscious(iter->first)) + { + CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first); + stats.getAiSequence().execute(iter->first, *ctrl, duration, /*outOfRange*/true); + } if(iter->first.getClass().isNpc()) { @@ -1722,7 +1727,10 @@ namespace MWMechanics { const float dist = (playerPos - iter->first.getRefData().getPosition().asVec3()).length(); bool isPlayer = iter->first == player; - bool inRange = isPlayer || dist <= mActorsProcessingRange; + CreatureStats &stats = iter->first.getClass().getCreatureStats(iter->first); + int packageId = stats.getAiSequence().getTypeId(); + bool travelling = (packageId == AiPackage::TypeIdTravel) || (packageId == AiPackage::TypeIdInternalTravel); + bool inRange = isPlayer || dist <= mActorsProcessingRange || travelling; int activeFlag = 1; // Can be changed back to '2' to keep updating bounding boxes off screen (more accurate, but slower) if (isPlayer) activeFlag = 2; diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index e02240352..0c675bfc1 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -198,7 +198,7 @@ bool isActualAiPackage(int packageTypeId) packageTypeId <= AiPackage::TypeIdActivate); } -void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, float duration) +void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, float duration, bool outOfRange) { if(actor != getPlayer()) { @@ -214,7 +214,7 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac if (isActualAiPackage(packageTypeId)) mLastAiPackage = packageTypeId; // if active package is combat one, choose nearest target - if (packageTypeId == AiPackage::TypeIdCombat) + if (!outOfRange && packageTypeId == AiPackage::TypeIdCombat) { std::list::iterator itActualCombat; @@ -272,6 +272,10 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac try { + if (outOfRange && packageTypeId != AiPackage::TypeIdTravel + && packageTypeId != AiPackage::TypeIdInternalTravel) + return; + if (package->execute (actor, characterController, mAiState, duration)) { // Put repeating noncombat AI packages on the end of the stack so they can be used again diff --git a/apps/openmw/mwmechanics/aisequence.hpp b/apps/openmw/mwmechanics/aisequence.hpp index 5df440407..7f07d5aae 100644 --- a/apps/openmw/mwmechanics/aisequence.hpp +++ b/apps/openmw/mwmechanics/aisequence.hpp @@ -110,7 +110,7 @@ namespace MWMechanics void stopPursuit(); /// Execute current package, switching if needed. - void execute (const MWWorld::Ptr& actor, CharacterController& characterController, float duration); + void execute (const MWWorld::Ptr& actor, CharacterController& characterController, float duration, bool outOfRange=false); /// Simulate the passing of time using the currently active AI package void fastForward(const MWWorld::Ptr &actor);