@ -1169,9 +1169,9 @@ namespace MWMechanics
& & ! victim . getClass ( ) . getCreatureStats ( victim ) . getAiSequence ( ) . hasPackage ( AiPackageTypeId : : Pursue ) )
reported = reportCrime ( player , victim , type , ESM : : RefId ( ) , arg ) ;
// TODO: combat should be started with an "unaware" flag, which makes the victim flee?
if ( ! reported )
startCombat ( victim ,
player ) ; // TODO: combat should be started with an "unaware" flag, which makes the victim flee?
startCombat ( victim , player , & playerFollowers ) ;
}
return crimeSeen ;
}
@ -1412,7 +1412,7 @@ namespace MWMechanics
observerStats . modCrimeDispositionModifier ( dispositionModifier ) ;
}
startCombat ( actor , player );
startCombat ( actor , player , & playerFollowers );
// Apply aggression value to the base Fight rating, so that the actor can continue fighting
// after a Calm spell wears off
@ -1463,7 +1463,7 @@ namespace MWMechanics
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
// Note: accidental or collateral damage attacks are ignored.
if ( ! victim . getClass ( ) . getCreatureStats ( victim ) . getAiSequence ( ) . isInPursuit ( ) )
startCombat ( victim , player );
startCombat ( victim , player , & playerFollowers );
// Set the crime ID, which we will use to calm down participants
// once the bounty has been paid.
@ -1508,14 +1508,14 @@ namespace MWMechanics
if ( ! peaceful )
{
startCombat ( target , attacker );
startCombat ( target , attacker , nullptr );
// Force friendly actors into combat to prevent infighting between followers
std : : set < MWWorld : : Ptr > followersTarget ;
getActorsSidingWith ( target , followersTarget ) ;
for ( const auto & follower : followersTarget )
{
if ( follower ! = attacker & & follower ! = player )
startCombat ( follower , attacker );
startCombat ( follower , attacker , nullptr );
}
}
}
@ -1664,7 +1664,8 @@ namespace MWMechanics
}
}
void MechanicsManager : : startCombat ( const MWWorld : : Ptr & ptr , const MWWorld : : Ptr & target )
void MechanicsManager : : startCombat (
const MWWorld : : Ptr & ptr , const MWWorld : : Ptr & target , const std : : set < MWWorld : : Ptr > * targetAllies )
{
CreatureStats & stats = ptr . getClass ( ) . getCreatureStats ( ptr ) ;
@ -1682,6 +1683,30 @@ namespace MWMechanics
}
const bool inCombat = stats . getAiSequence ( ) . isInCombat ( ) ;
bool shout = ! inCombat ;
if ( inCombat )
{
const auto isInCombatWithOneOf = [ & ] ( const auto & allies ) {
for ( const MWWorld : : Ptr & ally : allies )
{
if ( stats . getAiSequence ( ) . isInCombat ( ally ) )
return true ;
}
return false ;
} ;
if ( targetAllies )
shout = ! isInCombatWithOneOf ( * targetAllies ) ;
else
{
shout = stats . getAiSequence ( ) . isInCombat ( target ) ;
if ( ! shout )
{
std : : set < MWWorld : : Ptr > sidingActors ;
getActorsSidingWith ( target , sidingActors ) ;
shout = ! isInCombatWithOneOf ( sidingActors ) ;
}
}
}
stats . getAiSequence ( ) . stack ( MWMechanics : : AiCombat ( target ) , ptr ) ;
if ( target = = getPlayer ( ) )
{
@ -1716,7 +1741,7 @@ namespace MWMechanics
}
// Must be done after the target is set up, so that CreatureTargetted dialogue filter works properly
if ( ! inComba t)
if ( shou t)
MWBase : : Environment : : get ( ) . getDialogueManager ( ) - > say ( ptr , ESM : : RefId : : stringRefId ( " attack " ) ) ;
}