forked from mirror/openmw-tes3mp
parent
993860a4b1
commit
6272e1c674
2 changed files with 41 additions and 10 deletions
|
@ -280,7 +280,7 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void Actors::engageCombat (const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, bool againstPlayer)
|
||||
void Actors::engageCombat (const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies, bool againstPlayer)
|
||||
{
|
||||
CreatureStats& creatureStats1 = actor1.getClass().getCreatureStats(actor1);
|
||||
if (creatureStats1.getAiSequence().isInCombat(actor2))
|
||||
|
@ -306,7 +306,8 @@ namespace MWMechanics
|
|||
// Get actors allied with actor1. Includes those following or escorting actor1, actors following or escorting those actors, (recursive)
|
||||
// and any actor currently being followed or escorted by actor1
|
||||
std::set<MWWorld::Ptr> allies1;
|
||||
getActorsSidingWith(actor1, allies1);
|
||||
|
||||
getActorsSidingWith(actor1, allies1, cachedAllies);
|
||||
|
||||
// If an ally of actor1 has been attacked by actor2 or has attacked actor2, start combat between actor1 and actor2
|
||||
for (std::set<MWWorld::Ptr>::const_iterator it = allies1.begin(); it != allies1.end(); ++it)
|
||||
|
@ -328,10 +329,10 @@ namespace MWMechanics
|
|||
aggressive = true;
|
||||
}
|
||||
|
||||
std::set<MWWorld::Ptr> playerFollowersAndEscorters;
|
||||
getActorsSidingWith(MWMechanics::getPlayer(), playerFollowersAndEscorters);
|
||||
std::set<MWWorld::Ptr> playerAllies;
|
||||
getActorsSidingWith(MWMechanics::getPlayer(), playerAllies, cachedAllies);
|
||||
|
||||
bool isPlayerFollowerOrEscorter = std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), actor1) != playerFollowersAndEscorters.end();
|
||||
bool isPlayerFollowerOrEscorter = std::find(playerAllies.begin(), playerAllies.end(), actor1) != playerAllies.end();
|
||||
|
||||
// If actor2 and at least one actor2 are in combat with actor1, actor1 and its allies start combat with them
|
||||
// Doesn't apply for player followers/escorters
|
||||
|
@ -341,7 +342,9 @@ namespace MWMechanics
|
|||
if (actor2.getClass().getCreatureStats(actor2).getAiSequence().isInCombat(actor1))
|
||||
{
|
||||
std::set<MWWorld::Ptr> allies2;
|
||||
getActorsSidingWith(actor2, allies2);
|
||||
|
||||
getActorsSidingWith(actor2, allies2, cachedAllies);
|
||||
|
||||
// Check that an ally of actor2 is also in combat with actor1
|
||||
for (std::set<MWWorld::Ptr>::const_iterator it = allies2.begin(); it != allies2.end(); ++it)
|
||||
{
|
||||
|
@ -383,11 +386,11 @@ namespace MWMechanics
|
|||
// Do aggression check if actor2 is the player or a player follower or escorter
|
||||
if (!aggressive)
|
||||
{
|
||||
if (againstPlayer || std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), actor2) != playerFollowersAndEscorters.end())
|
||||
if (againstPlayer || std::find(playerAllies.begin(), playerAllies.end(), actor2) != playerAllies.end())
|
||||
{
|
||||
// Player followers and escorters with high fight should not initiate combat with the player or with
|
||||
// other player followers or escorters
|
||||
if (std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), actor1) == playerFollowersAndEscorters.end())
|
||||
if (std::find(playerAllies.begin(), playerAllies.end(), actor1) == playerAllies.end())
|
||||
aggressive = MWBase::Environment::get().getMechanicsManager()->isAggressive(actor1, actor2);
|
||||
}
|
||||
}
|
||||
|
@ -1075,6 +1078,8 @@ namespace MWMechanics
|
|||
|
||||
/// \todo move update logic to Actor class where appropriate
|
||||
|
||||
std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> > cachedAllies; // will be filled as engageCombat iterates
|
||||
|
||||
// AI and magic effects update
|
||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
||||
{
|
||||
|
@ -1126,7 +1131,7 @@ namespace MWMechanics
|
|||
{
|
||||
if (it->first == iter->first || iter->first == player) // player is not AI-controlled
|
||||
continue;
|
||||
engageCombat(iter->first, it->first, it->first == player);
|
||||
engageCombat(iter->first, it->first, cachedAllies, it->first == player);
|
||||
}
|
||||
}
|
||||
if (timerUpdateHeadTrack == 0)
|
||||
|
@ -1591,6 +1596,30 @@ namespace MWMechanics
|
|||
getActorsSidingWith(*it, out);
|
||||
}
|
||||
|
||||
void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies) {
|
||||
std::list<MWWorld::Ptr> followers = getActorsSidingWith(actor);
|
||||
|
||||
// If we have already found actor's allies, use the cache
|
||||
std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >::const_iterator search = cachedAllies.find(actor);
|
||||
if (search != cachedAllies.end())
|
||||
out = search->second;
|
||||
else
|
||||
{
|
||||
for (std::list<MWWorld::Ptr>::iterator it = followers.begin(); it != followers.end(); ++it)
|
||||
if (out.insert(*it).second)
|
||||
getActorsSidingWith(*it, out);
|
||||
|
||||
// Cache ptrs and their sets of allies
|
||||
cachedAllies.insert(std::make_pair(actor, out));
|
||||
for (std::set<MWWorld::Ptr>::const_iterator it = out.begin(); it != out.end(); ++it)
|
||||
{
|
||||
search = cachedAllies.find(*it);
|
||||
if (search == cachedAllies.end())
|
||||
cachedAllies.insert(std::make_pair(*it, out));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<int> Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor)
|
||||
{
|
||||
std::list<int> list;
|
||||
|
|
|
@ -88,7 +88,7 @@ namespace MWMechanics
|
|||
@Notes: If againstPlayer = true then actor2 should be the Player.
|
||||
If one of the combatants is creature it should be actor1.
|
||||
*/
|
||||
void engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, bool againstPlayer);
|
||||
void engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies, bool againstPlayer);
|
||||
|
||||
void updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor,
|
||||
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance);
|
||||
|
@ -127,6 +127,8 @@ namespace MWMechanics
|
|||
void getActorsFollowing(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out);
|
||||
/// Recursive version of getActorsSidingWith
|
||||
void getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out);
|
||||
/// Recursive version of getActorsSidingWith that takes, adds to and returns a cache of actors mapped to their allies
|
||||
void getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies);
|
||||
|
||||
/// Get the list of AiFollow::mFollowIndex for all actors following this target
|
||||
std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
||||
|
|
Loading…
Reference in a new issue