Scripts/Icecrown Citadel: Added Festergut script, thx Cromash for providing the base and Cyrax for sniffs

Scripts/Icecrown Citadel: Added Professor Putricide script handling ONLY Festergut related events

--HG--
branch : trunk
This commit is contained in:
Shauren
2010-08-30 11:36:15 +02:00
parent dc2c28985f
commit 6c3b39ac01
13 changed files with 872 additions and 9 deletions
@@ -428,6 +428,8 @@ void AddSC_boss_marwyn();
void AddSC_boss_lord_marrowgar(); // Icecrown Citadel
void AddSC_boss_lady_deathwhisper();
void AddSC_boss_deathbringer_saurfang();
void AddSC_boss_festergut();
void AddSC_boss_professor_putricide();
void AddSC_icecrown_citadel_teleport();
void AddSC_instance_icecrown_citadel();
@@ -1105,6 +1107,8 @@ void AddNorthrendScripts()
AddSC_boss_lord_marrowgar(); // Icecrown Citadel
AddSC_boss_lady_deathwhisper();
AddSC_boss_deathbringer_saurfang();
AddSC_boss_festergut();
AddSC_boss_professor_putricide();
AddSC_icecrown_citadel_teleport();
AddSC_instance_icecrown_citadel();
@@ -0,0 +1,452 @@
/*
* Copyright (C) 2008-2010 Trinity <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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptPCH.h"
#include "icecrown_citadel.h"
enum eScriptTexts
{
SAY_STINKY_DEAD = -1631078,
SAY_AGGRO = -1631079,
EMOTE_GAS_SPORE = -1631081,
EMOTE_WARN_GAS_SPORE = -1631082,
SAY_PUNGENT_BLIGHT = -1631083,
EMOTE_WARN_PUNGENT_BLIGHT = -1631084,
EMOTE_PUNGENT_BLIGHT = -1631085,
SAY_KILL_1 = -1631086,
SAY_KILL_2 = -1631087,
SAY_BERSERK = -1631088,
SAY_DEATH = -1631089
};
enum eSpells
{
// Festergut
SPELL_INHALE_BLIGHT = 69165,
SPELL_PUNGENT_BLIGHT = 69195,
SPELL_GASTRIC_BLOAT = 72219, // 72214 is the proper way (with proc) but atm procs can't have cooldown for creatures
SPELL_GASTRIC_EXPLOSION = 72227,
SPELL_GAS_SPORE = 69278,
SPELL_VILE_GAS = 69240,
SPELL_INOCULATED = 69291,
// Stinky
SPELL_MORTAL_WOUND = 71127,
SPELL_DECIMATE = 71123,
SPELL_PLAGUE_STENCH = 71805
};
// Used for HasAura checks
#define PUNGENT_BLIGHT_HELPER RAID_MODE(69195,71219,73031,73032)
#define INOCULATED_HELPER RAID_MODE(69291,72101,72102,72103)
static const uint32 gaseousBlight[3] = {69157, 69162, 69164};
static const uint32 gaseousBlightVisual[3] = {69126, 69152, 69154};
enum eEvents
{
EVENT_BERSERK = 1,
EVENT_INHALE_BLIGHT = 2,
EVENT_VILE_GAS = 3,
EVENT_GAS_SPORE = 4,
EVENT_GASTRIC_BLOAT = 5,
EVENT_DECIMATE = 6,
EVENT_MORTAL_WOUND = 7
};
#define DATA_INOCULATED_STACK 69291
class boss_festergut : public CreatureScript
{
public:
boss_festergut() : CreatureScript("boss_festergut") { }
struct boss_festergutAI : public BossAI
{
boss_festergutAI(Creature* pCreature) : BossAI(pCreature, DATA_FESTERGUT)
{
ASSERT(instance);
uiMaxInoculatedStack = 0;
uiInhaleCounter = 0;
gasDummyGUID = 0;
}
void Reset()
{
events.Reset();
events.ScheduleEvent(EVENT_BERSERK, 300000);
events.ScheduleEvent(EVENT_INHALE_BLIGHT, urand(25000, 30000));
events.ScheduleEvent(EVENT_VILE_GAS, urand(30000, 32500));
events.ScheduleEvent(EVENT_GAS_SPORE, urand(20000, 25000));
events.ScheduleEvent(EVENT_GASTRIC_BLOAT, urand(12500, 15000));
uiMaxInoculatedStack = 0;
uiInhaleCounter = 0;
me->RemoveAurasDueToSpell(SPELL_BERSERK2);
if (Creature* gasDummy = GetClosestCreatureWithEntry(me, NPC_GAS_DUMMY, 100.0f, true))
{
gasDummyGUID = gasDummy->GetGUID();
for (uint8 i = 0; i < 3; ++i)
{
gasDummy->RemoveAurasDueToSpell(gaseousBlight[i]);
gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]);
}
}
instance->SetBossState(DATA_FESTERGUT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/)
{
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);
DoZoneInCombat(me);
}
void JustDied(Unit* /*killer*/)
{
DoScriptText(SAY_DEATH, me);
instance->SetBossState(DATA_FESTERGUT, DONE);
if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->DoAction(ACTION_FESTERGUT_DEATH);
}
void JustReachedHome()
{
instance->SetBossState(DATA_FESTERGUT, FAIL);
}
void EnterEvadeMode()
{
ScriptedAI::EnterEvadeMode();
if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->EnterEvadeMode();
}
void KilledUnit(Unit *victim)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
DoScriptText(RAND(SAY_KILL_1, SAY_KILL_2), me);
}
void MoveInLineOfSight(Unit* /*who*/)
{
// don't enter combat
}
void SpellHitTarget(Unit* target, const SpellEntry* spell)
{
if (spell->Id == PUNGENT_BLIGHT_HELPER)
target->RemoveAurasDueToSpell(INOCULATED_HELPER);
}
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_INHALE_BLIGHT:
{
if (Creature* gasDummy = Unit::GetCreature(*me, gasDummyGUID))
for (uint8 i = 0; i < 3; ++i)
{
gasDummy->RemoveAurasDueToSpell(gaseousBlight[i]);
gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]);
}
if (uiInhaleCounter == 3)
{
DoScriptText(EMOTE_WARN_PUNGENT_BLIGHT, me);
DoScriptText(SAY_PUNGENT_BLIGHT, me);
DoCast(me, SPELL_PUNGENT_BLIGHT);
uiInhaleCounter = 0;
if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->DoAction(ACTION_FESTERGUT_GAS);
}
else
{
DoCast(me, SPELL_INHALE_BLIGHT);
// just cast and dont bother with target, conditions will handle it
++uiInhaleCounter;
if (uiInhaleCounter < 3)
me->CastSpell(me, gaseousBlight[uiInhaleCounter], true, NULL, NULL, me->GetGUID());
}
events.ScheduleEvent(EVENT_INHALE_BLIGHT, urand(33500, 35000));
return;
}
case EVENT_VILE_GAS:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, 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);
DoScriptText(EMOTE_GAS_SPORE, me);
events.ScheduleEvent(EVENT_GAS_SPORE, urand(40000, 45000));
case EVENT_GASTRIC_BLOAT:
DoCastVictim(SPELL_GASTRIC_BLOAT);
events.ScheduleEvent(EVENT_GASTRIC_BLOAT, urand(15000, 17500));
break;
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK2);
DoScriptText(SAY_BERSERK, me);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void SetData(uint32 type, uint32 data)
{
if (type == DATA_INOCULATED_STACK && data > uiMaxInoculatedStack)
uiMaxInoculatedStack = data;
}
uint32 GetData(uint32 type)
{
if (type == DATA_INOCULATED_STACK)
return uint32(uiMaxInoculatedStack);
return 0;
}
private:
uint32 uiMaxInoculatedStack;
uint8 uiInhaleCounter;
uint64 gasDummyGUID;
};
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_festergutAI(pCreature);
}
};
class npc_stinky_icc : public CreatureScript
{
public:
npc_stinky_icc() : CreatureScript("npc_stinky_icc") { }
struct npc_stinky_iccAI : public ScriptedAI
{
npc_stinky_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));
DoCast(me, SPELL_PLAGUE_STENCH);
}
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 festergutGUID = pInstance ? pInstance->GetData64(DATA_FESTERGUT) : 0;
if (Creature *festergut = me->GetCreature(*me, festergutGUID))
DoScriptText(SAY_STINKY_DEAD, festergut);
}
private:
EventMap events;
InstanceScript* pInstance;
};
CreatureAI* GetAI(Creature* pCreature) const
{
return new npc_stinky_iccAI(pCreature);
}
};
class spell_festergut_pungent_blight : public SpellScriptLoader
{
public:
spell_festergut_pungent_blight() : SpellScriptLoader("spell_festergut_pungent_blight") { }
class spell_festergut_pungent_blight_SpellScript : public SpellScript
{
void HandleScript(SpellEffIndex effIndex)
{
SpellEntry const* spellInfo = sSpellStore.LookupEntry(GetEffectValue());
if (!spellInfo)
return;
// Get Inhaled Blight id for our difficulty
spellInfo = sSpellMgr.GetSpellForDifficultyFromSpell(spellInfo, GetCaster());
// ...and remove it
GetCaster()->RemoveAurasDueToSpell(spellInfo->Id);
DoScriptText(EMOTE_PUNGENT_BLIGHT, GetCaster());
}
void Register()
{
OnEffect += SpellEffectFn(spell_festergut_pungent_blight_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_festergut_pungent_blight_SpellScript();
}
};
class spell_festergut_gastric_bloat : public SpellScriptLoader
{
public:
spell_festergut_gastric_bloat() : SpellScriptLoader("spell_festergut_gastric_bloat") { }
class spell_festergut_gastric_bloat_SpellScript : public SpellScript
{
void HandleScript(SpellEffIndex effIndex)
{
Aura const* aura = GetHitUnit()->GetAura(GetSpellInfo()->Id);
if (!(aura && aura->GetStackAmount() == 10))
return;
//PreventHitAura();
SpellEntry const* spellInfo = sSpellStore.LookupEntry(SPELL_GASTRIC_EXPLOSION);
if (!spellInfo)
return;
// Get Gastric Explosion id for our difficulty
spellInfo = sSpellMgr.GetSpellForDifficultyFromSpell(spellInfo, GetCaster());
GetHitUnit()->RemoveAurasDueToSpell(GetSpellInfo()->Id);
GetHitUnit()->CastSpell(GetHitUnit(), spellInfo, true);
}
void Register()
{
OnEffect += SpellEffectFn(spell_festergut_gastric_bloat_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_festergut_gastric_bloat_SpellScript();
}
};
class spell_festergut_blighted_spores : public SpellScriptLoader
{
public:
spell_festergut_blighted_spores() : SpellScriptLoader("spell_festergut_blighted_spores") { }
class spell_festergut_blighted_spores_AuraScript : public AuraScript
{
void ExtraEffect(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/)
{
if (!GetCaster()->IsAIEnabled || GetCaster()->GetTypeId() != TYPEID_UNIT)
return;
uint32 inoculateId = CAST_AI(ScriptedAI, GetCaster()->ToCreature()->AI())->INOCULATED_HELPER;
uint32 currStack = 0;
if (Aura const* inoculate = aurApp->GetTarget()->GetAura(inoculateId))
currStack = inoculate->GetStackAmount();
aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), SPELL_INOCULATED, true);
++currStack;
if (GetCaster())
GetCaster()->ToCreature()->AI()->SetData(DATA_INOCULATED_STACK, currStack);
}
void Register()
{
OnEffectApply += AuraEffectApplyFn(spell_festergut_blighted_spores_AuraScript::ExtraEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_festergut_blighted_spores_AuraScript();
}
};
class achievement_flu_shot_shortage : public AchievementCriteriaScript
{
public:
achievement_flu_shot_shortage() : AchievementCriteriaScript("achievement_flu_shot_shortage") { }
bool OnCheck(Player* /*source*/, Unit* target)
{
if (target && target->GetTypeId() == TYPEID_UNIT)
return target->ToCreature()->AI()->GetData(DATA_INOCULATED_STACK) < 3;
return false;
}
};
void AddSC_boss_festergut()
{
new boss_festergut();
new npc_stinky_icc();
new spell_festergut_pungent_blight();
new spell_festergut_gastric_bloat();
new spell_festergut_blighted_spores();
new achievement_flu_shot_shortage();
}
@@ -0,0 +1,212 @@
/*
* Copyright (C) 2008-2010 Trinity <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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ScriptPCH.h"
#include "icecrown_citadel.h"
enum eScriptTexts
{
// Festergut
SAY_FESTERGUT_GASEOUS_BLIGHT = -1631080,
SAY_FESTERGUT_DEATH = -1631090,
};
enum eSpells
{
// Festergut
SPELL_RELEASE_GAS_VISUAL = 69125,
SPELL_GASEOUS_BLIGHT_LARGE = 69157,
SPELL_GASEOUS_BLIGHT_MEDIUM = 69162,
SPELL_GASEOUS_BLIGHT_SMALL = 69164,
SPELL_MALLABLE_GOO_H = 70852,
};
enum eEvents
{
// Festergut
EVENT_FESTERGUT_DIES = 1,
EVENT_FESTERGUT_GOO = 2,
};
enum ePhases
{
PHASE_FESTERGUT = 1,
PHASE_ROTFACE = 2,
PHASE_COMBAT = 3,
PHASE_MASK_NOT_SELF = (1 << PHASE_FESTERGUT) | (1 << PHASE_ROTFACE)
};
enum ePoints
{
POINT_FESTERGUT = -366260,
};
static const Position festergutWatchPos = {4324.82f, 3166.03f, 389.3831f, 3.316126f}; //emote 432 (release gas)
class boss_professor_putricide : public CreatureScript
{
public:
boss_professor_putricide() : CreatureScript("boss_professor_putricide") { }
struct boss_professor_putricideAI : public BossAI
{
boss_professor_putricideAI(Creature* pCreature) : BossAI(pCreature, DATA_PROFESSOR_PUTRICIDE),
fBaseSpeed(pCreature->GetSpeedRate(MOVE_RUN))
{
ASSERT(instance);
phase = ePhases(0);
}
void Reset()
{
events.Reset();
summons.DespawnAll();
_SetPhase(PHASE_COMBAT);
me->SetReactState(REACT_DEFENSIVE);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
}
void DoAction(const int32 action)
{
switch (action)
{
case ACTION_FESTERGUT_COMBAT:
_SetPhase(PHASE_FESTERGUT);
me->SetSpeed(MOVE_RUN, fBaseSpeed*2.0f, true);
me->GetMotionMaster()->MovePoint(POINT_FESTERGUT, festergutWatchPos);
me->SetReactState(REACT_PASSIVE);
if (IsHeroic())
{
DoZoneInCombat(me);
events.ScheduleEvent(EVENT_FESTERGUT_GOO, urand(15000, 20000), 0, PHASE_FESTERGUT);
}
break;
case ACTION_FESTERGUT_GAS:
DoScriptText(SAY_FESTERGUT_GASEOUS_BLIGHT, me);
if (Creature* festergut = Unit::GetCreature(*me, instance->GetData64(DATA_FESTERGUT)))
festergut->CastSpell(festergut, SPELL_RELEASE_GAS_VISUAL, false, NULL, NULL, me->GetGUID()); // cast from festergut for LoS (with prof's GUID for logs)
break;
case ACTION_FESTERGUT_DEATH:
events.ScheduleEvent(EVENT_FESTERGUT_DIES, 4000, 0, PHASE_FESTERGUT);
break;
default:
break;
}
}
void JustReachedHome()
{
if (phase == PHASE_COMBAT)
instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, FAIL);
}
void MovementInform(uint32 type, uint32 id)
{
if (type == POINT_MOTION_TYPE && id == 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());
}
}
void UpdateAI(const uint32 diff)
{
if ((!UpdateVictim() && !(events.GetPhaseMask() & PHASE_MASK_NOT_SELF)) || !CheckInRoom())
return;
events.Update(diff);
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_FESTERGUT_DIES:
DoScriptText(SAY_FESTERGUT_DEATH, me);
EnterEvadeMode();
break;
case EVENT_FESTERGUT_GOO:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 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;
default:
break;
}
}
}
void _SetPhase(ePhases newPhase)
{
phase = newPhase;
events.SetPhase(newPhase);
}
private:
ePhases phase; // external of EventMap because event phase gets reset on evade
const float fBaseSpeed;
};
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_professor_putricideAI(pCreature);
}
};
// Stinky and Precious spell, it's here because its used for both (Festergut and Rotface "pet")
class spell_stinky_precious_decimate : public SpellScriptLoader
{
public:
spell_stinky_precious_decimate() : SpellScriptLoader("spell_stinky_precious_decimate") { }
class spell_stinky_precious_decimate_SpellScript : public SpellScript
{
void HandleScript(SpellEffIndex effIndex)
{
if (GetHitUnit()->GetHealthPct() > float(GetEffectValue()))
{
uint32 newHealth = GetHitUnit()->GetMaxHealth() * uint32(GetEffectValue()) / 100;
if (GetHitUnit()->GetMaxHealth() >= newHealth)
GetHitUnit()->SetHealth(newHealth);
}
}
void Register()
{
OnEffect += SpellEffectFn(spell_stinky_precious_decimate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_stinky_precious_decimate_SpellScript();
}
};
void AddSC_boss_professor_putricide()
{
new boss_professor_putricide();
new spell_stinky_precious_decimate();
}
@@ -21,7 +21,8 @@
enum eSharedSpells
{
SPELL_BERSERK = 26662
SPELL_BERSERK = 26662,
SPELL_BERSERK2 = 47008
};
enum eData
@@ -69,6 +70,13 @@ enum eCreatures
NPC_SE_HIGH_OVERLORD_SAURFANG = 37187,
NPC_SE_KOR_KRON_REAVER = 37920,
NPC_SE_SKYBREAKER_MARINE = 37830,
NPC_FESTERGUT = 36626,
NPC_GAS_DUMMY = 36659,
NPC_ROTFACE = 36627,
NPC_PROFESSOR_PUTRICIDE = 36678,
};
enum eGameobjects
@@ -84,6 +92,14 @@ enum eGameobjects
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,
};
enum eAchievementCriteria
@@ -94,4 +110,11 @@ enum eAchievementCriteria
CRITERIA_BONED_25H = 13394,
};
enum ePutricideActions
{
ACTION_FESTERGUT_COMBAT = -366260,
ACTION_FESTERGUT_GAS = -366261,
ACTION_FESTERGUT_DEATH = -366262,
};
#endif // DEF_ICECROWN_CITADEL_H
@@ -25,6 +25,9 @@ static const DoorData doorData[8] =
{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
};
@@ -45,6 +48,12 @@ class instance_icecrown_citadel : public InstanceMapScript
uiSaurfangEventNPC = 0;
uiDeathbringersCache = 0;
uiSaurfangTeleport = 0;
memset(uiPutricidePipes, 0, 2*sizeof(uint32));
memset(uiPutricideGates, 0, 2*sizeof(uint32));
uiPutricideCollision;
uiFestergut = 0;
uiRotface = 0;
uiProfessorPutricide = 0;
isBonedEligible = false;
}
@@ -75,6 +84,15 @@ class instance_icecrown_citadel : public InstanceMapScript
if (TeamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_SE_SKYBREAKER_MARINE, ALLIANCE);
break;
case NPC_FESTERGUT:
uiFestergut = creature->GetGUID();
break;
case NPC_ROTFACE:
uiRotface = creature->GetGUID();
break;
case NPC_PROFESSOR_PUTRICIDE:
uiProfessorPutricide = creature->GetGUID();
break;
default:
break;
}
@@ -88,6 +106,9 @@ class instance_icecrown_citadel : public InstanceMapScript
case GO_ICEWALL:
case GO_LORD_MARROWGAR_S_ENTRANCE:
case GO_ORATORY_OF_THE_DAMNED_ENTRANCE:
case GO_ORANGE_PLAGUE_MONSTER_ENTRANCE:
case GO_GREEN_PLAGUE_MONSTER_ENTRANCE:
case GO_SCIENTIST_ENTRANCE:
AddDoor(pGo, add);
break;
case GO_LADY_DEATHWHISPER_ELEVATOR:
@@ -110,6 +131,35 @@ class instance_icecrown_citadel : public InstanceMapScript
case GO_SCOURGE_TRANSPORTER_SAURFANG:
uiSaurfangTeleport = pGo->GetGUID();
break;
case GO_SCIENTIST_AIRLOCK_DOOR_COLLISION:
uiPutricideCollision = pGo->GetGUID();
if (GetBossState(DATA_FESTERGUT) == DONE && GetBossState(DATA_ROTFACE) == DONE)
HandleGameObject(uiPutricideCollision, true, pGo);
break;
case GO_SCIENTIST_AIRLOCK_DOOR_ORANGE:
uiPutricideGates[0] = pGo->GetGUID();
if (GetBossState(DATA_FESTERGUT) == DONE && GetBossState(DATA_ROTFACE) == DONE)
pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
else if (GetBossState(DATA_FESTERGUT) == DONE)
HandleGameObject(uiPutricideGates[1], false, pGo);
break;
case GO_SCIENTIST_AIRLOCK_DOOR_GREEN:
uiPutricideGates[1] = pGo->GetGUID();
if (GetBossState(DATA_ROTFACE) == DONE && GetBossState(DATA_FESTERGUT) == DONE)
pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
else if (GetBossState(DATA_ROTFACE) == DONE)
HandleGameObject(uiPutricideGates[1], false, pGo);
break;
case GO_DOODAD_ICECROWN_ORANGETUBES02:
uiPutricidePipes[0] = pGo->GetGUID();
if (GetBossState(DATA_FESTERGUT) == DONE)
HandleGameObject(uiPutricidePipes[0], true, pGo);
break;
case GO_DOODAD_ICECROWN_GREENTUBES02:
uiPutricidePipes[1] = pGo->GetGUID();
if (GetBossState(DATA_ROTFACE) == DONE)
HandleGameObject(uiPutricidePipes[1], true, pGo);
break;
default:
break;
}
@@ -127,6 +177,10 @@ class instance_icecrown_citadel : public InstanceMapScript
return uiSaurfangDoor;
case GO_SCOURGE_TRANSPORTER_SAURFANG:
return uiSaurfangTeleport;
case DATA_FESTERGUT:
return uiFestergut;
case DATA_PROFESSOR_PUTRICIDE:
return uiProfessorPutricide;
default:
break;
}
@@ -167,7 +221,35 @@ class instance_icecrown_citadel : public InstanceMapScript
}
break;
case DATA_FESTERGUT:
if (state == DONE)
{
if (GetBossState(DATA_ROTFACE) == DONE)
HandleGameObject(uiPutricideCollision, true);
if (GetBossState(DATA_ROTFACE) == DONE)
{
if (GameObject* pGo = instance->GetGameObject(uiPutricideGates[0]))
pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
else
HandleGameObject(uiPutricideGates[0], false);
HandleGameObject(uiPutricidePipes[0], true);
}
break;
case DATA_ROTFACE:
if (state == DONE)
{
if (GetBossState(DATA_FESTERGUT) == DONE)
HandleGameObject(uiPutricideCollision, true);
if (GetBossState(DATA_FESTERGUT) == DONE)
{
if (GameObject* pGo = instance->GetGameObject(uiPutricideGates[1]))
pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
else
HandleGameObject(uiPutricideGates[1], false);
HandleGameObject(uiPutricidePipes[1], true);
}
break;
case DATA_PROFESSOR_PUTRICIDE:
case DATA_BLOOD_PRINCE_COUNCIL:
case DATA_BLOOD_QUEEN_LANA_THEL:
@@ -256,6 +338,12 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 uiSaurfangEventNPC; // Muradin Bronzebeard or High Overlord Saurfang
uint64 uiDeathbringersCache;
uint64 uiSaurfangTeleport;
uint64 uiPutricidePipes[2];
uint64 uiPutricideGates[2];
uint64 uiPutricideCollision;
uint64 uiFestergut;
uint64 uiRotface;
uint64 uiProfessorPutricide;
bool isBonedEligible;
};