diff options
author | Shauren <none@none> | 2010-10-09 16:50:03 +0200 |
---|---|---|
committer | Shauren <none@none> | 2010-10-09 16:50:03 +0200 |
commit | 9a47bc96a1ebb3d10d6a8ead0f26f958c4f8b838 (patch) | |
tree | b9a4e1c4faa0def87936e1acfd8eb01e7496908a | |
parent | aae2f3b48e259d95e97621d012632b336f9023b8 (diff) |
Scripts/Icecrown Citadel: Added Rotface script
Scripts/Icecrown Citadel: Corrected death speech for Stinky and Festergut
Scripts/Icecrown Citadel: Fixed Boned! achievement conditions
--HG--
branch : trunk
18 files changed, 979 insertions, 25 deletions
diff --git a/sql/base/world_database.sql b/sql/base/world_database.sql index c917a3adf72..4d2ffdcdd54 100644 --- a/sql/base/world_database.sql +++ b/sql/base/world_database.sql @@ -18154,6 +18154,11 @@ INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment ( 67623,-67620, 1, 'Remove Paralytic Toxin when hit by Burning Bite'), (-66683, 68667, 0, 'Icehowl - Surge of Adrenaline'), (-67661, 68667, 0, 'Icehowl - Surge of Adrenaline'), +-- Icecrown Citadel +(-69674, 69706, 0, 'Rotface: Mutated Infection Summon'), +(-71224, 69706, 0, 'Rotface: Mutated Infection Summon'), +(-73022, 69706, 0, 'Rotface: Mutated Infection Summon'), +(-73023, 69706, 0, 'Rotface: Mutated Infection Summon'), -- Warsong Gulch ( 54861,-23335, 0, 'Drop Flag on Nitro Boost WSG'), ( 54861,-23333, 0, 'Drop Flag on Nitro Boost WSG'), @@ -26838,6 +26843,16 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES ( 71222, 'spell_festergut_blighted_spores'), ( 73033, 'spell_festergut_blighted_spores'), ( 73034, 'spell_festergut_blighted_spores'), +( 69782, 'spell_rotface_ooze_flood'), +( 69796, 'spell_rotface_ooze_flood'), +( 69798, 'spell_rotface_ooze_flood'), +( 69801, 'spell_rotface_ooze_flood'), +( 69538, 'spell_rotface_little_ooze_combine'), +( 69553, 'spell_rotface_large_ooze_combine'), +( 69610, 'spell_rotface_large_ooze_buff_combine'), +( 69839, 'spell_rotface_unstable_ooze_explosion_init'), +( 69832, 'spell_rotface_unstable_ooze_explosion'), +( 71441, 'spell_rotface_unstable_ooze_explosion_suicide'), ( 62717, 'spell_ignis_slag_pot'), ( 63477, 'spell_ignis_slag_pot'), -- quest diff --git a/sql/scripts/world_script_texts.sql b/sql/scripts/world_script_texts.sql index 0186eaba102..5085835e905 100644 --- a/sql/scripts/world_script_texts.sql +++ b/sql/scripts/world_script_texts.sql @@ -2842,6 +2842,21 @@ INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1` (36626,-1631089,'Da ... Ddy...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16904,1,0,0,'SAY_DEATH'), (36678,-1631090,'Oh, Festergut. You were always my favorite. Next to Rotface. The good news is you left behind so much gas, I can practically taste it!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17124,1,0,0,'SAY_FESTERGUT_DEATH'), +-- Rotface + (36678,-1631091,'Great news, everyone! The slime is flowing again!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17126,1,0,1,'SAY_ROTFACE_OOZE_FLOOD1'), + (36678,-1631092,'Good news, everyone! I''ve fixed the poison slime pipes!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17123,1,0,1,'SAY_ROTFACE_OOZE_FLOOD2'), + (36678,-1631093,'Terrible news, everyone, Rotface is dead! But great news everyone, he left behind plenty of ooze for me to use! Whaa...? I''m a poet, and I didn''t know it? Astounding!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17146,1,0,0,'SAY_ROTFACE_DEATH'), + (36627,-1631094,'What? Precious? Noooooooooo!!!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16993,1,0,0,'SAY_PRECIOUS_DIES'), + (36627,-1631095,'WEEEEEE!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16986,1,0,0,'SAY_AGGRO'), + (36627,-1631096,'%s begins to cast Slime Spray!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_SLIME_SPRAY'), + (36627,-1631097,'Icky sticky.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16991,1,0,0,'SAY_SLIME_SPRAY'), + (36627,-1631098,'|TInterface\Icons\spell_shadow_unstableaffliction_2.blp:16|t%s begins to cast |cFFFF0000Unstable Ooze Explosion!|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_UNSTABLE_EXPLOSION'), + (36627,-1631099,'I think I made an angry poo-poo. It gonna blow!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16992,1,0,0,'SAY_UNSTABLE_EXPLOSION'), + (36627,-1631100,'Daddy make toys out of you!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16988,1,0,0,'SAY_KILL_1'), + (36627,-1631101,'I brokes-ded it...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16987,1,0,0,'SAY_KILL_2'), + (36627,-1631102,'Sleepy Time!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16990,1,0,0,'SAY_BERSERK'), + (36627,-1631103,'Bad news daddy...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16989,1,0,0,'SAY_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 f13819b4af7..49be107aaa5 100644 --- a/sql/scripts/world_scripts_full.sql +++ b/sql/scripts/world_scripts_full.sql @@ -843,6 +843,10 @@ UPDATE `creature_template` SET `ScriptName`='npc_muradin_bronzebeard_icc' WHERE UPDATE `creature_template` SET `ScriptName`='npc_saurfang_event' WHERE `entry` IN (37920,37830); UPDATE `creature_template` SET `ScriptName`='boss_festergut' WHERE `entry`=36626; UPDATE `creature_template` SET `ScriptName`='npc_stinky_icc' WHERE `entry`=37025; +UPDATE `creature_template` SET `ScriptName`='boss_rotface' WHERE `entry`=36627; +UPDATE `creature_template` SET `ScriptName`='npc_little_ooze' WHERE `entry`=36897; +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; /* IRONFORGE */ diff --git a/sql/updates/10189_world_script_texts.sql b/sql/updates/10189_world_script_texts.sql new file mode 100644 index 00000000000..4d0470fbb17 --- /dev/null +++ b/sql/updates/10189_world_script_texts.sql @@ -0,0 +1,15 @@ +DELETE FROM `script_texts` WHERE `entry` BETWEEN -1631103 AND -1631091; +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 +(36678,-1631091,'Great news, everyone! The slime is flowing again!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17126,1,0,1,'SAY_ROTFACE_OOZE_FLOOD1'), +(36678,-1631092,'Good news, everyone! I''ve fixed the poison slime pipes!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17123,1,0,1,'SAY_ROTFACE_OOZE_FLOOD2'), +(36678,-1631093,'Terrible news, everyone, Rotface is dead! But great news everyone, he left behind plenty of ooze for me to use! Whaa...? I''m a poet, and I didn''t know it? Astounding!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17146,1,0,0,'SAY_ROTFACE_DEATH'), +(36627,-1631094,'What? Precious? Noooooooooo!!!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16993,1,0,0,'SAY_PRECIOUS_DIES'), +(36627,-1631095,'WEEEEEE!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16986,1,0,0,'SAY_AGGRO'), +(36627,-1631096,'%s begins to cast Slime Spray!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_SLIME_SPRAY'), +(36627,-1631097,'Icky sticky.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16991,1,0,0,'SAY_SLIME_SPRAY'), +(36627,-1631098,'|TInterface\Icons\spell_shadow_unstableaffliction_2.blp:16|t%s begins to cast |cFFFF0000Unstable Ooze Explosion!|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,3,0,0,'EMOTE_UNSTABLE_EXPLOSION'), +(36627,-1631099,'I think I made an angry poo-poo. It gonna blow!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16992,1,0,0,'SAY_UNSTABLE_EXPLOSION'), +(36627,-1631100,'Daddy make toys out of you!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16988,1,0,0,'SAY_KILL_1'), +(36627,-1631101,'I brokes-ded it...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16987,1,0,0,'SAY_KILL_2'), +(36627,-1631102,'Sleepy Time!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16990,1,0,0,'SAY_BERSERK'), +(36627,-1631103,'Bad news daddy...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16989,1,0,0,'SAY_DEATH'); diff --git a/sql/updates/10189_world_scriptname.sql b/sql/updates/10189_world_scriptname.sql new file mode 100644 index 00000000000..5d4891e224e --- /dev/null +++ b/sql/updates/10189_world_scriptname.sql @@ -0,0 +1,4 @@ +UPDATE `creature_template` SET `ScriptName`='boss_rotface' WHERE `entry`=36627; +UPDATE `creature_template` SET `ScriptName`='npc_little_ooze' WHERE `entry`=36897; +UPDATE `creature_template` SET `ScriptName`='npc_big_ooze' WHERE `entry`=36899; +UPDATE `creature_template` SET `ScriptName`='npc_precious_icc' WHERE `entry`=37217; diff --git a/sql/updates/10189_world_spell_linked_spell.sql b/sql/updates/10189_world_spell_linked_spell.sql new file mode 100644 index 00000000000..57ee6b62ce1 --- /dev/null +++ b/sql/updates/10189_world_spell_linked_spell.sql @@ -0,0 +1,6 @@ +DELETE FROM `spell_linked_spell` WHERE `spell_effect`=69706; +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(-69674,69706,0, 'Rotface: Mutated Infection Summon'), +(-71224,69706,0, 'Rotface: Mutated Infection Summon'), +(-73022,69706,0, 'Rotface: Mutated Infection Summon'), +(-73023,69706,0, 'Rotface: Mutated Infection Summon'); diff --git a/sql/updates/10189_world_spell_script_names.sql b/sql/updates/10189_world_spell_script_names.sql new file mode 100644 index 00000000000..ea82c897700 --- /dev/null +++ b/sql/updates/10189_world_spell_script_names.sql @@ -0,0 +1,18 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (69782,69796,69798,69801) AND `ScriptName`='spell_rotface_ooze_flood'; +DELETE FROM `spell_script_names` WHERE `spell_id`=69538 AND `ScriptName`='spell_rotface_little_ooze_combine'; +DELETE FROM `spell_script_names` WHERE `spell_id`=69553 AND `ScriptName`='spell_rotface_large_ooze_combine'; +DELETE FROM `spell_script_names` WHERE `spell_id`=69610 AND `ScriptName`='spell_rotface_large_ooze_buff_combine'; +DELETE FROM `spell_script_names` WHERE `spell_id`=69839 AND `ScriptName`='spell_rotface_unstable_ooze_explosion_init'; +DELETE FROM `spell_script_names` WHERE `spell_id`=69832 AND `ScriptName`='spell_rotface_unstable_ooze_explosion'; +DELETE FROM `spell_script_names` WHERE `spell_id`=71441 AND `ScriptName`='spell_rotface_unstable_ooze_explosion_suicide'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(69782,'spell_rotface_ooze_flood'), +(69796,'spell_rotface_ooze_flood'), +(69798,'spell_rotface_ooze_flood'), +(69801,'spell_rotface_ooze_flood'), +(69538,'spell_rotface_little_ooze_combine'), +(69553,'spell_rotface_large_ooze_combine'), +(69610,'spell_rotface_large_ooze_buff_combine'), +(69839,'spell_rotface_unstable_ooze_explosion_init'), +(69832,'spell_rotface_unstable_ooze_explosion'), +(71441,'spell_rotface_unstable_ooze_explosion_suicide'); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 4754a33eebd..fda7e67a81c 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -446,6 +446,7 @@ void AddSC_boss_lord_marrowgar(); // Icecrown Citadel void AddSC_boss_lady_deathwhisper(); void AddSC_boss_deathbringer_saurfang(); void AddSC_boss_festergut(); +void AddSC_boss_rotface(); void AddSC_boss_professor_putricide(); void AddSC_icecrown_citadel_teleport(); void AddSC_instance_icecrown_citadel(); @@ -1105,6 +1106,7 @@ void AddNorthrendScripts() AddSC_boss_lady_deathwhisper(); AddSC_boss_deathbringer_saurfang(); AddSC_boss_festergut(); + AddSC_boss_rotface(); AddSC_boss_professor_putricide(); 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 51d8972ff3f..629f9b9850f 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2344,9 +2344,18 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const return; // Beacon of Light case 53563: + { Unit * triggerCaster = (Unit *)(GetBase()->GetOwner()); - triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, 0, this,triggerCaster->GetGUID()); + triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, 0, this, triggerCaster->GetGUID()); return; + } + // Slime Spray - temporary here until preventing default effect works again + // added on 9.10.2010 + case 69508: + { + caster->CastSpell(triggerTarget, triggerSpellId, true, NULL, NULL, caster->GetGUID()); + return; + } } } @@ -2356,7 +2365,7 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const if (triggeredSpellInfo) { Unit * triggerCaster = GetTriggeredSpellCaster(triggeredSpellInfo, caster, triggerTarget); - triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, 0, this); + triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, NULL, this); sLog.outDebug("AuraEffect::TriggerSpell: Spell %u Trigger %u",GetId(), triggeredSpellInfo->Id); } else if (target->GetTypeId() != TYPEID_UNIT || !sScriptMgr.OnDummyEffect(caster, GetId(), SpellEffIndex(GetEffIndex()), triggerTarget->ToCreature())) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 6e4ead80a2e..0aed57b9c4e 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2778,6 +2778,17 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) ++itr; } break; + case 69782: case 69796: // Ooze Flood + case 69798: case 69801: // Ooze Flood + // get 2 targets except 2 nearest + unitList.sort(Trinity::ObjectDistanceOrderPred(m_caster)); + unitList.resize(4); + while (unitList.size() > 2) + unitList.pop_front(); + // crashfix + if (unitList.empty()) + return; + break; } // Death Pact if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 370e960088c..c8f1d11dd9b 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3618,6 +3618,9 @@ void SpellMgr::LoadSpellCustomAttr() case 27820: // Mana Detonation //case 28062: case 39090: // Positive/Negative Charge //case 28085: case 39093: + case 69782: case 69796: // Ooze Flood + case 69798: case 69801: // Ooze Flood + case 69538: case 69553: case 69610: // Ooze Combine mSpellCustomAttr[i] |= SPELL_ATTR_CU_EXCLUDE_SELF; count++; break; diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index 1f6188e10b2..f556f462b47 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -143,13 +143,14 @@ set(scripts_STAT_SRCS Northrend/VioletHold/boss_erekem.cpp Northrend/VioletHold/violet_hold.cpp Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp - Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp - Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp - Northrend/IcecrownCitadel/boss_professor_putricide.cpp Northrend/IcecrownCitadel/icecrown_citadel.h Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp - Northrend/IcecrownCitadel/boss_festergut.cpp Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp + Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp + Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp + Northrend/IcecrownCitadel/boss_festergut.cpp + Northrend/IcecrownCitadel/boss_rotface.cpp + Northrend/IcecrownCitadel/boss_professor_putricide.cpp Northrend/zuldrak.cpp Northrend/icecrown.cpp Northrend/Gundrak/boss_slad_ran.cpp diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp index a6f4cc32eca..5980255c8fc 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp @@ -307,7 +307,8 @@ class npc_stinky_icc : public CreatureScript { uint64 festergutGUID = pInstance ? pInstance->GetData64(DATA_FESTERGUT) : 0; if (Creature *festergut = me->GetCreature(*me, festergutGUID)) - DoScriptText(SAY_STINKY_DEAD, festergut); + if (festergut->isAlive()) + DoScriptText(SAY_STINKY_DEAD, festergut); } private: @@ -369,8 +370,6 @@ class spell_festergut_gastric_bloat : public SpellScriptLoader if (!(aura && aura->GetStackAmount() == 10)) return; - //PreventHitAura(); - SpellEntry const* spellInfo = sSpellStore.LookupEntry(SPELL_GASTRIC_EXPLOSION); if (!spellInfo) return; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index a97d6f6f136..4f90df15497 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -120,6 +120,7 @@ class boss_lord_marrowgar : public CreatureScript void JustReachedHome() { instance->SetBossState(DATA_LORD_MARROWGAR, FAIL); + instance->SetData(DATA_BONED_ACHIEVEMENT, uint32(true)); // reset } void KilledUnit(Unit *victim) @@ -369,7 +370,7 @@ class npc_bone_spike : public CreatureScript if (events.ExecuteEvent() == EVENT_FAIL_BONED) if (InstanceScript* instance = me->GetInstanceScript()) - instance->SetData(COMMAND_FAIL_BONED, 0); + instance->SetData(DATA_BONED_ACHIEVEMENT, uint32(false)); } void SetTrappedUnit(Unit* unit) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 913c62caf02..f93cd6420ae 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -23,6 +23,9 @@ enum eScriptTexts // Festergut SAY_FESTERGUT_GASEOUS_BLIGHT = -1631080, SAY_FESTERGUT_DEATH = -1631090, + SAY_ROTFACE_OOZE_FLOOD1 = -1631091, + SAY_ROTFACE_OOZE_FLOOD2 = -1631092, + SAY_ROTFACE_DEATH = -1631093, }; enum eSpells @@ -33,13 +36,21 @@ enum eSpells SPELL_GASEOUS_BLIGHT_MEDIUM = 69162, SPELL_GASEOUS_BLIGHT_SMALL = 69164, SPELL_MALLABLE_GOO_H = 70852, + + // Rotface + SPELL_VILE_GAS_H = 69240, }; enum eEvents { // Festergut - EVENT_FESTERGUT_DIES = 1, - EVENT_FESTERGUT_GOO = 2, + EVENT_FESTERGUT_DIES = 1, + EVENT_FESTERGUT_GOO = 2, + + // Rotface + EVENT_ROTFACE_DIES = 3, + EVENT_ROTFACE_VILE_GAS = 4, + EVENT_ROTFACE_OOZE_FLOOD = 5, }; enum ePhases @@ -54,9 +65,13 @@ enum ePhases enum ePoints { POINT_FESTERGUT = 366260, + POINT_ROTFACE = 366270, }; -static const Position festergutWatchPos = {4324.82f, 3166.03f, 389.3831f, 3.316126f}; //emote 432 (release gas) +static const Position festergutWatchPos = {4324.820f, 3166.03f, 389.3831f, 3.316126f}; //emote 432 (release gas) +static const Position rotfaceWatchPos = {4390.371f, 3164.50f, 389.3890f, 5.497787f}; //emote 432 (release gas) + +static const uint32 oozeFloodSpells[4] = {69782, 69796, 69798, 69801}; class boss_professor_putricide : public CreatureScript { @@ -106,6 +121,54 @@ class boss_professor_putricide : public CreatureScript case ACTION_FESTERGUT_DEATH: events.ScheduleEvent(EVENT_FESTERGUT_DIES, 4000, 0, PHASE_FESTERGUT); break; + case ACTION_ROTFACE_COMBAT: + { + _SetPhase(PHASE_ROTFACE); + me->SetSpeed(MOVE_RUN, fBaseSpeed*2.0f, true); + me->GetMotionMaster()->MovePoint(POINT_ROTFACE, rotfaceWatchPos); + me->SetReactState(REACT_PASSIVE); + oozeFloodStage = 0; + if (IsHeroic()) + { + DoZoneInCombat(me); + events.ScheduleEvent(EVENT_ROTFACE_VILE_GAS, urand(15000, 20000), 0, PHASE_ROTFACE); + } + // init random sequence of floods + if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) + { + std::list<Creature*> list; + GetCreatureListWithEntryInGrid(list, rotface, NPC_PUDDLE_STALKER, 36.0f); + if (list.size() > 4) + { + list.sort(Trinity::ObjectDistanceOrderPred(rotface)); + do + { + list.pop_back(); + } while (list.size() > 4); + } + + uint8 i = 0; + while (!list.empty()) + { + std::list<Creature*>::iterator itr = list.begin(); + std::advance(itr, urand(0, list.size()-1)); + oozeFloodDummy[i++] = (*itr)->GetGUID(); + list.erase(itr); + } + } + break; + } + case ACTION_ROTFACE_OOZE: + DoScriptText(RAND(SAY_ROTFACE_OOZE_FLOOD1, SAY_ROTFACE_OOZE_FLOOD2), me); + if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) + if (Creature* dummy = Unit::GetCreature(*me, oozeFloodDummy[oozeFloodStage])) + dummy->CastSpell(dummy, oozeFloodSpells[oozeFloodStage], true, NULL, NULL, me->GetGUID()); // cast from self for LoS (with prof's GUID for logs) + if (++oozeFloodStage == 4) + oozeFloodStage = 0; + break; + case ACTION_ROTFACE_DEATH: + events.ScheduleEvent(EVENT_ROTFACE_DIES, 4500, 0, PHASE_ROTFACE); + break; default: break; } @@ -113,18 +176,28 @@ class boss_professor_putricide : public CreatureScript void JustReachedHome() { + me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); if (phase == PHASE_COMBAT) instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, FAIL); } void MovementInform(uint32 type, uint32 id) { - if (type == POINT_MOTION_TYPE && id == POINT_FESTERGUT) + if (type != POINT_MOTION_TYPE) + return; + switch (id) { - 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()); + case POINT_FESTERGUT: + 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: + me->SetSpeed(MOVE_RUN, fBaseSpeed, true); + DoAction(ACTION_ROTFACE_OOZE); + events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000, 0, PHASE_ROTFACE); + break; } } @@ -147,25 +220,39 @@ class boss_professor_putricide : public CreatureScript EnterEvadeMode(); break; case EVENT_FESTERGUT_GOO: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) DoCast(target, SPELL_MALLABLE_GOO_H, true); // triggered, to skip LoS check events.ScheduleEvent(EVENT_FESTERGUT_GOO, urand(15000, 20000), 0, PHASE_FESTERGUT); break; + case EVENT_ROTFACE_DIES: + DoScriptText(SAY_ROTFACE_DEATH, me); + EnterEvadeMode(); + break; + case EVENT_ROTFACE_VILE_GAS: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + DoCast(target, SPELL_VILE_GAS_H, true); // triggered, to skip LoS check + events.ScheduleEvent(EVENT_ROTFACE_VILE_GAS, urand(15000, 20000), 0, PHASE_ROTFACE); + break; + case EVENT_ROTFACE_OOZE_FLOOD: + DoAction(ACTION_ROTFACE_OOZE); + events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000, 0, PHASE_ROTFACE); default: break; } } } + private: void _SetPhase(ePhases newPhase) { phase = newPhase; events.SetPhase(newPhase); } - private: - ePhases phase; // external of EventMap because event phase gets reset on evade + ePhases phase; // external of EventMap because event phase gets reset on evade const float fBaseSpeed; + uint64 oozeFloodDummy[4]; + uint8 oozeFloodStage; }; CreatureAI* GetAI(Creature* pCreature) const @@ -174,7 +261,7 @@ class boss_professor_putricide : public CreatureScript } }; -// Stinky and Precious spell, it's here because its used for both (Festergut and Rotface "pet") +// Stinky and Precious spell, it's here because its used for both (Festergut and Rotface "pets") class spell_stinky_precious_decimate : public SpellScriptLoader { public: diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp new file mode 100644 index 00000000000..e5a84f9b1b5 --- /dev/null +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -0,0 +1,742 @@ +/* + * 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 "SpellAuras.h" +#include "icecrown_citadel.h" + +// KNOWN BUGS: +// ~ No Slime Spray animation directly at target spot + +enum eTexts +{ + SAY_PRECIOUS_DIES = -1631094, + SAY_AGGRO = -1631095, + EMOTE_SLIME_SPRAY = -1631096, + SAY_SLIME_SPRAY = -1631097, + EMOTE_UNSTABLE_EXPLOSION = -1631098, + SAY_UNSTABLE_EXPLOSION = -1631099, + SAY_KILL_1 = -1631100, + SAY_KILL_2 = -1631101, + SAY_BERSERK = -1631102, + SAY_DEATH = -1631103 +}; + +enum eSpells +{ + // Rotface + SPELL_SLIME_SPRAY = 69508, // every 20 seconds + SPELL_MUTATED_INFECTION = 69674, // hastens every 1:30 + + // Oozes + SPELL_LITTLE_OOZE_COMBINE = 69537, // combine 2 Small Oozes + SPELL_LARGE_OOZE_COMBINE = 69552, // combine 2 Large Oozes + SPELL_LARGE_OOZE_BUFF_COMBINE = 69611, // combine Large and Small Ooze + SPELL_OOZE_MERGE = 69889, // 2 Small Oozes summon a Large Ooze + SPELL_WEAK_RADIATING_OOZE = 69750, // passive damage aura - small + SPELL_RADIATING_OOZE = 69760, // passive damage aura - large + SPELL_UNSTABLE_OOZE = 69558, // damage boost and counter for explosion + SPELL_GREEN_ABOMINATION_HITTIN__YA_PROC = 70001, // prevents getting hit by infection + SPELL_UNSTABLE_OOZE_EXPLOSION = 69839, + SPELL_STICKY_OOZE = 69774, + SPELL_UNSTABLE_OOZE_EXPLOSION_TRIGGER = 69832, + + // Precious + SPELL_MORTAL_WOUND = 71127, + SPELL_DECIMATE = 71123 +}; + +#define MUTATED_INFECTION RAID_MODE<int32>(69674,71224,73022,73023) + +enum eEvents +{ + EVENT_SLIME_SPRAY = 1, + EVENT_HASTEN_INFECTIONS = 2, + EVENT_MUTATED_INFECTION = 3, + + EVENT_DECIMATE = 4, + EVENT_MORTAL_WOUND = 5, + + EVENT_STICKY_OOZE = 6, + EVENT_UNSTABLE_DESPAWN = 7 +}; + +class boss_rotface : public CreatureScript +{ + public: + boss_rotface() : CreatureScript("boss_rotface") { } + + struct boss_rotfaceAI : public BossAI + { + boss_rotfaceAI(Creature* pCreature) : BossAI(pCreature, DATA_ROTFACE) + { + ASSERT(instance); + infectionStage = 0; + infectionCooldown = 14000; + } + + void Reset() + { + events.Reset(); + events.ScheduleEvent(EVENT_SLIME_SPRAY, 20000); + events.ScheduleEvent(EVENT_HASTEN_INFECTIONS, 90000); + events.ScheduleEvent(EVENT_MUTATED_INFECTION, 14000); + infectionStage = 0; + infectionCooldown = 14000; + summons.DespawnAll(); + + instance->SetBossState(DATA_ROTFACE, NOT_STARTED); + } + + 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); + + DoZoneInCombat(me); + } + + void JustDied(Unit* /*killer*/) + { + DoScriptText(SAY_DEATH, me); + instance->SetBossState(DATA_ROTFACE, DONE); + if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE))) + professor->AI()->DoAction(ACTION_ROTFACE_DEATH); + } + + void JustReachedHome() + { + instance->SetBossState(DATA_ROTFACE, FAIL); + instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(true)); // reset + } + + void KilledUnit(Unit *victim) + { + if (victim->GetTypeId() == TYPEID_PLAYER) + DoScriptText(RAND(SAY_KILL_1, SAY_KILL_2), me); + } + + void EnterEvadeMode() + { + ScriptedAI::EnterEvadeMode(); + if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE))) + professor->AI()->EnterEvadeMode(); + } + + void SpellHitTarget(Unit* target, SpellEntry const* spell) + { + if (spell->Id == SPELL_SLIME_SPRAY) + DoScriptText(SAY_SLIME_SPRAY, me); + } + + void MoveInLineOfSight(Unit* /*who*/) + { + // don't enter combat + } + + Unit* GetAuraEffectTriggerTarget(uint32 spellId, uint8 /*effIndex*/) + { + if (spellId == SPELL_SLIME_SPRAY) + { + for (std::list<uint64>::iterator itr = summons.begin(); itr != summons.end();) + { + Creature *summon = Unit::GetCreature(*me, *itr); + if (!summon) + summons.erase(itr++); + else if (summon->GetEntry() == NPC_OOZE_SPRAY_STALKER) + return summon; + else + ++itr; + } + } + + return NULL; + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim() || !CheckInRoom()) + return; + + events.Update(diff); + + if (me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SLIME_SPRAY: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0/*1*/, 0.0f, true)) + { + Position pos; + target->GetPosition(&pos); + if (Creature* dummy = DoSummon(NPC_OOZE_SPRAY_STALKER, pos, 8000, TEMPSUMMON_TIMED_DESPAWN)) + { + DoScriptText(EMOTE_SLIME_SPRAY, me); + DoCastAOE(SPELL_SLIME_SPRAY); + } + } + events.ScheduleEvent(EVENT_SLIME_SPRAY, 20000); + break; + case EVENT_HASTEN_INFECTIONS: + if (infectionStage < 4) + { + infectionCooldown -= 2000; + events.ScheduleEvent(EVENT_HASTEN_INFECTIONS, 90000); + } + break; + case EVENT_MUTATED_INFECTION: + { + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -MUTATED_INFECTION); + if (!target) + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -MUTATED_INFECTION); + if (target) + DoCast(target, SPELL_MUTATED_INFECTION); + events.ScheduleEvent(EVENT_MUTATED_INFECTION, infectionCooldown); + break; + } + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + uint8 infectionStage; + uint32 infectionCooldown; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new boss_rotfaceAI(pCreature); + } +}; + +class npc_little_ooze : public CreatureScript +{ + public: + npc_little_ooze() : CreatureScript("npc_little_ooze") { } + + struct npc_little_oozeAI : public ScriptedAI + { + npc_little_oozeAI(Creature* pCreature) : ScriptedAI(pCreature) + { + } + + void IsSummonedBy(Unit* summoner) + { + DoCast(me, SPELL_LITTLE_OOZE_COMBINE, true); + DoCast(me, SPELL_WEAK_RADIATING_OOZE, true); + events.ScheduleEvent(EVENT_STICKY_OOZE, 5000); + me->AddThreat(summoner, 500000.0f); + // register in Rotface's summons - not summoned with Rotface as owner + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) + rotface->AI()->JustSummoned(me); + } + + void JustDied(Unit* /*killer*/) + { + if (TempSummon* summ = me->ToTempSummon()) + { + summ->UnSummon(); + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) + rotface->AI()->SummonedCreatureDespawn(me); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (events.ExecuteEvent() == EVENT_STICKY_OOZE) + { + DoCastVictim(SPELL_STICKY_OOZE); + events.ScheduleEvent(EVENT_STICKY_OOZE, 15000); + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_little_oozeAI(pCreature); + } +}; + +class npc_big_ooze : public CreatureScript +{ + public: + npc_big_ooze() : CreatureScript("npc_big_ooze") { } + + struct npc_big_oozeAI : public ScriptedAI + { + npc_big_oozeAI(Creature* pCreature) : ScriptedAI(pCreature), bExploded(false) + { + } + + void IsSummonedBy(Unit* /*summoner*/) + { + DoCast(me, SPELL_LARGE_OOZE_COMBINE, true); + DoCast(me, SPELL_LARGE_OOZE_BUFF_COMBINE, true); + DoCast(me, SPELL_RADIATING_OOZE, true); + DoCast(me, SPELL_UNSTABLE_OOZE, true); + DoCast(me, SPELL_GREEN_ABOMINATION_HITTIN__YA_PROC, true); + events.ScheduleEvent(EVENT_STICKY_OOZE, 5000); + // register in Rotface's summons - not summoned with Rotface as owner + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) + rotface->AI()->JustSummoned(me); + } + + void JustDied(Unit* /*killer*/) + { + if (TempSummon* summ = me->ToTempSummon()) + { + summ->UnSummon(); + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE))) + rotface->AI()->SummonedCreatureDespawn(me); + } + } + + void DoAction(const int32 action) + { + if (action == EVENT_STICKY_OOZE) + events.CancelEvent(EVENT_STICKY_OOZE); + else if (action == EVENT_UNSTABLE_DESPAWN) + { + bExploded = true; + me->RemoveAllAuras(); + me->SetVisibility(VISIBILITY_OFF); + events.Reset(); + events.ScheduleEvent(EVENT_UNSTABLE_DESPAWN, 60000); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_STICKY_OOZE: + DoCastVictim(SPELL_STICKY_OOZE); + events.ScheduleEvent(EVENT_STICKY_OOZE, 15000); + break; + case EVENT_UNSTABLE_DESPAWN: + me->Kill(me); + break; + default: + break; + } + } + + if (!bExploded) + DoMeleeAttackIfReady(); + } + + private: + EventMap events; + bool bExploded; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_big_oozeAI(pCreature); + } +}; + +class npc_precious_icc : public CreatureScript +{ + public: + npc_precious_icc() : CreatureScript("npc_precious_icc") { } + + struct npc_precious_iccAI : public ScriptedAI + { + npc_precious_iccAI(Creature* pCreature) : ScriptedAI(pCreature) + { + pInstance = pCreature->GetInstanceScript(); + } + + void Reset() + { + events.Reset(); + events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000)); + events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(3000, 7000)); + } + + 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_DECIMATE: + DoCastVictim(SPELL_DECIMATE); + events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000)); + break; + case EVENT_MORTAL_WOUND: + DoCastVictim(SPELL_MORTAL_WOUND); + events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 12500)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*who*/) + { + uint64 rotfaceGUID = pInstance ? pInstance->GetData64(DATA_ROTFACE) : 0; + if (Creature *rotface = Unit::GetCreature(*me, rotfaceGUID)) + if (rotface->isAlive()) + DoScriptText(SAY_PRECIOUS_DIES, rotface); + } + + private: + EventMap events; + InstanceScript* pInstance; + }; + + CreatureAI* GetAI(Creature* pCreature) const + { + return new npc_precious_iccAI(pCreature); + } +}; + +class spell_rotface_ooze_flood : public SpellScriptLoader +{ + public: + spell_rotface_ooze_flood() : SpellScriptLoader("spell_rotface_ooze_flood") { } + + class spell_rotface_ooze_flood_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rotface_ooze_flood_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (!GetHitUnit()) + return; + std::list<Creature*> list; + GetHitUnit()->GetCreatureListWithEntryInGrid(list, GetHitUnit()->GetEntry(), 12.5f); + list.sort(Trinity::ObjectDistanceOrderPred(GetHitUnit())); + GetHitUnit()->CastSpell(list.back(), GetEffectValue(), false, NULL, NULL, GetOriginalCaster() ? GetOriginalCaster()->GetGUID() : 0); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_rotface_ooze_flood_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_rotface_ooze_flood_SpellScript(); + } +}; + +class spell_rotface_little_ooze_combine : public SpellScriptLoader +{ + public: + spell_rotface_little_ooze_combine() : SpellScriptLoader("spell_rotface_little_ooze_combine") { } + + class spell_rotface_little_ooze_combine_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rotface_little_ooze_combine_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (!(GetHitUnit() && GetHitUnit()->isAlive())) + return; + + GetCaster()->RemoveAurasDueToSpell(SPELL_LITTLE_OOZE_COMBINE); + GetHitUnit()->RemoveAurasDueToSpell(SPELL_LITTLE_OOZE_COMBINE); + GetHitUnit()->CastSpell(GetCaster(), SPELL_OOZE_MERGE, true); + if (TempSummon* summ = GetHitUnit()->ToTempSummon()) + summ->UnSummon(); + else + GetHitCreature()->ForcedDespawn(); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_rotface_little_ooze_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_rotface_little_ooze_combine_SpellScript(); + } +}; + +class spell_rotface_large_ooze_combine : public SpellScriptLoader +{ + public: + spell_rotface_large_ooze_combine() : SpellScriptLoader("spell_rotface_large_ooze_combine") { } + + class spell_rotface_large_ooze_combine_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rotface_large_ooze_combine_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (!(GetHitUnit() && GetHitUnit()->isAlive())) + return; + + if (Aura* unstable = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE)) + { + if (Aura* targetAura = GetHitUnit()->GetAura(SPELL_UNSTABLE_OOZE)) + unstable->ModStackAmount(targetAura->GetStackAmount()); + else + unstable->ModStackAmount(1); + + // no idea why, but this does not trigger explosion on retail (only small+large do) + } + + // just for safety + GetHitUnit()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE); + GetHitUnit()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE); + + if (TempSummon* summ = GetHitUnit()->ToTempSummon()) + summ->UnSummon(); + else if (GetHitCreature()) + GetHitCreature()->ForcedDespawn(); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_rotface_large_ooze_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_rotface_large_ooze_combine_SpellScript(); + } +}; + +class spell_rotface_large_ooze_buff_combine : public SpellScriptLoader +{ + public: + spell_rotface_large_ooze_buff_combine() : SpellScriptLoader("spell_rotface_large_ooze_buff_combine") { } + + class spell_rotface_large_ooze_buff_combine_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rotface_large_ooze_buff_combine_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (!(GetHitUnit() && GetHitUnit()->isAlive())) + return; + + if (Aura* unstable = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE)) + { + uint8 newStack = unstable->GetStackAmount()+1; + unstable->SetStackAmount(newStack); + + // explode! + if (newStack >= 5) + { + GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE); + GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE); + DoScriptText(EMOTE_UNSTABLE_EXPLOSION, GetCaster()); + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (Creature* rotface = Unit::GetCreature(*GetCaster(), instance->GetData64(DATA_ROTFACE))) + if (rotface->isAlive()) + DoScriptText(SAY_UNSTABLE_EXPLOSION, rotface); + + if (Creature* cre = GetCaster()->ToCreature()) + cre->AI()->DoAction(EVENT_STICKY_OOZE); + GetCaster()->CastSpell(GetCaster(), SPELL_UNSTABLE_OOZE_EXPLOSION, false, NULL, NULL, GetCaster()->GetGUID()); + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(false)); + } + } + + if (TempSummon* summ = GetHitUnit()->ToTempSummon()) + summ->UnSummon(); + else if (GetHitCreature()) + GetHitCreature()->ForcedDespawn(); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_rotface_large_ooze_buff_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_rotface_large_ooze_buff_combine_SpellScript(); + } +}; + +class spell_rotface_unstable_ooze_explosion_init : public SpellScriptLoader +{ + public: + spell_rotface_unstable_ooze_explosion_init() : SpellScriptLoader("spell_rotface_unstable_ooze_explosion_init") { } + + class spell_rotface_unstable_ooze_explosion_init_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rotface_unstable_ooze_explosion_init_SpellScript); + + bool Validate(SpellEntry const* /*spell*/) + { + if (!sSpellStore.LookupEntry(SPELL_UNSTABLE_OOZE_EXPLOSION_TRIGGER)) + return false; + return true; + } + + void HandleCast(SpellEffIndex effIndex) + { + PreventHitEffect(effIndex); + if (!GetHitUnit()) + return; + + float x, y, z; + GetHitUnit()->GetPosition(x, y, z); + Creature* dummy = GetCaster()->SummonCreature(NPC_UNSTABLE_EXPLOSION_STALKER, x, y, z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000); + GetCaster()->CastSpell(dummy, SPELL_UNSTABLE_OOZE_EXPLOSION_TRIGGER, true); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_rotface_unstable_ooze_explosion_init_SpellScript::HandleCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_rotface_unstable_ooze_explosion_init_SpellScript(); + } +}; + +class spell_rotface_unstable_ooze_explosion : public SpellScriptLoader +{ + public: + spell_rotface_unstable_ooze_explosion() : SpellScriptLoader("spell_rotface_unstable_ooze_explosion") { } + + class spell_rotface_unstable_ooze_explosion_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rotface_unstable_ooze_explosion_SpellScript); + + void CheckTarget(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(EFFECT_0); + if (!GetTargetUnit()) + return; + + uint32 triggered_spell_id = GetSpellInfo()->EffectTriggerSpell[effIndex]; + + float x, y, z; + GetTargetUnit()->GetPosition(x, y, z); + // let Rotface handle the cast - caster dies before this executes + if (InstanceScript* script = GetTargetUnit()->GetInstanceScript()) + if (Creature* rotface = script->instance->GetCreature(script->GetData64(DATA_ROTFACE))) + rotface->CastSpell(x, y, z, GetSpellInfo()->EffectTriggerSpell[effIndex], true, NULL, NULL, GetCaster()->GetGUID(), GetTargetUnit()); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_rotface_unstable_ooze_explosion_SpellScript::CheckTarget, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_rotface_unstable_ooze_explosion_SpellScript(); + } +}; + +class spell_rotface_unstable_ooze_explosion_suicide : public SpellScriptLoader +{ + public: + spell_rotface_unstable_ooze_explosion_suicide() : SpellScriptLoader("spell_rotface_unstable_ooze_explosion_suicide") { } + + class spell_rotface_unstable_ooze_explosion_suicide_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rotface_unstable_ooze_explosion_suicide_AuraScript); + + void DespawnSelf(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp) + { + PreventDefaultAction(); + Unit* target = aurApp->GetTarget(); + if (!target || target->GetTypeId() != TYPEID_UNIT) + return; + + target->ToCreature()->AI()->DoAction(EVENT_UNSTABLE_DESPAWN); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_rotface_unstable_ooze_explosion_suicide_AuraScript::DespawnSelf, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rotface_unstable_ooze_explosion_suicide_AuraScript(); + } +}; + +void AddSC_boss_rotface() +{ + new boss_rotface(); + new npc_little_ooze(); + new npc_big_ooze(); + new npc_precious_icc(); + new spell_rotface_ooze_flood(); + new spell_rotface_little_ooze_combine(); + new spell_rotface_large_ooze_combine(); + new spell_rotface_large_ooze_buff_combine(); + new spell_rotface_unstable_ooze_explosion_init(); + new spell_rotface_unstable_ooze_explosion(); + new spell_rotface_unstable_ooze_explosion_suicide(); +} diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index c6f6fa46454..9b838b6e5ab 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -41,7 +41,8 @@ enum eData DATA_SAURFANG_EVENT_NPC = 12, - COMMAND_FAIL_BONED = 13, + DATA_BONED_ACHIEVEMENT = 13, + DATA_OOZE_DANCE_ACHIEVEMENT = 14, }; #define MAX_ENCOUNTER 12 @@ -74,6 +75,9 @@ enum eCreatures NPC_GAS_DUMMY = 36659, NPC_ROTFACE = 36627, + NPC_OOZE_SPRAY_STALKER = 37986, + NPC_PUDDLE_STALKER = 37013, + NPC_UNSTABLE_EXPLOSION_STALKER = 38107, NPC_PROFESSOR_PUTRICIDE = 36678, }; @@ -107,6 +111,10 @@ enum eAchievementCriteria CRITERIA_BONED_25N = 12962, CRITERIA_BONED_10H = 13393, CRITERIA_BONED_25H = 13394, + CRITERIA_DANCES_WITH_OOZES_10N = 12984, + CRITERIA_DANCES_WITH_OOZES_25N = 12966, + CRITERIA_DANCES_WITH_OOZES_10H = 12985, + CRITERIA_DANCES_WITH_OOZES_25H = 12983, }; enum ePutricideActions @@ -114,6 +122,9 @@ enum ePutricideActions ACTION_FESTERGUT_COMBAT = -366260, ACTION_FESTERGUT_GAS = -366261, ACTION_FESTERGUT_DEATH = -366262, + ACTION_ROTFACE_COMBAT = -366270, + ACTION_ROTFACE_OOZE = -366271, + ACTION_ROTFACE_DEATH = -366272, }; #endif // DEF_ICECROWN_CITADEL_H diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index d9ac057b4cd..41917b96b9d 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -53,7 +53,8 @@ class instance_icecrown_citadel : public InstanceMapScript uiFestergut = 0; uiRotface = 0; uiProfessorPutricide = 0; - isBonedEligible = false; + isBonedEligible = true; + isOozeDanceEligible = true; } void OnCreatureCreate(Creature* creature, bool /*add*/) @@ -178,6 +179,8 @@ class instance_icecrown_citadel : public InstanceMapScript return uiSaurfangTeleport; case DATA_FESTERGUT: return uiFestergut; + case DATA_ROTFACE: + return uiRotface; case DATA_PROFESSOR_PUTRICIDE: return uiProfessorPutricide; default: @@ -265,9 +268,11 @@ class instance_icecrown_citadel : public InstanceMapScript { switch (type) { - case COMMAND_FAIL_BONED: + case DATA_BONED_ACHIEVEMENT: isBonedEligible = data ? true : false; break; + case DATA_OOZE_DANCE_ACHIEVEMENT: + isOozeDanceEligible = data ? true : false; default: break; } @@ -282,6 +287,11 @@ class instance_icecrown_citadel : public InstanceMapScript case CRITERIA_BONED_10H: case CRITERIA_BONED_25H: return isBonedEligible; + case CRITERIA_DANCES_WITH_OOZES_10N: + case CRITERIA_DANCES_WITH_OOZES_25N: + case CRITERIA_DANCES_WITH_OOZES_10H: + case CRITERIA_DANCES_WITH_OOZES_25H: + return isOozeDanceEligible; default: break; } @@ -344,6 +354,7 @@ class instance_icecrown_citadel : public InstanceMapScript uint64 uiRotface; uint64 uiProfessorPutricide; bool isBonedEligible; + bool isOozeDanceEligible; }; InstanceScript* GetInstanceScript(InstanceMap* pMap) const |