diff options
26 files changed, 1880 insertions, 88 deletions
diff --git a/sql/base/world_database.sql b/sql/base/world_database.sql index 828ef681506..263608e894d 100644 --- a/sql/base/world_database.sql +++ b/sql/base/world_database.sql @@ -26871,6 +26871,20 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES ( 72457, 'spell_putricide_regurgitated_ooze'), ( 72875, 'spell_putricide_regurgitated_ooze'), ( 72876, 'spell_putricide_regurgitated_ooze'), +( 71598, 'spell_creature_permanent_feign_death'), +( 71806, 'spell_taldaram_glittering_sparks'), +( 71718, 'spell_taldaram_summon_flame_ball'), +( 72040, 'spell_taldaram_summon_flame_ball'), +( 55891, 'spell_taldaram_flame_ball_visual'), +( 55947, 'spell_taldaram_flame_ball_visual'), +( 71756, 'spell_taldaram_ball_of_inferno_flame'), +( 72782, 'spell_taldaram_ball_of_inferno_flame'), +( 72783, 'spell_taldaram_ball_of_inferno_flame'), +( 72784, 'spell_taldaram_ball_of_inferno_flame'), +( 72080, 'spell_valanar_kinetic_bomb'), +( 72087, 'spell_valanar_kinetic_bomb_knockback'), +( 73001, 'spell_blood_council_shadow_prison'), +( 72999, 'spell_blood_council_shadow_prison_damage'), -- Ulduar ( 62717, 'spell_ignis_slag_pot'), ( 63477, 'spell_ignis_slag_pot'), diff --git a/sql/scripts/world_script_texts.sql b/sql/scripts/world_script_texts.sql index 4fc024299f8..d8f9ebd8534 100644 --- a/sql/scripts/world_script_texts.sql +++ b/sql/scripts/world_script_texts.sql @@ -2909,6 +2909,33 @@ INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1` (36678,-1631113,'Great news, everyone!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17118,1,0,0,'SAY_BERSERK'), (36678,-1631114,'Bad news, everyone! I don''t think I''m going to make it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17117,1,0,0,'SAY_DEATH'), +-- Blood Prince Council + (38004,-1631115,'Foolish mortals. You thought us defeated so easily? The San''layn are the Lich King''s immortal soldiers! Now you shall face their might combined!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16795,1,0,1,'SAY_INTRO_1'), + (38004,-1631116,'Rise up, brothers, and destroy our enemies.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16796,1,0,0,'SAY_INTRO_2'), + (37972,-1631117,'Such wondrous power! The Darkfallen Orb has made me INVINCIBLE!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16727,1,0,0,'SAY_KELESETH_INVOCATION'), + (37972,-1631118,'Invocation of Blood jumps to Prince Keleseth!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_KELESETH_INVOCATION'), + (37972,-1631119,'Blood will flow!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16728,1,0,0,'SAY_KELESETH_SPECIAL'), + (37972,-1631120,'Were you ever a threat?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16723,1,0,0,'SAY_KELESETH_KILL_1'), + (37972,-1631121,'Truth is found in death.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16724,1,0,0,'SAY_KELESETH_KILL_2'), + (37972,-1631122,'%s cackles maniacally!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16726,2,0,0,'EMOTE_KELESETH_BERSERK'), + (37972,-1631123,'My queen... they come...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16725,1,0,0,'SAY_KELESETH_DEATH'), + (37973,-1631124,'Tremble before Taldaram, mortals, for the power of the orb flows through me!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16857,1,0,0,'SAY_TALDARAM_INVOCATION'), + (37973,-1631125,'Invocation of Blood jumps to Prince Taldaram!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_TALDARAM_INVOCATION'), + (37973,-1631126,'Delight in the pain!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16858,1,0,0,'SAY_TALDARAM_SPECIAL'), + (37973,-1631127,'Inferno Flames speed toward $N!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_TALDARAM_FLAME'), + (37973,-1631128,'Worm food.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16853,1,0,0,'SAY_TALDARAM_KILL_1'), + (37973,-1631129,'Beg for mercy!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16854,1,0,0,'SAY_TALDARAM_KILL_2'), + (37973,-1631130,'%s laughs.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16856,2,0,0,'EMOTE_TALDARAM_BERSERK'), + (37973,-1631131,'%s gurgles and dies.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16855,2,0,0,'EMOTE_TALDARAM_DEATH'), + (37970,-1631132,'Naxxanar was merely a setback! With the power of the orb, Valanar will have his vengeance!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16685,1,0,0,'SAY_VALANAR_INVOCATION'), + (37970,-1631133,'Invocation of Blood jumps to Prince Valanar!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_VALANAR_INVOCATION'), + (37970,-1631134,'My cup runneth over.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16686,1,0,0,'SAY_VALANAR_SPECIAL'), + (37970,-1631135,'%s begins casting Empowered Schock Vortex!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_VALANAR_SHOCK_VORTEX'), + (37970,-1631136,'Dinner... is served.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16681,1,0,0,'SAY_VALANAR_KILL_1'), + (37970,-1631137,'Do you see NOW the power of the Darkfallen?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16682,1,0,0,'SAY_VALANAR_KILL_2'), + (37970,-1631138,'BOW DOWN BEFORE THE SAN''LAYN!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16684,1,0,0,'SAY_VALANAR_BERSERK'), + (37970,-1631139,'...why...?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16683,1,0,0,'SAY_VALANAR_DEATH'), + -- -1 632 000 ICECROWN CITADEL: FROZEN HALLS: FORGE OF SOULS -- Bronjham (36497,-1632001,'Finally...a captive audience!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16595,1,0,0,'Bronjham SAY_AGGRO'), diff --git a/sql/scripts/world_scripts_full.sql b/sql/scripts/world_scripts_full.sql index 8f40112e46e..e6609631635 100644 --- a/sql/scripts/world_scripts_full.sql +++ b/sql/scripts/world_scripts_full.sql @@ -850,6 +850,14 @@ UPDATE `creature_template` SET `ScriptName`='npc_big_ooze' WHERE `entry`=36899; UPDATE `creature_template` SET `ScriptName`='npc_precious_icc' WHERE `entry`=37217; UPDATE `creature_template` SET `ScriptName`='boss_professor_putricide' WHERE `entry`=36678; UPDATE `creature_template` SET `ScriptName`='npc_volatile_ooze' WHERE `entry`=37697; +UPDATE `creature_template` SET `ScriptName`='boss_blood_council_controller' WHERE `entry`=38008; +UPDATE `creature_template` SET `ScriptName`='boss_prince_keleseth_icc' WHERE `entry`=37972; +UPDATE `creature_template` SET `ScriptName`='boss_prince_taldaram_icc' WHERE `entry`=37973; +UPDATE `creature_template` SET `ScriptName`='boss_prince_valanar_icc' WHERE `entry`=37970; +UPDATE `creature_template` SET `ScriptName`='npc_blood_queen_lana_thel' WHERE `entry`=38004; +UPDATE `creature_template` SET `ScriptName`='npc_kinetic_bomb' WHERE `entry`=38454; +UPDATE `creature_template` SET `ScriptName`='npc_dark_nucleus' WHERE `entry`=38369; +UPDATE `creature_template` SET `ScriptName`='npc_ball_of_flame' WHERE `entry` IN (38332,38451); /* IRONFORGE */ UPDATE `creature_template` SET `ScriptName`='npc_royal_historian_archesonus' WHERE `entry`=8879; diff --git a/sql/updates/10284_world_script_texts.sql b/sql/updates/10284_world_script_texts.sql new file mode 100644 index 00000000000..4a617507473 --- /dev/null +++ b/sql/updates/10284_world_script_texts.sql @@ -0,0 +1,27 @@ +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1631139 AND -1631115; +INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`,`sound`,`type`,`language`,`emote`,`comment`) VALUES +(38004,-1631115,'Foolish mortals. You thought us defeated so easily? The San''layn are the Lich King''s immortal soldiers! Now you shall face their might combined!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16795,1,0,1,'SAY_INTRO_1'), +(38004,-1631116,'Rise up, brothers, and destroy our enemies.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16796,1,0,0,'SAY_INTRO_2'), +(37972,-1631117,'Such wondrous power! The Darkfallen Orb has made me INVINCIBLE!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16727,1,0,0,'SAY_KELESETH_INVOCATION'), +(37972,-1631118,'Invocation of Blood jumps to Prince Keleseth!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_KELESETH_INVOCATION'), +(37972,-1631119,'Blood will flow!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16728,1,0,0,'SAY_KELESETH_SPECIAL'), +(37972,-1631120,'Were you ever a threat?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16723,1,0,0,'SAY_KELESETH_KILL_1'), +(37972,-1631121,'Truth is found in death.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16724,1,0,0,'SAY_KELESETH_KILL_2'), +(37972,-1631122,'%s cackles maniacally!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16726,2,0,0,'EMOTE_KELESETH_BERSERK'), +(37972,-1631123,'My queen... they come...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16725,1,0,0,'SAY_KELESETH_DEATH'), +(37973,-1631124,'Tremble before Taldaram, mortals, for the power of the orb flows through me!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16857,1,0,0,'SAY_TALDARAM_INVOCATION'), +(37973,-1631125,'Invocation of Blood jumps to Prince Taldaram!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_TALDARAM_INVOCATION'), +(37973,-1631126,'Delight in the pain!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16858,1,0,0,'SAY_TALDARAM_SPECIAL'), +(37973,-1631127,'Inferno Flames speed toward $N!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_TALDARAM_FLAME'), +(37973,-1631128,'Worm food.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16853,1,0,0,'SAY_TALDARAM_KILL_1'), +(37973,-1631129,'Beg for mercy!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16854,1,0,0,'SAY_TALDARAM_KILL_2'), +(37973,-1631130,'%s laughs.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16856,2,0,0,'EMOTE_TALDARAM_BERSERK'), +(37973,-1631131,'%s gurgles and dies.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16855,2,0,0,'EMOTE_TALDARAM_DEATH'), +(37970,-1631132,'Naxxanar was merely a setback! With the power of the orb, Valanar will have his vengeance!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16685,1,0,0,'SAY_VALANAR_INVOCATION'), +(37970,-1631133,'Invocation of Blood jumps to Prince Valanar!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_VALANAR_INVOCATION'), +(37970,-1631134,'My cup runneth over.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16686,1,0,0,'SAY_VALANAR_SPECIAL'), +(37970,-1631135,'%s begins casting Empowered Schock Vortex!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_VALANAR_SHOCK_VORTEX'), +(37970,-1631136,'Dinner... is served.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16681,1,0,0,'SAY_VALANAR_KILL_1'), +(37970,-1631137,'Do you see NOW the power of the Darkfallen?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16682,1,0,0,'SAY_VALANAR_KILL_2'), +(37970,-1631138,'BOW DOWN BEFORE THE SAN''LAYN!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16684,1,0,0,'SAY_VALANAR_BERSERK'), +(37970,-1631139,'...why...?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16683,1,0,0,'SAY_VALANAR_DEATH'); diff --git a/sql/updates/10284_world_scriptname.sql b/sql/updates/10284_world_scriptname.sql new file mode 100644 index 00000000000..0dba0a9e82a --- /dev/null +++ b/sql/updates/10284_world_scriptname.sql @@ -0,0 +1,8 @@ +UPDATE `creature_template` SET `ScriptName`='boss_blood_council_controller' WHERE `entry`=38008; +UPDATE `creature_template` SET `ScriptName`='boss_prince_keleseth_icc' WHERE `entry`=37972; +UPDATE `creature_template` SET `ScriptName`='boss_prince_taldaram_icc' WHERE `entry`=37973; +UPDATE `creature_template` SET `ScriptName`='boss_prince_valanar_icc' WHERE `entry`=37970; +UPDATE `creature_template` SET `ScriptName`='npc_blood_queen_lana_thel' WHERE `entry`=38004; +UPDATE `creature_template` SET `ScriptName`='npc_kinetic_bomb' WHERE `entry`=38454; +UPDATE `creature_template` SET `ScriptName`='npc_dark_nucleus' WHERE `entry`=38369; +UPDATE `creature_template` SET `ScriptName`='npc_ball_of_flame' WHERE `entry` IN (38332,38451); diff --git a/sql/updates/10284_world_spell_script_names.sql b/sql/updates/10284_world_spell_script_names.sql new file mode 100644 index 00000000000..08bc5a3826a --- /dev/null +++ b/sql/updates/10284_world_spell_script_names.sql @@ -0,0 +1,25 @@ +DELETE FROM `spell_script_names` WHERE `spell_id`=71598 AND `ScriptName`='spell_creature_permanent_feign_death'; +DELETE FROM `spell_script_names` WHERE `spell_id`=71806 AND `ScriptName`='spell_taldaram_glittering_sparks'; +DELETE FROM `spell_script_names` WHERE `spell_id` IN (71718,72040) AND `ScriptName`='spell_taldaram_summon_flame_ball'; +DELETE FROM `spell_script_names` WHERE `spell_id` IN (55891,55947) AND `ScriptName`='spell_taldaram_flame_ball_visual'; +DELETE FROM `spell_script_names` WHERE `spell_id` IN (71756,72782,72783,72783) AND `ScriptName`='spell_taldaram_ball_of_inferno_flame'; +DELETE FROM `spell_script_names` WHERE `spell_id`=72080 AND `ScriptName`='spell_valanar_kinetic_bomb'; +DELETE FROM `spell_script_names` WHERE `spell_id`=72087 AND `ScriptName`='spell_valanar_kinetic_bomb_knockback'; +DELETE FROM `spell_script_names` WHERE `spell_id`=73001 AND `ScriptName`='spell_blood_council_shadow_prison'; +DELETE FROM `spell_script_names` WHERE `spell_id`=72999 AND `ScriptName`='spell_blood_council_shadow_prison_damage'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(71598,'spell_creature_permanent_feign_death'), +(71806,'spell_taldaram_glittering_sparks'), +(71718,'spell_taldaram_summon_flame_ball'), +(72040,'spell_taldaram_summon_flame_ball'), +(55891,'spell_taldaram_flame_ball_visual'), +(55947,'spell_taldaram_flame_ball_visual'), +(71756,'spell_taldaram_ball_of_inferno_flame'), +(72782,'spell_taldaram_ball_of_inferno_flame'), +(72783,'spell_taldaram_ball_of_inferno_flame'), +(72784,'spell_taldaram_ball_of_inferno_flame'), +(72080,'spell_valanar_kinetic_bomb'), +(72087,'spell_valanar_kinetic_bomb_knockback'), +(73001,'spell_blood_council_shadow_prison'), +(72999,'spell_blood_council_shadow_prison_damage'); + diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index e82f5d3b501..90d8d0f6e05 100755 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -94,7 +94,7 @@ class CreatureAI : public UnitAI virtual void EnterCombat(Unit* /*enemy*/) {} // Called at any Damage to any victim (before damage apply) - virtual void DamageDealt(Unit * /*done_to*/, uint32 & /*damage*/) { } + virtual void DamageDealt(Unit * /*done_to*/, uint32 & /*damage*/, DamageEffectType /*damagetype*/) { } // Called at any Damage from any attacker (before damage apply) // Note: it for recalculation damage or special reaction at damage diff --git a/src/server/game/AI/SmartAI/SmartAI.cpp b/src/server/game/AI/SmartAI/SmartAI.cpp index 0ba379fb5e0..37e9847d0e5 100755 --- a/src/server/game/AI/SmartAI/SmartAI.cpp +++ b/src/server/game/AI/SmartAI/SmartAI.cpp @@ -98,7 +98,7 @@ void SmartAI::SpellHitTarget(Unit* /*target*/, const SpellEntry* /*pSpell*/) { } -void SmartAI::DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) +void SmartAI::DamageTaken(Unit* /*done_by*/, uint32& /*damage*/, DamageEffectType /*damagetype*/) { } diff --git a/src/server/game/AI/SmartAI/SmartAI.h b/src/server/game/AI/SmartAI/SmartAI.h index d78abf8061e..d71a2d786a9 100755 --- a/src/server/game/AI/SmartAI/SmartAI.h +++ b/src/server/game/AI/SmartAI/SmartAI.h @@ -289,7 +289,7 @@ class SmartAI : public CreatureAI void SpellHitTarget(Unit* target, const SpellEntry*); // Called at any Damage from any attacker (before damage apply) - void DamageTaken(Unit* done_by, uint32& damage); + void DamageTaken(Unit* done_by, uint32& damage, DamageEffectType damagetype); // Called when the creature receives heal void HealReceived(Unit* done_by, uint32& addhealth); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d04efc0b408..3896c8a6a81 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -549,7 +549,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa pVictim->ToCreature()->AI()->DamageTaken(this, damage); if (GetTypeId() == TYPEID_UNIT && this->ToCreature()->IsAIEnabled) - this->ToCreature()->AI()->DamageDealt(pVictim, damage); + this->ToCreature()->AI()->DamageDealt(pVictim, damage, damagetype); if (damagetype != NODAMAGE) { @@ -7930,6 +7930,13 @@ bool Unit::HandleAuraProc(Unit * pVictim, uint32 damage, Aura * triggeredByAura, RemoveAuraFromStack(71564); *handled = true; break; + case 71756: + case 72782: + case 72783: + case 72784: + RemoveAuraFromStack(dummySpell->Id); + *handled = true; + break; } break; case SPELLFAMILY_PALADIN: diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 8b1b62dbc9a..762631dee6e 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -5259,7 +5259,6 @@ void ObjectMgr::ValidateSpellScripts() SpellEntry const * spellEntry = sSpellStore.LookupEntry(itr->first); std::vector<std::pair<SpellScriptLoader *, SpellScriptsMap::iterator> > SpellScriptLoaders; sScriptMgr.CreateSpellScriptLoaders(itr->first, SpellScriptLoaders); - SpellScriptsMap::iterator bitr; itr = mSpellScripts.upper_bound(itr->first); for (std::vector<std::pair<SpellScriptLoader *, SpellScriptsMap::iterator> >::iterator sitr = SpellScriptLoaders.begin(); sitr != SpellScriptLoaders.end(); ++sitr) diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index fda7e67a81c..3fe0cde699c 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -448,6 +448,7 @@ void AddSC_boss_deathbringer_saurfang(); void AddSC_boss_festergut(); void AddSC_boss_rotface(); void AddSC_boss_professor_putricide(); +void AddSC_boss_blood_prince_council(); void AddSC_icecrown_citadel_teleport(); void AddSC_instance_icecrown_citadel(); @@ -1108,6 +1109,7 @@ void AddNorthrendScripts() AddSC_boss_festergut(); AddSC_boss_rotface(); AddSC_boss_professor_putricide(); + AddSC_boss_blood_prince_council(); AddSC_icecrown_citadel_teleport(); AddSC_instance_icecrown_citadel(); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index a629ba995ff..a18d9d30941 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2245,9 +2245,16 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const return; } // Tear of Azzinoth Summon Channel - it's not really supposed to do anything,and this only prevents the console spam - case 39857: triggerSpellId = 39856; break; + case 39857: + triggerSpellId = 39856; + break; // Personalized Weather - case 46736: triggerSpellId = 46737; break; + case 46736: + triggerSpellId = 46737; + break; + // Ball of Flames Visual + case 71706: + return; } break; } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 61a2a17b4d1..7a449062444 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2207,7 +2207,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) dist = (float)target->GetSpellRadiusForTarget(target, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); if (dist < objSize) dist = objSize; - else if (cur == TARGET_DEST_CASTER_RANDOM) + else if (cur == TARGET_DEST_TARGET_RANDOM) dist = objSize + (dist - objSize) * (float)rand_norm(); switch(cur) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index b59fa23ae04..639276dde6e 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3928,6 +3928,13 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ENEMY; count++; break; + case 71708: // Empowered Flare + case 72785: // Empowered Flare + case 72786: // Empowered Flare + case 72787: // Empowered Flare + spellInfo->AttributesEx3 |= SPELL_ATTR_EX3_NO_DONE_BONUS; + count++; + break; default: break; } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp index b403e6bfb77..2e2db0e1fa4 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp @@ -187,7 +187,7 @@ class boss_janalai : public CreatureScript // DoZoneInCombat(); } - void DamageDealt(Unit *pTarget, uint32 &damage) + void DamageDealt(Unit *pTarget, uint32 &damage, DamageEffectType /*damagetype*/) { if (isFlameBreathing) { diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index f556f462b47..6de8a63ff1c 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -151,6 +151,7 @@ set(scripts_STAT_SRCS Northrend/IcecrownCitadel/boss_festergut.cpp Northrend/IcecrownCitadel/boss_rotface.cpp Northrend/IcecrownCitadel/boss_professor_putricide.cpp + Northrend/IcecrownCitadel/boss_blood_prince_council.cpp Northrend/zuldrak.cpp Northrend/icecrown.cpp Northrend/Gundrak/boss_slad_ran.cpp diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp new file mode 100644 index 00000000000..26478b41687 --- /dev/null +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -0,0 +1,1540 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "icecrown_citadel.h" + +enum eTexts +{ + // Blood Queen Lana'Thel + SAY_INTRO_1 = -1631115, + SAY_INTRO_2 = -1631116, + + // Prince Keleseth + SAY_KELESETH_INVOCATION = -1631117, + EMOTE_KELESETH_INVOCATION = -1631118, + SAY_KELESETH_SPECIAL = -1631119, + SAY_KELESETH_KILL_1 = -1631120, + SAY_KELESETH_KILL_2 = -1631121, + EMOTE_KELESETH_BERSERK = -1631122, + SAY_KELESETH_DEATH = -1631123, + + // Prince Taldaram + SAY_TALDARAM_INVOCATION = -1631124, + EMOTE_TALDARAM_INVOCATION = -1631125, + SAY_TALDARAM_SPECIAL = -1631126, + EMOTE_TALDARAM_FLAME = -1631127, + SAY_TALDARAM_KILL_1 = -1631128, + SAY_TALDARAM_KILL_2 = -1631129, + EMOTE_TALDARAM_BERSERK = -1631130, + EMOTE_TALDARAM_DEATH = -1631131, + + // Prince Valanar + SAY_VALANAR_INVOCATION = -1631132, + EMOTE_VALANAR_INVOCATION = -1631133, + SAY_VALANAR_SPECIAL = -1631134, + EMOTE_VALANAR_SHOCK_VORTEX = -1631135, + SAY_VALANAR_KILL_1 = -1631136, + SAY_VALANAR_KILL_2 = -1631137, + SAY_VALANAR_BERSERK = -1631138, + SAY_VALANAR_DEATH = -1631139 +}; + +enum eSpells +{ + SPELL_FEIGN_DEATH = 71598, + SPELL_OOC_INVOCATION_VISUAL = 70934, + SPELL_INVOCATION_VISUAL_ACTIVE = 71596, + + // Heroic mode + SPELL_SHADOW_PRISON = 72998, + SPELL_SHADOW_PRISON_DAMAGE = 72999, + SPELL_SHADOW_PRISON_DUMMY = 73001, + + // Prince Keleseth + SPELL_INVOCATION_OF_BLOOD_KELESETH = 70981, + SPELL_SHADOW_RESONANCE = 71943, + SPELL_SHADOW_LANCE = 71405, + SPELL_EMPOWERED_SHADOW_LANCE = 71815, + + // Dark Nucleus + SPELL_SHADOW_RESONANCE_AURA = 72980, + SPELL_SHADOW_RESONANCE_RESIST = 71822, + + // Prince Taldaram + SPELL_INVOCATION_OF_BLOOD_TALDARAM = 70982, + SPELL_GLITTERING_SPARKS = 71806, + SPELL_CONJURE_FLAME = 71718, + SPELL_CONJURE_EMPOWERED_FLAME = 72040, + + // Ball of Flame + SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891, // cast from creature_template_addon (needed cast before entering world) + SPELL_BALL_OF_FLAMES_VISUAL = 71706, + SPELL_BALL_OF_FLAMES = 71714, + SPELL_FLAMES = 71393, + SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947, + + // Ball of Inferno Flame + SPELL_BALL_OF_FLAMES_PROC = 71756, + SPELL_BALL_OF_FLAMES_PERIODIC = 71709, + + // Prince Valanar + SPELL_INVOCATION_OF_BLOOD_VALANAR = 70952, + SPELL_KINETIC_BOMB_TARGET = 72053, + SPELL_KINETIC_BOMB = 72080, + SPELL_SHOCK_VORTEX = 72037, + SPELL_EMPOWERED_SHOCK_VORTEX = 72039, + + // Kinetic Bomb + SPELL_UNSTABLE = 72059, + SPELL_KINETIC_BOMB_VISUAL = 72054, + SPELL_KINETIC_BOMB_EXPLOSION = 72052, + + // Shock Vortex + SPELL_SHOCK_VORTEX_PERIODIC = 71945, + SPELL_SHOCK_VORTEX_DUMMY = 72633, +}; + +enum eEvents +{ + EVENT_INTRO_1 = 1, + EVENT_INTRO_2 = 2, + + EVENT_INVOCATION_OF_BLOOD = 3, + EVENT_BERSERK = 4, + + // Keleseth + EVENT_SHADOW_RESONANCE = 5, + EVENT_SHADOW_LANCE = 6, + + // Taldaram + EVENT_GLITTERING_SPARKS = 7, + EVENT_CONJURE_FLAME = 8, + + // Valanar + EVENT_KINETIC_BOMB = 9, + EVENT_SHOCK_VORTEX = 10, + EVENT_BOMB_DESPAWN = 11, + EVENT_CONTINUE_FALLING = 12, +}; + +enum eActions +{ + ACTION_STAND_UP = 1, + ACTION_CAST_INVOCATION = 2, + ACTION_REMOVE_INVOCATION = 3, + ACTION_KINETIC_BOMB_JUMP = 4, + ACTION_FLAME_BALL_CHASE = 5, +}; + +enum ePoints +{ + POINT_INTRO_DESPAWN = 380040, + POINT_KINETIC_BOMB_IMPACT = 384540, +}; + +enum eDisplays +{ + DISPLAY_KINETIC_BOMB = 31095, +}; + +class StandUpEvent : public BasicEvent +{ + public: + StandUpEvent(Creature& owner) : BasicEvent(), m_owner(owner) { } + bool Execute(uint64 /*eventTime*/, uint32 /*diff*/) + { + m_owner.HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + return true; + } + + private: + Creature& m_owner; +}; + +static const Position introFinalPos = {4660.490f, 2769.200f, 430.0000f, 0.000000f}; +static const Position triggerPos = {4680.231f, 2769.134f, 379.9256f, 3.121708f}; +static const Position triggerEndPos = {4680.180f, 2769.150f, 365.5000f, 3.121708f}; + +class boss_blood_council_controller : public CreatureScript +{ + public: + boss_blood_council_controller() : CreatureScript("boss_blood_council_controller") { } + + struct boss_blood_council_controllerAI : public BossAI + { + boss_blood_council_controllerAI(Creature* pCreature) : BossAI(pCreature, DATA_BLOOD_PRINCE_COUNCIL) + { + } + + void InitializeAI() + { + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + Reset(); + } + + void Reset() + { + events.Reset(); + me->SetReactState(REACT_PASSIVE); + invocationStage = 0; + + instance->SetBossState(DATA_BLOOD_PRINCE_COUNCIL, NOT_STARTED); + } + + void EnterCombat(Unit* who) + { + instance->SetBossState(DATA_BLOOD_PRINCE_COUNCIL, IN_PROGRESS); + + DoCast(me, SPELL_INVOCATION_OF_BLOOD_VALANAR); + + if (Creature* keleseth = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_KELESETH_GUID))) + if (!keleseth->isInCombat()) + DoZoneInCombat(keleseth); + + if (Creature* taldaram = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_TALDARAM_GUID))) + if (!taldaram->isInCombat()) + DoZoneInCombat(taldaram); + + if (Creature* valanar = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_VALANAR_GUID))) + if (!valanar->isInCombat()) + DoZoneInCombat(valanar); + + events.ScheduleEvent(EVENT_INVOCATION_OF_BLOOD, 30000); + + invocationOrder[0] = InvocationData(instance->GetData64(DATA_PRINCE_VALANAR_GUID), SPELL_INVOCATION_OF_BLOOD_VALANAR, EMOTE_VALANAR_INVOCATION, 71070); + if (urand(0, 1)) + { + invocationOrder[1] = InvocationData(instance->GetData64(DATA_PRINCE_TALDARAM_GUID), SPELL_INVOCATION_OF_BLOOD_TALDARAM, EMOTE_TALDARAM_INVOCATION, 71081); + invocationOrder[2] = InvocationData(instance->GetData64(DATA_PRINCE_KELESETH_GUID), SPELL_INVOCATION_OF_BLOOD_KELESETH, EMOTE_KELESETH_INVOCATION, 71080); + } + else + { + invocationOrder[1] = InvocationData(instance->GetData64(DATA_PRINCE_KELESETH_GUID), SPELL_INVOCATION_OF_BLOOD_KELESETH, EMOTE_KELESETH_INVOCATION, 71080); + invocationOrder[2] = InvocationData(instance->GetData64(DATA_PRINCE_TALDARAM_GUID), SPELL_INVOCATION_OF_BLOOD_TALDARAM, EMOTE_TALDARAM_INVOCATION, 71081); + } + + if (IsHeroic()) + { + Map::PlayerList const &PlList = me->GetMap()->GetPlayers(); + if (PlList.isEmpty()) + return; + + for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i) + { + if (Player* player = i->getSource()) + { + if (player->isGameMaster()) + continue; + + if (player->isAlive()) + player->AddAura(SPELL_SHADOW_PRISON_DUMMY, player); + } + } + } + } + + void JustReachedHome() + { + instance->SetBossState(DATA_BLOOD_PRINCE_COUNCIL, FAIL); + } + + void JustDied(Unit* /*killer*/) + { + _JustDied(); + // kill the other 2 princes too + for (uint8 i = 0; i < 2; ++i) + { + if (++invocationStage == 3) + invocationStage = 0; + + if (Creature* prince = ObjectAccessor::GetCreature(*me, invocationOrder[invocationStage].guid)) + prince->Kill(prince); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INVOCATION_OF_BLOOD: + { + Creature* oldPrince = ObjectAccessor::GetCreature(*me, invocationOrder[invocationStage].guid); + if (++invocationStage == 3) + invocationStage = 0; + + Creature* newPrince = ObjectAccessor::GetCreature(*me, invocationOrder[invocationStage].guid); + if (oldPrince) + { + oldPrince->AI()->DoAction(ACTION_REMOVE_INVOCATION); + if (newPrince) + oldPrince->CastSpell(newPrince, invocationOrder[invocationStage].visualSpell, true); + } + + if (newPrince) + newPrince->SetHealth(me->GetHealth()); + + DoCast(me, invocationOrder[invocationStage].spellId); + DoScriptText(invocationOrder[invocationStage].textId, me); + events.ScheduleEvent(EVENT_INVOCATION_OF_BLOOD, 30000); + break; + } + default: + break; + } + } + } + + private: + struct InvocationData + { + uint64 guid; + uint32 spellId; + int32 textId; + uint32 visualSpell; + + InvocationData(uint64 _guid, uint32 _spellId, int32 _textId, uint32 _visualSpell) + { + guid = _guid; + spellId = _spellId; + textId = _textId; + visualSpell = _visualSpell; + } + + InvocationData() : guid(0), spellId(0), textId(0), visualSpell(0) { } + } invocationOrder[3]; + uint8 invocationStage; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new boss_blood_council_controllerAI(pCreature); + } +}; + +class boss_prince_keleseth_icc : public CreatureScript +{ + public: + boss_prince_keleseth_icc() : CreatureScript("boss_prince_keleseth_icc") { } + + struct boss_prince_kelesethAI : public BossAI + { + boss_prince_kelesethAI(Creature* pCreature) : BossAI(pCreature, DATA_BLOOD_PRINCE_COUNCIL) + { + bIsEmpowered = false; + spawnHealth = pCreature->GetMaxHealth(); + } + + void InitializeAI() + { + if (CreatureData const* data = sObjectMgr.GetCreatureData(me->GetDBTableGUIDLow())) + if (data->curhealth) + spawnHealth = data->curhealth; + + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + JustRespawned(); + + me->SetReactState(REACT_DEFENSIVE); + } + + void Reset() + { + events.Reset(); + summons.DespawnAll(); + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + bIsEmpowered = false; + me->SetHealth(spawnHealth); + instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(true)); + me->SetReactState(REACT_DEFENSIVE); + if (IsHeroic()) + DoCast(me, SPELL_SHADOW_PRISON); + } + + void MoveInLineOfSight(Unit* /*who*/) + { + } + + void EnterCombat(Unit* /*who*/) + { + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BLOOD_PRINCES_CONTROL))) + if (!controller->isInCombat()) + DoZoneInCombat(controller); + + events.ScheduleEvent(EVENT_BERSERK, 600000); + events.ScheduleEvent(EVENT_SHADOW_RESONANCE, urand(10000, 15000)); + events.ScheduleEvent(EVENT_SHADOW_LANCE, 2000); + } + + void JustDied(Unit* /*killer*/) + { + DoScriptText(SAY_KELESETH_DEATH, me); + } + + void JustRespawned() + { + DoCast(me, SPELL_FEIGN_DEATH); + me->SetHealth(spawnHealth); + } + + void SpellHit(Unit* /*caster*/, SpellEntry const* spell) + { + if (spell->Id == SPELL_INVOCATION_OF_BLOOD_KELESETH) + DoAction(ACTION_CAST_INVOCATION); + } + + void JustSummoned(Creature* summon) + { + summons.Summon(summon); + } + + void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) + { + if (damageType != SPELL_DIRECT_DAMAGE) + return; + + if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000)) + instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(false)); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (!bIsEmpowered) + damage = 0; + } + + void KilledUnit(Unit *victim) + { + if (victim->GetTypeId() == TYPEID_PLAYER) + DoScriptText(RAND(SAY_KELESETH_KILL_1, SAY_KELESETH_KILL_2), me); + } + + void DoAction(const int32 action) + { + switch (action) + { + case ACTION_STAND_UP: + me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE); + me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why + me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000)); + break; + case ACTION_CAST_INVOCATION: + DoScriptText(SAY_KELESETH_INVOCATION, me); + DoCast(me, SPELL_INVOCATION_VISUAL_ACTIVE, true); + bIsEmpowered = true; + break; + case ACTION_REMOVE_INVOCATION: + me->SetHealth(spawnHealth); + me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE); + me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_KELESETH); + bIsEmpowered = false; + break; + default: + break; + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BERSERK: + DoCast(me, SPELL_BERSERK); + DoScriptText(EMOTE_KELESETH_BERSERK, me); + break; + case EVENT_SHADOW_RESONANCE: + DoScriptText(SAY_KELESETH_SPECIAL, me); + DoCast(me, SPELL_SHADOW_RESONANCE); + events.ScheduleEvent(EVENT_SHADOW_RESONANCE, urand(10000, 15000)); + break; + case EVENT_SHADOW_LANCE: + if (bIsEmpowered) + DoCastVictim(SPELL_EMPOWERED_SHADOW_LANCE); + else + DoCastVictim(SPELL_SHADOW_LANCE); + events.ScheduleEvent(EVENT_SHADOW_LANCE, 2000); + break; + default: + break; + } + } + + // does not melee + } + + private: + bool bIsEmpowered; // bool check faster than map lookup + uint32 spawnHealth; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new boss_prince_kelesethAI(pCreature); + } +}; + +class boss_prince_taldaram_icc : public CreatureScript +{ + public: + boss_prince_taldaram_icc() : CreatureScript("boss_prince_taldaram_icc") { } + + struct boss_prince_taldaramAI : public BossAI + { + boss_prince_taldaramAI(Creature* pCreature) : BossAI(pCreature, DATA_BLOOD_PRINCE_COUNCIL) + { + bIsEmpowered = false; + spawnHealth = pCreature->GetMaxHealth(); + } + + void InitializeAI() + { + if (CreatureData const* data = sObjectMgr.GetCreatureData(me->GetDBTableGUIDLow())) + if (data->curhealth) + spawnHealth = data->curhealth; + + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + JustRespawned(); + + me->SetReactState(REACT_DEFENSIVE); + } + + void Reset() + { + events.Reset(); + summons.DespawnAll(); + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + bIsEmpowered = false; + me->SetHealth(spawnHealth); + instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(true)); + me->SetReactState(REACT_DEFENSIVE); + if (IsHeroic()) + DoCast(me, SPELL_SHADOW_PRISON); + } + + void MoveInLineOfSight(Unit* /*who*/) + { + } + + void EnterCombat(Unit* /*who*/) + { + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BLOOD_PRINCES_CONTROL))) + if (!controller->isInCombat()) + DoZoneInCombat(controller); + + events.ScheduleEvent(EVENT_BERSERK, 600000); + events.ScheduleEvent(EVENT_GLITTERING_SPARKS, urand(12000,15000)); + events.ScheduleEvent(EVENT_CONJURE_FLAME, 20000); + } + + void JustDied(Unit* /*killer*/) + { + DoScriptText(EMOTE_TALDARAM_DEATH, me); + } + + void JustRespawned() + { + DoCast(me, SPELL_FEIGN_DEATH); + me->SetHealth(spawnHealth); + } + + void SpellHit(Unit* /*caster*/, SpellEntry const* spell) + { + if (spell->Id == SPELL_INVOCATION_OF_BLOOD_TALDARAM) + DoAction(ACTION_CAST_INVOCATION); + } + + void JustSummoned(Creature* summon) + { + summons.Summon(summon); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -10.0f, true); // first try at distance + if (!target) + target = SelectTarget(SELECT_TARGET_RANDOM, 0/*1*/, 0.0f, true); // too bad for you raiders, its going to boom + + if (summon->GetEntry() == NPC_BALL_OF_INFERNO_FLAME) + DoScriptText(EMOTE_TALDARAM_FLAME, summon, target); // safe, has NULL checks + + if (target) + summon->AI()->SetGUID(target->GetGUID()); + } + + void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) + { + if (damageType != SPELL_DIRECT_DAMAGE) + return; + + if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000)) + instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(false)); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (!bIsEmpowered) + damage = 0; + } + + void KilledUnit(Unit *victim) + { + if (victim->GetTypeId() == TYPEID_PLAYER) + DoScriptText(RAND(SAY_TALDARAM_KILL_1, SAY_TALDARAM_KILL_2), me); + } + + void DoAction(const int32 action) + { + switch (action) + { + case ACTION_STAND_UP: + me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE); + me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why + me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000)); + break; + case ACTION_CAST_INVOCATION: + DoScriptText(SAY_TALDARAM_INVOCATION, me); + DoCast(me, SPELL_INVOCATION_VISUAL_ACTIVE, true); + bIsEmpowered = true; + break; + case ACTION_REMOVE_INVOCATION: + me->SetHealth(spawnHealth); + me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE); + me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_TALDARAM); + bIsEmpowered = false; + break; + default: + break; + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BERSERK: + DoCast(me, SPELL_BERSERK); + DoScriptText(EMOTE_TALDARAM_BERSERK, me); + break; + case EVENT_GLITTERING_SPARKS: + DoCastVictim(SPELL_GLITTERING_SPARKS); + events.ScheduleEvent(EVENT_GLITTERING_SPARKS, urand(15000, 50000)); + break; + case EVENT_CONJURE_FLAME: + if (bIsEmpowered) + { + DoCast(me, SPELL_CONJURE_EMPOWERED_FLAME); + events.ScheduleEvent(EVENT_CONJURE_FLAME, urand(15000, 25000)); + } + else + { + DoCast(me, SPELL_CONJURE_FLAME); + events.ScheduleEvent(EVENT_CONJURE_FLAME, urand(20000, 30000)); + } + DoScriptText(SAY_TALDARAM_SPECIAL, me); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + bool bIsEmpowered; // bool check faster than map lookup + uint32 spawnHealth; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new boss_prince_taldaramAI(pCreature); + } +}; + +class boss_prince_valanar_icc : public CreatureScript +{ + public: + boss_prince_valanar_icc() : CreatureScript("boss_prince_valanar_icc") { } + + struct boss_prince_valanarAI : public BossAI + { + boss_prince_valanarAI(Creature* pCreature) : BossAI(pCreature, DATA_BLOOD_PRINCE_COUNCIL) + { + bIsEmpowered = false; + spawnHealth = pCreature->GetMaxHealth(); + } + + void InitializeAI() + { + if (CreatureData const* data = sObjectMgr.GetCreatureData(me->GetDBTableGUIDLow())) + if (data->curhealth) + spawnHealth = data->curhealth; + + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + JustRespawned(); + + me->SetReactState(REACT_DEFENSIVE); + } + + void Reset() + { + events.Reset(); + summons.DespawnAll(); + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + bIsEmpowered = false; + me->SetHealth(me->GetMaxHealth()); + instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(true)); + me->SetReactState(REACT_DEFENSIVE); + if (IsHeroic()) + DoCast(me, SPELL_SHADOW_PRISON); + } + + void MoveInLineOfSight(Unit* /*who*/) + { + } + + void EnterCombat(Unit* /*who*/) + { + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BLOOD_PRINCES_CONTROL))) + if (!controller->isInCombat()) + DoZoneInCombat(controller); + + events.ScheduleEvent(EVENT_BERSERK, 600000); + events.ScheduleEvent(EVENT_KINETIC_BOMB, urand(18000, 24000)); + events.ScheduleEvent(EVENT_SHOCK_VORTEX, urand(15000, 20000)); + } + + void JustDied(Unit* /*killer*/) + { + DoScriptText(SAY_VALANAR_DEATH, me); + } + + void JustRespawned() + { + DoCast(me, SPELL_FEIGN_DEATH); + me->SetHealth(spawnHealth); + } + + void JustSummoned(Creature* summon) + { + switch (summon->GetEntry()) + { + case NPC_KINETIC_BOMB_TARGET: + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell(summon, SPELL_KINETIC_BOMB, true, NULL, NULL, me->GetGUID()); + break; + case NPC_KINETIC_BOMB: + { + float x, y, z; + summon->GetPosition(x, y, z); + float ground_Z = summon->GetMap()->GetHeight(x, y, z, true, 500.0f); + summon->GetMotionMaster()->MovePoint(POINT_KINETIC_BOMB_IMPACT, x, y, ground_Z); + break; + } + case NPC_SHOCK_VORTEX: + summon->CastSpell(summon, SPELL_SHOCK_VORTEX_DUMMY, true); + summon->CastSpell(summon, SPELL_SHOCK_VORTEX_PERIODIC, true); + break; + default: + break; + } + summons.Summon(summon); + if (me->isInCombat()) + DoZoneInCombat(summon); + } + + void SpellHit(Unit* /*caster*/, SpellEntry const* spell) + { + if (spell->Id == SPELL_INVOCATION_OF_BLOOD_VALANAR) + DoAction(ACTION_CAST_INVOCATION); + } + + void DamageDealt(Unit* /*target*/, uint32& damage, DamageEffectType damageType) + { + if (damageType != SPELL_DIRECT_DAMAGE) + return; + + if (damage > RAID_MODE<uint32>(23000, 25000, 23000, 25000)) + instance->SetData(DATA_ORB_WHISPERER_ACHIEVEMENT, uint32(false)); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (!bIsEmpowered) + damage = 0; + } + + void KilledUnit(Unit *victim) + { + if (victim->GetTypeId() == TYPEID_PLAYER) + DoScriptText(RAND(SAY_VALANAR_KILL_1, SAY_VALANAR_KILL_2), me); + } + + void DoAction(const int32 action) + { + switch (action) + { + case ACTION_STAND_UP: + me->RemoveAurasDueToSpell(SPELL_FEIGN_DEATH); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE); + me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why + me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000)); + break; + case ACTION_CAST_INVOCATION: + DoScriptText(SAY_VALANAR_INVOCATION, me); + DoCast(me, SPELL_INVOCATION_VISUAL_ACTIVE, true); + bIsEmpowered = true; + break; + case ACTION_REMOVE_INVOCATION: + me->SetHealth(spawnHealth); + me->RemoveAurasDueToSpell(SPELL_INVOCATION_VISUAL_ACTIVE); + me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_VALANAR); + bIsEmpowered = false; + break; + default: + break; + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BERSERK: + DoCast(me, SPELL_BERSERK); + DoScriptText(SAY_VALANAR_BERSERK, me); + break; + case EVENT_KINETIC_BOMB: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + { + DoCast(target, SPELL_KINETIC_BOMB_TARGET); + DoScriptText(SAY_VALANAR_SPECIAL, me); + } + events.ScheduleEvent(EVENT_KINETIC_BOMB, urand(18000, 24000)); + break; + case EVENT_SHOCK_VORTEX: + if (bIsEmpowered) + { + DoCast(me, SPELL_EMPOWERED_SHOCK_VORTEX); + DoScriptText(EMOTE_VALANAR_SHOCK_VORTEX, me); + events.ScheduleEvent(EVENT_SHOCK_VORTEX, 30000); + } + else + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + DoCast(target, SPELL_SHOCK_VORTEX); + events.ScheduleEvent(EVENT_SHOCK_VORTEX, urand(18000, 23000)); + } + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + bool bIsEmpowered; // bool check faster than map lookup + uint32 spawnHealth; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new boss_prince_valanarAI(pCreature); + } +}; + +class npc_blood_queen_lana_thel : public CreatureScript +{ + public: + npc_blood_queen_lana_thel() : CreatureScript("npc_blood_queen_lana_thel") { } + + struct npc_blood_queen_lana_thelAI : public ScriptedAI + { + npc_blood_queen_lana_thelAI(Creature* pCreature) : ScriptedAI(pCreature) + { + bIntroDone = false; + instance = pCreature->GetInstanceScript(); + } + + void InitializeAI() + { + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + Reset(); + } + + void Reset() + { + events.Reset(); + me->SetVisibility(VISIBILITY_ON); + me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); + } + + void MoveInLineOfSight(Unit* who) + { + if (bIntroDone) + return; + + if (!me->IsWithinDistInMap(who, 35.0f)) + return; + + bIntroDone = true; + DoScriptText(SAY_INTRO_1, me); + events.SetPhase(1); + events.ScheduleEvent(EVENT_INTRO_1, 14000); + // summon a visual trigger + if (Creature* summon = DoSummon(NPC_FLOATING_TRIGGER, triggerPos, 15000, TEMPSUMMON_TIMED_DESPAWN)) + { + summon->CastSpell(summon, SPELL_OOC_INVOCATION_VISUAL, true); + summon->SetSpeed(MOVE_FLIGHT, 0.15f, true); + summon->GetMotionMaster()->MovePoint(0, triggerEndPos); + } + } + + void MovementInform(uint32 type, uint32 id) + { + if (type == POINT_MOTION_TYPE && id == POINT_INTRO_DESPAWN) + me->SetVisibility(VISIBILITY_OFF); + } + + void UpdateAI(const uint32 diff) + { + if (!events.GetPhaseMask()) + return; + + events.Update(diff); + + if (events.ExecuteEvent() == EVENT_INTRO_1) + { + DoScriptText(SAY_INTRO_2, me); + me->GetMotionMaster()->MovePoint(POINT_INTRO_DESPAWN, introFinalPos); + events.Reset(); + + // remove Feign Death from princes + if (Creature* keleseth = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_KELESETH_GUID))) + keleseth->AI()->DoAction(ACTION_STAND_UP); + + if (Creature* taldaram = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_TALDARAM_GUID))) + taldaram->AI()->DoAction(ACTION_STAND_UP); + + if (Creature* valanar = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_VALANAR_GUID))) + { + valanar->AI()->DoAction(ACTION_STAND_UP); + valanar->SetHealth(valanar->GetMaxHealth()); + } + } + } + + private: + bool bIntroDone; + EventMap events; + InstanceScript* instance; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_blood_queen_lana_thelAI(pCreature); + } +}; + +class npc_ball_of_flame : public CreatureScript +{ + public: + npc_ball_of_flame() : CreatureScript("npc_ball_of_flame") { } + + struct npc_ball_of_flameAI : public ScriptedAI + { + npc_ball_of_flameAI(Creature* pCreature) : ScriptedAI(pCreature) + { + despawnTimer = 0; + } + + void Reset() + { + me->CastSpell(me, SPELL_BALL_OF_FLAMES_VISUAL, true); + if (me->GetEntry() == NPC_BALL_OF_INFERNO_FLAME) + { + me->CastSpell(me, SPELL_BALL_OF_FLAMES_PROC, true); + me->CastSpell(me, SPELL_BALL_OF_FLAMES_PERIODIC, true); + } + } + + void MovementInform(uint32 type, uint32 id) + { + if (type == TARGETED_MOTION_TYPE && id == GUID_LOPART(chaseGUID) && chaseGUID) + { + me->RemoveAurasDueToSpell(SPELL_BALL_OF_FLAMES_PERIODIC); + DoCastAOE(SPELL_FLAMES); + despawnTimer = 1000; + chaseGUID = 0; + } + } + + void SetGUID(const uint64& guid, int32 /*type*/) + { + chaseGUID = guid; + } + + void DoAction(const int32 action) + { + if (action == ACTION_FLAME_BALL_CHASE) + if (Player* target = ObjectAccessor::GetPlayer(*me, chaseGUID)) + { + // need to clear states now because this call is before AuraEffect is fully removed + me->clearUnitState(UNIT_STAT_CASTING | UNIT_STAT_STUNNED); + if (target && me->Attack(target, true)) + me->GetMotionMaster()->MoveChase(target, 1.0f); + } + } + + void UpdateAI(const uint32 diff) + { + if (!despawnTimer) + return; + + if (despawnTimer <= diff) + { + despawnTimer = 0; + DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT); + } + else + despawnTimer -= diff; + } + + private: + uint32 despawnTimer; + uint64 chaseGUID; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_ball_of_flameAI(pCreature); + } +}; + +class npc_kinetic_bomb : public CreatureScript +{ + public: + npc_kinetic_bomb() : CreatureScript("npc_kinetic_bomb") { } + + struct npc_kinetic_bombAI : public ScriptedAI + { + npc_kinetic_bombAI(Creature* pCreature) : ScriptedAI(pCreature) { } + + void Reset() + { + events.Reset(); + me->SetDisplayId(DISPLAY_KINETIC_BOMB); + me->CastSpell(me, SPELL_UNSTABLE, true); + me->CastCustomSpell(SPELL_KINETIC_BOMB_VISUAL, SPELLVALUE_BASE_POINT0, 0x7FFFFFFF, me, true); + me->SetReactState(REACT_PASSIVE); + me->SetSpeed(MOVE_FLIGHT, IsHeroic() ? 0.3f : 0.15f, true); + me->GetPosition(x, y, groundZ); + groundZ = me->GetMap()->GetHeight(x, y, groundZ, true, 500.0f); + } + + void DoAction(const int32 action) + { + if (action == SPELL_KINETIC_BOMB_EXPLOSION) + events.ScheduleEvent(EVENT_BOMB_DESPAWN, 1000); + else if (action == ACTION_KINETIC_BOMB_JUMP) + { + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveJump(x, y, me->GetPositionZ()+7.0f, 1.0f, 7.0f); + events.ScheduleEvent(EVENT_CONTINUE_FALLING, 700); + } + } + + void UpdateAI(const uint32 diff) + { + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BOMB_DESPAWN: + me->SetVisibility(VISIBILITY_OFF); + break; + case EVENT_CONTINUE_FALLING: + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MovePoint(POINT_KINETIC_BOMB_IMPACT, x, y, groundZ); + break; + default: + break; + } + } + } + + private: + EventMap events; + float x, y, groundZ; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_kinetic_bombAI(pCreature); + } +}; + +class npc_dark_nucleus : public CreatureScript +{ + public: + npc_dark_nucleus() : CreatureScript("npc_dark_nucleus") { } + + struct npc_dark_nucleusAI : public ScriptedAI + { + npc_dark_nucleusAI(Creature* pCreature) : ScriptedAI(pCreature) + { + lockedTarget = false; + targetAuraCheck = 0; + } + + void Reset() + { + me->SetReactState(REACT_PASSIVE); + me->CastSpell(me, SPELL_SHADOW_RESONANCE_AURA, true); + } + + void EnterCombat(Unit* who) + { + targetAuraCheck = 1000; + if (me->GetDistance(who) >= 15.0f) + { + DoStartMovement(who); + return; + } + + DoCast(who, SPELL_SHADOW_RESONANCE_RESIST); + me->clearUnitState(UNIT_STAT_CASTING); + } + + void MoveInLineOfSight(Unit* who) + { + if (me->GetDistance(who) >= 15.0f) + return; + + ScriptedAI::MoveInLineOfSight(who); + } + + void DamageTaken(Unit* attacker, uint32& /*damage*/) + { + if (attacker == me) + return; + + if (!lockedTarget) + if (me->getVictim() == attacker) + lockedTarget = true; + } + + void UpdateAI(const uint32 diff) + { + if (!me->isInCombat()) + return; + + if (targetAuraCheck <= diff) + { + targetAuraCheck = 1000; + if (Unit *victim = me->getVictim()) + if (me->GetDistance(victim) < 15.0f && + !victim->HasAura(SPELL_SHADOW_RESONANCE_RESIST, me->GetGUID())) + { + DoCast(victim, SPELL_SHADOW_RESONANCE_RESIST); + me->clearUnitState(UNIT_STAT_CASTING); + } + } + else + targetAuraCheck -= diff; + + if (!lockedTarget) + { + if (Unit *victim = me->SelectVictim()) + { + if (me->getVictim() && me->getVictim() != victim) + { + me->getVictim()->RemoveAurasDueToSpell(SPELL_SHADOW_RESONANCE_RESIST, me->GetGUID()); + lockedTarget = true; + } + + lockedTarget = true; + AttackStart(victim); + DoCast(victim, SPELL_SHADOW_RESONANCE_RESIST); + me->clearUnitState(UNIT_STAT_CASTING); + } + } + } + + private: + uint32 targetAuraCheck; // no point for EventMap with only one timer + bool lockedTarget; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_dark_nucleusAI(pCreature); + } +}; + +class spell_taldaram_glittering_sparks : public SpellScriptLoader +{ + public: + spell_taldaram_glittering_sparks() : SpellScriptLoader("spell_taldaram_glittering_sparks") { } + + class spell_taldaram_glittering_sparks_SpellScript : public SpellScript + { + PrepareSpellScript(spell_taldaram_glittering_sparks_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetCaster(), GetEffectValue(), true); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_taldaram_glittering_sparks_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_taldaram_glittering_sparks_SpellScript(); + } +}; + +class spell_taldaram_summon_flame_ball : public SpellScriptLoader +{ + public: + spell_taldaram_summon_flame_ball() : SpellScriptLoader("spell_taldaram_summon_flame_ball") { } + + class spell_taldaram_summon_flame_ball_SpellScript : public SpellScript + { + PrepareSpellScript(spell_taldaram_summon_flame_ball_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetCaster(), GetEffectValue(), true); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_taldaram_summon_flame_ball_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_taldaram_summon_flame_ball_SpellScript(); + } +}; + +class spell_taldaram_flame_ball_visual : public SpellScriptLoader +{ + public: + spell_taldaram_flame_ball_visual() : SpellScriptLoader("spell_taldaram_flame_ball_visual") { } + + class spell_flame_ball_visual_AuraScript : public AuraScript + { + PrepareAuraScript(spell_flame_ball_visual_AuraScript); + + bool Load() + { + if (GetCaster()->GetEntry() == NPC_BALL_OF_FLAME || GetCaster()->GetEntry() == NPC_BALL_OF_INFERNO_FLAME) + return true; + return false; + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/) + { + Creature* target = aurApp->GetTarget()->ToCreature(); + if (!target) + return; + + // SPELL_FLAME_SPHERE_SPAWN_EFFECT + if (GetSpellProto()->Id == SPELL_FLAME_SPHERE_SPAWN_EFFECT) + { + target->CastSpell(target, SPELL_BALL_OF_FLAMES, true); + target->AI()->DoAction(ACTION_FLAME_BALL_CHASE); + } + else // SPELL_FLAME_SPHERE_DEATH_EFFECT + { + if (TempSummon* summ = target->ToTempSummon()) + summ->UnSummon(); + else + target->ForcedDespawn(); + } + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_flame_ball_visual_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_flame_ball_visual_AuraScript(); + } +}; + +class spell_taldaram_ball_of_inferno_flame : public SpellScriptLoader +{ + public: + spell_taldaram_ball_of_inferno_flame() : SpellScriptLoader("spell_taldaram_ball_of_inferno_flame") { } + + class spell_taldaram_ball_of_inferno_flame_SpellScript : public SpellScript + { + PrepareSpellScript(spell_taldaram_ball_of_inferno_flame_SpellScript); + + void ModAuraStack() + { + if (Aura* aur = GetHitAura()) + aur->SetStackAmount(GetSpellInfo()->StackAmount); + } + + void Register() + { + AfterHit += SpellHitFn(spell_taldaram_ball_of_inferno_flame_SpellScript::ModAuraStack); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_taldaram_ball_of_inferno_flame_SpellScript(); + } +}; + +class spell_valanar_kinetic_bomb : public SpellScriptLoader +{ + public: + spell_valanar_kinetic_bomb() : SpellScriptLoader("spell_valanar_kinetic_bomb") { } + + class spell_valanar_kinetic_bomb_SpellScript : public SpellScript + { + PrepareSpellScript(spell_valanar_kinetic_bomb_SpellScript); + + void ChangeSummonPos(SpellEffIndex /*effIndex*/) + { + WorldLocation* summonPos = GetTargetDest(); + Position offset = {0.0f, 0.0f, 20.0f, 0.0f}; + summonPos->RelocateOffset(offset); // +20 in height + } + + void Register() + { + OnEffect += SpellEffectFn(spell_valanar_kinetic_bomb_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); + } + }; + + class spell_valanar_kinetic_bomb_AuraScript : public AuraScript + { + PrepareAuraScript(spell_valanar_kinetic_bomb_AuraScript); + + void HandleDummyTick(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp) + { + Unit* target = aurApp->GetTarget(); + if (target->GetTypeId() != TYPEID_UNIT) + return; + + if (Creature* bomb = target->FindNearestCreature(NPC_KINETIC_BOMB, 1.0f, true)) + { + bomb->CastSpell(bomb, SPELL_KINETIC_BOMB_EXPLOSION, true); + bomb->RemoveAurasDueToSpell(SPELL_KINETIC_BOMB_VISUAL); + target->RemoveAura(const_cast<AuraApplication*>(aurApp)); + bomb->AI()->DoAction(SPELL_KINETIC_BOMB_EXPLOSION); + } + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_valanar_kinetic_bomb_AuraScript::HandleDummyTick, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_valanar_kinetic_bomb_SpellScript(); + } + + AuraScript* GetAuraScript() const + { + return new spell_valanar_kinetic_bomb_AuraScript(); + } +}; + +class spell_valanar_kinetic_bomb_knockback : public SpellScriptLoader +{ + public: + spell_valanar_kinetic_bomb_knockback() : SpellScriptLoader("spell_valanar_kinetic_bomb_knockback") { } + + class spell_valanar_kinetic_bomb_knockback_SpellScript : public SpellScript + { + PrepareSpellScript(spell_valanar_kinetic_bomb_knockback_SpellScript); + + void KnockIntoAir() + { + if (Creature* target = GetHitCreature()) + target->AI()->DoAction(ACTION_KINETIC_BOMB_JUMP); + } + + void Register() + { + AfterHit += SpellHitFn(spell_valanar_kinetic_bomb_knockback_SpellScript::KnockIntoAir); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_valanar_kinetic_bomb_knockback_SpellScript(); + } +}; + +class spell_blood_council_shadow_prison : public SpellScriptLoader +{ + public: + spell_blood_council_shadow_prison() : SpellScriptLoader("spell_blood_council_shadow_prison") { } + + class spell_blood_council_shadow_prison_AuraScript : public AuraScript + { + PrepareAuraScript(spell_blood_council_shadow_prison_AuraScript); + + void HandleDummyTick(AuraEffect const* aurEff, AuraApplication const* aurApp) + { + if (aurApp->GetTarget()->isMoving()) + aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), SPELL_SHADOW_PRISON_DAMAGE, true, NULL, aurEff); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_blood_council_shadow_prison_AuraScript::HandleDummyTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_blood_council_shadow_prison_AuraScript(); + } +}; + +class spell_blood_council_shadow_prison_damage : public SpellScriptLoader +{ + public: + spell_blood_council_shadow_prison_damage() : SpellScriptLoader("spell_blood_council_shadow_prison_damage") { } + + class spell_blood_council_shadow_prison_SpellScript : public SpellScript + { + PrepareSpellScript(spell_blood_council_shadow_prison_SpellScript); + + void AddExtraDamage() + { + if (Aura* aur = GetHitUnit()->GetAura(GetSpellInfo()->Id)) + if (AuraEffect const* eff = aur->GetEffect(1)) + SetHitDamage(GetHitDamage()+eff->GetAmount()); + } + + void Register() + { + OnHit += SpellHitFn(spell_blood_council_shadow_prison_SpellScript::AddExtraDamage); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_blood_council_shadow_prison_SpellScript(); + } +}; + +void AddSC_boss_blood_prince_council() +{ + new boss_blood_council_controller(); + new boss_prince_keleseth_icc(); + new boss_prince_taldaram_icc(); + new boss_prince_valanar_icc(); + new npc_blood_queen_lana_thel(); + new npc_ball_of_flame(); + new npc_kinetic_bomb(); + new npc_dark_nucleus(); + new spell_taldaram_glittering_sparks(); + new spell_taldaram_summon_flame_ball(); + new spell_taldaram_flame_ball_visual(); + new spell_taldaram_ball_of_inferno_flame(); + new spell_valanar_kinetic_bomb(); + new spell_valanar_kinetic_bomb_knockback(); + new spell_blood_council_shadow_prison(); + new spell_blood_council_shadow_prison_damage(); +} diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index a66767ccf6d..ac976eb4de1 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -233,12 +233,19 @@ class boss_deathbringer_saurfang : public CreatureScript { boss_deathbringer_saurfangAI(Creature* pCreature) : BossAI(pCreature, DATA_DEATHBRINGER_SAURFANG) { - ASSERT(instance); ASSERT(pCreature->GetVehicleKit()); // we dont actually use it, just check if exists bIntroDone = false; uiFallenChampionCount = 0; } + void InitializeAI() + { + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + Reset(); + } + void Reset() { events.Reset(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp index ace192a17e3..3092ddf8ef2 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp @@ -80,12 +80,19 @@ class boss_festergut : public CreatureScript { boss_festergutAI(Creature* pCreature) : BossAI(pCreature, DATA_FESTERGUT) { - ASSERT(instance); uiMaxInoculatedStack = 0; uiInhaleCounter = 0; gasDummyGUID = 0; } + void InitializeAI() + { + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + Reset(); + } + void Reset() { events.Reset(); @@ -115,7 +122,6 @@ class boss_festergut : public CreatureScript DoScriptText(SAY_AGGRO, me); if (Creature* gasDummy = GetClosestCreatureWithEntry(me, NPC_GAS_DUMMY, 100.0f, true)) gasDummyGUID = gasDummy->GetGUID(); - instance->SetBossState(DATA_FESTERGUT, IN_PROGRESS); if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE))) professor->AI()->DoAction(ACTION_FESTERGUT_COMBAT); @@ -202,10 +208,19 @@ class boss_festergut : public CreatureScript return; } case EVENT_VILE_GAS: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, -5.0f, true)) + { + std::list<Unit*> targets; + uint32 minTargets = RAID_MODE(3,8,3,8); + SelectTargetList(targets, minTargets, SELECT_TARGET_RANDOM, -5.0f, true); + float minDist = 0.0f; + if (targets.size() >= minTargets) + minDist = -5.0f; + + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, minDist, true)) DoCast(target, SPELL_VILE_GAS); events.ScheduleEvent(EVENT_VILE_GAS, urand(28000, 35000)); break; + } case EVENT_GAS_SPORE: DoScriptText(EMOTE_WARN_GAS_SPORE, me); me->CastCustomSpell(SPELL_GAS_SPORE, SPELLVALUE_MAX_TARGETS, RAID_MODE<int32>(2,3,2,3), me); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index 70abca40bc6..628c5eb3312 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -160,11 +160,18 @@ class boss_lady_deathwhisper : public CreatureScript { boss_lady_deathwhisperAI(Creature* pCreature) : BossAI(pCreature, DATA_LADY_DEATHWHISPER) { - ASSERT(instance); bIntroDone = false; uiDominateMindCount = RAID_MODE(0,1,1,3); } + void InitializeAI() + { + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + Reset(); + } + void Reset() { me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA)); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 4f90df15497..b0bad028cbc 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -81,7 +81,6 @@ class boss_lord_marrowgar : public CreatureScript { boss_lord_marrowgarAI(Creature *pCreature) : BossAI(pCreature, DATA_LORD_MARROWGAR) { - ASSERT(instance); bIntroDone = false; uiBoneStormDuration = RAID_MODE(20000,30000,20000,30000); fBaseSpeed = pCreature->GetSpeedRate(MOVE_RUN); @@ -89,6 +88,14 @@ class boss_lord_marrowgar : public CreatureScript coldflameLastPos.Relocate(pCreature); } + void InitializeAI() + { + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + Reset(); + } + void Reset() { me->SetSpeed(MOVE_RUN, fBaseSpeed, true); @@ -349,7 +356,7 @@ class npc_bone_spike : public CreatureScript void JustDied(Unit * /*killer*/) { events.Reset(); - if (Unit* trapped = Unit::GetUnit((*me), uiTrappedGUID)) + if (Player* trapped = ObjectAccessor::GetPlayer(*me, uiTrappedGUID)) trapped->RemoveAurasDueToSpell(SPELL_IMPALED); } @@ -364,7 +371,7 @@ class npc_bone_spike : public CreatureScript return; events.Update(diff); - Unit* trapped = Unit::GetUnit(*me, uiTrappedGUID); + Player* trapped = ObjectAccessor::GetPlayer(*me, uiTrappedGUID); if ((trapped && trapped->isAlive() && !trapped->HasAura(SPELL_IMPALED)) || !trapped) me->Kill(me); @@ -373,10 +380,11 @@ class npc_bone_spike : public CreatureScript instance->SetData(DATA_BONED_ACHIEVEMENT, uint32(false)); } - void SetTrappedUnit(Unit* unit) + void SetGUID(const uint64& guid, int32 /*type = 0*/) { - unit->EnterVehicle(vehicle, 0); - uiTrappedGUID = unit->GetGUID(); + uiTrappedGUID = guid; + if (Player* target = ObjectAccessor::GetPlayer(*me, guid)) + target->EnterVehicle(vehicle, 0); } void PassengerBoarded(Unit * who, int8 /*seatId*/, bool apply) @@ -460,9 +468,9 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader if (!target) break; yell = true; - //marrowgarAI->DoCast(*itr, SPELL_IMPALE); // this is the proper spell but if we use it we dont have any way to assign a victim to it + //GetCaster()->CastSpell(target, SPELL_IMPALE, true); // this is the proper spell but if we use it we dont have any way to assign a victim to it Creature* pBone = GetCaster()->SummonCreature(NPC_BONE_SPIKE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN); - CAST_AI(npc_bone_spike::npc_bone_spikeAI, pBone->AI())->SetTrappedUnit(target); + pBone->AI()->SetGUID(target->GetGUID()); } if (yell) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 2bf5fed9e5e..a6878464d44 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -75,6 +75,7 @@ enum eSpells SPELL_PLAGUE_SICKNESS = 70953, SPELL_UNBOUND_PLAGUE_PROTECTION = 70955, SPELL_MUTATED_PLAGUE = 72451, + SPELL_UNHOLY_INFUSION_CREDIT = 71518, // Slime Puddle SPELL_GROW_STACKER = 70345, @@ -181,15 +182,22 @@ class boss_professor_putricide : public CreatureScript boss_professor_putricideAI(Creature* pCreature) : BossAI(pCreature, DATA_PROFESSOR_PUTRICIDE), fBaseSpeed(pCreature->GetSpeedRate(MOVE_RUN)), bExperimentState(EXPERIMENT_STATE_OOZE) { - ASSERT(instance); phase = ePhases(0); } + void InitializeAI() + { + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + Reset(); + } + void Reset() { if (!(events.GetPhaseMask() & PHASE_MASK_NOT_SELF)) instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, NOT_STARTED); - instance->SetData(DATA_NAUSEA___ACHIEVEMENT, uint32(true)); + instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(true)); events.Reset(); summons.DespawnAll(); @@ -238,6 +246,7 @@ class boss_professor_putricide : public CreatureScript { DoScriptText(SAY_DEATH, me); instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, DONE); + DoCastAOE(SPELL_UNHOLY_INFUSION_CREDIT, true); } void JustSummoned(Creature* summon) @@ -253,9 +262,6 @@ class boss_professor_putricide : public CreatureScript // no possible aura seen in sniff adding the aurastate summon->SetFlag(UNIT_FIELD_AURASTATE, 1 << (AURA_STATE_UNKNOWN22-1)); summon->CastSpell(summon, SPELL_GASEOUS_BLOAT_PROC, true); - // taunt immunity - summon->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_GASEOUS_BLOAT_PROTECTION)) { summon->AI()->AttackStart(target); @@ -269,9 +275,6 @@ class boss_professor_putricide : public CreatureScript // no possible aura seen in sniff adding the aurastate summon->SetFlag(UNIT_FIELD_AURASTATE, 1 << (AURA_STATE_UNKNOWN19-1)); summon->CastSpell(summon, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, true); - // taunt immunity - summon->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); - summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_VOLATILE_OOZE_PROTECTION)) { summon->AI()->AttackStart(target); @@ -320,12 +323,14 @@ class boss_professor_putricide : public CreatureScript switch (id) { case POINT_FESTERGUT: + instance->SetBossState(DATA_FESTERGUT, IN_PROGRESS); // needed here for delayed gate close me->SetSpeed(MOVE_RUN, fBaseSpeed, true); DoAction(ACTION_FESTERGUT_GAS); if (Creature* festergut = Unit::GetCreature(*me, instance->GetData64(DATA_FESTERGUT))) festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, false, NULL, NULL, festergut->GetGUID()); break; case POINT_ROTFACE: + instance->SetBossState(DATA_ROTFACE, IN_PROGRESS); // needed here for delayed gate close me->SetSpeed(MOVE_RUN, fBaseSpeed, true); DoAction(ACTION_ROTFACE_OOZE); events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000, 0, PHASE_ROTFACE); @@ -1271,7 +1276,7 @@ class spell_putricide_regurgitated_ooze : public SpellScriptLoader void ExtraEffect(SpellEffIndex /*effIndex*/) { if (InstanceScript* instance = GetCaster()->GetInstanceScript()) - instance->SetData(DATA_NAUSEA___ACHIEVEMENT, uint32(false)); + instance->SetData(DATA_NAUSEA_ACHIEVEMENT, uint32(false)); } void Register() diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index 692dc145ac9..4016c5480e3 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -86,11 +86,18 @@ class boss_rotface : public CreatureScript { boss_rotfaceAI(Creature* pCreature) : BossAI(pCreature, DATA_ROTFACE) { - ASSERT(instance); infectionStage = 0; infectionCooldown = 14000; } + void InitializeAI() + { + if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName)) + me->IsAIEnabled = false; + else if (!me->isDead()) + Reset(); + } + void Reset() { events.Reset(); @@ -107,7 +114,6 @@ class boss_rotface : public CreatureScript void EnterCombat(Unit* /*who*/) { DoScriptText(SAY_AGGRO, me); - instance->SetBossState(DATA_ROTFACE, IN_PROGRESS); if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE))) professor->AI()->DoAction(ACTION_ROTFACE_COMBAT); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 5d3eee1499f..9fa70731068 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -18,6 +18,8 @@ #ifndef DEF_ICECROWN_CITADEL_H #define DEF_ICECROWN_CITADEL_H +static const char* ICCScriptName = "instance_icecrown_citadel"; + enum eSharedSpells { SPELL_BERSERK = 26662, @@ -26,25 +28,29 @@ enum eSharedSpells enum eData { - DATA_LORD_MARROWGAR = 0, - DATA_LADY_DEATHWHISPER = 1, - DATA_GUNSHIP_EVENT = 2, - DATA_DEATHBRINGER_SAURFANG = 3, - DATA_FESTERGUT = 4, - DATA_ROTFACE = 5, - DATA_PROFESSOR_PUTRICIDE = 6, - DATA_BLOOD_PRINCE_COUNCIL = 7, - DATA_BLOOD_QUEEN_LANA_THEL = 8, - DATA_VALITHRIA_DREAMWALKER = 9, - DATA_SINDRAGOSA = 10, - DATA_THE_LICH_KING = 11, - - DATA_SAURFANG_EVENT_NPC = 12, - - DATA_BONED_ACHIEVEMENT = 13, - DATA_OOZE_DANCE_ACHIEVEMENT = 14, - DATA_PUTRICIDE_TABLE = 15, - DATA_NAUSEA___ACHIEVEMENT = 16, + DATA_LORD_MARROWGAR = 0, + DATA_LADY_DEATHWHISPER = 1, + DATA_GUNSHIP_EVENT = 2, + DATA_DEATHBRINGER_SAURFANG = 3, + DATA_FESTERGUT = 4, + DATA_ROTFACE = 5, + DATA_PROFESSOR_PUTRICIDE = 6, + DATA_BLOOD_PRINCE_COUNCIL = 7, + DATA_BLOOD_QUEEN_LANA_THEL = 8, + DATA_VALITHRIA_DREAMWALKER = 9, + DATA_SINDRAGOSA = 10, + DATA_THE_LICH_KING = 11, + + DATA_SAURFANG_EVENT_NPC = 12, + DATA_BONED_ACHIEVEMENT = 13, + DATA_OOZE_DANCE_ACHIEVEMENT = 14, + DATA_PUTRICIDE_TABLE = 15, + DATA_NAUSEA_ACHIEVEMENT = 16, + DATA_ORB_WHISPERER_ACHIEVEMENT = 17, + DATA_PRINCE_KELESETH_GUID = 18, + DATA_PRINCE_TALDARAM_GUID = 19, + DATA_PRINCE_VALANAR_GUID = 20, + DATA_BLOOD_PRINCES_CONTROL = 21, }; #define MAX_ENCOUNTER 12 @@ -110,30 +116,48 @@ enum eCreatures NPC_VOLATILE_OOZE = 37697, NPC_CHOKING_GAS_BOMB = 38159, NPC_TEAR_GAS_TARGET_STALKER = 38317, + + // Blood Prince Council + NPC_PRINCE_KELESETH = 37972, + NPC_PRINCE_TALDARAM = 37973, + NPC_PRINCE_VALANAR = 37970, + NPC_BLOOD_ORB_CONTROLLER = 38008, + NPC_FLOATING_TRIGGER = 30298, + NPC_DARK_NUCLEUS = 38369, + NPC_BALL_OF_FLAME = 38332, + NPC_BALL_OF_INFERNO_FLAME = 38451, + NPC_KINETIC_BOMB_TARGET = 38458, + NPC_KINETIC_BOMB = 38454, + NPC_SHOCK_VORTEX = 38422, }; enum eGameobjects { - GO_DOODAD_ICECROWN_ICEWALL02 = 201910, - GO_ICEWALL = 201911, - GO_LORD_MARROWGAR_S_ENTRANCE = 201857, - GO_ORATORY_OF_THE_DAMNED_ENTRANCE = 201563, - GO_LADY_DEATHWHISPER_ELEVATOR = 202220, - GO_SAURFANG_S_DOOR = 201825, - GO_DEATHBRINGER_S_CACHE_10N = 202239, - GO_DEATHBRINGER_S_CACHE_25N = 202240, - GO_DEATHBRINGER_S_CACHE_10H = 202238, - GO_DEATHBRINGER_S_CACHE_25H = 202241, - GO_SCOURGE_TRANSPORTER_SAURFANG = 202244, - GO_ORANGE_PLAGUE_MONSTER_ENTRANCE = 201371, - GO_GREEN_PLAGUE_MONSTER_ENTRANCE = 201370, - GO_SCIENTIST_AIRLOCK_DOOR_COLLISION = 201612, - GO_SCIENTIST_AIRLOCK_DOOR_ORANGE = 201613, - GO_SCIENTIST_AIRLOCK_DOOR_GREEN = 201614, - GO_DOODAD_ICECROWN_ORANGETUBES02 = 201617, - GO_DOODAD_ICECROWN_GREENTUBES02 = 201618, - GO_SCIENTIST_ENTRANCE = 201372, - GO_DRINK_ME = 201584, + GO_DOODAD_ICECROWN_ICEWALL02 = 201910, + GO_ICEWALL = 201911, + GO_LORD_MARROWGAR_S_ENTRANCE = 201857, + GO_ORATORY_OF_THE_DAMNED_ENTRANCE = 201563, + GO_LADY_DEATHWHISPER_ELEVATOR = 202220, + GO_SAURFANG_S_DOOR = 201825, + GO_DEATHBRINGER_S_CACHE_10N = 202239, + GO_DEATHBRINGER_S_CACHE_25N = 202240, + GO_DEATHBRINGER_S_CACHE_10H = 202238, + GO_DEATHBRINGER_S_CACHE_25H = 202241, + GO_SCOURGE_TRANSPORTER_SAURFANG = 202244, + GO_ORANGE_PLAGUE_MONSTER_ENTRANCE = 201371, + GO_GREEN_PLAGUE_MONSTER_ENTRANCE = 201370, + GO_SCIENTIST_AIRLOCK_DOOR_COLLISION = 201612, + GO_SCIENTIST_AIRLOCK_DOOR_ORANGE = 201613, + GO_SCIENTIST_AIRLOCK_DOOR_GREEN = 201614, + GO_DOODAD_ICECROWN_ORANGETUBES02 = 201617, + GO_DOODAD_ICECROWN_GREENTUBES02 = 201618, + GO_SCIENTIST_ENTRANCE = 201372, + GO_DRINK_ME = 201584, + GO_CRIMSON_HALL_DOOR = 201376, + GO_BLOOD_ELF_COUNCIL_DOOR = 201378, + GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT = 201377, + GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01 = 201746, + GO_DOODAD_ICECROWN_GRATE_01 = 201755, }; enum eAchievementCriteria @@ -150,6 +174,10 @@ enum eAchievementCriteria CRITERIA_NAUSEA_25N = 12968, CRITERIA_NAUSEA_10H = 12988, CRITERIA_NAUSEA_25H = 12981, + CRITERIA_ORB_WHISPERER_10N = 13033, + CRITERIA_ORB_WHISPERER_25N = 12969, + CRITERIA_ORB_WHISPERER_10H = 13034, + CRITERIA_ORB_WHISPERER_25H = 13032, }; enum ePutricideActions diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 673ef17ae59..7e53962e436 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -18,22 +18,27 @@ #include "ScriptPCH.h" #include "icecrown_citadel.h" -static const DoorData doorData[8] = +static const DoorData doorData[] = { - {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM, BOUNDARY_N }, - {GO_ICEWALL, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, - {GO_DOODAD_ICECROWN_ICEWALL02, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, - {GO_ORATORY_OF_THE_DAMNED_ENTRANCE, DATA_LADY_DEATHWHISPER, DOOR_TYPE_ROOM, BOUNDARY_N }, - {GO_ORANGE_PLAGUE_MONSTER_ENTRANCE, DATA_FESTERGUT, DOOR_TYPE_ROOM, BOUNDARY_E }, - {GO_GREEN_PLAGUE_MONSTER_ENTRANCE, DATA_ROTFACE, DOOR_TYPE_ROOM, BOUNDARY_E }, - {GO_SCIENTIST_ENTRANCE, DATA_PROFESSOR_PUTRICIDE, DOOR_TYPE_ROOM, BOUNDARY_E }, - {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END + {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM, BOUNDARY_N }, + {GO_ICEWALL, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {GO_DOODAD_ICECROWN_ICEWALL02, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {GO_ORATORY_OF_THE_DAMNED_ENTRANCE, DATA_LADY_DEATHWHISPER, DOOR_TYPE_ROOM, BOUNDARY_N }, + {GO_ORANGE_PLAGUE_MONSTER_ENTRANCE, DATA_FESTERGUT, DOOR_TYPE_ROOM, BOUNDARY_E }, + {GO_GREEN_PLAGUE_MONSTER_ENTRANCE, DATA_ROTFACE, DOOR_TYPE_ROOM, BOUNDARY_E }, + {GO_SCIENTIST_ENTRANCE, DATA_PROFESSOR_PUTRICIDE, DOOR_TYPE_ROOM, BOUNDARY_E }, + {GO_CRIMSON_HALL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_ROOM, BOUNDARY_S }, + {GO_BLOOD_ELF_COUNCIL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_W }, + {GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_E }, + {GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_ROOM, BOUNDARY_S }, + {GO_DOODAD_ICECROWN_GRATE_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END }; class instance_icecrown_citadel : public InstanceMapScript { public: - instance_icecrown_citadel() : InstanceMapScript("instance_icecrown_citadel", 631) { } + instance_icecrown_citadel() : InstanceMapScript(ICCScriptName, 631) { } struct instance_icecrown_citadel_InstanceMapScript : public InstanceScript { @@ -47,16 +52,19 @@ class instance_icecrown_citadel : public InstanceMapScript uiSaurfangEventNPC = 0; uiDeathbringersCache = 0; uiSaurfangTeleport = 0; - memset(uiPutricidePipes, 0, 2*sizeof(uint32)); - memset(uiPutricideGates, 0, 2*sizeof(uint32)); + memset(uiPutricidePipes, 0, 2*sizeof(uint64)); + memset(uiPutricideGates, 0, 2*sizeof(uint64)); uiPutricideCollision = 0; uiFestergut = 0; uiRotface = 0; uiProfessorPutricide = 0; - uiPutricideTable; + uiPutricideTable = 0; + memset(uiBloodCouncil, 0, 3*sizeof(uint64)); + uiBloodCouncilController = 0; isBonedEligible = true; isOozeDanceEligible = true; isNauseaEligible = true; + isOrbWhispererEligible = true; } void OnCreatureCreate(Creature* creature, bool /*add*/) @@ -123,6 +131,18 @@ class instance_icecrown_citadel : public InstanceMapScript case NPC_PROFESSOR_PUTRICIDE: uiProfessorPutricide = creature->GetGUID(); break; + case NPC_PRINCE_KELESETH: + uiBloodCouncil[0] = creature->GetGUID(); + break; + case NPC_PRINCE_TALDARAM: + uiBloodCouncil[1] = creature->GetGUID(); + break; + case NPC_PRINCE_VALANAR: + uiBloodCouncil[2] = creature->GetGUID(); + break; + case NPC_BLOOD_ORB_CONTROLLER: + uiBloodCouncilController = creature->GetGUID(); + break; default: break; } @@ -139,6 +159,11 @@ class instance_icecrown_citadel : public InstanceMapScript case GO_ORANGE_PLAGUE_MONSTER_ENTRANCE: case GO_GREEN_PLAGUE_MONSTER_ENTRANCE: case GO_SCIENTIST_ENTRANCE: + case GO_CRIMSON_HALL_DOOR: + case GO_BLOOD_ELF_COUNCIL_DOOR: + case GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT: + case GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01: + case GO_DOODAD_ICECROWN_GRATE_01: AddDoor(pGo, add); break; case GO_LADY_DEATHWHISPER_ELEVATOR: @@ -218,7 +243,14 @@ class instance_icecrown_citadel : public InstanceMapScript return uiProfessorPutricide; case DATA_PUTRICIDE_TABLE: return uiPutricideTable; - break; + case DATA_PRINCE_KELESETH_GUID: + return uiBloodCouncil[0]; + case DATA_PRINCE_TALDARAM_GUID: + return uiBloodCouncil[1]; + case DATA_PRINCE_VALANAR_GUID: + return uiBloodCouncil[2]; + case DATA_BLOOD_PRINCES_CONTROL: + return uiBloodCouncilController; default: break; } @@ -290,13 +322,14 @@ class instance_icecrown_citadel : public InstanceMapScript HandleGameObject(uiPutricidePipes[1], true); } break; - case DATA_PROFESSOR_PUTRICIDE: case DATA_BLOOD_PRINCE_COUNCIL: case DATA_BLOOD_QUEEN_LANA_THEL: case DATA_VALITHRIA_DREAMWALKER: case DATA_SINDRAGOSA: case DATA_THE_LICH_KING: break; + default: + break; } return true; @@ -312,9 +345,12 @@ class instance_icecrown_citadel : public InstanceMapScript case DATA_OOZE_DANCE_ACHIEVEMENT: isOozeDanceEligible = data ? true : false; break; - case DATA_NAUSEA___ACHIEVEMENT: + case DATA_NAUSEA_ACHIEVEMENT: isNauseaEligible = data ? true : false; break; + case DATA_ORB_WHISPERER_ACHIEVEMENT: + isOrbWhispererEligible = data ? true : false; + break; default: break; } @@ -339,6 +375,11 @@ class instance_icecrown_citadel : public InstanceMapScript case CRITERIA_NAUSEA_10H: case CRITERIA_NAUSEA_25H: return isNauseaEligible; + case CRITERIA_ORB_WHISPERER_10N: + case CRITERIA_ORB_WHISPERER_25N: + case CRITERIA_ORB_WHISPERER_10H: + case CRITERIA_ORB_WHISPERER_25H: + return isOrbWhispererEligible; default: break; } @@ -401,9 +442,12 @@ class instance_icecrown_citadel : public InstanceMapScript uint64 uiRotface; uint64 uiProfessorPutricide; uint64 uiPutricideTable; + uint64 uiBloodCouncil[3]; + uint64 uiBloodCouncilController; bool isBonedEligible; bool isOozeDanceEligible; bool isNauseaEligible; + bool isOrbWhispererEligible; }; InstanceScript* GetInstanceScript(InstanceMap* pMap) const |