Scripts/Naxxramas: Instructor Razuvious rework:

- Fix missing yells
- Rearrange existing yells to match live
- Sniffed positions for adds
- Improve add respawn handling
- Make adds not fight the player for control (don't use their spells on their own etc.)
- Update adds' hotbar keys to match live (this will affect other creatures with nonsequential possess keys as well)
- Fix adds' movement when mind controlled, they no longer move automatically when right-clicking (this affects all mind-controlled creatures)
- Blizzlike timers
This commit is contained in:
treeston
2015-11-29 17:19:51 +01:00
parent b3e718dcca
commit 54d583b0fb
5 changed files with 190 additions and 49 deletions

View File

@@ -17,43 +17,40 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellInfo.h"
#include "naxxramas.h"
//Razuvious - NO TEXT sound only
//8852 aggro01 - Hah hah, I'm just getting warmed up!
//8853 aggro02 Stand and fight!
//8854 aggro03 Show me what you've got!
//8861 slay1 - You should've stayed home!
//8863 slay2-
//8858 cmmnd3 - You disappoint me, students!
//8855 cmmnd1 - Do as I taught you!
//8856 cmmnd2 - Show them no mercy!
//8859 cmmnd4 - The time for practice is over! Show me what you've learned!
//8861 Sweep the leg! Do you have a problem with that?
//8860 death - An honorable... death...
//8947 - Aggro Mixed? - ?
#define SOUND_AGGRO RAND(8852, 8853, 8854)
#define SOUND_SLAY RAND(8861, 8863)
#define SOUND_COMMND RAND(8855, 8856, 8858, 8859, 8861)
#define SOUND_DEATH 8860
#define SOUND_AGGROMIX 8847
enum Yells
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_TAUNTED = 2,
SAY_DEATH = 3
};
enum Spells
{
SPELL_UNBALANCING_STRIKE = 26613,
SPELL_DISRUPTING_SHOUT = 29107,
SPELL_JAGGED_KNIFE = 55550,
SPELL_HOPELESS = 29125
SPELL_UNBALANCING_STRIKE = 26613,
SPELL_DISRUPTING_SHOUT = 29107,
SPELL_JAGGED_KNIFE = 55550,
SPELL_HOPELESS = 29125,
SPELL_UNDERSTUDY_TAUNT = 29060,
SPELL_UNDERSTUDY_BLOOD_STRIKE = 61696,
SPELL_FORCE_OBEDIENCE = 55479
};
enum Events
{
EVENT_NONE,
EVENT_ATTACK = 1,
EVENT_STRIKE,
EVENT_SHOUT,
EVENT_KNIFE,
EVENT_COMMAND,
EVENT_KNIFE
};
enum SummonGroups
{
SUMMON_GROUP_10MAN = 1,
SUMMON_GROUP_25MAN = 2
};
class boss_razuvious : public CreatureScript
@@ -70,36 +67,60 @@ public:
{
boss_razuviousAI(Creature* creature) : BossAI(creature, BOSS_RAZUVIOUS) { }
void KilledUnit(Unit* /*victim*/) override
void SummonAdds()
{
if (!(rand32() % 3))
DoPlaySoundToSet(me, SOUND_SLAY);
me->SummonCreatureGroup(SUMMON_GROUP_10MAN);
if (Is25ManRaid())
me->SummonCreatureGroup(SUMMON_GROUP_25MAN);
}
void DamageTaken(Unit* pDone_by, uint32& uiDamage) override
void InitializeAI() override
{
// Damage done by the controlled Death Knight understudies should also count toward damage done by players
if (pDone_by->GetTypeId() == TYPEID_UNIT && (pDone_by->GetEntry() == 16803 || pDone_by->GetEntry() == 29941))
if (!me->isDead())
{
me->LowerPlayerDamageReq(uiDamage);
Reset();
SummonAdds();
}
}
void JustReachedHome() override
{
_JustReachedHome();
SummonAdds();
me->GetMotionMaster()->Initialize();
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER || (victim->GetTypeId() == TYPEID_UNIT && victim->GetEntry() == NPC_DK_UNDERSTUDY))
Talk(SAY_SLAY);
}
void SpellHit(Unit* caster, SpellInfo const* spell) override
{
if (spell->Id == SPELL_UNDERSTUDY_TAUNT)
Talk(SAY_TAUNTED, caster);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
DoPlaySoundToSet(me, SOUND_DEATH);
me->CastSpell(me, SPELL_HOPELESS, true); /// @todo this may affect other creatures
Talk(SAY_DEATH);
DoCastAOE(SPELL_HOPELESS, true);
events.Reset();
instance->SetBossState(BOSS_RAZUVIOUS, DONE);
}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
DoPlaySoundToSet(me, SOUND_AGGRO);
events.ScheduleEvent(EVENT_STRIKE, 30000);
events.ScheduleEvent(EVENT_SHOUT, 25000);
events.ScheduleEvent(EVENT_COMMAND, 40000);
events.ScheduleEvent(EVENT_KNIFE, 10000);
me->StopMoving();
summons.DoZoneInCombat();
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_ATTACK, 7 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_STRIKE, 21 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SHOUT, 16 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_KNIFE, 10 * IN_MILLISECONDS);
}
void UpdateAI(uint32 diff) override
@@ -113,33 +134,112 @@ public:
{
switch (eventId)
{
case EVENT_ATTACK:
SetCombatMovement(true);
if (Unit* victim = me->GetVictim())
me->GetMotionMaster()->MoveChase(victim);
break;
case EVENT_STRIKE:
DoCastVictim(SPELL_UNBALANCING_STRIKE);
events.ScheduleEvent(EVENT_STRIKE, 30000);
events.ScheduleEvent(EVENT_STRIKE, 6 * IN_MILLISECONDS);
return;
case EVENT_SHOUT:
DoCastAOE(SPELL_DISRUPTING_SHOUT);
events.ScheduleEvent(EVENT_SHOUT, 25000);
events.ScheduleEvent(EVENT_SHOUT, 16 * IN_MILLISECONDS);
return;
case EVENT_KNIFE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f))
DoCast(target, SPELL_JAGGED_KNIFE);
events.ScheduleEvent(EVENT_KNIFE, 10000);
return;
case EVENT_COMMAND:
DoPlaySoundToSet(me, SOUND_COMMND);
events.ScheduleEvent(EVENT_COMMAND, 40000);
events.ScheduleEvent(EVENT_KNIFE, urandms(10,15));
return;
}
}
DoMeleeAttackIfReady();
}
void Reset() override
{
SetCombatMovement(false);
_Reset();
}
};
};
class npc_dk_understudy : public CreatureScript
{
public:
npc_dk_understudy() : CreatureScript("npc_dk_understudy") { }
struct npc_dk_understudyAI : public ScriptedAI
{
npc_dk_understudyAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), bloodStrikeTimer(0) { }
void EnterCombat(Unit* /*who*/) override
{
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
if (Creature* razuvious = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_RAZUVIOUS)))
razuvious->AI()->DoZoneInCombat(nullptr, 250.0f);
}
void JustReachedHome() override
{
if (_instance->GetBossState(BOSS_RAZUVIOUS) == DONE)
me->DespawnOrUnsummon();
else
ScriptedAI::JustReachedHome();
}
void UpdateAI(uint32 diff) override
{
if (!me->isPossessedByPlayer() && !UpdateVictim())
return;
if (!me->isPossessedByPlayer())
{
if (diff < bloodStrikeTimer)
bloodStrikeTimer -= diff;
else
DoCastVictim(SPELL_UNDERSTUDY_BLOOD_STRIKE);
}
DoMeleeAttackIfReady();
}
void OnCharmed(bool apply) override
{
ScriptedAI::OnCharmed(apply);
if (apply)
{
if (!me->IsInCombat())
EnterCombat(nullptr);
me->StopMoving();
me->SetReactState(REACT_PASSIVE);
_charmer = me->GetCharmerGUID();
}
else
{
me->SetReactState(REACT_AGGRESSIVE);
if (Unit* charmer = ObjectAccessor::GetUnit(*me, _charmer))
me->AddThreat(charmer, 100000.0f);
DoZoneInCombat(nullptr, 250.0f);
}
}
private:
InstanceScript* const _instance;
ObjectGuid _charmer;
uint32 bloodStrikeTimer;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<npc_dk_understudyAI>(creature);
}
};
void AddSC_boss_razuvious()
{
new boss_razuvious();
new npc_dk_understudy();
}

View File

@@ -60,7 +60,6 @@ DoorData const doorData[] =
MinionData const minionData[] =
{
{ NPC_DK_UNDERSTUDY, BOSS_RAZUVIOUS },
{ NPC_SIR, BOSS_HORSEMEN },
{ NPC_THANE, BOSS_HORSEMEN },
{ NPC_LADY, BOSS_HORSEMEN },
@@ -143,6 +142,9 @@ class instance_naxxramas : public InstanceMapScript
case NPC_FAERLINA:
FaerlinaGUID = creature->GetGUID();
break;
case NPC_RAZUVIOUS:
RazuviousGUID = creature->GetGUID();
break;
case NPC_THANE:
ThaneGUID = creature->GetGUID();
break;
@@ -378,6 +380,8 @@ class instance_naxxramas : public InstanceMapScript
return AnubRekhanGUID;
case DATA_FAERLINA:
return FaerlinaGUID;
case DATA_RAZUVIOUS:
return RazuviousGUID;
case DATA_THANE:
return ThaneGUID;
case DATA_LADY:
@@ -652,6 +656,8 @@ class instance_naxxramas : public InstanceMapScript
ObjectGuid HeiganGUID;
/* The Military Quarter */
// Instructor Razuvious
ObjectGuid RazuviousGUID;
// Gothik the Harvester
ObjectGuid GothikGateGUID;
// The Four Horsemen

View File

@@ -66,6 +66,7 @@ enum Data64
{
DATA_ANUBREKHAN,
DATA_FAERLINA,
DATA_RAZUVIOUS,
DATA_THANE,
DATA_LADY,
DATA_BARON,
@@ -87,6 +88,7 @@ enum CreaturesIds
{
NPC_ANUBREKHAN = 15956,
NPC_FAERLINA = 15953,
NPC_RAZUVIOUS = 16061,
NPC_THANE = 16064,
NPC_LADY = 16065,
NPC_BARON = 30549,