mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Merge branch 'dont_hate_the_game_hate_the_player' into 'master'
Don't add additional targets to allies that are already in combat Closes #5318 and #3867 See merge request OpenMW/openmw!1434
This commit is contained in:
commit
053c2106c1
@ -11,6 +11,7 @@
|
||||
Bug #3792: 1 frame late magicka recalc breaks early scripted magicka reactions to Intelligence change
|
||||
Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes
|
||||
Bug #3855: AI sometimes spams defensive spells
|
||||
Bug #3867: All followers attack player when one follower enters combat with player
|
||||
Bug #3905: Great House Dagoth issues
|
||||
Bug #4203: Resurrecting an actor doesn't close the loot GUI
|
||||
Bug #4376: Moved actors don't respawn in their original cells
|
||||
@ -26,6 +27,7 @@
|
||||
Bug #5192: Actor turn rate is too slow
|
||||
Bug #5207: Loose summons can be present in scene
|
||||
Bug #5279: Ingame console stops auto-scrolling after clicking output
|
||||
Bug #5318: Aiescort behaves differently from vanilla
|
||||
Bug #5371: 'Dead' slaughterfish added by mod are animated/alive
|
||||
Bug #5377: Console does not appear after using menutest in inventory
|
||||
Bug #5379: Wandering NPCs falling through cantons
|
||||
|
@ -1980,7 +1980,7 @@ namespace MWMechanics
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<MWWorld::Ptr> Actors::getActorsSidingWith(const MWWorld::Ptr& actorPtr)
|
||||
std::vector<MWWorld::Ptr> Actors::getActorsSidingWith(const MWWorld::Ptr& actorPtr, bool excludeInfighting)
|
||||
{
|
||||
std::vector<MWWorld::Ptr> list;
|
||||
for (const Actor& actor : mActors)
|
||||
@ -1999,10 +1999,20 @@ namespace MWMechanics
|
||||
// Actors that are targeted by this actor's Follow or Escort packages also side with them
|
||||
for (const auto& package : stats.getAiSequence())
|
||||
{
|
||||
if (excludeInfighting && !sameActor && package->getTypeId() == AiPackageTypeId::Combat && package->getTarget() == actorPtr)
|
||||
break;
|
||||
if (package->sideWithTarget() && !package->getTarget().isEmpty())
|
||||
{
|
||||
if (sameActor)
|
||||
{
|
||||
if(excludeInfighting)
|
||||
{
|
||||
MWWorld::Ptr ally = package->getTarget();
|
||||
std::vector<MWWorld::Ptr> enemies;
|
||||
if(ally.getClass().getCreatureStats(ally).getAiSequence().getCombatTargets(enemies)
|
||||
&& std::find(enemies.begin(), enemies.end(), actorPtr) != enemies.end())
|
||||
break;
|
||||
}
|
||||
list.push_back(package->getTarget());
|
||||
}
|
||||
else if (package->getTarget() == actorPtr)
|
||||
@ -2039,11 +2049,11 @@ namespace MWMechanics
|
||||
getActorsFollowing(follower, out);
|
||||
}
|
||||
|
||||
void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out) {
|
||||
auto followers = getActorsSidingWith(actor);
|
||||
void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out, bool excludeInfighting) {
|
||||
auto followers = getActorsSidingWith(actor, excludeInfighting);
|
||||
for(const MWWorld::Ptr &follower : followers)
|
||||
if (out.insert(follower).second)
|
||||
getActorsSidingWith(follower, out);
|
||||
getActorsSidingWith(follower, out, excludeInfighting);
|
||||
}
|
||||
|
||||
void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies) {
|
||||
@ -2053,7 +2063,7 @@ namespace MWMechanics
|
||||
out.insert(search->second.begin(), search->second.end());
|
||||
else
|
||||
{
|
||||
auto followers = getActorsSidingWith(actor);
|
||||
auto followers = getActorsSidingWith(actor, true);
|
||||
for (const MWWorld::Ptr &follower : followers)
|
||||
if (out.insert(follower).second)
|
||||
getActorsSidingWith(follower, out, cachedAllies);
|
||||
|
@ -93,11 +93,6 @@ namespace MWMechanics
|
||||
|
||||
/// Removes an actor from combat and makes all of their allies stop fighting the actor's targets
|
||||
void stopCombat(const MWWorld::Ptr& ptr);
|
||||
/** Start combat between two actors
|
||||
@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, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies, bool againstPlayer);
|
||||
|
||||
void playIdleDialogue(const MWWorld::Ptr& actor);
|
||||
void updateMovementSpeed(const MWWorld::Ptr& actor);
|
||||
@ -144,15 +139,13 @@ namespace MWMechanics
|
||||
|
||||
///Returns the list of actors which are siding with the given actor in fights
|
||||
/**ie AiFollow or AiEscort is active and the target is the actor **/
|
||||
std::vector<MWWorld::Ptr> getActorsSidingWith(const MWWorld::Ptr& actor);
|
||||
std::vector<MWWorld::Ptr> getActorsSidingWith(const MWWorld::Ptr& actor, bool excludeInfighting = false);
|
||||
std::vector<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
|
||||
|
||||
/// Recursive version of getActorsFollowing
|
||||
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);
|
||||
void getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out, bool excludeInfighting = false);
|
||||
|
||||
/// Get the list of AiFollow::mFollowIndex for all actors following this target
|
||||
std::vector<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
||||
@ -218,6 +211,16 @@ namespace MWMechanics
|
||||
void purgeSpellEffects (int casterActorId);
|
||||
|
||||
void predictAndAvoidCollisions(float duration);
|
||||
|
||||
/** Start combat between two actors
|
||||
@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, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies, bool againstPlayer);
|
||||
|
||||
/// Recursive version of getActorsSidingWith that takes, adds to and returns a cache of actors mapped to their allies. Excludes infighting
|
||||
void getActorsSidingWith(const MWWorld::Ptr &actor, std::set<MWWorld::Ptr>& out, std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr> >& cachedAllies);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1457,7 +1457,14 @@ namespace MWMechanics
|
||||
}
|
||||
|
||||
if (!peaceful)
|
||||
{
|
||||
startCombat(target, attacker);
|
||||
// Force friendly actors into combat to prevent infighting between followers
|
||||
std::set<MWWorld::Ptr> followersTarget;
|
||||
getActorsSidingWith(target, followersTarget);
|
||||
for(const auto& follower : followersTarget)
|
||||
startCombat(follower, attacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user