diff --git a/sql/updates/world/4.3.4/2020_07_24_00_world.sql b/sql/updates/world/4.3.4/2020_07_24_00_world.sql new file mode 100644 index 00000000000..354abb6df20 --- /dev/null +++ b/sql/updates/world/4.3.4/2020_07_24_00_world.sql @@ -0,0 +1,23 @@ +-- Deathbringer & Valithria +DELETE FROM `creature_onkill_reputation` WHERE `creature_id` IN (37813,38402,38582,38583,36789,38174); +-- +UPDATE `creature_template_addon` SET `auras`="" WHERE `entry` IN (37918,30682,20089,38068); +-- Valithria Dreamwalker fixes +DELETE FROM `creature` WHERE `id`=37868; +DELETE FROM `creature_summon_groups` WHERE `summonerId`=38752; +INSERT INTO `creature_summon_groups` (`summonerId`,`summonerType`,`groupId`,`entry`,`position_x`,`position_y`,`position_z`,`orientation`,`summonType`,`summonTime`) VALUES +-- Group All Difficulty +(38752,0,1,37868,4222.86,2504.58,364.96,3.90954,8,0), -- Risen Archmage +(38752,0,1,37868,4223.4 ,2465.11,364.952,2.3911,8,0), -- Risen Archmage +-- Group 10 Man +(38752,0,2,37868,4230.44,2478.56,364.953,2.93215,8,0), -- Risen Archmage +(38752,0,2,37868,4230.53,2490.22,364.957,3.36849,8,0), -- Risen Archmage +-- Group 25 man +(38752,0,3,37868,4185.29,2464.01,364.87,0.798137,8,0), -- Risen Archmage +(38752,0,3,37868,4183.7 ,2503.93,364.879,5.50843,8,0); -- Risen Archmage + +UPDATE `creature` SET `phaseMask`=20 WHERE `id` IN(38421,37950); +UPDATE `creature_template` SET `flags_extra`=2 WHERE `entry`=37950; +UPDATE `conditions` SET `ConditionValue2`=37950 WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN(72031,72032,72033,71946); +-- +UPDATE `creature_template` SET `flags_extra`= `flags_extra`|1073741824 WHERE `entry` IN (36789,38174); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 7759ac01e10..8684eac0b3a 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -92,33 +92,33 @@ enum ScriptTexts enum Spells { // Deathbringer Saurfang - SPELL_ZERO_POWER = 72242, - SPELL_GRIP_OF_AGONY = 70572, // Intro - SPELL_BLOOD_LINK = 72178, - SPELL_MARK_OF_THE_FALLEN_CHAMPION_S = 72256, - SPELL_RUNE_OF_BLOOD_S = 72408, + SPELL_ZERO_POWER = 72242, + SPELL_GRIP_OF_AGONY = 70572, // Intro + SPELL_BLOOD_LINK = 72178, + SPELL_MARK_OF_THE_FALLEN_CHAMPION_S = 72256, + SPELL_RUNE_OF_BLOOD_S = 72408, - SPELL_SUMMON_BLOOD_BEAST = 72172, - SPELL_SUMMON_BLOOD_BEAST_25_MAN = 72356, // Additional cast, does not replace - SPELL_FRENZY = 72737, - SPELL_BLOOD_NOVA_TRIGGER = 72378, - SPELL_BLOOD_NOVA = 72380, - SPELL_BLOOD_POWER = 72371, - SPELL_BLOOD_LINK_POWER = 72195, - SPELL_BLOOD_LINK_DUMMY = 72202, - SPELL_MARK_OF_THE_FALLEN_CHAMPION = 72293, - SPELL_BOILING_BLOOD = 72385, - SPELL_RUNE_OF_BLOOD = 72410, + SPELL_SUMMON_BLOOD_BEAST = 72172, + SPELL_SUMMON_BLOOD_BEAST_25_MAN = 72356, // Additional cast, does not replace + SPELL_FRENZY = 72737, + SPELL_BLOOD_NOVA_TRIGGER = 72378, + SPELL_BLOOD_NOVA = 72380, + SPELL_BLOOD_POWER = 72371, + SPELL_BLOOD_LINK_POWER = 72195, + SPELL_BLOOD_LINK_DUMMY = 72202, + SPELL_MARK_OF_THE_FALLEN_CHAMPION = 72293, + SPELL_BOILING_BLOOD = 72385, + SPELL_RUNE_OF_BLOOD = 72410, // Blood Beast - SPELL_BLOOD_LINK_BEAST = 72176, - SPELL_RESISTANT_SKIN = 72723, - SPELL_SCENT_OF_BLOOD = 72769, // Heroic only + SPELL_BLOOD_LINK_BEAST = 72176, + SPELL_RESISTANT_SKIN = 72723, + SPELL_SCENT_OF_BLOOD = 72769, // Heroic only - SPELL_RIDE_VEHICLE = 70640, // Outro - SPELL_ACHIEVEMENT = 72928, + SPELL_RIDE_VEHICLE = 70640, // Outro + SPELL_ACHIEVEMENT = 72928, SPELL_REMOVE_MARKS_OF_THE_FALLEN_CHAMPION = 72257, - SPELL_PERMANENT_FEIGN_DEATH = 70628, + SPELL_PERMANENT_FEIGN_DEATH = 70628 }; // Helper to get id of the aura on different modes (HasAura(baseId) wont work) @@ -269,11 +269,11 @@ class boss_deathbringer_saurfang : public CreatureScript _frenzied = false; _dead = false; me->SetPower(POWER_ENERGY, 0); - DoCast(me, SPELL_ZERO_POWER, true); - DoCast(me, SPELL_BLOOD_LINK, true); - DoCast(me, SPELL_BLOOD_POWER, true); - DoCast(me, SPELL_MARK_OF_THE_FALLEN_CHAMPION_S, true); - DoCast(me, SPELL_RUNE_OF_BLOOD_S, true); + DoCastSelf(SPELL_ZERO_POWER, true); + DoCastSelf(SPELL_BLOOD_LINK, true); + DoCastSelf(SPELL_BLOOD_POWER, true); + DoCastSelf(SPELL_MARK_OF_THE_FALLEN_CHAMPION_S, true); + DoCastSelf(SPELL_RUNE_OF_BLOOD_S, true); me->RemoveAurasDueToSpell(SPELL_BERSERK); me->RemoveAurasDueToSpell(SPELL_FRENZY); } @@ -299,7 +299,7 @@ class boss_deathbringer_saurfang : public CreatureScript me->SetImmuneToPC(false); if (!_introDone) { - DoCast(me, SPELL_GRIP_OF_AGONY); + DoCastSelf(SPELL_GRIP_OF_AGONY); if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SAURFANG_EVENT_NPC))) creature->AI()->DoAction(ACTION_INTERRUPT_INTRO); } @@ -361,7 +361,7 @@ class boss_deathbringer_saurfang : public CreatureScript if (!_frenzied && HealthBelowPct(31)) // AT 30%, not below { _frenzied = true; - DoCast(me, SPELL_FRENZY); + DoCastSelf(SPELL_FRENZY, true); Talk(SAY_FRENZY); } @@ -372,13 +372,13 @@ class boss_deathbringer_saurfang : public CreatureScript _EnterEvadeMode(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetImmuneToPC(true); - + me->RemoveAurasOnEvade(); DoCastAOE(SPELL_REMOVE_MARKS_OF_THE_FALLEN_CHAMPION); - DoCast(me, SPELL_ACHIEVEMENT, true); + DoCastSelf(SPELL_ACHIEVEMENT, true); Talk(SAY_DEATH); + DoCastSelf(SPELL_REPUTATION_BOSS_KILL, true); + DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH); - //instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MARK_OF_THE_FALLEN_CHAMPION); - DoCast(me, SPELL_PERMANENT_FEIGN_DEATH); if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SAURFANG_EVENT_NPC))) creature->AI()->DoAction(ACTION_START_OUTRO); } @@ -474,7 +474,7 @@ class boss_deathbringer_saurfang : public CreatureScript case EVENT_INTRO_ALLIANCE_6: Talk(SAY_INTRO_ALLIANCE_6); Talk(SAY_INTRO_ALLIANCE_7); - DoCast(me, SPELL_GRIP_OF_AGONY); + DoCastSelf(SPELL_GRIP_OF_AGONY); break; case EVENT_INTRO_HORDE_2: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -485,7 +485,7 @@ class boss_deathbringer_saurfang : public CreatureScript Talk(SAY_INTRO_HORDE_4); break; case EVENT_INTRO_HORDE_9: - DoCast(me, SPELL_GRIP_OF_AGONY); + DoCastSelf(SPELL_GRIP_OF_AGONY); Talk(SAY_INTRO_HORDE_9); break; case EVENT_INTRO_FINISH: @@ -495,10 +495,10 @@ class boss_deathbringer_saurfang : public CreatureScript break; case EVENT_SUMMON_BLOOD_BEAST: for (uint32 i10 = 0; i10 < 2; ++i10) - DoCast(me, SPELL_SUMMON_BLOOD_BEAST+i10); + DoCastSelf(SPELL_SUMMON_BLOOD_BEAST + i10); if (Is25ManRaid()) for (uint32 i25 = 0; i25 < 3; ++i25) - DoCast(me, SPELL_SUMMON_BLOOD_BEAST_25_MAN+i25); + DoCastSelf(SPELL_SUMMON_BLOOD_BEAST_25_MAN + i25); Talk(SAY_BLOOD_BEASTS); events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 40000, 0, PHASE_COMBAT); if (IsHeroic()) @@ -513,11 +513,11 @@ class boss_deathbringer_saurfang : public CreatureScript events.ScheduleEvent(EVENT_RUNE_OF_BLOOD, urand(20000, 25000), 0, PHASE_COMBAT); break; case EVENT_BOILING_BLOOD: - DoCast(me, SPELL_BOILING_BLOOD); + DoCastSelf(SPELL_BOILING_BLOOD); events.ScheduleEvent(EVENT_BOILING_BLOOD, urand(15000, 20000), 0, PHASE_COMBAT); break; case EVENT_BERSERK: - DoCast(me, SPELL_BERSERK); + DoCastSelf(SPELL_BERSERK); Talk(SAY_BERSERK); break; case EVENT_SCENT_OF_BLOOD: diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index e73e1141b39..786b92ea444 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -60,8 +60,9 @@ enum Spells SPELL_DREAM_SLIP = 71196, SPELL_ACHIEVEMENT_CHECK = 72706, SPELL_CLEAR_ALL = 71721, - SPELL_AWARD_REPUTATION_BOSS_KILL = 73843, SPELL_CORRUPTION_VALITHRIA = 70904, + SPELL_MANA_VOID_AURA = 71085, + SPELL_COLUMN_OF_FROST_AURA = 70715, // The Lich King SPELL_TIMER_GLUTTONOUS_ABOMINATION = 70915, @@ -110,37 +111,37 @@ enum Spells enum Events { // Valithria Dreamwalker - EVENT_INTRO_TALK = 1, - EVENT_BERSERK = 2, - EVENT_DREAM_PORTAL = 3, - EVENT_DREAM_SLIP = 4, + EVENT_INTRO_TALK = 1, + EVENT_BERSERK, + EVENT_DREAM_PORTAL, + EVENT_DREAM_SLIP, // The Lich King - EVENT_GLUTTONOUS_ABOMINATION_SUMMONER = 5, - EVENT_SUPPRESSER_SUMMONER = 6, - EVENT_BLISTERING_ZOMBIE_SUMMONER = 7, - EVENT_RISEN_ARCHMAGE_SUMMONER = 8, - EVENT_BLAZING_SKELETON_SUMMONER = 9, + EVENT_GLUTTONOUS_ABOMINATION_SUMMONER, + EVENT_SUPPRESSER_SUMMONER, + EVENT_BLISTERING_ZOMBIE_SUMMONER, + EVENT_RISEN_ARCHMAGE_SUMMONER, + EVENT_BLAZING_SKELETON_SUMMONER, // Risen Archmage - EVENT_FROSTBOLT_VOLLEY = 10, - EVENT_MANA_VOID = 11, - EVENT_COLUMN_OF_FROST = 12, + EVENT_FROSTBOLT_VOLLEY, + EVENT_MANA_VOID, + EVENT_COLUMN_OF_FROST, // Blazing Skeleton - EVENT_FIREBALL = 13, - EVENT_LEY_WASTE = 14, + EVENT_FIREBALL, + EVENT_LEY_WASTE, // Suppresser - EVENT_SUPPRESSION = 15, + EVENT_SUPPRESSION, // Gluttonous Abomination - EVENT_GUT_SPRAY = 16, + EVENT_GUT_SPRAY, // Dream Cloud // Nightmare Cloud - EVENT_CHECK_PLAYER = 17, - EVENT_EXPLODE = 18, + EVENT_CHECK_PLAYER, + EVENT_EXPLODE, }; enum Misc @@ -148,42 +149,40 @@ enum Misc ACTION_ENTER_COMBAT = 1, MISSED_PORTALS = 2, ACTION_DEATH = 3, - DATA_SUPPRESSERS_COUNT = 4 + ACTION_SETUP_ARCHMAGES = 4, + DATA_SUPPRESSERS_COUNT = 4, + POINT_VALITHRIA = 42, + SUMMON_GROUP_ALL = 1, + SUMMON_GROUP_10 = 2, + SUMMON_GROUP_25 = 3 }; -class RisenArchmageCheck +Position const ValithriaSpawnPos = {4210.813f, 2484.443f, 364.9558f, 0.01745329f}; + +struct ValithriaManaVoidSelector { - public: - // look for all permanently spawned Risen Archmages that are not yet in combat - bool operator()(Creature* creature) + explicit ValithriaManaVoidSelector(WorldObject const* source) : _source(source) { - return creature->IsAlive() && creature->GetEntry() == NPC_RISEN_ARCHMAGE && - creature->GetSpawnId() && !creature->IsInCombat(); } + + bool operator()(Unit* unit) const + { + return unit->GetPowerType() == POWER_MANA && _source->GetDistance(unit) > 15.0f; + } + + WorldObject const* _source; }; -struct ManaVoidSelector -{ - explicit ManaVoidSelector(WorldObject const* source) : _source(source) { } - - bool operator()(Unit* unit) const - { - return unit->GetPowerType() == POWER_MANA && _source->GetDistance(unit) > 15.0f; - } - - WorldObject const* _source; -}; - -class DelayedCastEvent : public BasicEvent +class ValithriaDelayedCastEvent : public BasicEvent { public: - DelayedCastEvent(Creature* trigger, uint32 spellId, ObjectGuid originalCaster, uint32 despawnTime) : _trigger(trigger), _originalCaster(originalCaster), _spellId(spellId), _despawnTime(despawnTime) + ValithriaDelayedCastEvent(Creature* trigger, uint32 spellId, ObjectGuid originalCaster, uint32 despawnTime) : _trigger(trigger), _originalCaster(originalCaster), _spellId(spellId), _despawnTime(despawnTime) { } bool Execute(uint64 /*time*/, uint32 /*diff*/) override { - _trigger->CastSpell(_trigger, _spellId, false, nullptr, nullptr, _originalCaster); + _trigger->CastSpell(_trigger, _spellId, _originalCaster); if (_despawnTime) _trigger->DespawnOrUnsummon(_despawnTime); return true; @@ -196,10 +195,12 @@ class DelayedCastEvent : public BasicEvent uint32 _despawnTime; }; -class AuraRemoveEvent : public BasicEvent +class ValithriaAuraRemoveEvent : public BasicEvent { public: - AuraRemoveEvent(Creature* trigger, uint32 spellId) : _trigger(trigger), _spellId(spellId) { } + ValithriaAuraRemoveEvent(Creature* trigger, uint32 spellId) : _trigger(trigger), _spellId(spellId) + { + } bool Execute(uint64 /*time*/, uint32 /*diff*/) override { @@ -215,7 +216,9 @@ class AuraRemoveEvent : public BasicEvent class ValithriaDespawner : public BasicEvent { public: - explicit ValithriaDespawner(Creature* creature) : _creature(creature) { } + explicit ValithriaDespawner(Creature* creature) : _creature(creature) + { + } bool Execute(uint64 /*currTime*/, uint32 /*diff*/) override { @@ -240,11 +243,12 @@ class ValithriaDespawner : public BasicEvent case NPC_COLUMN_OF_FROST: case NPC_ROT_WORM: case NPC_RISEN_ARCHMAGE: + case NPC_GREEN_DRAGON_COMBAT_TRIGGER: break; default: return; } - + creature->DespawnOrUnsummon(0, 10s); } @@ -255,12 +259,13 @@ class ValithriaDespawner : public BasicEvent class boss_valithria_dreamwalker : public CreatureScript { public: - boss_valithria_dreamwalker() : CreatureScript("boss_valithria_dreamwalker") { } + boss_valithria_dreamwalker() : CreatureScript("boss_valithria_dreamwalker") + { + } struct boss_valithria_dreamwalkerAI : public ScriptedAI { - boss_valithria_dreamwalkerAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()), _portalCount(RAID_MODE(3, 8, 3, 8)) + boss_valithria_dreamwalkerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _portalCount(RAID_MODE(3, 8, 3, 8)) { Initialize(); _spawnHealth = me->GetHealth(); @@ -281,12 +286,12 @@ class boss_valithria_dreamwalker : public CreatureScript if (data->curhealth) _spawnHealth = data->curhealth; - if (!me->isDead()) - Reset(); + ScriptedAI::InitializeAI(); } void Reset() override { + _events.Reset(); me->SetHealth(_spawnHealth); me->SetReactState(REACT_PASSIVE); me->LoadCreaturesAddon(); @@ -308,10 +313,10 @@ class boss_valithria_dreamwalker : public CreatureScript if (action != ACTION_ENTER_COMBAT) return; - DoCast(me, SPELL_COPY_DAMAGE); + DoCastSelf(SPELL_COPY_DAMAGE); _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); - _events.ScheduleEvent(EVENT_INTRO_TALK, 15000); - _events.ScheduleEvent(EVENT_DREAM_PORTAL, urand(45000, 48000)); + _events.ScheduleEvent(EVENT_INTRO_TALK, 15s); + _events.ScheduleEvent(EVENT_DREAM_PORTAL, 45s, 48s); if (IsHeroic()) _events.ScheduleEvent(EVENT_BERSERK, 420000); } @@ -330,9 +335,9 @@ class boss_valithria_dreamwalker : public CreatureScript Talk(SAY_VALITHRIA_SUCCESS); _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); me->RemoveAurasDueToSpell(SPELL_CORRUPTION_VALITHRIA); - DoCast(me, SPELL_ACHIEVEMENT_CHECK); + DoCastSelf(SPELL_ACHIEVEMENT_CHECK); DoCastAOE(SPELL_DREAMWALKERS_RAGE); - _events.ScheduleEvent(EVENT_DREAM_SLIP, 3500); + _events.ScheduleEvent(EVENT_DREAM_SLIP, 3500ms); if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_LICH_KING))) lichKing->AI()->EnterEvadeMode(); } @@ -342,8 +347,10 @@ class boss_valithria_dreamwalker : public CreatureScript Talk(SAY_VALITHRIA_75_PERCENT); } else if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == NOT_STARTED) + { if (Creature* archmage = me->FindNearestCreature(NPC_RISEN_ARCHMAGE, 30.0f)) - archmage->EngageWithTarget(healer); // call JustEngagedWith on one of them, that will make it all start + DoZoneInCombat(archmage); // on one of them, that will make it all start + } } void DamageTaken(Unit* /*attacker*/, uint32& damage) override @@ -356,7 +363,7 @@ class boss_valithria_dreamwalker : public CreatureScript Talk(SAY_VALITHRIA_25_PERCENT); } - if (damage > me->GetHealth()) + if (damage >= me->GetHealth()) { damage = 0; if (!_justDied) @@ -375,17 +382,17 @@ class boss_valithria_dreamwalker : public CreatureScript { if (spell->Id == SPELL_DREAM_SLIP) { - DoCast(me, SPELL_CLEAR_ALL); - DoCast(me, SPELL_AWARD_REPUTATION_BOSS_KILL); + DoCastSelf(SPELL_CLEAR_ALL); + DoCastSelf(SPELL_REPUTATION_BOSS_KILL, true); // this display id was found in sniff instead of the one on aura me->SetDisplayId(11686); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->DespawnOrUnsummon(4000); - if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_LICH_KING))) - lichKing->CastSpell(lichKing, SPELL_SPAWN_CHEST, false); - if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_TRIGGER))) me->Kill(trigger); + + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_LICH_KING))) + lichKing->CastSpell(lichKing, SPELL_SPAWN_CHEST); } } @@ -393,13 +400,13 @@ class boss_valithria_dreamwalker : public CreatureScript { if (summon->GetEntry() == NPC_DREAM_PORTAL_PRE_EFFECT) { - summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_DREAM_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000)); - summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_DREAM_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000)); + summon->m_Events.AddEvent(new ValithriaDelayedCastEvent(summon, SPELL_SUMMON_DREAM_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000)); + summon->m_Events.AddEvent(new ValithriaAuraRemoveEvent(summon, SPELL_DREAM_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000)); } else if (summon->GetEntry() == NPC_NIGHTMARE_PORTAL_PRE_EFFECT) { - summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_NIGHTMARE_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000)); - summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_NIGHTMARE_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000)); + summon->m_Events.AddEvent(new ValithriaDelayedCastEvent(summon, SPELL_SUMMON_NIGHTMARE_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000)); + summon->m_Events.AddEvent(new ValithriaAuraRemoveEvent(summon, SPELL_NIGHTMARE_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000)); } } @@ -435,15 +442,18 @@ class boss_valithria_dreamwalker : public CreatureScript if (!IsHeroic()) Talk(SAY_VALITHRIA_DREAM_PORTAL); for (uint32 i = 0; i < _portalCount; ++i) - DoCast(me, SUMMON_PORTAL); - _events.ScheduleEvent(EVENT_DREAM_PORTAL, urand(45000, 48000)); + DoCastSelf(SUMMON_PORTAL); + _events.ScheduleEvent(EVENT_DREAM_PORTAL, 45s, 48s); break; case EVENT_DREAM_SLIP: - DoCast(me, SPELL_DREAM_SLIP); + DoCastSelf(SPELL_DREAM_SLIP); break; default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } } @@ -480,7 +490,7 @@ class npc_green_dragon_combat_trigger : public CreatureScript struct npc_green_dragon_combat_triggerAI : public BossAI { - npc_green_dragon_combat_triggerAI(Creature* creature) : BossAI(creature, DATA_VALITHRIA_DREAMWALKER), _evadeCheck(false) + npc_green_dragon_combat_triggerAI(Creature* creature) : BossAI(creature, DATA_VALITHRIA_DREAMWALKER) { } @@ -488,38 +498,50 @@ class npc_green_dragon_combat_trigger : public CreatureScript { _Reset(); me->SetReactState(REACT_PASSIVE); + summons.DespawnAll(); + // Setup Archmages + me->SummonCreatureGroup(SUMMON_GROUP_ALL); + if (Is25ManRaid()) + me->SummonCreatureGroup(SUMMON_GROUP_25); + else + me->SummonCreatureGroup(SUMMON_GROUP_10); + + EntryCheckPredicate pred(NPC_RISEN_ARCHMAGE); + summons.DoAction(ACTION_SETUP_ARCHMAGES, pred); } - void JustEngagedWith(Unit* target) override + void JustEnteredCombat(Unit* target) override { + if (IsEngaged()) + return; + if (!instance->CheckRequiredBosses(DATA_VALITHRIA_DREAMWALKER, target->ToPlayer())) { - EnterEvadeMode(); + EnterEvadeMode(EVADE_REASON_SEQUENCE_BREAK); instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT); return; } + EngagementStart(target); + me->setActive(true); DoZoneInCombat(); instance->SetBossState(DATA_VALITHRIA_DREAMWALKER, IN_PROGRESS); if (Creature* valithria = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER))) valithria->AI()->DoAction(ACTION_ENTER_COMBAT); + EntryCheckPredicate pred(NPC_RISEN_ARCHMAGE); + summons.DoAction(ACTION_ENTER_COMBAT, pred); } - void AttackStart(Unit* target) override + void JustExitedCombat() override { - if (target->GetTypeId() == TYPEID_PLAYER) - BossAI::AttackStart(target); - } + EngagementOver(); - bool CanAIAttack(Unit const* target) const override - { - return target->GetTypeId() == TYPEID_PLAYER; - } + me->setActive(false); - void JustReachedHome() override - { - _JustReachedHome(); + // JustExitedCombat is called on death too, so if creature is dead, avoid "respawn" event + if (!me->IsAlive()) + return; DoAction(ACTION_DEATH); } @@ -528,30 +550,11 @@ class npc_green_dragon_combat_trigger : public CreatureScript if (action == ACTION_DEATH) { instance->SetBossState(DATA_VALITHRIA_DREAMWALKER, NOT_STARTED); - me->m_Events.AddEvent(new ValithriaDespawner(me), me->m_Events.CalculateTime(5000)); + me->m_Events.AddEventAtOffset(new ValithriaDespawner(me), 5s); + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_VALITHRIA_LICH_KING))) + lichKing->AI()->EnterEvadeMode(); } } - - void UpdateAI(uint32 /*diff*/) override - { - if (!me->IsInCombat()) - return; - - // check evade every second tick - _evadeCheck ^= true; - if (!_evadeCheck) - return; - - // check if there is any player engaged, if not - evade - for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) - if (pair.second->GetOther(me)->GetTypeId() == TYPEID_PLAYER) - return; - - EnterEvadeMode(); - } - - private: - bool _evadeCheck; }; CreatureAI* GetAI(Creature* creature) const override @@ -567,19 +570,18 @@ class npc_the_lich_king_controller : public CreatureScript struct npc_the_lich_king_controllerAI : public ScriptedAI { - npc_the_lich_king_controllerAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) + npc_the_lich_king_controllerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } void Reset() override { _events.Reset(); - _events.ScheduleEvent(EVENT_GLUTTONOUS_ABOMINATION_SUMMONER, 5000); - _events.ScheduleEvent(EVENT_SUPPRESSER_SUMMONER, 10000); - _events.ScheduleEvent(EVENT_BLISTERING_ZOMBIE_SUMMONER, 15000); - _events.ScheduleEvent(EVENT_RISEN_ARCHMAGE_SUMMONER, 20000); - _events.ScheduleEvent(EVENT_BLAZING_SKELETON_SUMMONER, 30000); + _events.ScheduleEvent(EVENT_GLUTTONOUS_ABOMINATION_SUMMONER, 5s); + _events.ScheduleEvent(EVENT_SUPPRESSER_SUMMONER, 10s); + _events.ScheduleEvent(EVENT_BLISTERING_ZOMBIE_SUMMONER, 15s); + _events.ScheduleEvent(EVENT_RISEN_ARCHMAGE_SUMMONER, 20s); + _events.ScheduleEvent(EVENT_BLAZING_SKELETON_SUMMONER, 30s); me->SetReactState(REACT_PASSIVE); } @@ -606,7 +608,7 @@ class npc_the_lich_king_controller : public CreatureScript { // must not be in dream phase PhasingHandler::RemovePhase(summon, 173, true); - summon->AI()->DoZoneInCombat(); + DoZoneInCombat(summon); if (summon->GetEntry() != NPC_SUPPRESSER) if (Unit* target = me->GetCombatManager().GetAnyTarget()) summon->AI()->AttackStart(target); @@ -627,23 +629,26 @@ class npc_the_lich_king_controller : public CreatureScript switch (eventId) { case EVENT_GLUTTONOUS_ABOMINATION_SUMMONER: - DoCast(me, SPELL_TIMER_GLUTTONOUS_ABOMINATION); + DoCastSelf(SPELL_TIMER_GLUTTONOUS_ABOMINATION); break; case EVENT_SUPPRESSER_SUMMONER: - DoCast(me, SPELL_TIMER_SUPPRESSER); + DoCastSelf(SPELL_TIMER_SUPPRESSER); break; case EVENT_BLISTERING_ZOMBIE_SUMMONER: - DoCast(me, SPELL_TIMER_BLISTERING_ZOMBIE); + DoCastSelf(SPELL_TIMER_BLISTERING_ZOMBIE); break; case EVENT_RISEN_ARCHMAGE_SUMMONER: - DoCast(me, SPELL_TIMER_RISEN_ARCHMAGE); + DoCastSelf(SPELL_TIMER_RISEN_ARCHMAGE); break; case EVENT_BLAZING_SKELETON_SUMMONER: - DoCast(me, SPELL_TIMER_BLAZING_SKELETON); + DoCastSelf(SPELL_TIMER_BLAZING_SKELETON); break; default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } } @@ -665,15 +670,14 @@ class npc_risen_archmage : public CreatureScript struct npc_risen_archmageAI : public ScriptedAI { - npc_risen_archmageAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) + npc_risen_archmageAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { Initialize(); } void Initialize() { - _canCallJustEngagedWith = true; + _isInitialArchmage = false; } bool CanAIAttack(Unit const* target) const override @@ -684,62 +688,57 @@ class npc_risen_archmage : public CreatureScript void Reset() override { _events.Reset(); - _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, urand(5000, 15000)); - _events.ScheduleEvent(EVENT_MANA_VOID, urand(20000, 25000)); - _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, urand(10000, 20000)); + _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 5s, 15s); + _events.ScheduleEvent(EVENT_MANA_VOID, 20s, 25s); + _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, 10s, 20s); Initialize(); } - void JustEngagedWith(Unit* target) override + void JustEnteredCombat(Unit* who) override { - me->FinishSpell(CURRENT_CHANNELED_SPELL, false); - if (me->GetSpawnId() && _canCallJustEngagedWith) - { - std::list archmages; - RisenArchmageCheck check; - Trinity::CreatureListSearcher searcher(me, archmages, check); - Cell::VisitGridObjects(me, searcher, 100.0f); - for (std::list::iterator itr = archmages.begin(); itr != archmages.end(); ++itr) - (*itr)->AI()->DoAction(ACTION_ENTER_COMBAT); + if (IsEngaged()) + return; + me->InterruptNonMeleeSpells(false); + + EngagementStart(who); + + if (_isInitialArchmage) + { if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_LICH_KING))) - { - lichKing->EngageWithTarget(target); - lichKing->AI()->DoZoneInCombat(); - } + DoZoneInCombat(lichKing); if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_TRIGGER))) - { - trigger->EngageWithTarget(target); - trigger->AI()->DoZoneInCombat(); - } + DoZoneInCombat(trigger); } } void DoAction(int32 action) override { - if (action != ACTION_ENTER_COMBAT) - return; - - _canCallJustEngagedWith = false; - DoZoneInCombat(); - _canCallJustEngagedWith = true; + if (action == ACTION_ENTER_COMBAT) + DoZoneInCombat(); + else if (action == ACTION_SETUP_ARCHMAGES) + _isInitialArchmage = true; } void JustSummoned(Creature* summon) override { if (summon->GetEntry() == NPC_COLUMN_OF_FROST) - summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_COLUMN_OF_FROST_DAMAGE, ObjectGuid::Empty, 8000), summon->m_Events.CalculateTime(2000)); + { + summon->CastSpell(summon, SPELL_COLUMN_OF_FROST_AURA, true); + summon->m_Events.AddEvent(new ValithriaDelayedCastEvent(summon, SPELL_COLUMN_OF_FROST_DAMAGE, ObjectGuid::Empty, 8000), summon->m_Events.CalculateTime(2000)); + } else if (summon->GetEntry() == NPC_MANA_VOID) + { + summon->CastSpell(summon, SPELL_MANA_VOID_AURA, true); summon->DespawnOrUnsummon(36000); + } } void UpdateAI(uint32 diff) override { - if (!me->IsInCombat()) - if (me->GetSpawnId()) - if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) - DoCast(me, SPELL_CORRUPTION); + if (!me->IsInCombat() && me->IsAlive() && _isInitialArchmage && !me->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) + DoCastSelf(SPELL_CORRUPTION); if (!UpdateVictim()) return; @@ -754,22 +753,25 @@ class npc_risen_archmage : public CreatureScript switch (eventId) { case EVENT_FROSTBOLT_VOLLEY: - DoCast(me, SPELL_FROSTBOLT_VOLLEY); - _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, urand(8000, 15000)); + DoCastSelf(SPELL_FROSTBOLT_VOLLEY); + _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 8s, 15s); break; case EVENT_MANA_VOID: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, ManaVoidSelector(me))) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, ValithriaManaVoidSelector(me))) DoCast(target, SPELL_MANA_VOID); - _events.ScheduleEvent(EVENT_MANA_VOID, urand(20000, 25000)); + _events.ScheduleEvent(EVENT_MANA_VOID, 20s, 25s); break; case EVENT_COLUMN_OF_FROST: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -10.0f, true)) DoCast(target, SPELL_COLUMN_OF_FROST); - _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, urand(15000, 25000)); + _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, 15s, 25s); break; default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } DoMeleeAttackIfReady(); @@ -778,7 +780,7 @@ class npc_risen_archmage : public CreatureScript private: EventMap _events; InstanceScript* _instance; - bool _canCallJustEngagedWith; + bool _isInitialArchmage; }; CreatureAI* GetAI(Creature* creature) const override @@ -801,8 +803,8 @@ class npc_blazing_skeleton : public CreatureScript void Reset() override { _events.Reset(); - _events.ScheduleEvent(EVENT_FIREBALL, urand(2000, 4000)); - _events.ScheduleEvent(EVENT_LEY_WASTE, urand(15000, 20000)); + _events.ScheduleEvent(EVENT_FIREBALL, 2s, 4s); + _events.ScheduleEvent(EVENT_LEY_WASTE, 15s, 20s); } void UpdateAI(uint32 diff) override @@ -822,15 +824,18 @@ class npc_blazing_skeleton : public CreatureScript case EVENT_FIREBALL: if (!me->IsWithinMeleeRange(me->GetVictim())) DoCastVictim(SPELL_FIREBALL); - _events.ScheduleEvent(EVENT_FIREBALL, urand(2000, 4000)); + _events.ScheduleEvent(EVENT_FIREBALL, 2s, 4s); break; case EVENT_LEY_WASTE: - DoCast(me, SPELL_LEY_WASTE); - _events.ScheduleEvent(EVENT_LEY_WASTE, urand(15000, 20000)); + DoCastSelf(SPELL_LEY_WASTE); + _events.ScheduleEvent(EVENT_LEY_WASTE, 15s, 20s); break; default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } DoMeleeAttackIfReady(); @@ -853,39 +858,30 @@ class npc_suppresser : public CreatureScript struct npc_suppresserAI : public ScriptedAI { - npc_suppresserAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) + npc_suppresserAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } void Reset() override { _events.Reset(); - _events.ScheduleEvent(EVENT_SUPPRESSION, urand(10000, 15000)); - me->SetReactState(REACT_PASSIVE); } void IsSummonedBy(Unit* /*summoner*/) override { if (Creature* valithria = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER))) { - float x, y, z; - valithria->GetContactPoint(me, x,y,z); - me->GetMotionMaster()->MovePoint(42, x, y, z); + me->EngageWithTarget(valithria); + me->GetThreatManager().FixateTarget(valithria); } + else + me->DespawnOrUnsummon(); } - void MovementInform(uint32 /*type*/, uint32 id) override + void MovementInform(uint32 type, uint32 /*id*/) override { - if (id == 42) - { - me->SetReactState(REACT_AGGRESSIVE); - if (Creature* valithria = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER))) - { - AttackStart(valithria); - DoCastAOE(SPELL_SUPPRESSION); - } - } + if (type == CHASE_MOTION_TYPE) + _events.RescheduleEvent(EVENT_SUPPRESSION, 1); } void UpdateAI(uint32 diff) override @@ -898,24 +894,20 @@ class npc_suppresser : public CreatureScript if (me->HasUnitState(UNIT_STATE_CASTING)) return; - // this code will never be reached while channeling while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_SUPPRESSION: DoCastAOE(SPELL_SUPPRESSION); - _events.ScheduleEvent(EVENT_SUPPRESSION, 5000); + _events.Repeat(5s); break; default: break; } } - // this creature has REACT_PASSIVE so it does not always have victim here - if (Unit* victim = me->GetVictim()) - if (victim->GetEntry() != NPC_VALITHRIA_DREAMWALKER) - DoMeleeAttackIfReady(); + DoMeleeAttackIfReady(); } private: @@ -942,7 +934,7 @@ class npc_blistering_zombie : public CreatureScript void JustDied(Unit* /*killer*/) override { - DoCast(me, SPELL_ACID_BURST, true); + DoCastSelf(SPELL_ACID_BURST, true); } void UpdateAI(uint32 /*diff*/) override @@ -974,12 +966,15 @@ class npc_gluttonous_abomination : public CreatureScript void Reset() override { _events.Reset(); - _events.ScheduleEvent(EVENT_GUT_SPRAY, urand(10000, 13000)); + _events.ScheduleEvent(EVENT_GUT_SPRAY, 10s, 13s); } - void JustDied(Unit* /*killer*/) override + void JustDied(Unit* killer) override { - DoCast(me, SPELL_ROT_WORM_SPAWNER, true); + if (killer && killer->GetEntry() == NPC_VALITHRIA_DREAMWALKER) + return; + + DoCastSelf(SPELL_ROT_WORM_SPAWNER, true); } void UpdateAI(uint32 diff) override @@ -997,8 +992,8 @@ class npc_gluttonous_abomination : public CreatureScript switch (eventId) { case EVENT_GUT_SPRAY: - DoCast(me, SPELL_GUT_SPRAY); - _events.ScheduleEvent(EVENT_GUT_SPRAY, urand(10000, 13000)); + DoCastSelf(SPELL_GUT_SPRAY); + _events.ScheduleEvent(EVENT_GUT_SPRAY, 10s, 13s); break; default: break; @@ -1025,14 +1020,13 @@ class npc_dream_portal : public CreatureScript struct npc_dream_portalAI : public CreatureAI { - npc_dream_portalAI(Creature* creature) : CreatureAI(creature), - _used(false) + npc_dream_portalAI(Creature* creature) : CreatureAI(creature), _used(false) { } - void OnSpellClick(Unit* /*clicker*/, bool& result) override + void OnSpellClick(Unit* /*clicker*/, bool& spellClickHandled) override { - if (!result) + if (!spellClickHandled) return; _used = true; @@ -1066,16 +1060,15 @@ class npc_dream_cloud : public CreatureScript struct npc_dream_cloudAI : public ScriptedAI { - npc_dream_cloudAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) + npc_dream_cloudAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } void Reset() override { _events.Reset(); - _events.ScheduleEvent(EVENT_CHECK_PLAYER, 1000); - me->SetCorpseDelay(0); // remove corpse immediately + _events.ScheduleEvent(EVENT_CHECK_PLAYER, 1s); + me->SetCorpseDelay(0); // remove corpse immediately me->LoadCreaturesAddon(); } @@ -1103,7 +1096,7 @@ class npc_dream_cloud : public CreatureScript case EVENT_EXPLODE: me->GetMotionMaster()->MoveIdle(); // must use originalCaster the same for all clouds to allow stacking - me->CastSpell(me, EMERALD_VIGOR, false, nullptr, nullptr, _instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER)); + me->CastSpell(me, EMERALD_VIGOR, _instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER)); me->DespawnOrUnsummon(100); break; default: @@ -1224,7 +1217,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader if (!GetHitUnit()) return; - GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true, nullptr, nullptr, GetCaster()->GetInstanceScript()->GetGuidData(DATA_VALITHRIA_LICH_KING)); + GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, GetCaster()->GetInstanceScript()->GetGuidData(DATA_VALITHRIA_LICH_KING)); } void Register() override @@ -1315,7 +1308,7 @@ class spell_dreamwalker_summon_suppresser_effect : public SpellScriptLoader if (!GetHitUnit()) return; - GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true, nullptr, nullptr, GetCaster()->GetInstanceScript()->GetGuidData(DATA_VALITHRIA_LICH_KING)); + GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, GetCaster()->GetInstanceScript()->GetGuidData(DATA_VALITHRIA_LICH_KING)); } void Register() override @@ -1401,6 +1394,13 @@ class spell_dreamwalker_nightmare_cloud : public SpellScriptLoader { PrepareAuraScript(spell_dreamwalker_nightmare_cloud_AuraScript); + public: + spell_dreamwalker_nightmare_cloud_AuraScript() + { + _instance = nullptr; + } + + private: bool Load() override { _instance = GetOwner()->GetInstanceScript(); @@ -1418,7 +1418,7 @@ class spell_dreamwalker_nightmare_cloud : public SpellScriptLoader OnEffectPeriodic += AuraEffectPeriodicFn(spell_dreamwalker_nightmare_cloud_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); } - InstanceScript* _instance = nullptr; + InstanceScript* _instance; }; AuraScript* GetAuraScript() const override @@ -1439,12 +1439,9 @@ class spell_dreamwalker_twisted_nightmares : public SpellScriptLoader void HandleScript(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - // impossible with TARGET_UNIT_CASTER - //if (!GetHitUnit()) - // return; if (InstanceScript* instance = GetHitUnit()->GetInstanceScript()) - GetHitUnit()->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[effIndex].TriggerSpell, true, nullptr, nullptr, instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER)); + GetHitUnit()->CastSpell(nullptr, GetSpellInfo()->Effects[effIndex].TriggerSpell, instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER)); } void Register() override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 67f1716ef82..e3031e84784 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -42,6 +42,7 @@ enum ICSharedSpells { SPELL_BERSERK = 26662, SPELL_BERSERK2 = 47008, + SPELL_REPUTATION_BOSS_KILL = 73843, // Deathbound Ward SPELL_STONEFORM = 70733,