TrinityCore
Loading...
Searching...
No Matches
boss_magus_telestra.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 Achievement implementation requires additional research.
20 Telestra's clones are unkillable and only executes set of actions when damaged to full health. Those actions includes cast of
21 'Telestra Clone Dies' aura which lands on boss(3 auras for 3 clones). Comments claims 'frost' clone can fail achievement due to
22 her Blizzard spell. Thing is action sets on retail cannot be started when creature casts spell(general mechanic or supported by flag or by
23 special action-check which can be used directly in action set as first action, preventing execution of next events until current cast is
24 finished. You can notice that everywhere - bosses don't enter in another phase while casting spells, for example).
25
26 But while actions clones executes surely has something related to achievement, Telestra Clone Dies auras probably aren't. The problem is those
27 auras are missiles and it may take seconds to hit boss, leaving a small chance to complete achievement. Speed of missiles is just 5 and unique
28 missile motion makes it slower. On top of that when clone dies, it can be not close enough to the boss.
29
30 That achievement is more trickier, some people claim it can be enough to kill clones only once, or it requires to kill clones twice. Or that
31 it is possible to get achievement even if she didn't summoned clones.
32 At least we can be sure auras are scripted to inform AI that all 3 clones are dead because once 3 auras are applied on boss, she casts a spell
33 which we can use later in SpellHit hook to perform merge sequence.
34
35 Currently we force clones to use SetData (in DB) to inform boss that clone is dead. And auras are used only to inform boss that
36 all clones are dead.
37 World Trigger spawned in front of boss may be related to something.
38 */
39
40#include "GameEventMgr.h"
41#include "GameTime.h"
42#include "ScriptedCreature.h"
43#include "ScriptMgr.h"
44#include "SpellInfo.h"
45#include "SpellScript.h"
46#include "nexus.h"
47
56
78
92
100
102{
104 _split1(false), _split2(false), _unkillable(false), _splitted(false)
105 {
106 Initialize();
107 }
108
110 {
111 for (uint8 n = 0; n < 3; ++n)
112 time[n] = 0;
113
115 }
116
117 void Reset() override
118 {
119 _Reset();
120 _split1 = false;
121 _split2 = false;
122 _unkillable = false;
123 _splitted = false;
124 Initialize();
125
128
131 }
132
133 void JustEngagedWith(Unit* who) override
134 {
137
141 }
142
143 void AttackStart(Unit* who) override
144 {
146 }
147
148 void KilledUnit(Unit* who) override
149 {
150 if (who->GetTypeId() == TYPEID_PLAYER)
151 Talk(SAY_KILL);
152 }
153
154 void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
155 {
156 if (damage >= me->GetHealth() && _unkillable)
157 damage = me->GetHealth() - 1;
158
159 // Boss can receive damage while being already splitted, prevent performing second split if already splitted
160 if (_splitted)
161 return;
162
163 // Once in normal
164 if (!_split1 && me->HealthBelowPctDamaged(50, damage) && !IsHeroic())
165 {
166 _split1 = true;
168 }
169
170 // Twice in heroic
171 if (!_split1 && me->HealthBelowPctDamaged(65, damage) && IsHeroic())
172 {
173 _split1 = true;
175 }
176
177 if (!_split2 && me->HealthBelowPctDamaged(35, damage) && IsHeroic())
178 {
179 _split2 = true;
181 }
182 }
183
184 void OnSpellCast(SpellInfo const* spell) override
185 {
186 if (spell->Id == SPELL_SUMMON_CLONES)
188 }
189
190 void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
191 {
192 if (spellInfo->Id == SPELL_TRIGGER_000)
194 }
195
196 void JustDied(Unit* /*killer*/) override
197 {
198 _JustDied();
200 }
201
202 void SetData(uint32 type, uint32 data) override
203 {
204 if (type == 0 && data == 1)
206 }
207
208 void DoAction(int32 action) override
209 {
210 if (action == ACTION_MAGUS_DEAD)
211 {
212 uint8 i = 0;
213 while (time[i] != 0)
214 ++i;
215
217 if (i == 2)
218 {
219 if ((time[2] - time[1] < 5) && (time[1] - time[0] < 5))
221
222 // Reset time
223 for (uint8 n = 0; n < 3; ++n)
224 time[n] = 0;
225 }
226 }
227 }
228
229 uint32 GetData(uint32 type) const override
230 {
231 if (type == DATA_SPLIT_PERSONALITY)
232 return splitPersonality;
233
234 return 0;
235 }
236
237 void UpdateAI(uint32 diff) override
238 {
239 if (!UpdateVictim())
240 return;
241
242 events.Update(diff);
243
245 return;
246
247 while (uint32 eventId = events.ExecuteEvent())
248 {
249 switch (eventId)
250 {
251 // Combat spells
252 case EVENT_ICE_NOVA:
254 events.Repeat(20s, 25s);
255 break;
256 case EVENT_FIREBOMB:
258 events.Repeat(1600ms, 2400ms);
259 break;
262 events.Repeat(20s, 25s);
263 break;
264
265 // Split sequence, continues in OnSpellCast
266 case EVENT_SPLIT:
267 _splitted = true;
268 // Cancel combat spells
269 events.Reset();
273 break;
274 case EVENT_SPLIT_2:
275 _unkillable = true;
276 // Hack, transform creature (from aura) has visible and invisible models and probability is NYI
277 me->SetDisplayId(15435);
279 // Not restored later, maybe after wipe
282 break;
283 case EVENT_SPLIT_3:
285 break;
286
287 // Merge sequence
288 case EVENT_MERGE:
296 _unkillable = false;
298 break;
299 case EVENT_MERGE_2:
304 _splitted = false;
305 break;
306 default:
307 break;
308 }
309
311 return;
312 }
313
315 }
316
317private:
322 time_t time[3];
324};
325
326// 47710 - Summon Telestra Clones
354
355// 47711 - Telestra Clone Dies (Fire)
356// 47712 - Telestra Clone Dies (Frost)
357// 47713 - Telestra Clone Dies (Arcane)
379
381{
382 public:
383 achievement_split_personality() : AchievementCriteriaScript("achievement_split_personality")
384 {
385 }
386
387 bool OnCheck(Player* /*player*/, Unit* target) override
388 {
389 if (!target)
390 return false;
391
392 if (Creature* Telestra = target->ToCreature())
393 if (Telestra->AI()->GetData(DATA_SPLIT_PERSONALITY) == 2)
394 return true;
395
396 return false;
397 }
398};
399
@ EQUIP_UNEQUIP
Definition CreatureAI.h:76
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
#define sGameEventMgr
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
Spells
Definition PlayerAI.cpp:32
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
SpellEffIndex
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_DUMMY
#define SpellEffectFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
@ DATA_SPLIT_PERSONALITY
@ GAME_EVENT_WINTER_VEIL
@ ACTION_MAGUS_DEAD
@ SPELL_SUMMON_CLONE_FROST
@ SPELL_CLONE_DIES_FIRE
@ SPELL_CLONE_DIES_FROST
@ SPELL_TELEPORT
@ SPELL_SUMMON_CLONE_FIRE
@ SPELL_CLONE_DIES_ARCANE
@ SPELL_ICE_NOVA
@ SPELL_FIREBOMB
@ SPELL_SUMMON_CLONES
@ SPELL_TRIGGER_000
@ SPELL_SUMMON_CLONE_ARCANE
@ SPELL_GRAVITY_WELL
@ SPELL_WEAR_CHRISTMAS_HAT
@ SPELL_SPAWN_BACK_IN
void AddSC_boss_magus_telestra()
@ EVENT_MERGE_2
@ EVENT_SPLIT_2
@ EVENT_GRAVITY_WELL
@ EVENT_FIREBOMB
@ EVENT_ICE_NOVA
@ EVENT_SPLIT_3
HookList< EffectApplyHandler > AfterEffectApply
Unit * GetTarget() const
void JustEngagedWith(Unit *who) override
EventMap events
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void SetDisplayId(uint32 modelId) override
void SetReactState(ReactStates st)
Definition Creature.h:119
void Update(uint32 time)
Definition EventMap.h:67
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
EventId ExecuteEvent()
Definition EventMap.cpp:73
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
static Creature * ToCreature(Object *o)
Definition Object.h:186
TypeID GetTypeId() const
Definition Object.h:93
uint32 Id
Definition SpellInfo.h:289
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHit
void AttackStartCaster(Unit *victim, float dist)
Definition UnitAI.cpp:48
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Definition Unit.h:769
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:11964
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
uint32 GetHealth() const
Definition Unit.h:913
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
bool HealthBelowPctDamaged(int32 pct, uint32 damage) const
Definition Unit.h:918
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
bool OnCheck(Player *, Unit *target) override
bool Validate(SpellInfo const *) override
void AfterApply(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_magus_telestra_clone_dies)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_magus_telestra_summon_clones)
time_t GetGameTime()
Definition GameTime.cpp:42
@ DATA_MAGUS_TELESTRA
Definition nexus.h:31
#define RegisterNexusCreatureAI(ai_name)
Definition nexus.h:74
bool IsHeroic() const
void SetEquipmentSlots(bool loadDefault, int32 mainHand=EQUIP_NO_CHANGE, int32 offHand=EQUIP_NO_CHANGE, int32 ranged=EQUIP_NO_CHANGE)
uint32 GetData(uint32 type) const override
void OnSpellCast(SpellInfo const *spell) override
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
void DoAction(int32 action) override
void SpellHit(WorldObject *, SpellInfo const *spellInfo) override
void SetData(uint32 type, uint32 data) override
void JustEngagedWith(Unit *who) override
void AttackStart(Unit *who) override
void JustDied(Unit *) override
boss_magus_telestra(Creature *creature)
void UpdateAI(uint32 diff) override
void KilledUnit(Unit *who) override