Core/Creatures: Moved autoattack handling from scripts to game
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=`StaticFlags1`|0x100000 WHERE `Entry` IN (
|
||||
15589, -- Eye of C'Thun
|
||||
15727, -- C'Thun
|
||||
16129, -- Shadow Fissure
|
||||
16474, -- Blizzard
|
||||
17096, -- Astral Flare
|
||||
17907, -- Frost Wyrm
|
||||
17990, -- Underbog Mushroom
|
||||
18412, -- Cyclone (The Crone)
|
||||
18729, -- Infernal Rain (Hellfire)
|
||||
19427, -- Voidwalker Summoner
|
||||
19781, -- Astral Flare
|
||||
19782, -- Astral Flare
|
||||
19783, -- Astral Flare
|
||||
21364, -- Phoenix Egg
|
||||
22950, -- High Nethermancer Zerevor
|
||||
23417, -- Reliquary Combat Trigger
|
||||
23426, -- The Illidari Council
|
||||
25265, -- Demonic Vapor
|
||||
25267, -- Demonic Vapor (Trail)
|
||||
25502, -- Shield Orb
|
||||
25603, -- Felfire Portal
|
||||
25741, -- M'uru
|
||||
25744, -- Dark Fiend
|
||||
25855, -- Singularity
|
||||
27629, -- Wyrmrest Defender
|
||||
27692, -- Emerald Drake
|
||||
27755, -- Amber Drake
|
||||
27756, -- Ruby Drake
|
||||
28926, -- Spark of Ionar
|
||||
29271, -- Ethereal Sphere
|
||||
30234, -- Hover Disk
|
||||
30249, -- Scion of Eternity
|
||||
30391, -- Healthy Mushroom
|
||||
30435, -- Poisonous Mushroom
|
||||
30616, -- Flame Tsunami
|
||||
30641, -- Twilight Fissure
|
||||
30882, -- Twilight Egg
|
||||
31216, -- Mirror Image
|
||||
32582, -- Ethereal Sphere
|
||||
33052, -- Living Constellation
|
||||
33090, -- Pool of Tar
|
||||
33134, -- Sara
|
||||
33139, -- Flame Leviathan Turret
|
||||
33169, -- Icicle
|
||||
33173, -- Snowpacked Icicle
|
||||
33229, -- Melee Target
|
||||
33243, -- Ranged Target
|
||||
33272, -- Charge Target
|
||||
33280, -- Voice of Yogg-Saron
|
||||
33552, -- Yogg-Saron
|
||||
33651, -- VX-001
|
||||
33670, -- Aerial Command Unit
|
||||
33983, -- Constrictor Tentacle
|
||||
33985, -- Corruptor Tentacle
|
||||
33990, -- Laughing Skull
|
||||
34441, -- Vivienne Blackwhisper
|
||||
34444, -- Thrakgar
|
||||
34445, -- Liandra Suncaller
|
||||
34447, -- Caiphus the Stern
|
||||
34449, -- Ginselle Blightslinger
|
||||
34450, -- Harkzog
|
||||
34451, -- Birana Stormhoof
|
||||
34459, -- Erin Misthoof
|
||||
34460, -- Kavina Grovesong
|
||||
34465, -- Velanaa
|
||||
34466, -- Anthar Forgemender
|
||||
34468, -- Noozle Whizzlestick
|
||||
34469, -- Melador Valestrider
|
||||
34470, -- Saamul
|
||||
34473, -- Brienna Nightfell
|
||||
34474, -- Serissa Grimdabbler
|
||||
34628, -- Concentrated Darkness
|
||||
34630, -- Concentrated Light
|
||||
34660, -- Anub'arak (Spike)
|
||||
36549, -- Beasts Combat Stalker
|
||||
36672, -- Coldflame
|
||||
36855, -- Lady Deathwhisper
|
||||
36968, -- Kor'kron Axethrower
|
||||
36969, -- Skybreaker Rifleman
|
||||
36978, -- Skybreaker Mortar Soldier
|
||||
36980, -- Ice Tomb
|
||||
36982, -- Kor'kron Rocketeer
|
||||
37116, -- Skybreaker Sorcerer
|
||||
37117, -- Kor'kron Battle-Mage
|
||||
38008, -- Blood Orb Controller
|
||||
38332, -- Ball of Flame
|
||||
38451, -- Ball of Inferno Flame
|
||||
38454 -- Kinetic Bomb
|
||||
);
|
||||
@@ -43,10 +43,7 @@ int32 AggressorAI::Permissible(Creature const* creature)
|
||||
|
||||
void AggressorAI::UpdateAI(uint32 /*diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
UpdateVictim();
|
||||
}
|
||||
|
||||
/////////////////
|
||||
@@ -107,8 +104,6 @@ void CombatAI::UpdateAI(uint32 diff)
|
||||
if (AISpellInfoType const* info = GetAISpellInfo(spellId, me->GetMap()->GetDifficultyID()))
|
||||
_events.ScheduleEvent(spellId, info->cooldown, info->cooldown * 2);
|
||||
}
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void CombatAI::SpellInterrupted(uint32 spellId, uint32 unTimeMs)
|
||||
@@ -202,6 +197,7 @@ TurretAI::TurretAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, s
|
||||
_minimumRange = spellInfo ? spellInfo->GetMinRange(false) : 0;
|
||||
creature->m_CombatDistance = spellInfo ? spellInfo->GetMaxRange(false) : 0;
|
||||
creature->m_SightDistance = creature->m_CombatDistance;
|
||||
creature->SetCanMelee(false);
|
||||
}
|
||||
|
||||
bool TurretAI::CanAIAttack(Unit const* who) const
|
||||
@@ -235,6 +231,7 @@ VehicleAI::VehicleAI(Creature* creature, uint32 scriptId) : CreatureAI(creature,
|
||||
LoadConditions();
|
||||
_dismiss = false;
|
||||
_dismissTimer = VEHICLE_DISMISS_TIME;
|
||||
me->SetCanMelee(false);
|
||||
}
|
||||
|
||||
// NOTE: VehicleAI::UpdateAI runs even while the vehicle is mounted
|
||||
|
||||
@@ -31,10 +31,7 @@ int32 GuardAI::Permissible(Creature const* creature)
|
||||
|
||||
void GuardAI::UpdateAI(uint32 /*diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
UpdateVictim();
|
||||
}
|
||||
|
||||
bool GuardAI::CanSeeAlways(WorldObject const* obj)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
PassiveAI::PassiveAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetCanMelee(false);
|
||||
}
|
||||
|
||||
PossessedAI::PossessedAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
|
||||
@@ -32,6 +33,7 @@ PossessedAI::PossessedAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
|
||||
NullCreatureAI::NullCreatureAI(Creature* c, uint32 scriptId) : CreatureAI(c, scriptId)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetCanMelee(false);
|
||||
}
|
||||
|
||||
int32 NullCreatureAI::Permissible(Creature const* creature)
|
||||
@@ -62,8 +64,6 @@ void PossessedAI::UpdateAI(uint32 /*diff*/)
|
||||
{
|
||||
if (!me->IsValidAttackTarget(me->GetVictim()))
|
||||
me->AttackStop();
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,15 +80,6 @@ void PetAI::UpdateAI(uint32 diff)
|
||||
StopAttack();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check before attacking to prevent pets from leaving stay position
|
||||
if (me->GetCharmInfo()->HasCommandState(COMMAND_STAY))
|
||||
{
|
||||
if (me->GetCharmInfo()->IsCommandAttack() || (me->GetCharmInfo()->IsAtStay() && me->IsWithinMeleeRange(me->GetVictim())))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -28,8 +28,5 @@ int32 ReactorAI::Permissible(Creature const* creature)
|
||||
|
||||
void ReactorAI::UpdateAI(uint32 /*diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
UpdateVictim();
|
||||
}
|
||||
|
||||
@@ -58,41 +58,6 @@ void UnitAI::AttackStartCaster(Unit* victim, float dist)
|
||||
me->GetMotionMaster()->MoveChase(victim, dist);
|
||||
}
|
||||
|
||||
void UnitAI::DoMeleeAttackIfReady()
|
||||
{
|
||||
if (me->IsCreature() && !me->ToCreature()->CanMelee())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
Spell* channeledSpell = me->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
|
||||
if (!channeledSpell || !channeledSpell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_ALLOW_ACTIONS_DURING_CHANNEL))
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = me->GetVictim();
|
||||
|
||||
if (!me->IsWithinMeleeRange(victim))
|
||||
return;
|
||||
|
||||
// Check that the victim is in front of the unit
|
||||
if (!me->HasInArc(2 * float(M_PI) / 3, victim))
|
||||
return;
|
||||
|
||||
//Make sure our attack is ready and we aren't currently casting before checking distance
|
||||
if (me->isAttackReady())
|
||||
{
|
||||
me->AttackerStateUpdate(victim);
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
|
||||
if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK))
|
||||
{
|
||||
me->AttackerStateUpdate(victim, OFF_ATTACK);
|
||||
me->resetAttackTimer(OFF_ATTACK);
|
||||
}
|
||||
}
|
||||
|
||||
bool UnitAI::DoSpellAttackIfReady(uint32 spellId)
|
||||
{
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || !me->isAttackReady())
|
||||
|
||||
@@ -160,7 +160,6 @@ class TC_GAME_API UnitAI
|
||||
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const& args = {});
|
||||
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const& args = {}) { return DoCast(nullptr, spellId, args); }
|
||||
|
||||
void DoMeleeAttackIfReady();
|
||||
bool DoSpellAttackIfReady(uint32 spellId);
|
||||
|
||||
static std::unordered_map<std::pair<uint32, Difficulty>, AISpellInfoType> AISpellInfo;
|
||||
|
||||
@@ -591,8 +591,6 @@ void PlayerAI::DoAutoAttackIfReady()
|
||||
{
|
||||
if (IsRangedAttacker())
|
||||
DoRangedAttackIfReady();
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void PlayerAI::CancelAllShapeshifts()
|
||||
|
||||
@@ -149,10 +149,7 @@ void ScriptedAI::AttackStart(Unit* who)
|
||||
void ScriptedAI::UpdateAI(uint32 /*diff*/)
|
||||
{
|
||||
// Check if we have a current target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
UpdateVictim();
|
||||
}
|
||||
|
||||
void ScriptedAI::DoStartMovement(Unit* victim, float distance, float angle)
|
||||
@@ -629,8 +626,6 @@ void BossAI::UpdateAI(uint32 diff)
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool BossAI::CanAIAttack(Unit const* target) const
|
||||
@@ -716,6 +711,4 @@ void WorldBossAI::UpdateAI(uint32 diff)
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
@@ -248,10 +248,7 @@ void EscortAI::UpdateAI(uint32 diff)
|
||||
|
||||
void EscortAI::UpdateEscortAI(uint32 /*diff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
UpdateVictim();
|
||||
}
|
||||
|
||||
void EscortAI::AddWaypoint(uint32 id, float x, float y, float z, bool run)
|
||||
|
||||
@@ -147,10 +147,7 @@ void FollowerAI::UpdateAI(uint32 uiDiff)
|
||||
|
||||
void FollowerAI::UpdateFollowerAI(uint32 /*uiDiff*/)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
UpdateVictim();
|
||||
}
|
||||
|
||||
void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, uint32 quest)
|
||||
|
||||
@@ -283,21 +283,13 @@ void SmartAI::UpdateAI(uint32 diff)
|
||||
|
||||
CheckConditions(diff);
|
||||
|
||||
bool hasVictim = UpdateVictim();
|
||||
UpdateVictim();
|
||||
|
||||
GetScript()->OnUpdate(diff);
|
||||
|
||||
UpdatePath(diff);
|
||||
UpdateFollow(diff);
|
||||
UpdateDespawn(diff);
|
||||
|
||||
if (!IsAIControlled())
|
||||
return;
|
||||
|
||||
if (!hasVictim)
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool SmartAI::IsEscortInvokerInRange()
|
||||
|
||||
@@ -852,6 +852,8 @@ void Creature::Update(uint32 diff)
|
||||
|
||||
Unit::AIUpdateTick(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
// creature can be dead after UpdateAI call
|
||||
// CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly)
|
||||
if (!IsAlive())
|
||||
|
||||
@@ -235,8 +235,6 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this)
|
||||
m_deathTimer = 0;
|
||||
m_deathExpireTime = 0;
|
||||
|
||||
m_swingErrorMsg = 0;
|
||||
|
||||
for (uint8 j = 0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; ++j)
|
||||
{
|
||||
m_bgBattlegroundQueueID[j].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE;
|
||||
@@ -1011,78 +1009,7 @@ void Player::Update(uint32 p_time)
|
||||
|
||||
m_achievementMgr->UpdateTimedCriteria(Milliseconds(p_time));
|
||||
|
||||
if (HasUnitState(UNIT_STATE_MELEE_ATTACKING) && !HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_CHARGING))
|
||||
{
|
||||
if (Unit* victim = GetVictim())
|
||||
{
|
||||
// default combat reach 10
|
||||
/// @todo add weapon, skill check
|
||||
|
||||
if (isAttackReady(BASE_ATTACK))
|
||||
{
|
||||
if (!IsWithinMeleeRange(victim))
|
||||
{
|
||||
setAttackTimer(BASE_ATTACK, 100);
|
||||
if (m_swingErrorMsg != 1) // send single time (client auto repeat)
|
||||
{
|
||||
SendAttackSwingNotInRange();
|
||||
m_swingErrorMsg = 1;
|
||||
}
|
||||
}
|
||||
//120 degrees of radiant range, if player is not in boundary radius
|
||||
else if (!IsWithinBoundaryRadius(victim) && !HasInArc(2 * float(M_PI) / 3, victim))
|
||||
{
|
||||
setAttackTimer(BASE_ATTACK, 100);
|
||||
if (m_swingErrorMsg != 2) // send single time (client auto repeat)
|
||||
{
|
||||
SendAttackSwingBadFacingAttack();
|
||||
m_swingErrorMsg = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_swingErrorMsg = 0; // reset swing error state
|
||||
|
||||
// prevent base and off attack in same time, delay attack at 0.2 sec
|
||||
if (haveOffhandWeapon())
|
||||
if (getAttackTimer(OFF_ATTACK) < ATTACK_DISPLAY_DELAY)
|
||||
setAttackTimer(OFF_ATTACK, ATTACK_DISPLAY_DELAY);
|
||||
|
||||
// do attack
|
||||
AttackerStateUpdate(victim, BASE_ATTACK);
|
||||
resetAttackTimer(BASE_ATTACK);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsInFeralForm() && haveOffhandWeapon() && isAttackReady(OFF_ATTACK))
|
||||
{
|
||||
if (!IsWithinMeleeRange(victim))
|
||||
setAttackTimer(OFF_ATTACK, 100);
|
||||
else if (!IsWithinBoundaryRadius(victim) && !HasInArc(2 * float(M_PI) / 3, victim))
|
||||
{
|
||||
setAttackTimer(BASE_ATTACK, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
// prevent base and off attack in same time, delay attack at 0.2 sec
|
||||
if (getAttackTimer(BASE_ATTACK) < ATTACK_DISPLAY_DELAY)
|
||||
setAttackTimer(BASE_ATTACK, ATTACK_DISPLAY_DELAY);
|
||||
|
||||
// do attack
|
||||
AttackerStateUpdate(victim, OFF_ATTACK);
|
||||
resetAttackTimer(OFF_ATTACK);
|
||||
}
|
||||
}
|
||||
|
||||
/*Unit* owner = victim->GetOwner();
|
||||
Unit* u = owner ? owner : victim;
|
||||
if (u->IsPvP() && (!duel || duel->opponent != u))
|
||||
{
|
||||
UpdatePvP(true);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
if (HasPlayerFlag(PLAYER_FLAGS_RESTING))
|
||||
_restMgr->Update(now);
|
||||
@@ -21308,29 +21235,17 @@ void Player::SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGui
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
}
|
||||
|
||||
void Player::SendAttackSwingCantAttack() const
|
||||
{
|
||||
SendDirectMessage(WorldPackets::Combat::AttackSwingError(WorldPackets::Combat::AttackSwingError::CantAttack).Write());
|
||||
}
|
||||
|
||||
void Player::SendAttackSwingCancelAttack() const
|
||||
{
|
||||
SendDirectMessage(WorldPackets::Combat::CancelCombat().Write());
|
||||
}
|
||||
|
||||
void Player::SendAttackSwingDeadTarget() const
|
||||
void Player::SetAttackSwingError(Optional<AttackSwingErr> err)
|
||||
{
|
||||
SendDirectMessage(WorldPackets::Combat::AttackSwingError(WorldPackets::Combat::AttackSwingError::DeadTarget).Write());
|
||||
}
|
||||
if (err && err != m_swingErrorMsg)
|
||||
SendDirectMessage(WorldPackets::Combat::AttackSwingError(*err).Write());
|
||||
|
||||
void Player::SendAttackSwingNotInRange() const
|
||||
{
|
||||
SendDirectMessage(WorldPackets::Combat::AttackSwingError(WorldPackets::Combat::AttackSwingError::NotInRange).Write());
|
||||
}
|
||||
|
||||
void Player::SendAttackSwingBadFacingAttack() const
|
||||
{
|
||||
SendDirectMessage(WorldPackets::Combat::AttackSwingError(WorldPackets::Combat::AttackSwingError::BadFacing).Write());
|
||||
m_swingErrorMsg = err;
|
||||
}
|
||||
|
||||
void Player::SendAutoRepeatCancel(Unit* target)
|
||||
|
||||
@@ -2126,11 +2126,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void DestroyForPlayer(Player* target) const override;
|
||||
|
||||
// notifiers
|
||||
void SendAttackSwingCantAttack() const;
|
||||
void SendAttackSwingCancelAttack() const;
|
||||
void SendAttackSwingDeadTarget() const;
|
||||
void SendAttackSwingNotInRange() const;
|
||||
void SendAttackSwingBadFacingAttack() const;
|
||||
void SetAttackSwingError(Optional<AttackSwingErr> err);
|
||||
void SendAutoRepeatCancel(Unit* target);
|
||||
void SendExplorationExperience(uint32 Area, uint32 Experience) const;
|
||||
|
||||
@@ -3096,7 +3093,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
bool m_canBlock;
|
||||
bool m_canTitanGrip;
|
||||
uint32 m_titanGripPenaltySpellId;
|
||||
uint8 m_swingErrorMsg;
|
||||
Optional<AttackSwingErr> m_swingErrorMsg;
|
||||
|
||||
// Social
|
||||
PlayerSocial* m_social;
|
||||
|
||||
@@ -407,8 +407,8 @@ Unit::~Unit()
|
||||
ASSERT(m_appliedAuras.empty());
|
||||
ASSERT(m_ownedAuras.empty());
|
||||
ASSERT(m_removedAuras.empty());
|
||||
ASSERT(m_gameObj.empty());
|
||||
ASSERT(m_dynObj.empty());
|
||||
ASSERT(m_gameObj.empty());
|
||||
ASSERT(m_areaTrigger.empty());
|
||||
ASSERT(!m_unitMovedByMe || (m_unitMovedByMe == this));
|
||||
ASSERT(!m_playerMovingMe || (m_playerMovingMe == this));
|
||||
@@ -456,10 +456,10 @@ void Unit::Update(uint32 p_time)
|
||||
{
|
||||
if (uint32 base_att = getAttackTimer(BASE_ATTACK))
|
||||
setAttackTimer(BASE_ATTACK, (p_time >= base_att ? 0 : base_att - p_time));
|
||||
if (uint32 ranged_att = getAttackTimer(RANGED_ATTACK))
|
||||
setAttackTimer(RANGED_ATTACK, (p_time >= ranged_att ? 0 : ranged_att - p_time));
|
||||
if (uint32 off_att = getAttackTimer(OFF_ATTACK))
|
||||
setAttackTimer(OFF_ATTACK, (p_time >= off_att ? 0 : off_att - p_time));
|
||||
if (uint32 ranged_att = getAttackTimer(RANGED_ATTACK))
|
||||
setAttackTimer(RANGED_ATTACK, (p_time >= ranged_att ? 0 : ranged_att - p_time));
|
||||
}
|
||||
|
||||
// update abilities available only for fraction of time
|
||||
@@ -2087,12 +2087,15 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extra)
|
||||
void Unit::DoMeleeAttackIfReady()
|
||||
{
|
||||
if (HasUnitFlag(UNIT_FLAG_PACIFIED))
|
||||
if (!HasUnitState(UNIT_STATE_MELEE_ATTACKING))
|
||||
return;
|
||||
|
||||
if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) && !extra)
|
||||
if (HasUnitState(UNIT_STATE_CHARGING))
|
||||
return;
|
||||
|
||||
if (IsCreature() && !ToCreature()->CanMelee())
|
||||
return;
|
||||
|
||||
if (HasUnitState(UNIT_STATE_CASTING))
|
||||
@@ -2102,6 +2105,69 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = GetVictim();
|
||||
if (!victim)
|
||||
return;
|
||||
|
||||
auto getAutoAttackError = [&]() -> Optional<AttackSwingErr>
|
||||
{
|
||||
if (!IsWithinMeleeRange(victim))
|
||||
return AttackSwingErr::NotInRange;
|
||||
|
||||
//120 degrees of radiant range, if player is not in boundary radius
|
||||
if (!IsWithinBoundaryRadius(victim) && !HasInArc(2 * float(M_PI) / 3, victim))
|
||||
return AttackSwingErr::BadFacing;
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
if (isAttackReady(BASE_ATTACK))
|
||||
{
|
||||
Optional<AttackSwingErr> autoAttackError = getAutoAttackError();
|
||||
if (!autoAttackError)
|
||||
{
|
||||
// prevent base and off attack in same time, delay attack at 0.2 sec
|
||||
if (haveOffhandWeapon())
|
||||
if (getAttackTimer(OFF_ATTACK) < ATTACK_DISPLAY_DELAY)
|
||||
setAttackTimer(OFF_ATTACK, ATTACK_DISPLAY_DELAY);
|
||||
|
||||
// do attack
|
||||
AttackerStateUpdate(victim, BASE_ATTACK);
|
||||
resetAttackTimer(BASE_ATTACK);
|
||||
}
|
||||
else
|
||||
setAttackTimer(BASE_ATTACK, 100);
|
||||
|
||||
if (Player* attackerPlayer = ToPlayer())
|
||||
attackerPlayer->SetAttackSwingError(autoAttackError);
|
||||
}
|
||||
|
||||
if (!IsInFeralForm() && haveOffhandWeapon() && isAttackReady(OFF_ATTACK))
|
||||
{
|
||||
Optional<AttackSwingErr> autoAttackError = getAutoAttackError();
|
||||
if (!autoAttackError)
|
||||
{
|
||||
// prevent base and off attack in same time, delay attack at 0.2 sec
|
||||
if (getAttackTimer(BASE_ATTACK) < ATTACK_DISPLAY_DELAY)
|
||||
setAttackTimer(BASE_ATTACK, ATTACK_DISPLAY_DELAY);
|
||||
|
||||
// do attack
|
||||
AttackerStateUpdate(victim, OFF_ATTACK);
|
||||
resetAttackTimer(OFF_ATTACK);
|
||||
}
|
||||
else
|
||||
setAttackTimer(OFF_ATTACK, 100);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extra)
|
||||
{
|
||||
if (HasUnitFlag(UNIT_FLAG_PACIFIED))
|
||||
return;
|
||||
|
||||
if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) && !extra)
|
||||
return;
|
||||
|
||||
if (HasAuraType(SPELL_AURA_DISABLE_ATTACKING_EXCEPT_ABILITIES))
|
||||
return;
|
||||
|
||||
@@ -5070,7 +5136,7 @@ void Unit::_RegisterDynObject(DynamicObject* dynObj)
|
||||
|
||||
void Unit::_UnregisterDynObject(DynamicObject* dynObj)
|
||||
{
|
||||
m_dynObj.remove(dynObj);
|
||||
std::erase(m_dynObj, dynObj);
|
||||
if (GetTypeId() == TYPEID_UNIT && IsAIEnabled())
|
||||
ToCreature()->AI()->JustUnregisteredDynObject(dynObj);
|
||||
}
|
||||
@@ -5093,8 +5159,6 @@ std::vector<DynamicObject*> Unit::GetDynObjects(uint32 spellId) const
|
||||
|
||||
void Unit::RemoveDynObject(uint32 spellId)
|
||||
{
|
||||
if (m_dynObj.empty())
|
||||
return;
|
||||
for (DynObjectList::iterator i = m_dynObj.begin(); i != m_dynObj.end();)
|
||||
{
|
||||
DynamicObject* dynObj = *i;
|
||||
@@ -5111,7 +5175,7 @@ void Unit::RemoveDynObject(uint32 spellId)
|
||||
void Unit::RemoveAllDynObjects()
|
||||
{
|
||||
while (!m_dynObj.empty())
|
||||
m_dynObj.front()->Remove();
|
||||
m_dynObj.back()->Remove();
|
||||
}
|
||||
|
||||
GameObject* Unit::GetGameObject(uint32 spellId) const
|
||||
@@ -5598,14 +5662,8 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
|
||||
|
||||
Creature* creature = ToCreature();
|
||||
// creatures cannot attack while evading
|
||||
if (creature)
|
||||
{
|
||||
if (creature->IsInEvadeMode())
|
||||
return false;
|
||||
|
||||
if (!creature->CanMelee())
|
||||
meleeAttack = false;
|
||||
}
|
||||
if (creature && creature->IsInEvadeMode())
|
||||
return false;
|
||||
|
||||
// nobody can attack GM in GM-mode
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
@@ -11022,7 +11080,6 @@ void Unit::SetControlled(bool apply, UnitState state)
|
||||
case UNIT_STATE_CONFUSED:
|
||||
if (!HasUnitState(UNIT_STATE_STUNNED))
|
||||
{
|
||||
ClearUnitState(UNIT_STATE_MELEE_ATTACKING);
|
||||
SendMeleeAttackStop();
|
||||
// SendAutoRepeatCancel ?
|
||||
SetConfused(true);
|
||||
@@ -11031,7 +11088,6 @@ void Unit::SetControlled(bool apply, UnitState state)
|
||||
case UNIT_STATE_FLEEING:
|
||||
if (!HasUnitState(UNIT_STATE_STUNNED | UNIT_STATE_CONFUSED))
|
||||
{
|
||||
ClearUnitState(UNIT_STATE_MELEE_ATTACKING);
|
||||
SendMeleeAttackStop();
|
||||
// SendAutoRepeatCancel ?
|
||||
SetFeared(true);
|
||||
|
||||
@@ -1053,7 +1053,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProcContainer& procAuras);
|
||||
|
||||
void HandleEmoteCommand(Emote emoteId, Player* target = nullptr, Trinity::IteratorPair<int32 const*> spellVisualKitIds = {}, int32 sequenceVariation = 0);
|
||||
void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false);
|
||||
void DoMeleeAttackIfReady();
|
||||
void AttackerStateUpdate(Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false);
|
||||
|
||||
void CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK);
|
||||
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
|
||||
@@ -1957,7 +1958,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
int32 m_procDeep; // tracked for proc system correctness (what spells should proc what)
|
||||
int32 m_procChainLength; // tracked to protect against infinite proc loops (hard limit, will disallow procs even if they should happen)
|
||||
|
||||
typedef std::list<DynamicObject*> DynObjectList;
|
||||
typedef std::vector<DynamicObject*> DynObjectList;
|
||||
DynObjectList m_dynObj;
|
||||
|
||||
typedef std::list<GameObject*> GameObjectList;
|
||||
|
||||
@@ -473,6 +473,14 @@ enum HitInfo
|
||||
HITINFO_FAKE_DAMAGE = 0x01000000 // enables damage animation even if no damage done, set only if no damage
|
||||
};
|
||||
|
||||
enum class AttackSwingErr : uint8
|
||||
{
|
||||
NotInRange = 0,
|
||||
BadFacing = 1,
|
||||
CantAttack = 2,
|
||||
DeadTarget = 3
|
||||
};
|
||||
|
||||
#define MAX_DECLINED_NAME_CASES 5
|
||||
|
||||
struct TC_GAME_API DeclinedName
|
||||
|
||||
@@ -96,7 +96,7 @@ WorldPacket const* WorldPackets::Combat::AIReaction::Write()
|
||||
|
||||
WorldPacket const* WorldPackets::Combat::AttackSwingError::Write()
|
||||
{
|
||||
_worldPacket.WriteBits(Reason, 3);
|
||||
_worldPacket.WriteBits(AsUnderlyingType(Reason), 3);
|
||||
_worldPacket.FlushBits();
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "Packet.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "UnitDefines.h"
|
||||
|
||||
class Unit;
|
||||
enum Powers : int8;
|
||||
@@ -41,20 +42,12 @@ namespace WorldPackets
|
||||
class AttackSwingError final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
enum AttackSwingErr : uint8
|
||||
{
|
||||
NotInRange = 0,
|
||||
BadFacing = 1,
|
||||
CantAttack = 2,
|
||||
DeadTarget = 3
|
||||
};
|
||||
|
||||
AttackSwingError() : ServerPacket(SMSG_ATTACK_SWING_ERROR, 4) { }
|
||||
AttackSwingError(AttackSwingErr reason) : ServerPacket(SMSG_ATTACK_SWING_ERROR, 4), Reason(reason) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
AttackSwingErr Reason = CantAttack;
|
||||
AttackSwingErr Reason = AttackSwingErr::CantAttack;
|
||||
};
|
||||
|
||||
class AttackStop final : public ClientPacket
|
||||
|
||||
@@ -434,9 +434,7 @@ struct boss_garothi_worldbreaker : public BossAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->GetVictim() && me->GetVictim()->IsWithinMeleeRange(me))
|
||||
DoMeleeAttackIfReady();
|
||||
else
|
||||
if (!me->GetVictim() || !me->GetVictim()->IsWithinMeleeRange(me))
|
||||
DoSpellAttackIfReady(SPELL_CARNAGE);
|
||||
}
|
||||
private:
|
||||
|
||||
@@ -291,8 +291,6 @@ struct boss_guarm : public BossAI
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
|
||||
|
||||
@@ -620,8 +620,6 @@ struct npc_illidari_fighting_invasion_begins : public ScriptedAI
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1110,8 +1108,6 @@ struct npc_inquisitor_baleful_molten_shore : public ScriptedAI
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -205,8 +205,6 @@ struct boss_leymor : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -284,8 +282,6 @@ struct npc_arcane_tender : public ScriptedAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
EventMap _events;
|
||||
|
||||
@@ -227,7 +227,6 @@ struct boss_telash_greywing : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
|
||||
@@ -124,8 +124,6 @@ struct npc_av_marshal_or_warmaster : public ScriptedAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -169,8 +169,6 @@ struct boss_balinda : public ScriptedAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -125,8 +125,6 @@ struct boss_drekthar : public ScriptedAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -126,8 +126,6 @@ struct boss_galvangar : public ScriptedAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -85,10 +85,7 @@ struct boss_vanndar : public ScriptedAI
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -245,8 +245,6 @@ class boss_alizabal : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -140,8 +140,6 @@ class boss_occuthar : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -111,8 +111,6 @@ class boss_pit_lord_argaloth : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-11
@@ -202,8 +202,6 @@ public: npc_twilight_flame_caller() : CreatureScript("npc_twilight_flame_caller"
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -313,8 +311,6 @@ class npc_twilight_torturer : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -414,8 +410,6 @@ class npc_twilight_sadist : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -489,7 +483,6 @@ class npc_mad_prisoner : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -559,8 +552,6 @@ class npc_crazed_mage : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -653,8 +644,6 @@ class npc_raz_the_crazed : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
-2
@@ -95,8 +95,6 @@ class boss_ascendant_lord_obsidius : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -102,8 +102,6 @@ class boss_beauty : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -109,8 +109,6 @@ class boss_corla : public CreatureScript
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
-2
@@ -97,8 +97,6 @@ class boss_karsh_steelbender : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-2
@@ -122,8 +122,6 @@ class boss_romogg_bonecrusher : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-2
@@ -425,8 +425,6 @@ public:
|
||||
DoCastVictim(SPELL_MIGHTYBLOW);
|
||||
MightyBlow_Timer = 10000;
|
||||
} else MightyBlow_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
-2
@@ -76,8 +76,6 @@ class boss_ambassador_flamelash : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-6
@@ -279,8 +279,6 @@ struct boss_coren_direbrew : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -326,10 +324,7 @@ struct npc_coren_direbrew_sisters : public ScriptedAI
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
-2
@@ -105,8 +105,6 @@ class boss_emperor_dagran_thaurissan : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-2
@@ -117,8 +117,6 @@ class boss_general_angerforge : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-2
@@ -86,8 +86,6 @@ class boss_high_interrogator_gerstahn : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -86,8 +86,6 @@ class boss_magmus : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
|
||||
-2
@@ -225,8 +225,6 @@ class boss_doomrel : public CreatureScript
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||
|
||||
-1
@@ -93,7 +93,6 @@ struct boss_drakkisath : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-1
@@ -95,7 +95,6 @@ struct boss_gizrul_the_slavener : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -168,7 +168,6 @@ struct boss_gyth : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -99,7 +99,6 @@ struct boss_halycon : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool Summoned;
|
||||
|
||||
-1
@@ -81,7 +81,6 @@ struct boss_highlord_omokk : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-2
@@ -124,8 +124,6 @@ struct boss_lord_valthalak : public BossAI
|
||||
frenzy15 = true;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool frenzy40;
|
||||
|
||||
-1
@@ -86,7 +86,6 @@ struct boss_mother_smolderweb : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-1
@@ -126,7 +126,6 @@ struct boss_overlord_wyrmthalak : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-3
@@ -273,7 +273,6 @@ struct boss_pyroguard_emberseer : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -344,8 +343,6 @@ struct npc_blackhand_incarcerator : public ScriptedAI
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
-1
@@ -81,7 +81,6 @@ struct quartermaster_zigris : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-1
@@ -438,7 +438,6 @@ struct boss_rend_blackhand : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
-1
@@ -88,7 +88,6 @@ struct boss_shadow_hunter_voshgajin : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -97,7 +97,6 @@ public:
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
-1
@@ -90,7 +90,6 @@ struct boss_urok_doomhowl : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-1
@@ -107,7 +107,6 @@ struct boss_warmaster_voone : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-2
@@ -119,8 +119,6 @@ struct boss_broodlord : public BossAI
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-5
@@ -171,9 +171,7 @@ struct boss_chromaggus : public BossAI
|
||||
Breath1_Spell = SPELL_FROSTBURN;
|
||||
Breath2_Spell = SPELL_IGNITEFLESH;
|
||||
break;
|
||||
};
|
||||
|
||||
EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
@@ -275,8 +273,6 @@ struct boss_chromaggus : public BossAI
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -77,8 +77,6 @@ struct boss_ebonroc : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -79,8 +79,6 @@ struct boss_firemaw : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -85,8 +85,6 @@ struct boss_flamegor : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -568,8 +568,6 @@ struct boss_nefarian : public BossAI
|
||||
Phase3 = true;
|
||||
Talk(SAY_RAISE_SKELETONS);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -152,7 +152,6 @@ struct boss_razorgore : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
-2
@@ -213,8 +213,6 @@ struct boss_vaelastrasz : public BossAI
|
||||
Talk(SAY_HALFLIFE);
|
||||
HasYelled = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
|
||||
|
||||
@@ -107,8 +107,6 @@ struct boss_baron_geddon : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -85,8 +85,6 @@ struct boss_garr : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -145,10 +143,7 @@ struct npc_firesworn : public ScriptedAI
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -89,8 +89,6 @@ struct boss_gehennas : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -107,8 +107,6 @@ struct boss_golemagg : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,10 +152,7 @@ struct npc_core_rager : public ScriptedAI
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -87,8 +87,6 @@ struct boss_lucifron : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -101,8 +101,6 @@ struct boss_magmadar : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-2
@@ -145,8 +145,6 @@ struct boss_majordomo : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -292,8 +292,6 @@ struct boss_ragnaros : public BossAI
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,14 +315,6 @@ struct npc_son_of_flame : public ScriptedAI //didnt work correctly in EAI for me
|
||||
instance->SetData(DATA_RAGNAROS_ADDS, 1);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
};
|
||||
|
||||
@@ -104,8 +104,6 @@ struct boss_shazzrah : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
-4
@@ -119,8 +119,6 @@ struct boss_sulfuron : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -184,8 +182,6 @@ struct npc_flamewaker_priest : public ScriptedAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -488,10 +488,7 @@ public:
|
||||
} else uiTimer -= uiDiff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
UpdateVictim();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
@@ -530,14 +527,6 @@ public:
|
||||
creature->AI()->SetData(2, 1);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 /*diff*/) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (!me->IsSummon())
|
||||
|
||||
@@ -116,8 +116,6 @@ public:
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -219,10 +219,7 @@ public:
|
||||
if (!UpdateVictim() && _phase != PHASE_NONE)
|
||||
return;
|
||||
|
||||
scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
scheduler.Update(diff);
|
||||
}
|
||||
|
||||
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
|
||||
@@ -370,10 +367,7 @@ public:
|
||||
if (!UpdateVictim() || _phase == PHASE_MOUNTED)
|
||||
return;
|
||||
|
||||
scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -287,6 +287,7 @@ public:
|
||||
if (Vanish_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_VANISH);
|
||||
me->SetCanMelee(false);
|
||||
InVanish = true;
|
||||
Vanish_Timer = 30000;
|
||||
Wait_Timer = 5000;
|
||||
@@ -316,11 +317,9 @@ public:
|
||||
target->CastSpell(target, SPELL_GARROTE, true);
|
||||
|
||||
InVanish = false;
|
||||
me->SetCanMelee(true);
|
||||
} else Wait_Timer -= diff;
|
||||
}
|
||||
|
||||
if (!InVanish)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -371,8 +370,6 @@ struct boss_moroes_guestAI : public ScriptedAI
|
||||
{
|
||||
if (instance->GetBossState(DATA_MOROES) != IN_PROGRESS)
|
||||
EnterEvadeMode();
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -345,8 +345,6 @@ public:
|
||||
}
|
||||
} else PhaseTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -370,8 +370,6 @@ public:
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -550,8 +550,6 @@ public:
|
||||
EnfeebleResetTimer = 9000;
|
||||
} else EnfeebleTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void Cleanup(Creature* infernal, InfernalPoint *point)
|
||||
|
||||
@@ -173,6 +173,7 @@ public:
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
me->SetCanMelee(true);
|
||||
|
||||
// Not in progress
|
||||
instance->SetBossState(DATA_ARAN, NOT_STARTED);
|
||||
@@ -488,8 +489,7 @@ public:
|
||||
} else FlameWreathCheckTime -= diff;
|
||||
}
|
||||
|
||||
if (ArcaneCooldown && FireCooldown && FrostCooldown)
|
||||
DoMeleeAttackIfReady();
|
||||
me->SetCanMelee(ArcaneCooldown && FireCooldown && FrostCooldown);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*pAttacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
|
||||
@@ -185,10 +185,7 @@ public:
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -303,10 +300,7 @@ public:
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -229,8 +229,6 @@ public:
|
||||
SummonTito();
|
||||
else SummonTitoTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -291,8 +289,6 @@ public:
|
||||
DoCastVictim(SPELL_YIPPING);
|
||||
YipTimer = 10000;
|
||||
} else YipTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -423,8 +419,6 @@ public:
|
||||
DoCast(target, SPELL_BRAIN_WIPE);
|
||||
BrainWipeTimer = 20000;
|
||||
} else BrainWipeTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -538,8 +532,6 @@ public:
|
||||
RustTimer = 6000;
|
||||
} else RustTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -652,8 +644,6 @@ public:
|
||||
DoCastVictim(SPELL_FRIGHTENED_SCREAM);
|
||||
ScreamTimer = urand(20000, 30000);
|
||||
} else ScreamTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -737,8 +727,6 @@ public:
|
||||
DoCastVictim(SPELL_CHAIN_LIGHTNING);
|
||||
ChainLightningTimer = 15000;
|
||||
} else ChainLightningTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -914,8 +902,6 @@ public:
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
if (ChaseTimer <= diff)
|
||||
{
|
||||
if (!IsChasing)
|
||||
@@ -1358,8 +1344,6 @@ public:
|
||||
DoCastVictim(SPELL_POISON_THRUST);
|
||||
PoisonThrustTimer = urand(10000, 20000);
|
||||
} else PoisonThrustTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1480,8 +1464,6 @@ void boss_julianne::boss_julianneAI::UpdateAI(uint32 diff)
|
||||
|
||||
EternalAffectionTimer = urand(45000, 60000);
|
||||
} else EternalAffectionTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void boss_julianne::boss_julianneAI::DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/)
|
||||
|
||||
@@ -474,8 +474,6 @@ struct npc_felblood_kaelthas_phoenix : public ScriptedAI
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
|
||||
@@ -334,8 +334,6 @@ public:
|
||||
|
||||
SWPainTimer = 10000;
|
||||
} else SWPainTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -508,6 +506,7 @@ public:
|
||||
{
|
||||
Initialize();
|
||||
me->SetVisible(true);
|
||||
me->SetCanMelee(true);
|
||||
|
||||
boss_priestess_lackey_commonAI::Reset();
|
||||
}
|
||||
@@ -531,6 +530,7 @@ public:
|
||||
AddThreat(unit, 1000.0f);
|
||||
|
||||
InVanish = true;
|
||||
me->SetCanMelee(false);
|
||||
Vanish_Timer = 30000;
|
||||
Wait_Timer = 10000;
|
||||
} else Vanish_Timer -= diff;
|
||||
@@ -543,6 +543,7 @@ public:
|
||||
DoCastVictim(SPELL_KIDNEY_SHOT, true);
|
||||
me->SetVisible(true); // ...? Hacklike
|
||||
InVanish = false;
|
||||
me->SetCanMelee(true);
|
||||
} else Wait_Timer -= diff;
|
||||
}
|
||||
|
||||
@@ -563,9 +564,6 @@ public:
|
||||
DoCastVictim(SPELL_EVISCERATE);
|
||||
Eviscerate_Timer = 4000;
|
||||
} else Eviscerate_Timer -= diff;
|
||||
|
||||
if (!InVanish)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -668,8 +666,6 @@ public:
|
||||
|
||||
Fear_Timer = 10000;
|
||||
} else Fear_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -732,8 +728,6 @@ public:
|
||||
DoCastVictim(SPELL_SNAP_KICK);
|
||||
Snap_Kick_Timer = 4500;
|
||||
} else Snap_Kick_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -865,8 +859,6 @@ public:
|
||||
|
||||
Blink_Timer = 8000;
|
||||
} else Blink_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -987,8 +979,6 @@ public:
|
||||
DoCastVictim(SPELL_FRIGHTENING_SHOUT);
|
||||
Frightening_Shout_Timer = 18000;
|
||||
} else Frightening_Shout_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1088,8 +1078,6 @@ public:
|
||||
Freezing_Trap_Timer = 15000;
|
||||
}
|
||||
} else Freezing_Trap_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1202,8 +1190,6 @@ public:
|
||||
DoCast(me, SPELL_LESSER_HEALING_WAVE);
|
||||
Healing_Wave_Timer = 5000;
|
||||
} else Healing_Wave_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1304,8 +1290,6 @@ public:
|
||||
DoCast(me, SPELL_HIGH_EXPLOSIVE_SHEEP);
|
||||
High_Explosive_Sheep_Timer = 65000;
|
||||
} else High_Explosive_Sheep_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -239,8 +239,6 @@ class boss_selin_fireheart : public CreatureScript
|
||||
events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 20s, 25s, 0, PHASE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -167,8 +167,6 @@ class boss_vexallus : public CreatureScript
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -282,8 +282,6 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1069,31 +1067,22 @@ struct npc_scarlet_ghoul : public ScriptedAI
|
||||
Player* plrOwner = owner->ToPlayer();
|
||||
if (plrOwner && plrOwner->IsInCombat())
|
||||
{
|
||||
if (plrOwner->getAttackerForHelper() && plrOwner->getAttackerForHelper()->GetEntry() == NPC_GHOSTS)
|
||||
AttackStart(plrOwner->getAttackerForHelper());
|
||||
Unit* newTarget = plrOwner->getAttackerForHelper();
|
||||
if (newTarget && newTarget->GetEntry() == NPC_GHOSTS)
|
||||
AttackStart(newTarget);
|
||||
else
|
||||
FindMinions(owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim() || !me->GetVictim())
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
}
|
||||
|
||||
//ScriptedAI::UpdateAI(diff);
|
||||
//Check if we have a current target
|
||||
if (me->EnsureVictim()->GetEntry() == NPC_GHOSTS)
|
||||
{
|
||||
if (me->isAttackReady())
|
||||
{
|
||||
//If we are within range melee the target
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
bool CanAIAttack(Unit const* target) const override
|
||||
{
|
||||
return target->GetEntry() == NPC_GHOSTS;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1259,8 +1248,6 @@ struct npc_hearthglen_crusader : public ScriptedAI
|
||||
|
||||
if (!me->IsWithinCombatRange(me->GetVictim(), _minimumRange))
|
||||
DoSpellAttackIfReady(me->m_spells[0]);
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
|
||||
|
||||
@@ -416,8 +416,6 @@ public:
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1465,8 +1465,6 @@ public:
|
||||
SetHoldState(false);
|
||||
|
||||
} else uiFight_duration -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,8 +107,6 @@ struct boss_arcanist_doan : public BossAI
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE);
|
||||
DoCastAOE(SPELL_DETONATION);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -96,8 +96,6 @@ struct boss_azshir_the_sleepless : public BossAI
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user