forked from mirror/openmw-tes3mp
parent
59a9a7aafb
commit
fe4fb82646
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);
|
CreatureStats& creatureStats1 = actor1.getClass().getCreatureStats(actor1);
|
||||||
if (creatureStats1.getAiSequence().isInCombat(actor2))
|
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)
|
// 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
|
// and any actor currently being followed or escorted by actor1
|
||||||
std::set<MWWorld::Ptr> allies1;
|
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
|
// 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)
|
for (std::set<MWWorld::Ptr>::const_iterator it = allies1.begin(); it != allies1.end(); ++it)
|
||||||
|
@ -328,10 +329,10 @@ namespace MWMechanics
|
||||||
aggressive = true;
|
aggressive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<MWWorld::Ptr> playerFollowersAndEscorters;
|
std::set<MWWorld::Ptr> playerAllies;
|
||||||
getActorsSidingWith(MWMechanics::getPlayer(), playerFollowersAndEscorters);
|
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
|
// 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
|
// Doesn't apply for player followers/escorters
|
||||||
|
@ -341,7 +342,9 @@ namespace MWMechanics
|
||||||
if (actor2.getClass().getCreatureStats(actor2).getAiSequence().isInCombat(actor1))
|
if (actor2.getClass().getCreatureStats(actor2).getAiSequence().isInCombat(actor1))
|
||||||
{
|
{
|
||||||
std::set<MWWorld::Ptr> allies2;
|
std::set<MWWorld::Ptr> allies2;
|
||||||
getActorsSidingWith(actor2, allies2);
|
|
||||||
|
getActorsSidingWith(actor2, allies2, cachedAllies);
|
||||||
|
|
||||||
// Check that an ally of actor2 is also in combat with actor1
|
// 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)
|
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
|
// Do aggression check if actor2 is the player or a player follower or escorter
|
||||||
if (!aggressive)
|
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
|
// Player followers and escorters with high fight should not initiate combat with the player or with
|
||||||
// other player followers or escorters
|
// 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);
|
aggressive = MWBase::Environment::get().getMechanicsManager()->isAggressive(actor1, actor2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1072,6 +1075,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
/// \todo move update logic to Actor class where appropriate
|
/// \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
|
// AI and magic effects update
|
||||||
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
|
||||||
{
|
{
|
||||||
|
@ -1123,7 +1128,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if (it->first == iter->first || iter->first == player) // player is not AI-controlled
|
if (it->first == iter->first || iter->first == player) // player is not AI-controlled
|
||||||
continue;
|
continue;
|
||||||
engageCombat(iter->first, it->first, it->first == player);
|
engageCombat(iter->first, it->first, cachedAllies, it->first == player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timerUpdateHeadTrack == 0)
|
if (timerUpdateHeadTrack == 0)
|
||||||
|
@ -1588,6 +1593,30 @@ namespace MWMechanics
|
||||||
getActorsSidingWith(*it, out);
|
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> Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor)
|
||||||
{
|
{
|
||||||
std::list<int> list;
|
std::list<int> list;
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace MWMechanics
|
||||||
@Notes: If againstPlayer = true then actor2 should be the Player.
|
@Notes: If againstPlayer = true then actor2 should be the Player.
|
||||||
If one of the combatants is creature it should be actor1.
|
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,
|
void updateHeadTracking(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor,
|
||||||
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance);
|
MWWorld::Ptr& headTrackTarget, float& sqrHeadTrackDistance);
|
||||||
|
@ -127,6 +127,8 @@ namespace MWMechanics
|
||||||
void getActorsFollowing(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out);
|
void getActorsFollowing(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out);
|
||||||
/// Recursive version of getActorsSidingWith
|
/// Recursive version of getActorsSidingWith
|
||||||
void getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out);
|
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
|
/// Get the list of AiFollow::mFollowIndex for all actors following this target
|
||||||
std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
||||||
|
|
Loading…
Reference in a new issue