Just wanted to share how I determine if I'm in combat w/any units: (summary of what is in this thread + tested) I think the only difference is I've added a "is fleeing" check, as a unit that is feared won't be targeting you anymore.
Code:
// find all units we are in combat with
- (void)doCombatSearch{
// add all mobs + players
NSArray *mobs = [mobController allMobs];
NSArray *players = [playersController allPlayers];
UInt64 playerGUID = [[playerData player] GUID];
UInt64 unitTarget = 0;
BOOL playerHasPet = [[playerData player] hasPet];
for ( Mob *mob in mobs ){
unitTarget = [mob targetID];
if (
![mob isDead] && // 1 - living units only
[mob isInCombat] && // 2 - in Combat
[mob isSelectable] && // 3 - can select this target
[mob isAttackable] && // 4 - attackable
//[mob isTapped] && // 5 - tapped - in theory someone could tap a target while you're casting, and you get agg - so still kill (removed as a unit @ 100% could attack us and not be tapped)
[mob isValid] && // 6 - valid mob
( (unitTarget == playerGUID || // 7 - targetting us
(playerHasPet && unitTarget == [[playerData player] petGUID]) ) || // or targetting our pet
[mob isFleeing]) // or fleeing
){
// add mob!
if ( ![_unitsAttackingMe containsObject: (Unit*)mob] ){
[_unitsAttackingMe addObject: (Unit*)mob];
}
}
// remove unit
else if ([_unitsAttackingMe containsObject: (Unit*)mob]){
[_unitsAttackingMe removeObject:(Unit*)mob];
}
}
for ( Player *player in players ){
unitTarget = [player targetID];
if (
![player isDead] && // 1 - living units only
[player currentHealth] != 1 && // 2 - this should be a ghost check, being lazy for now
[player isInCombat] && // 3 - in Combat
[player isSelectable] && // 4 - can select this target
([player isAttackable] || [player isFeignDeath] ) && // 5 - attackable or feigned
[player isValid] && // 6 - valid
( (unitTarget == playerGUID || // 7 - targetting us
(playerHasPet && unitTarget == [[playerData player] petGUID]) ) || // or targetting our pet
[player isFleeing]) // or fleeing
){
// add player
if ( ![_unitsAttackingMe containsObject: (Unit*)player] ){
[_unitsAttackingMe addObject: (Unit*)player];
}
}
// remove unit
else if ([_unitsAttackingMe containsObject: (Unit*)player]){
[_unitsAttackingMe removeObject:(Unit*)player];
}
}
}