Core/Scripts: boss The Curator (Karazhan) rework (#19040)

Closes #16099
This commit is contained in:
Gustavo
2017-02-05 18:52:14 -02:00
committed by Aokromes
parent 7e8baf939a
commit bf87734b2e
3 changed files with 158 additions and 152 deletions

View File

@@ -0,0 +1,20 @@
UPDATE `creature` SET `position_x`=-11187.9, `position_y`=-1883.373, `position_z`=156.0449, `orientation`=5.375582, `spawndist`=0 WHERE `guid`=135489;
UPDATE `creature_template` SET `unit_flags`=33554432, `flags_extra`=256, `ScriptName`='npc_curator_astral_flare' WHERE `entry` IN (17096,19781,19782,19783);
DELETE FROM `creature_template_addon` WHERE `entry` IN (17096,19781,19782,19783);
INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES
(19781,0,0,0,1,0,30234),
(19782,0,0,0,1,0,30234),
(19783,0,0,0,1,0,30234),
(17096,0,0,0,1,0,30234);
DELETE FROM `waypoint_data` WHERE `id`=1354890;
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(1354890, 1, -11172.98, -1902.532, 165.7656, 0, 0, 0, 0, 100, 0),
(1354890, 2, -11160.56, -1901.736, 165.7654, 0, 0, 0, 0, 100, 0),
(1354890, 3, -11104.56, -1856.968, 165.7654, 0, 0, 0, 0, 100, 0),
(1354890, 4, -11114.04, -1864.641, 165.7654, 0, 0, 0, 0, 100, 0),
(1354890, 5, -11166.35, -1906.356, 165.7654, 0, 0, 0, 0, 100, 0),
(1354890, 6, -11170.42, -1906.521, 165.7654, 0, 0, 0, 0, 100, 0),
(1354890, 7, -11180.58, -1892.599, 160.9129, 0, 0, 0, 0, 100, 0),
(1354890, 8, -11194.23, -1875.336, 153.5438, 0, 0, 0, 0, 100, 0);

View File

@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
* Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -16,197 +15,177 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Curator
SD%Complete: 100
SDComment:
SDCategory: Karazhan
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
enum Curator
enum CuratorSays
{
SAY_AGGRO = 0,
SAY_SUMMON = 1,
SAY_EVOCATE = 2,
SAY_ENRAGE = 3,
SAY_KILL = 4,
SAY_DEATH = 5,
//Flare spell info
SPELL_ASTRAL_FLARE_PASSIVE = 30234, //Visual effect + Flare damage
//Curator spell info
SPELL_HATEFUL_BOLT = 30383,
SPELL_EVOCATION = 30254,
SPELL_ENRAGE = 30403, //Arcane Infusion: Transforms Curator and adds damage.
SPELL_BERSERK = 26662,
SAY_AGGRO = 0,
SAY_SUMMON = 1,
SAY_EVOCATE = 2,
SAY_ENRAGE = 3,
SAY_KILL = 4,
SAY_DEATH = 5
};
enum CuratorSpells
{
SPELL_HATEFUL_BOLT = 30383,
SPELL_EVOCATION = 30254,
SPELL_ARCANE_INFUSION = 30403,
SPELL_BERSERK = 26662,
SPELL_SUMMON_ASTRAL_FLARE_NE = 30236,
SPELL_SUMMON_ASTRAL_FLARE_NW = 30239,
SPELL_SUMMON_ASTRAL_FLARE_SE = 30240,
SPELL_SUMMON_ASTRAL_FLARE_SW = 30241
};
enum CuratorEvents
{
EVENT_HATEFUL_BOLT = 1,
EVENT_SUMMON_ASTRAL_FLARE,
EVENT_ARCANE_INFUSION,
EVENT_BERSERK
};
class boss_curator : public CreatureScript
{
public:
boss_curator() : CreatureScript("boss_curator") { }
CreatureAI* GetAI(Creature* creature) const override
struct boss_curatorAI : public BossAI
{
return new boss_curatorAI(creature);
}
struct boss_curatorAI : public ScriptedAI
{
boss_curatorAI(Creature* creature) : ScriptedAI(creature)
{
Initialize();
}
void Initialize()
{
AddTimer = 10000;
HatefulBoltTimer = 15000; //This time may be wrong
BerserkTimer = 720000; //12 minutes
Enraged = false;
Evocating = false;
}
uint32 AddTimer;
uint32 HatefulBoltTimer;
uint32 BerserkTimer;
bool Enraged;
bool Evocating;
boss_curatorAI(Creature* creature) : BossAI(creature, DATA_CURATOR), _infused(false) { }
void Reset() override
{
Initialize();
_Reset();
_infused = false;
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, true);
}
void KilledUnit(Unit* /*victim*/) override
void KilledUnit(Unit* victim) override
{
Talk(SAY_KILL);
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_KILL);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_HATEFUL_BOLT, Seconds(12));
events.ScheduleEvent(EVENT_SUMMON_ASTRAL_FLARE, Seconds(10));
events.ScheduleEvent(EVENT_BERSERK, Minutes(12));
}
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
{
if (!HealthAbovePct(15) && !_infused)
{
_infused = true;
events.ScheduleEvent(EVENT_ARCANE_INFUSION, Milliseconds(1));
events.CancelEvent(EVENT_SUMMON_ASTRAL_FLARE);
}
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case EVENT_HATEFUL_BOLT:
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
DoCast(target, SPELL_HATEFUL_BOLT);
events.Repeat(Seconds(7), Seconds(15));
break;
case EVENT_ARCANE_INFUSION:
DoCastSelf(SPELL_ARCANE_INFUSION, true);
break;
case EVENT_SUMMON_ASTRAL_FLARE:
if (roll_chance_i(50))
Talk(SAY_SUMMON);
DoCastSelf(RAND(SPELL_SUMMON_ASTRAL_FLARE_NE, SPELL_SUMMON_ASTRAL_FLARE_NW, SPELL_SUMMON_ASTRAL_FLARE_SE, SPELL_SUMMON_ASTRAL_FLARE_SW), true);
if (int32 mana = int32(me->GetMaxPower(POWER_MANA) / 10))
{
me->ModifyPower(POWER_MANA, -mana);
if (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA) < 10)
{
Talk(SAY_EVOCATE);
me->InterruptNonMeleeSpells(false);
DoCastSelf(SPELL_EVOCATION);
}
}
events.Repeat(Seconds(10));
break;
case EVENT_BERSERK:
Talk(SAY_ENRAGE);
DoCastSelf(SPELL_BERSERK, true);
break;
default:
break;
}
}
private:
bool _infused;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetKarazhanAI<boss_curatorAI>(creature);
}
};
class npc_curator_astral_flare : public CreatureScript
{
public:
npc_curator_astral_flare() : CreatureScript("npc_curator_astral_flare") { }
struct npc_curator_astral_flareAI : public ScriptedAI
{
npc_curator_astral_flareAI(Creature* creature) : ScriptedAI(creature)
{
me->SetReactState(REACT_PASSIVE);
}
void Reset() override
{
_scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/)
{
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoZoneInCombat();
});
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
//always decrease BerserkTimer
if (BerserkTimer <= diff)
{
//if evocate, then break evocate
if (Evocating)
{
if (me->HasAura(SPELL_EVOCATION))
me->RemoveAurasDueToSpell(SPELL_EVOCATION);
Evocating = false;
}
//may not be correct SAY (generic hard enrage)
Talk(SAY_ENRAGE);
me->InterruptNonMeleeSpells(true);
DoCast(me, SPELL_BERSERK);
//don't know if he's supposed to do summon/evocate after hard enrage (probably not)
Enraged = true;
} else BerserkTimer -= diff;
if (Evocating)
{
//not supposed to do anything while evocate
if (me->HasAura(SPELL_EVOCATION))
return;
else
Evocating = false;
}
if (!Enraged)
{
if (AddTimer <= diff)
{
//Summon Astral Flare
Creature* AstralFlare = DoSpawnCreature(17096, float(rand32() % 37), float(rand32() % 37), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
Unit* target = NULL;
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
if (AstralFlare && target)
{
AstralFlare->CastSpell(AstralFlare, SPELL_ASTRAL_FLARE_PASSIVE, false);
AstralFlare->AI()->AttackStart(target);
}
//Reduce Mana by 10% of max health
if (int32 mana = me->GetMaxPower(POWER_MANA))
{
mana /= 10;
me->ModifyPower(POWER_MANA, -mana);
//if this get's us below 10%, then we evocate (the 10th should be summoned now)
if (me->GetPower(POWER_MANA)*100 / me->GetMaxPower(POWER_MANA) < 10)
{
Talk(SAY_EVOCATE);
me->InterruptNonMeleeSpells(false);
DoCast(me, SPELL_EVOCATION);
Evocating = true;
//no AddTimer cooldown, this will make first flare appear instantly after evocate end, like expected
return;
}
else
{
if (urand(0, 1) == 0)
{
Talk(SAY_SUMMON);
}
}
}
AddTimer = 10000;
} else AddTimer -= diff;
if (!HealthAbovePct(15))
{
Enraged = true;
DoCast(me, SPELL_ENRAGE);
Talk(SAY_ENRAGE);
}
}
if (HatefulBoltTimer <= diff)
{
if (Enraged)
HatefulBoltTimer = 7000;
else
HatefulBoltTimer = 15000;
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
DoCast(target, SPELL_HATEFUL_BOLT);
} else HatefulBoltTimer -= diff;
DoMeleeAttackIfReady();
_scheduler.Update(diff);
}
private:
TaskScheduler _scheduler;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetKarazhanAI<npc_curator_astral_flareAI>(creature);
}
};
void AddSC_boss_curator()
{
new boss_curator();
new npc_curator_astral_flare();
}

View File

@@ -19,6 +19,7 @@
#ifndef DEF_KARAZHAN_H
#define DEF_KARAZHAN_H
#define KZScriptName "instance_karazhan"
#define DataHeader "KZ"
uint32 const EncounterCount = 12;
@@ -110,4 +111,10 @@ enum KZMisc
OPTIONAL_BOSS_REQUIRED_DEATH_COUNT = 50
};
template<class AI, class T>
inline AI* GetKarazhanAI(T* obj)
{
return GetInstanceAI<AI>(obj, KZScriptName);
}
#endif