TrinityCore
Loading...
Searching...
No Matches
pet_mage.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Ordered alphabetically using scriptname.
20 * Scriptnames of files in this file should be prefixed with "npc_pet_mag_".
21 */
22
23#include "ScriptMgr.h"
24#include "CellImpl.h"
25#include "CombatAI.h"
26#include "GridNotifiersImpl.h"
27#include "MotionMaster.h"
28#include "Pet.h"
29#include "PetAI.h"
30#include "ScriptedCreature.h"
31#include "SpellHistory.h"
32#include "Timer.h"
33
41
46
48{
49 const float CHASE_DISTANCE = 35.0f;
50
52
53 void InitializeAI() override
54 {
55 Unit* owner = me->GetOwner();
56 if (!owner)
57 return;
58
59 // here mirror image casts on summoner spell (not present in client dbc) 49866
60 // here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcast by mirror images (stats related?)
61 // Clone Me!
62 owner->CastSpell(me, SPELL_MAGE_CLONE_ME, true);
63 }
64
65 void UpdateAI(uint32 diff) override
66 {
67 Unit* owner = me->GetOwner();
68 if (!owner)
69 {
71 return;
72 }
73
76
77 if (!UpdateImageVictim())
78 return;
79
81 return;
82
84 {
87 }
88 else
90 }
91
92 bool CanAIAttack(Unit const* who) const override
93 {
94 Unit* owner = me->GetOwner();
95 return owner && who->IsAlive() && me->IsValidAttackTarget(who) && !who->HasBreakableByDamageCrowdControlAura() && who->IsInCombatWith(owner) && ScriptedAI::CanAIAttack(who);
96 }
97
98 // Do not reload Creature templates on evade mode enter - prevent visual lost
99 void EnterEvadeMode(EvadeReason /*why*/) override
100 {
101 if (!me->IsAlive())
102 {
104 return;
105 }
106
107 Unit* owner = me->GetCharmerOrOwner();
108
109 me->CombatStop(true);
110 me->SetLootRecipient(nullptr);
113 me->SetCannotReachTarget(false);
117
118 if (owner && !me->HasUnitState(UNIT_STATE_FOLLOW))
119 {
122 }
123 }
124
125private:
126 // custom UpdateVictim implementation to handle special target selection
127 // we prioritize between things that are in combat with owner based on the owner's threat to them
129 {
130 Unit* owner = me->GetOwner();
131 if (!owner)
132 return false;
133
134 if (!me->HasUnitState(UNIT_STATE_CASTING) && !me->IsEngaged() && !owner->IsInCombat())
135 return false;
136
137 Unit* currentTarget = me->GetVictim();
138 if (currentTarget && !CanAIAttack(currentTarget))
139 {
140 me->InterruptNonMeleeSpells(true); // do not finish casting on invalid targets
141 me->AttackStop();
142 currentTarget = nullptr;
143 }
144
145 // don't reselect if we're currently casting anyway
146 if (currentTarget && me->HasUnitState(UNIT_STATE_CASTING))
147 return true;
148
149 Unit* selectedTarget = nullptr;
150 CombatManager const& mgr = owner->GetCombatManager();
151 if (mgr.HasPvPCombat())
152 {
153 // select pvp target
154 float minDistance = 0.f;
155 for (auto const& pair : mgr.GetPvPCombatRefs())
156 {
157 Unit* target = pair.second->GetOther(owner);
158 if (target->GetTypeId() != TYPEID_PLAYER)
159 continue;
160 if (!CanAIAttack(target))
161 continue;
162
163 float dist = owner->GetDistance(target);
164 if (!selectedTarget || dist < minDistance)
165 {
166 selectedTarget = target;
167 minDistance = dist;
168 }
169 }
170 }
171
172 if (!selectedTarget)
173 {
174 // select pve target
175 float maxThreat = 0.f;
176 for (auto const& pair : mgr.GetPvECombatRefs())
177 {
178 Unit* target = pair.second->GetOther(owner);
179 if (!CanAIAttack(target))
180 continue;
181
182 float threat = target->GetThreatManager().GetThreat(owner);
183 if (threat >= maxThreat)
184 {
185 selectedTarget = target;
186 maxThreat = threat;
187 }
188 }
189 }
190
191 if (!selectedTarget)
192 {
194 return false;
195 }
196
197 if (selectedTarget != me->GetVictim())
198 AttackStartCaster(selectedTarget, CHASE_DISTANCE);
199 return true;
200 }
201
203};
204
uint32_t uint32
Definition Define.h:133
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
#define PET_FOLLOW_DIST
Definition PetDefines.h:85
#define RegisterCreatureAI(ai_name)
Definition ScriptMgr.h:1139
@ UNIT_STATE_FOLLOW
Definition Unit.h:229
@ UNIT_STATE_CASTING
Definition Unit.h:235
std::unordered_map< ObjectGuid, PvPCombatReference * > const & GetPvPCombatRefs() const
std::unordered_map< ObjectGuid, CombatReference * > const & GetPvECombatRefs() const
bool HasPvPCombat() const
@ EVADE_REASON_NO_HOSTILES
Definition CreatureAI.h:94
Creature *const me
Definition CreatureAI.h:82
void EngagementOver()
void SetLootRecipient(Unit *unit, bool withGroup=true)
void SetLastDamagedTime(time_t val)
Definition Creature.h:350
void DoNotReacquireSpellFocusTarget()
bool IsEngaged() const override
void ResetPlayerDamageReq()
Definition Creature.h:323
void SetCannotReachTarget(bool cannotReach)
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetTarget(ObjectGuid guid) override
void MoveFollow(Unit *target, float dist, ChaseAngle angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
static ObjectGuid const Empty
Definition ObjectGuid.h:140
TypeID GetTypeId() const
Definition Object.h:93
float GetThreat(Unit const *who, bool includeOffline=false) const
void AttackStartCaster(Unit *victim, float dist)
Definition UnitAI.cpp:48
virtual bool CanAIAttack(Unit const *) const
Definition UnitAI.h:139
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Definition Unit.h:769
ThreatManager & GetThreatManager()
Definition Unit.h:1155
bool HasBreakableByDamageCrowdControlAura(Unit *excludeCasterChannel=nullptr) const
Definition Unit.cpp:693
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool IsAlive() const
Definition Unit.h:1234
bool IsInCombatWith(Unit const *who) const
Definition Unit.h:1145
Unit * GetCharmerOrOwner() const
Definition Unit.h:1265
virtual float GetFollowAngle() const
Definition Unit.h:1782
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:5691
CombatManager & GetCombatManager()
Definition Unit.h:1130
bool AttackStop()
Definition Unit.cpp:5645
bool IsInCombat() const
Definition Unit.h:1144
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2856
Unit * GetOwner() const
Definition Object.cpp:2180
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1123
MirrorImageTimers
Definition pet_mage.cpp:43
@ TIMER_MIRROR_IMAGE_FIRE_BLAST
Definition pet_mage.cpp:44
void AddSC_mage_pet_scripts()
Definition pet_mage.cpp:205
@ SPELL_MAGE_FIRE_BLAST
Definition pet_mage.cpp:39
@ SPELL_MAGE_CLONE_ME
Definition pet_mage.cpp:36
@ SPELL_MAGE_FROST_BOLT
Definition pet_mage.cpp:38
@ SPELL_MAGE_MASTERS_THREAT_LIST
Definition pet_mage.cpp:37
void Update(int32 diff)
Definition Timer.h:121
bool Passed() const
Definition Timer.h:131
void Reset(int32 expiry)
Definition Timer.h:136
npc_pet_mage_mirror_image(Creature *creature)
Definition pet_mage.cpp:51
void InitializeAI() override
Definition pet_mage.cpp:53
void EnterEvadeMode(EvadeReason) override
Definition pet_mage.cpp:99
void UpdateAI(uint32 diff) override
Definition pet_mage.cpp:65
bool CanAIAttack(Unit const *who) const override
Definition pet_mage.cpp:92