Fix follower aggression when traveling. Summoning still has problems but less intrusive than current implementation.

pull/3011/head
Charles Calhoun 4 years ago committed by Alexei Dobrohotov
parent 3040b3b2b6
commit 14aacb81c5

@ -13,6 +13,7 @@
Bug #4631: Setting MSAA level too high doesn't fall back to highest supported level Bug #4631: Setting MSAA level too high doesn't fall back to highest supported level
Bug #4764: Data race in osg ParticleSystem Bug #4764: Data race in osg ParticleSystem
Bug #4774: Guards are ignorant of an invisible player that tries to attack them Bug #4774: Guards are ignorant of an invisible player that tries to attack them
Bug #5101: Hostile followers travel with the player
Bug #5108: Savegame bloating due to inefficient fog textures format Bug #5108: Savegame bloating due to inefficient fog textures format
Bug #5165: Active spells should use real time intead of timestamps Bug #5165: Active spells should use real time intead of timestamps
Bug #5358: ForceGreeting always resets the dialogue window completely Bug #5358: ForceGreeting always resets the dialogue window completely

@ -74,7 +74,7 @@ namespace MWGui
// Add price for the travelling followers // Add price for the travelling followers
std::set<MWWorld::Ptr> followers; std::set<MWWorld::Ptr> followers;
MWWorld::ActionTeleport::getFollowersToTeleport(player, followers); MWWorld::ActionTeleport::getFollowers(player, followers);
// Apply followers cost, unlike vanilla the first follower doesn't travel for free // Apply followers cost, unlike vanilla the first follower doesn't travel for free
price *= 1 + static_cast<int>(followers.size()); price *= 1 + static_cast<int>(followers.size());

@ -24,7 +24,7 @@ namespace MWWorld
{ {
// Find any NPCs that are following the actor and teleport them with him // Find any NPCs that are following the actor and teleport them with him
std::set<MWWorld::Ptr> followers; std::set<MWWorld::Ptr> followers;
getFollowersToTeleport(actor, followers); getFollowers(actor, followers, true);
for (std::set<MWWorld::Ptr>::iterator it = followers.begin(); it != followers.end(); ++it) for (std::set<MWWorld::Ptr>::iterator it = followers.begin(); it != followers.end(); ++it)
teleport(*it); teleport(*it);
@ -47,7 +47,9 @@ namespace MWWorld
} }
else else
{ {
if (mCellName.empty()) if (actor.getClass().getCreatureStats(actor).getAiSequence().isInCombat(world->getPlayerPtr()))
actor.getClass().getCreatureStats(actor).getAiSequence().stopCombat();
else if (mCellName.empty())
{ {
int cellX; int cellX;
int cellY; int cellY;
@ -60,7 +62,7 @@ namespace MWWorld
} }
} }
void ActionTeleport::getFollowersToTeleport(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out) { void ActionTeleport::getFollowers(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out, bool includeHostiles) {
std::set<MWWorld::Ptr> followers; std::set<MWWorld::Ptr> followers;
MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor, followers); MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor, followers);
@ -69,11 +71,17 @@ namespace MWWorld
MWWorld::Ptr follower = *it; MWWorld::Ptr follower = *it;
std::string script = follower.getClass().getScript(follower); std::string script = follower.getClass().getScript(follower);
if (!includeHostiles && follower.getClass().getCreatureStats(follower).getAiSequence().isInCombat(actor))
continue;
if (!script.empty() && follower.getRefData().getLocals().getIntVar(script, "stayoutside") == 1) if (!script.empty() && follower.getRefData().getLocals().getIntVar(script, "stayoutside") == 1)
continue; continue;
if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2() <= 800*800) if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2() > 800 * 800)
out.insert(follower); continue;
out.emplace(follower);
} }
} }
} }

@ -28,8 +28,9 @@ namespace MWWorld
/// @param teleportFollowers Whether to teleport any following actors of the target actor as well. /// @param teleportFollowers Whether to teleport any following actors of the target actor as well.
ActionTeleport (const std::string& cellName, const ESM::Position& position, bool teleportFollowers); ActionTeleport (const std::string& cellName, const ESM::Position& position, bool teleportFollowers);
/// Outputs every actor follower who is in teleport range and wasn't ordered to not enter interiors /// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the output,
static void getFollowersToTeleport(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out); /// e.g. so that the teleport action can calm them.
static void getFollowers(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out, bool includeHostiles = false);
}; };
} }

Loading…
Cancel
Save