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

@@ -0,0 +1,32 @@
-- instructor razuvious cleanup
DELETE FROM `creature_text` WHERE `entry`=16061;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`probability`,`sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
(16061,0,0,"Do as I taught you!",14,100,8855,13075,3,"Razuvious SAY_AGGRO #1"),
(16061,0,1,"The time for practice is over! Show me what you have learned!",14,100,8859,13078,3,"Razuvious SAY_AGGRO #2"),
(16061,0,2,"Show them no mercy!",14,100,8856,13076,3,"Razuvious SAY_AGGRO #3"),
(16061,1,0,"%s lets loose a triumphant shout.",41,30,0,13082,3,"Razuvious SAY_SLAY"),
(16061,2,0,"You should have stayed home.",14,50,8861,13081,3,"Razuvious SAY_TAUNTED #1"),
(16061,2,1,"You disappoint me, students!",14,50,8858,13077,3,"Razuvious SAY_TAUNTED #2"),
(16061,2,2,"I'm just getting warmed up!",14,50,8852,13072,3,"Razuvious SAY_TAUNTED #3"),
(16061,2,3,"Stand and fight!",14,50,8853,13073,3,"Razuvious SAY_TAUNTED #4"),
(16061,2,4,"Sweep the leg... Do you have a problem with that?",14,50,8861,13080,3,"Razuvious SAY_TAUNTED #5"),
(16061,3,0,"An honorable... death.",14,100,8860,13079,3,"Razuvious SAY_DEATH");
-- move understudies to summon groups for proper reset behavior
DELETE FROM `creature` WHERE `guid` IN (128184,128185);
DELETE FROM `linked_respawn` WHERE `guid` IN (128184,128185);
DELETE FROM `creature_summon_groups` WHERE `summonerId`=16061 AND `summonerType`=0;
INSERT INTO `creature_summon_groups` (`summonerId`,`summonerType`,`groupId`,`entry`,`position_x`,`position_y`,`position_z`,`orientation`,`summonType`) VALUES
(16061,0,1,16803,2757.476,-3111.519,267.7678,3.926991,8),
(16061,0,1,16803,2762.049,-3084.467,267.7678,2.129302,8),
(16061,0,2,16803,2778.911,-3114.142,267.7678,5.288348,8),
(16061,0,2,16803,2781.866,-3088.187,267.7678,0.9075712,8);
-- "Hopeless" debuff on death may only target understudies
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=29125;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`NegativeCondition`,`Comment`) VALUES
(13,1,29125,31,0,3,16803,0,"Instructor Razuvious - Hopeless debuff - only target Death Knight Understudy");
-- transition understudies to scripted AI to prevent them overriding player control
UPDATE `creature_template` SET `AIName`="",`ScriptName`="npc_dk_understudy" WHERE `entry`=16803;
DELETE FROM `smart_scripts` WHERE `entryorguid`=16803 AND `source_type`=0;

View File

@@ -3053,6 +3053,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 52479: // Gift of the Harvester
case 48246: // Ball of Flame
case 36327: // Shoot Arcane Explosion Arrow
case 55479: // Force Obedience
spellInfo->MaxAffectedTargets = 1;
break;
case 36384: // Skartax Purple Beam

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,