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

pull/593/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 #4764: Data race in osg ParticleSystem
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 #5165: Active spells should use real time intead of timestamps
Bug #5358: ForceGreeting always resets the dialogue window completely

@ -74,7 +74,7 @@ namespace MWGui
// Add price for the travelling 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
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
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)
teleport(*it);
@ -47,7 +47,9 @@ namespace MWWorld
}
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 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;
MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor, followers);
@ -69,11 +71,17 @@ namespace MWWorld
MWWorld::Ptr follower = *it;
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)
continue;
if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2() <= 800*800)
out.insert(follower);
if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2() > 800 * 800)
continue;
out.emplace(follower);
}
}
}

@ -28,8 +28,9 @@ namespace MWWorld
/// @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);
/// Outputs every actor follower who is in teleport range and wasn't ordered to not enter interiors
static void getFollowersToTeleport(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out);
/// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the output,
/// 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