diff options
author | xinef1 <w.szyszko2@gmail.com> | 2017-02-04 19:38:36 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2019-06-15 18:41:09 +0200 |
commit | d1cbd8a837116a0fadae06cf5714a345035eb799 (patch) | |
tree | 261991af0f578858f15bb8ce15d115b60c40f3b3 /src | |
parent | 2dcc2d0f058bc2e1d5a66352ec76db18bee189dc (diff) |
Core/Pets: Fixed flashing pet attack button (#18906)
(cherrypicked from 0fa38d0ae03e3d301fb1f94c48122ea81f000131)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/CoreAI/PetAI.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 20 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/PetHandler.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 13 |
5 files changed, 35 insertions, 24 deletions
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 24d4ee96f3c..bd9a0fdf5d5 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -72,7 +72,6 @@ void PetAI::_stopAttack() me->AttackStop(); me->InterruptNonMeleeSpells(false); - me->SendMeleeAttackStop(); // Should stop pet's attack button from flashing me->GetCharmInfo()->SetIsCommandAttack(false); ClearCharmInfoFlags(); HandleReturnMovement(); @@ -309,7 +308,6 @@ void PetAI::KilledUnit(Unit* victim) // next target selection me->AttackStop(); me->InterruptNonMeleeSpells(false); - me->SendMeleeAttackStop(); // Stops the pet's 'Attack' button from flashing // Before returning to owner, see if there are more things to attack if (Unit* nextTarget = SelectNextTarget(false)) @@ -448,6 +446,8 @@ void PetAI::HandleReturnMovement() me->GetMotionMaster()->MoveFollow(me->GetCharmerOrOwner(), PET_FOLLOW_DIST, me->GetFollowAngle()); } } + + me->ClearInPetCombat(); } void PetAI::DoAttack(Unit* target, bool chase) @@ -457,6 +457,12 @@ void PetAI::DoAttack(Unit* target, bool chase) if (me->Attack(target, true)) { + // properly fix fake combat after pet is sent to attack + if (Unit* owner = me->GetOwner()) + owner->AddUnitFlag(UNIT_FLAG_PET_IN_COMBAT); + + me->AddUnitFlag(UNIT_FLAG_PET_IN_COMBAT); + // Play sound to let the player know the pet is attacking something it picked on its own if (me->HasReactState(REACT_AGGRESSIVE) && !me->GetCharmInfo()->IsCommandAttack()) me->SendPetAIReaction(me->GetGUID()); @@ -524,10 +530,10 @@ bool PetAI::CanAttack(Unit* target) if (!target->IsAlive()) { + // if target is invalid, pet should evade automaticly // Clear target to prevent getting stuck on dead targets - me->AttackStop(); - me->InterruptNonMeleeSpells(false); - me->SendMeleeAttackStop(); + //me->AttackStop(); + //me->InterruptNonMeleeSpells(false); return false; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 5b83470dc4e..f5a0412d7f1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5605,6 +5605,10 @@ void Unit::CombatStop(bool includingCast) if (GetTypeId() == TYPEID_PLAYER) ToPlayer()->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel ClearInCombat(); + + // just in case + if (IsPetInCombat() && GetTypeId() != TYPEID_PLAYER) + ClearInPetCombat(); } void Unit::CombatStopWithPets(bool includingCast) @@ -7804,10 +7808,12 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy) Dismount(); } - for (Unit::ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) + for (Unit::ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end();) { - (*itr)->SetInCombatState(PvP, enemy); - (*itr)->AddUnitFlag(UNIT_FLAG_PET_IN_COMBAT); + Unit* controlled = *itr; + ++itr; + + controlled->SetInCombatState(PvP, enemy); } ProcSkillsAndAuras(enemy, PROC_FLAG_ENTER_COMBAT, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr); @@ -7838,10 +7844,16 @@ void Unit::ClearInCombat() else ToPlayer()->OnCombatExit(); - RemoveUnitFlag(UNIT_FLAG_PET_IN_COMBAT); RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LEAVE_COMBAT); } +void Unit::ClearInPetCombat() +{ + RemoveUnitFlag(UNIT_FLAG_PET_IN_COMBAT); + if (Unit* owner = GetOwner()) + owner->RemoveUnitFlag(UNIT_FLAG_PET_IN_COMBAT); +} + bool Unit::isTargetableForAttack(bool checkFakeDeath) const { if (!IsAlive()) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 9f0e19ea0d8..e56dc09df42 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1277,11 +1277,13 @@ class TC_GAME_API Unit : public WorldObject bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); } bool IsInCombat() const { return HasUnitFlag(UNIT_FLAG_IN_COMBAT); } + bool IsPetInCombat() const { return HasUnitFlag(UNIT_FLAG_PET_IN_COMBAT); } bool IsInCombatWith(Unit const* who) const; void CombatStart(Unit* target, bool initialAggro = true); void SetInCombatState(bool PvP, Unit* enemy = NULL); void SetInCombatWith(Unit* enemy); void ClearInCombat(); + void ClearInPetCombat(); uint32 GetCombatTimer() const { return m_CombatTimer; } bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const; diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 18b69ac2d0b..0a765ffec1c 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -133,6 +133,7 @@ void WorldSession::HandlePetStopAttack(WorldPackets::Pet::PetStopAttack& packet) return; pet->AttackStop(); + pet->ClearInPetCombat(); } void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2, Position const& pos) @@ -166,6 +167,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe case COMMAND_FOLLOW: //spellid=1792 //FOLLOW pet->AttackStop(); pet->InterruptNonMeleeSpells(false); + pet->ClearInPetCombat(); pet->GetMotionMaster()->MoveFollow(_player, PET_FOLLOW_DIST, pet->GetFollowAngle()); charmInfo->SetCommandState(COMMAND_FOLLOW); @@ -222,9 +224,6 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe } else // charmed player { - if (pet->GetVictim() && pet->GetVictim() != TargetUnit) - pet->AttackStop(); - charmInfo->SetIsCommandAttack(true); charmInfo->SetIsAtStay(false); charmInfo->SetIsFollowing(false); @@ -278,6 +277,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe { case REACT_PASSIVE: //passive pet->AttackStop(); + pet->ClearInPetCombat(); // no break; case REACT_DEFENSIVE: //recovery case REACT_AGGRESSIVE: //activete @@ -368,8 +368,6 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe // This is true if pet has no target or has target but targets differs. if (pet->GetVictim() != unit_target) { - if (pet->GetVictim()) - pet->AttackStop(); pet->GetMotionMaster()->Clear(); if (pet->ToCreature()->IsAIEnabled) pet->ToCreature()->AI()->AttackStart(unit_target); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index bbd597b9096..90ca90f9740 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -2046,16 +2046,9 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta // creature/player specific target checks if (unitTarget) { - if (HasAttribute(SPELL_ATTR1_CANT_TARGET_IN_COMBAT)) - { - if (unitTarget->IsInCombat()) - return SPELL_FAILED_TARGET_AFFECTING_COMBAT; - // player with active pet counts as a player in combat - else if (Player const* player = unitTarget->ToPlayer()) - if (Pet* pet = player->GetPet()) - if (pet->GetVictim() && !pet->HasUnitState(UNIT_STATE_CONTROLLED)) - return SPELL_FAILED_TARGET_AFFECTING_COMBAT; - } + // spells cannot be cast if player is in fake combat also + if (HasAttribute(SPELL_ATTR1_CANT_TARGET_IN_COMBAT) && (unitTarget->IsInCombat() || unitTarget->IsPetInCombat())) + return SPELL_FAILED_TARGET_AFFECTING_COMBAT; // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts if (HasAttribute(SPELL_ATTR3_ONLY_TARGET_GHOSTS) != unitTarget->HasAuraType(SPELL_AURA_GHOST)) |