Core/Units: Fix more issues in Unit::_IsValidAttackTarget. (Documentation on changes compared to the client function included)
This commit is contained in:
@@ -12166,13 +12166,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co
|
|||||||
&& target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
|
&& target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//! since 'this' in the client's context of this function *always* resembles the _player_ (feel free to correct me),
|
|
||||||
//! in the server context we will ignore the this->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) (possibly misnamed) check for non-players.
|
|
||||||
//! Feel free to change this if a more proper solution is found.
|
|
||||||
bool ignoreOwnOOCFlag = true;
|
|
||||||
if (Player const* playerAttacker = ToPlayer())
|
if (Player const* playerAttacker = ToPlayer())
|
||||||
{
|
{
|
||||||
ignoreOwnOOCFlag = false;
|
|
||||||
if (playerAttacker->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_UNK19))
|
if (playerAttacker->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_UNK19))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -12184,11 +12179,12 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co
|
|||||||
|| (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE))
|
|| (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE))
|
||||||
//! Also notable: in CGUnit_C__CanAttack the third parameter is a boolean that determines if the following flag check is exempted or not
|
//! Also notable: in CGUnit_C__CanAttack the third parameter is a boolean that determines if the following flag check is exempted or not
|
||||||
|| (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
|
|| (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
|
||||||
|| (!ignoreOwnOOCFlag && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)))
|
|| (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// CvC case - can attack each other only when one of them is hostile
|
// CvC case - can attack each other only when one of them is hostile
|
||||||
if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
|
if (GetTypeId() == TYPEID_UNIT && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)
|
||||||
|
&& target->GetTypeId() == TYPEID_UNIT && !target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
|
||||||
return GetReactionTo(target) <= REP_HOSTILE || target->GetReactionTo(this) <= REP_HOSTILE;
|
return GetReactionTo(target) <= REP_HOSTILE || target->GetReactionTo(this) <= REP_HOSTILE;
|
||||||
|
|
||||||
// PvP, PvC, CvP case
|
// PvP, PvC, CvP case
|
||||||
@@ -12201,8 +12197,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co
|
|||||||
if (creatureAttacker && creatureAttacker->GetCreatureInfo()->type_flags & CREATURE_TYPEFLAGS_UNK26)
|
if (creatureAttacker && creatureAttacker->GetCreatureInfo()->type_flags & CREATURE_TYPEFLAGS_UNK26)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Player const* playerAffectingAttacker = HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) ? GetAffectingPlayer() : NULL;
|
Player const* playerAffectingAttacker = GetAffectingPlayer();
|
||||||
Player const* playerAffectingTarget = target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) ? target->GetAffectingPlayer() : NULL;
|
Player const* playerAffectingTarget = target->GetAffectingPlayer();
|
||||||
|
|
||||||
// check duel - before sanctuary checks
|
// check duel - before sanctuary checks
|
||||||
if (playerAffectingAttacker && playerAffectingTarget)
|
if (playerAffectingAttacker && playerAffectingTarget)
|
||||||
@@ -12211,8 +12207,10 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co
|
|||||||
|
|
||||||
// PvP case - can't attack when attacker or target are in sanctuary
|
// PvP case - can't attack when attacker or target are in sanctuary
|
||||||
// however, 13850 client doesn't allow to attack when one of the unit's has sanctuary flag and is pvp
|
// however, 13850 client doesn't allow to attack when one of the unit's has sanctuary flag and is pvp
|
||||||
if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)
|
//! Machiavelli edit: I don't know if the unit flag check is correct here. In the above checks UNIT_FLAG_PVP_ATTACKABLE (0x80 in 12340) was replaced
|
||||||
&& ((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY) || (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY)))
|
//! with the proper flag which has 0x80 in 13580 - however I cannot find proof if this flag is correctly used here or not.
|
||||||
|
if (/*target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)
|
||||||
|
&& */((target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY) || (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_SANCTUARY)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// additional checks - only PvP case
|
// additional checks - only PvP case
|
||||||
|
|||||||
Reference in New Issue
Block a user