TrinityCore
Loading...
Searching...
No Matches
boss_ichoron.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#include "ScriptMgr.h"
19#include "InstanceScript.h"
20#include "MotionMaster.h"
21#include "ScriptedCreature.h"
22#include "SpellAuras.h"
23#include "SpellScript.h"
24#include "violet_hold.h"
25
37
61
68
73
74// 29313 - Ichoron
75// 32234 - Swirling Water Revenant
76struct boss_ichoron : public BossAI
77{
85
87 {
88 _isFrenzy = false;
89 _dehydration = true;
90 }
91
92 void Reset() override
93 {
94 Initialize();
96
98 }
99
100 void JustEngagedWith(Unit* who) override
101 {
104 }
105
111
112 void DoAction(int32 actionId) override
113 {
114 switch (actionId)
115 {
117 if (!me->IsAlive())
118 break;
119
121 _dehydration = false;
122 break;
124 {
127
129 DoCastAOE(SPELL_BURST, true);
130 DoCast(me, SPELL_DRAINED, true);
131
132 uint32 damage = me->CountPctFromMaxHealth(30);
133 me->LowerPlayerDamageReq(damage);
134 me->ModifyHealth(-std::min<int32>(damage, me->GetHealth() - 1));
135
136 scheduler.DelayAll(15s);
137 break;
138 }
139 case ACTION_DRAINED:
140 if (HealthAbovePct(30))
141 {
144 }
145 break;
146 default:
147 break;
148 }
149 }
150
151 uint32 GetData(uint32 type) const override
152 {
153 if (type == DATA_DEHYDRATION)
154 return _dehydration ? 1 : 0;
155 return 0;
156 }
157
158 void KilledUnit(Unit* victim) override
159 {
160 if (victim->GetTypeId() == TYPEID_PLAYER)
161 Talk(SAY_SLAY);
162 }
163
164 void JustDied(Unit* /*killer*/) override
165 {
167 _JustDied();
168 }
169
170 void JustSummoned(Creature* summon) override
171 {
172 summons.Summon(summon);
173
174 if (summon->GetEntry() == NPC_ICHOR_GLOBULE)
176 }
177
185
186 void UpdateAI(uint32 diff) override
187 {
188 if (!UpdateVictim())
189 return;
190
192 {
194 DoCast(me, SPELL_FRENZY, true);
195 _isFrenzy = true;
196 }
197
198 scheduler.Update(diff,
199 std::bind(&BossAI::DoMeleeAttackIfReady, this));
200 }
201
202 void ScheduleTasks() override
203 {
204 scheduler.Async([this]
205 {
208 });
209
210 scheduler.Schedule(10s, 15s, [this](TaskContext task)
211 {
213 task.Repeat(10s, 15s);
214 });
215
216 scheduler.Schedule(6s, 9s, [this](TaskContext task)
217 {
218 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f))
219 DoCast(target, SPELL_WATER_BLAST);
220 task.Repeat(6s, 9s);
221 });
222 }
223
224private:
227};
228
229// 29321 - Ichor Globule
231{
233 {
234 _instance = creature->GetInstanceScript();
235 creature->SetReactState(REACT_PASSIVE);
236 }
237
238 void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
239 {
240 Unit* unitCaster = caster->ToUnit();
241 if (!unitCaster)
242 return;
243
244 if (spellInfo->Id == SPELL_WATER_GLOBULE_VISUAL)
245 {
248 me->GetMotionMaster()->MoveFollow(unitCaster, 0.0f, 0.0f);
249 }
250 }
251
252 void MovementInform(uint32 type, uint32 id) override
253 {
254 if (type != FOLLOW_MOTION_TYPE)
255 return;
256
258 return;
259
261 me->DespawnOrUnsummon(1ms);
262 }
263
264 // on retail spell casted on a creature's death are not casted after death but keeping mob at 1 health, casting it and then letting the mob die.
265 // this feature should be still implemented
266 void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
267 {
269 return;
270
271 if (damage >= me->GetHealth())
272 {
273 _splashTriggered = true;
275 }
276 }
277
278 void UpdateAI(uint32 /*diff*/) override { }
279
280private:
283};
284
285// 59820 - Drained
317
318// 54269 - Merge
320{
322
323 bool Validate(SpellInfo const* /*spellInfo*/) override
324 {
326 }
327
328 void HandleScript(SpellEffIndex /*effIndex*/)
329 {
330 if (Creature* target = GetHitCreature())
331 {
332 if (Aura* aura = target->GetAura(SPELL_SHRINK))
333 aura->ModStackAmount(-1);
334
335 target->AI()->DoAction(ACTION_WATER_GLOBULE_HIT);
336 }
337 }
338
343};
344
345// 54306 - Protective Bubble
347{
349
350 bool Load() override
351 {
353 }
354
355 void HandleShatter(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
356 {
357 //if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL)
358 if (GetAura()->GetCharges() <= 1)
359 if (UnitAI* targetAI = GetTarget()->GetAI())
360 targetAI->DoAction(ACTION_PROTECTIVE_BUBBLE_SHATTERED);
361 }
362
367};
368
369// 54259 - Splatter
406
408{
409 public:
410 achievement_dehydration() : AchievementCriteriaScript("achievement_dehydration") { }
411
412 bool OnCheck(Player* /*player*/, Unit* target) override
413 {
414 if (!target)
415 return false;
416
417 if (Creature* Ichoron = target->ToCreature())
418 if (Ichoron->AI()->GetData(DATA_DEHYDRATION))
419 return true;
420
421 return false;
422 }
423};
424
First const & RAND(First const &first, Second const &second, Rest const &... rest)
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ FOLLOW_MOTION_TYPE
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
SpellEffIndex
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ AURA_REMOVE_BY_EXPIRE
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_MOD_STUN
#define SpellEffectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectRemoveFn(F, I, N, M)
@ UNIT_FLAG2_FEIGN_DEATH
@ REACT_PASSIVE
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_STATE_IGNORE_PATHFINDING
Definition Unit.h:248
DamageEffectType
Definition Unit.h:352
IchoronActions
@ ACTION_WATER_GLOBULE_HIT
@ ACTION_PROTECTIVE_BUBBLE_SHATTERED
@ ACTION_DRAINED
IchoronMisc
@ DATA_DEHYDRATION
void AddSC_boss_ichoron()
IchoronTexts
@ SAY_DEATH
@ SAY_AGGRO
@ SAY_BUBBLE
@ SAY_SLAY
@ SAY_SPAWN
@ SAY_SHATTER
@ SAY_ENRAGE
@ EMOTE_SHATTER
IchoronSpells
@ SPELL_SHRINK
@ SPELL_SPLATTER
@ SPELL_WATER_GLOBULE_SUMMON_3
@ SPELL_THREAT_PROC
@ SPELL_WATER_GLOBULE_SUMMON_4
@ SPELL_MERGE
@ SPELL_WATER_GLOBULE_SUMMON_2
@ SPELL_WATER_GLOBULE_SUMMON_1
@ SPELL_WATER_BOLT_VOLLEY
@ SPELL_WATER_GLOBULE_SUMMON_5
@ SPELL_WATER_GLOBULE_VISUAL
@ SPELL_WATER_GLOBULE_TRANSFORM
@ SPELL_FRENZY
@ SPELL_WATER_BLAST
@ SPELL_SPLASH
@ SPELL_PROTECTIVE_BUBBLE
@ SPELL_BURST
@ SPELL_DRAINED
void PreventDefaultAction()
AuraApplication const * GetTargetApplication() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< EffectPeriodicHandler > OnEffectPeriodic
WorldObject * GetOwner() const
HookList< EffectApplyHandler > AfterEffectApply
Aura * GetAura() const
Unit * GetTarget() const
uint8 GetCharges() const
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
TaskScheduler scheduler
void JustReachedHome() override
SummonList summons
void SummonedCreatureDespawn(Creature *summon) override
void Reset() override
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void LowerPlayerDamageReq(uint32 unDamage)
ObjectGuid GetObjectGuid(uint32 type) const
void MoveFollow(Unit *target, float dist, ChaseAngle angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
LowType GetCounter() const
Definition ObjectGuid.h:156
static ObjectGuid const Empty
Definition ObjectGuid.h:140
static Creature * ToCreature(Object *o)
Definition Object.h:186
static Unit * ToUnit(Object *o)
Definition Object.h:192
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
uint32 Id
Definition SpellInfo.h:289
Creature * GetHitCreature() const
HookList< EffectHandler > OnEffectHitTarget
bool empty() const
void Summon(Creature const *summon)
TaskContext & Repeat(std::chrono::duration< _Rep, _Period > const &duration)
TaskScheduler & DelayAll(std::chrono::duration< _Rep, _Period > const &duration)
Delays all tasks with the given duration.
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler & Async(std::function< void()> const &callable)
TaskScheduler & Update(success_t const &callback=EmptyCallback)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:243
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
int32 ModifyHealth(int32 val)
Definition Unit.cpp:8381
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
void SetUnitFlag2(UnitFlags2 flags)
Definition Unit.h:960
bool IsAlive() const
Definition Unit.h:1234
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
void AddUnitState(uint32 f)
Definition Unit.h:875
uint32 GetHealth() const
Definition Unit.h:913
void RemoveUnitFlag2(UnitFlags2 flags)
Definition Unit.h:961
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:922
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:954
void RemoveUnitFlag(UnitFlags flags)
Definition Unit.h:955
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:56
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
bool OnCheck(Player *, Unit *target) override
void HandleRemove(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_ichoron_drained)
void Register() override
void HandleApply(AuraEffect const *, AuraEffectHandleModes)
PrepareSpellScript(spell_ichoron_merge)
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
void Register() override
void HandleShatter(AuraEffect const *, AuraEffectHandleModes)
PrepareAuraScript(spell_ichoron_protective_bubble)
void PeriodicTick(AuraEffect const *)
PrepareAuraScript(spell_ichoron_splatter)
void Register() override
bool Validate(SpellInfo const *) override
void HandleRemove(AuraEffect const *, AuraEffectHandleModes)
bool HealthAbovePct(uint32 pct) const
bool HealthBelowPct(uint32 pct) const
void JustSummoned(Creature *summon) override
void KilledUnit(Unit *victim) override
void SummonedCreatureDespawn(Creature *summon) override
void DoAction(int32 actionId) override
uint32 GetData(uint32 type) const override
boss_ichoron(Creature *creature)
void UpdateAI(uint32 diff) override
void Reset() override
void JustReachedHome() override
void JustEngagedWith(Unit *who) override
void ScheduleTasks() override
void JustDied(Unit *) override
void MovementInform(uint32 type, uint32 id) override
InstanceScript * _instance
void DamageTaken(Unit *, uint32 &damage, DamageEffectType, SpellInfo const *) override
npc_ichor_globule(Creature *creature)
void UpdateAI(uint32) override
void SpellHit(WorldObject *caster, SpellInfo const *spellInfo) override
@ DATA_ICHORON
Definition violet_hold.h:55
@ DATA_HANDLE_CELLS
Definition violet_hold.h:86
#define RegisterVioletHoldCreatureAI(ai_name)
@ NPC_DUMMY_ICHORON
@ NPC_ICHOR_GLOBULE
Definition violet_hold.h:99
@ NPC_ICHORON
Definition violet_hold.h:98