fix(Core/Scripts): Fix DK pets not correctly attacking (#25128)
Co-authored-by: blinkysc <blinkysc@users.noreply.github.com> Co-authored-by: Treeston <treeston.mmoc@gmail.com> Co-authored-by: Malcrom <malcromdev@gmail.com> Co-authored-by: Aqua Deus <95978183+aquadeus@users.noreply.github.com>
This commit is contained in:
@@ -1840,44 +1840,39 @@ bool Creature::IsAlwaysDetectableFor(WorldObject const* seer) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Creature::CanStartAttack(Unit const* who) const
|
||||
bool Creature::CanStartAttack(Unit const* who, bool force) const
|
||||
{
|
||||
if (IsCivilian())
|
||||
return false;
|
||||
|
||||
// This set of checks is should be done only for creatures
|
||||
if ((IsImmuneToNPC() && !who->IsPlayer()) || // flag is valid only for non player characters
|
||||
(IsImmuneToPC() && who->IsPlayer())) // immune to PC and target is a player, return false
|
||||
{
|
||||
if ((IsImmuneToNPC() && !who->IsPlayer()) ||
|
||||
(IsImmuneToPC() && who->IsPlayer()))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Unit* owner = who->GetOwner())
|
||||
if (owner->IsPlayer() && IsImmuneToPC()) // immune to PC and target has player owner
|
||||
if (owner->IsPlayer() && IsImmuneToPC())
|
||||
return false;
|
||||
|
||||
// Do not attack non-combat pets
|
||||
if (who->IsCreature() && who->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET)
|
||||
return false;
|
||||
|
||||
if (!CanFly() && (GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE + m_CombatDistance)) // too much Z difference, skip very costy vmap calculations here
|
||||
if (!CanFly() && (GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE + m_CombatDistance))
|
||||
return false;
|
||||
|
||||
if (!_IsTargetAcceptable(who))
|
||||
return false;
|
||||
if (!force)
|
||||
{
|
||||
if (!_IsTargetAcceptable(who))
|
||||
return false;
|
||||
|
||||
if (IsNeutralToAll() || !IsWithinDistInMap(who, GetAggroRange(who) + m_CombatDistance, true, false, false)) // pussywizard: +m_combatDistance for turrets and similar
|
||||
return false;
|
||||
if (IsNeutralToAll() || !IsWithinDistInMap(who, GetAggroRange(who) + m_CombatDistance, true, false, false))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CanCreatureAttack(who))
|
||||
return false;
|
||||
|
||||
if (HasUnitState(UNIT_STATE_STUNNED))
|
||||
return false;
|
||||
|
||||
if (!IsHostileTo(who))
|
||||
return false;
|
||||
|
||||
return IsWithinLOSInMap(who);
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ public:
|
||||
CreatureSpellCooldowns m_CreatureSpellCooldowns;
|
||||
uint32 m_ProhibitSchoolTime[7];
|
||||
|
||||
bool CanStartAttack(Unit const* u) const;
|
||||
bool CanStartAttack(Unit const* u, bool force = false) const;
|
||||
float GetAggroRange(Unit const* target) const;
|
||||
float GetAttackDistance(Unit const* player) const;
|
||||
[[nodiscard]] float GetDetectionRange() const { return m_detectionDistance; }
|
||||
|
||||
@@ -943,13 +943,13 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
|
||||
// Hook for OnDamage Event
|
||||
sScriptMgr->OnDamage(attacker, victim, damage);
|
||||
|
||||
if (victim->IsPlayer() && attacker != victim)
|
||||
// Signal to pets that their owner was attacked - except when DOT.
|
||||
if (attacker != victim && damagetype != DOT)
|
||||
{
|
||||
// Signal to pets that their owner was attacked
|
||||
Pet* pet = victim->ToPlayer()->GetPet();
|
||||
|
||||
if (pet && pet->IsAlive())
|
||||
pet->AI()->OwnerAttackedBy(attacker);
|
||||
for (Unit* controlled : victim->m_Controlled)
|
||||
if (Creature* cControlled = controlled->ToCreature())
|
||||
if (CreatureAI* controlledAI = cControlled->AI())
|
||||
controlledAI->OwnerAttackedBy(attacker);
|
||||
}
|
||||
|
||||
//Dont deal damage to unit if .cheat god is enable.
|
||||
@@ -2766,13 +2766,6 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType /*= BASE_A
|
||||
LOG_DEBUG("entities.unit", "AttackerStateUpdate: (NPC) {} attacked {} for {} dmg, absorbed {}, blocked {}, resisted {}.",
|
||||
GetGUID().ToString(), victim->GetGUID().ToString(), dmgInfo.GetDamage(), dmgInfo.GetAbsorb(), dmgInfo.GetBlock(), dmgInfo.GetResist());
|
||||
|
||||
// Let the pet know we've started attacking someting. Handles melee attacks only
|
||||
// Spells such as auto-shot and others handled in WorldSession::HandleCastSpellOpcode
|
||||
if (IsPlayer() && !m_Controlled.empty())
|
||||
for (Unit::ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||
if (Unit* pet = *itr)
|
||||
if (pet->IsAlive() && pet->IsCreature())
|
||||
pet->ToCreature()->AI()->OwnerAttacked(victim);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7342,7 +7335,6 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
|
||||
// ToCreature()->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
if (creature && !IsControlledByPlayer())
|
||||
{
|
||||
// should not let player enter combat by right clicking target - doesn't helps
|
||||
EngageWithTarget(victim);
|
||||
|
||||
creature->SendAIReaction(AI_REACTION_HOSTILE);
|
||||
@@ -7363,6 +7355,16 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
|
||||
if (meleeAttack)
|
||||
SendMeleeAttackStart(victim);
|
||||
|
||||
// Let the pet know we've started attacking someting. Handles melee attacks only
|
||||
// Spells such as auto-shot and others handled in WorldSession::HandleCastSpellOpcode
|
||||
if (IsPlayer())
|
||||
{
|
||||
for (Unit* controlled : m_Controlled)
|
||||
if (Creature* cControlled = controlled->ToCreature())
|
||||
if (CreatureAI* controlledAI = cControlled->AI())
|
||||
controlledAI->OwnerAttacked(victim);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user