Big re-organization of repository [W.I.P]

This commit is contained in:
Yehonal
2016-08-11 20:25:27 +02:00
parent c62a72c0a8
commit 0f85ce1c54
3016 changed files with 1271 additions and 1 deletions

View File

@@ -1,494 +0,0 @@
/*
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
*/
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuras.h"
#include "icecrown_citadel.h"
enum ScriptTexts
{
SAY_STINKY_DEAD = 0,
SAY_AGGRO = 1,
EMOTE_GAS_SPORE = 2,
EMOTE_WARN_GAS_SPORE = 3,
SAY_PUNGENT_BLIGHT = 4,
EMOTE_WARN_PUNGENT_BLIGHT = 5,
EMOTE_PUNGENT_BLIGHT = 6,
SAY_KILL = 7,
SAY_BERSERK = 8,
SAY_DEATH = 9,
};
enum Spells
{
// 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,
SPELL_MALLABLE_GOO_H = 72296,
// Stinky
SPELL_MORTAL_WOUND = 71127,
SPELL_DECIMATE = 71123,
SPELL_PLAGUE_STENCH = 71805,
};
// Used for HasAura checks
#define PUNGENT_BLIGHT_HELPER RAID_MODE<uint32>(69195, 71219, 73031, 73032)
#define INOCULATED_HELPER RAID_MODE<uint32>(69291, 72101, 72102, 72103)
uint32 const gaseousBlight[3] = {69157, 69162, 69164};
uint32 const gaseousBlightVisual[3] = {69126, 69152, 69154};
#define DATA_INOCULATED_STACK 69291
enum Events
{
// Festergut
EVENT_NONE,
EVENT_BERSERK,
EVENT_INHALE_BLIGHT,
EVENT_VILE_GAS,
EVENT_GAS_SPORE,
EVENT_GASTRIC_BLOAT,
EVENT_FESTERGUT_GOO,
// Stinky
EVENT_DECIMATE,
EVENT_MORTAL_WOUND,
};
class boss_festergut : public CreatureScript
{
public:
boss_festergut() : CreatureScript("boss_festergut") { }
struct boss_festergutAI : public BossAI
{
boss_festergutAI(Creature* creature) : BossAI(creature, DATA_FESTERGUT)
{
_gasDummyGUID = 0;
}
uint64 _gasDummyGUID;
uint32 _maxInoculatedStack;
uint32 _inhaleCounter;
void Reset()
{
_maxInoculatedStack = 0;
_inhaleCounter = 0;
_Reset();
events.Reset();
if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true))
{
_gasDummyGUID = gasDummy->GetGUID();
for (uint8 i=0; i<3; ++i)
gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]);
}
}
void EnterCombat(Unit* who)
{
if (!instance->CheckRequiredBosses(DATA_FESTERGUT, who->ToPlayer()))
{
EnterEvadeMode();
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
events.ScheduleEvent(EVENT_BERSERK, 300000);
events.ScheduleEvent(EVENT_INHALE_BLIGHT, urand(25000, 30000));
events.ScheduleEvent(EVENT_GAS_SPORE, urand(20000, 25000));
events.ScheduleEvent(EVENT_VILE_GAS, urand(30000, 40000), 1);
events.ScheduleEvent(EVENT_GASTRIC_BLOAT, urand(12500, 15000));
if (IsHeroic())
events.ScheduleEvent(EVENT_FESTERGUT_GOO, urand(15000, 20000));
me->setActive(true);
Talk(SAY_AGGRO);
DoZoneInCombat();
if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true))
_gasDummyGUID = gasDummy->GetGUID();
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->DoAction(ACTION_FESTERGUT_COMBAT);
}
void JustDied(Unit* /*killer*/)
{
_JustDied();
Talk(SAY_DEATH);
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->DoAction(ACTION_FESTERGUT_DEATH);
RemoveBlight();
}
void JustReachedHome()
{
_JustReachedHome();
instance->SetBossState(DATA_FESTERGUT, FAIL);
}
void EnterEvadeMode()
{
ScriptedAI::EnterEvadeMode();
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->EnterEvadeMode();
}
void KilledUnit(Unit* victim)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_KILL);
}
void SpellHitTarget(Unit* target, SpellInfo const* spell)
{
if (spell->Id == PUNGENT_BLIGHT_HELPER)
target->RemoveAurasDueToSpell(INOCULATED_HELPER);
else if (Player* p = target->ToPlayer())
{
// Gaseous Blight damage
if ((spell->Id == 69159 || spell->Id == 70136 || spell->Id == 69161 || spell->Id == 70139 || spell->Id == 69163 || spell->Id == 70469) && p->GetQuestStatus(QUEST_RESIDUE_RENDEZVOUS_10) == QUEST_STATUS_INCOMPLETE ||
(spell->Id == 70135 || spell->Id == 70138 || spell->Id == 70468 || spell->Id == 70137 || spell->Id == 70140 || spell->Id == 70470) && p->GetQuestStatus(QUEST_RESIDUE_RENDEZVOUS_25) == QUEST_STATUS_INCOMPLETE)
p->CastSpell(p, SPELL_ORANGE_BLIGHT_RESIDUE, true);
}
}
void RemoveBlight()
{
if (Creature* gasDummy = ObjectAccessor::GetCreature(*me, _gasDummyGUID))
for (uint8 i = 0; i < 3; ++i)
{
me->RemoveAurasDueToSpell(gaseousBlight[i]);
gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]);
}
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_BERSERK:
me->CastSpell(me, SPELL_BERSERK2, true);
Talk(SAY_BERSERK);
break;
case EVENT_INHALE_BLIGHT:
RemoveBlight();
if (_inhaleCounter == 3)
{
Talk(EMOTE_WARN_PUNGENT_BLIGHT);
Talk(SAY_PUNGENT_BLIGHT);
me->CastSpell(me, SPELL_PUNGENT_BLIGHT, false);
_inhaleCounter = 0;
events.RescheduleEvent(EVENT_GAS_SPORE, urand(20000, 25000));
}
else
{
me->CastSpell(me, SPELL_INHALE_BLIGHT, false);
// just cast and dont bother with target, conditions will handle it
++_inhaleCounter;
if (_inhaleCounter < 3)
me->CastSpell(me, gaseousBlight[_inhaleCounter], true, NULL, NULL, me->GetGUID());
}
events.ScheduleEvent(EVENT_INHALE_BLIGHT, 34000);
break;
case EVENT_GAS_SPORE:
Talk(EMOTE_WARN_GAS_SPORE);
Talk(EMOTE_GAS_SPORE);
me->CastCustomSpell(SPELL_GAS_SPORE, SPELLVALUE_MAX_TARGETS, RAID_MODE<int32>(2, 3, 2, 3), me);
events.ScheduleEvent(EVENT_GAS_SPORE, urand(40000, 45000));
events.DelayEventsToMax(20000, 1); // delay EVENT_VILE_GAS
break;
case EVENT_VILE_GAS:
{
std::list<Unit*> targets;
uint32 minTargets = RAID_MODE<uint32>(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))
me->CastSpell(target, SPELL_VILE_GAS, false);
events.ScheduleEvent(EVENT_VILE_GAS, urand(28000, 35000), 1);
break;
}
case EVENT_GASTRIC_BLOAT:
me->CastSpell(me->GetVictim(), SPELL_GASTRIC_BLOAT, false);
events.ScheduleEvent(EVENT_GASTRIC_BLOAT, urand(15000, 17500));
break;
case EVENT_FESTERGUT_GOO:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->CastSpell(target, SPELL_MALLABLE_GOO_H, true);
events.ScheduleEvent(EVENT_FESTERGUT_GOO, urand(15000, 20000));
default:
break;
}
DoMeleeAttackIfReady();
}
void SetData(uint32 type, uint32 data)
{
if (type == DATA_INOCULATED_STACK && data > _maxInoculatedStack)
_maxInoculatedStack = data;
}
uint32 GetData(uint32 type) const
{
if (type == DATA_INOCULATED_STACK)
return _maxInoculatedStack;
return 0;
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<boss_festergutAI>(creature);
}
};
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
{
PrepareSpellScript(spell_festergut_pungent_blight_SpellScript);
bool Load()
{
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
if (caster->GetTypeId() != TYPEID_UNIT)
return;
// Get Inhaled Blight id for our difficulty
uint32 blightId = sSpellMgr->GetSpellIdForDifficulty(uint32(GetEffectValue()), caster);
// ...and remove it
caster->RemoveAurasDueToSpell(blightId);
caster->ToCreature()->AI()->Talk(EMOTE_PUNGENT_BLIGHT);
if (InstanceScript* inst = caster->GetInstanceScript())
if (Creature* professor = ObjectAccessor::GetCreature(*caster, inst->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->DoAction(ACTION_FESTERGUT_GAS);
}
void Register()
{
OnEffectHitTarget += 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_blighted_spores : public SpellScriptLoader
{
public:
spell_festergut_blighted_spores() : SpellScriptLoader("spell_festergut_blighted_spores") { }
class spell_festergut_blighted_spores_AuraScript : public AuraScript
{
PrepareAuraScript(spell_festergut_blighted_spores_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_INOCULATED))
return false;
return true;
}
void ExtraEffect(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Aura* a = aurEff->GetBase())
if (a->GetDuration() > a->GetMaxDuration()-1000) // this does not stack for different casters and previous is removed by new DoT, prevent it from giving inoculation in such case
return;
uint32 inoculatedId = sSpellMgr->GetSpellIdForDifficulty(SPELL_INOCULATED, GetTarget());
uint8 inoculatedStack = 1;
if (Aura* a = GetTarget()->GetAura(inoculatedId))
{
inoculatedStack += a->GetStackAmount();
if (a->GetDuration() > a->GetMaxDuration()-10000) // player may gain only one stack at a time, no matter how many spores explode near him
return;
}
GetTarget()->CastSpell(GetTarget(), SPELL_INOCULATED, true);
if (InstanceScript* instance = GetTarget()->GetInstanceScript())
if (Creature* festergut = ObjectAccessor::GetCreature(*GetTarget(), instance->GetData64(DATA_FESTERGUT)))
festergut->AI()->SetData(DATA_INOCULATED_STACK, inoculatedStack);
}
void Register()
{
AfterEffectRemove += AuraEffectRemoveFn(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 spell_festergut_gastric_bloat : public SpellScriptLoader
{
public:
spell_festergut_gastric_bloat() : SpellScriptLoader("spell_festergut_gastric_bloat") { }
class spell_festergut_gastric_bloat_SpellScript : public SpellScript
{
PrepareSpellScript(spell_festergut_gastric_bloat_SpellScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_GASTRIC_EXPLOSION))
return false;
return true;
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
Aura const* aura = GetHitUnit()->GetAura(GetSpellInfo()->Id);
if (!(aura && aura->GetStackAmount() == 10))
return;
GetHitUnit()->RemoveAurasDueToSpell(GetSpellInfo()->Id);
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GASTRIC_EXPLOSION, true);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_festergut_gastric_bloat_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_festergut_gastric_bloat_SpellScript();
}
};
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;
}
};
class npc_stinky_icc : public CreatureScript
{
public:
npc_stinky_icc() : CreatureScript("npc_stinky_icc") { }
struct npc_stinky_iccAI : public ScriptedAI
{
npc_stinky_iccAI(Creature* creature) : ScriptedAI(creature) {}
void Reset()
{
events.Reset();
}
void EnterCombat(Unit* /*target*/)
{
me->setActive(true);
me->CastSpell(me, SPELL_PLAGUE_STENCH, true);
events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000));
events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(1500, 2500));
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_DECIMATE:
me->CastSpell(me->GetVictim(), SPELL_DECIMATE, false);
events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000));
break;
case EVENT_MORTAL_WOUND:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(1500, 2500));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/)
{
if (InstanceScript* _instance = me->GetInstanceScript())
if (Creature* festergut = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FESTERGUT)))
if (festergut->IsAlive())
festergut->AI()->Talk(SAY_STINKY_DEAD);
}
private:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<npc_stinky_iccAI>(creature);
}
};
void AddSC_boss_festergut()
{
new boss_festergut();
new spell_festergut_pungent_blight();
new spell_festergut_blighted_spores();
new spell_festergut_gastric_bloat();
new achievement_flu_shot_shortage();
new npc_stinky_icc();
}

View File

@@ -1,701 +0,0 @@
/*
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
*/
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuras.h"
#include "MapManager.h"
#include "icecrown_citadel.h"
#include "PassiveAI.h"
#include "Player.h"
#include "Vehicle.h"
enum ScriptTexts
{
SAY_ENTER_ZONE = 0,
SAY_AGGRO = 1,
SAY_BONE_STORM = 2,
SAY_BONESPIKE = 3,
SAY_KILL = 4,
SAY_DEATH = 5,
SAY_BERSERK = 6,
EMOTE_BONE_STORM = 7,
};
enum Spells
{
// Lord Marrowgar
SPELL_BONE_SLICE = 69055,
SPELL_BONE_STORM = 69076,
SPELL_BONE_SPIKE_GRAVEYARD = 69057,
SPELL_COLDFLAME_NORMAL = 69140,
SPELL_COLDFLAME_BONE_STORM = 72705,
// Bone Spike
SPELL_IMPALED = 69065,
SPELL_RIDE_VEHICLE = 46598,
// Coldflame
SPELL_COLDFLAME_PASSIVE = 69145,
SPELL_COLDFLAME_SUMMON = 69147,
};
enum Events
{
EVENT_ENABLE_BONE_SLICE = 1,
EVENT_SPELL_BONE_SPIKE_GRAVEYARD,
EVENT_SPELL_COLDFLAME,
EVENT_SPELL_COLDFLAME_BONE_STORM,
EVENT_WARN_BONE_STORM,
EVENT_BEGIN_BONE_STORM,
EVENT_BONE_STORM_MOVE,
EVENT_END_BONE_STORM,
EVENT_ENRAGE,
};
uint32 const boneSpikeSummonId[3] = {69062, 72669, 72670};
struct BoneStormMoveTargetSelector : public std::unary_function<Unit*, bool>
{
public:
BoneStormMoveTargetSelector(Creature* source) : _source(source) { }
bool operator()(Unit const* target) const
{
if (!target)
return false;
if (target->GetExactDist(_source) > 175.0f)
return false;
if (target->GetTypeId() != TYPEID_PLAYER)
return false;
if (target->GetPositionX() > -337.0f)
return false;
return target != _source->GetVictim();
}
private:
Creature const* _source;
};
class boss_lord_marrowgar : public CreatureScript
{
public:
boss_lord_marrowgar() : CreatureScript("boss_lord_marrowgar") { }
struct boss_lord_marrowgarAI : public BossAI
{
boss_lord_marrowgarAI(Creature* creature) : BossAI(creature, DATA_LORD_MARROWGAR)
{
_introDone = false;
_boneSlice = false;
}
bool _introDone;
bool _boneSlice;
uint64 _lastBoneSliceTargets[3];
void Reset()
{
me->SetReactState(REACT_AGGRESSIVE);
_Reset();
events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000);
events.ScheduleEvent(EVENT_SPELL_BONE_SPIKE_GRAVEYARD, urand(10000, 15000));
events.ScheduleEvent(EVENT_SPELL_COLDFLAME, 5000);
events.ScheduleEvent(EVENT_WARN_BONE_STORM, urand(45000, 50000));
events.ScheduleEvent(EVENT_ENRAGE, 600000);
_boneSlice = false;
memset(_lastBoneSliceTargets, 0, 3 * sizeof(uint64));
instance->SetData(DATA_BONED_ACHIEVEMENT, uint32(true));
}
void EnterCombat(Unit* /*who*/)
{
Talk(SAY_AGGRO);
me->setActive(true);
DoZoneInCombat();
instance->SetBossState(DATA_LORD_MARROWGAR, IN_PROGRESS);
}
void SpellHitTarget(Unit* target, const SpellInfo* spell)
{
if (target && (spell->Id == 69055 || spell->Id == 70814)) // Bone Slice (Saber Lash)
for (uint8 i=0; i<3; ++i)
if (!_lastBoneSliceTargets[i])
{
_lastBoneSliceTargets[i] = target->GetGUID();
break;
}
}
uint64 GetGUID(int32 id) const
{
if (id >= 0 && id <= 2)
return _lastBoneSliceTargets[id];
return (uint64)0;
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.GetEvent())
{
case 0:
break;
case EVENT_ENABLE_BONE_SLICE:
_boneSlice = true;
events.PopEvent();
break;
case EVENT_SPELL_BONE_SPIKE_GRAVEYARD:
{
bool a = me->HasAura(SPELL_BONE_STORM);
if (IsHeroic() || !a)
me->CastSpell(me, SPELL_BONE_SPIKE_GRAVEYARD, a);
events.RepeatEvent(urand(15000, 20000));
}
break;
case EVENT_SPELL_COLDFLAME:
if (!me->HasAura(SPELL_BONE_STORM))
me->CastSpell((Unit*)NULL, SPELL_COLDFLAME_NORMAL, false);
events.RepeatEvent(5000);
break;
case EVENT_SPELL_COLDFLAME_BONE_STORM:
me->CastSpell(me, SPELL_COLDFLAME_BONE_STORM, false);
events.PopEvent();
break;
case EVENT_WARN_BONE_STORM:
_boneSlice = false;
Talk(EMOTE_BONE_STORM);
Talk(SAY_BONE_STORM);
me->FinishSpell(CURRENT_MELEE_SPELL, false);
me->CastSpell(me, SPELL_BONE_STORM, false);
me->SetReactState(REACT_PASSIVE); // to prevent chasing another target on UpdateVictim()
me->GetMotionMaster()->MoveIdle();
me->GetMotionMaster()->MovementExpired();
events.RepeatEvent(urand(90000, 95000));
events.ScheduleEvent(EVENT_BEGIN_BONE_STORM, 3050);
break;
case EVENT_BEGIN_BONE_STORM:
{
uint32 _boneStormDuration = RAID_MODE<uint32>(20000, 30000, 20000, 30000);
if (Aura* pStorm = me->GetAura(SPELL_BONE_STORM))
pStorm->SetDuration(int32(_boneStormDuration));
events.PopEvent();
events.ScheduleEvent(EVENT_BONE_STORM_MOVE, 0);
events.ScheduleEvent(EVENT_END_BONE_STORM, _boneStormDuration+1);
}
break;
case EVENT_BONE_STORM_MOVE:
{
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
{
events.RepeatEvent(1);
break;
}
events.RepeatEvent(5000);
Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0, BoneStormMoveTargetSelector(me));
if (!unit)
{
if (unit = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 175.0f, true))
if (unit->GetPositionX() > -337.0f)
{
EnterEvadeMode();
return;
}
}
if (unit)
me->GetMotionMaster()->MoveCharge(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), 25.0f, 1337);
break;
}
break;
case EVENT_END_BONE_STORM:
me->StopMoving();
me->GetMotionMaster()->MovementExpired();
me->SetReactState(REACT_AGGRESSIVE);
DoStartMovement(me->GetVictim());
events.PopEvent();
events.CancelEvent(EVENT_BONE_STORM_MOVE);
events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000);
if (!IsHeroic())
events.RescheduleEvent(EVENT_SPELL_BONE_SPIKE_GRAVEYARD, urand(15000, 20000));
break;
case EVENT_ENRAGE:
me->CastSpell(me, SPELL_BERSERK, true);
Talk(SAY_BERSERK);
events.PopEvent();
break;
}
if (me->HasAura(SPELL_BONE_STORM))
return;
if (_boneSlice && !me->GetCurrentSpell(CURRENT_MELEE_SPELL))
DoCastVictim(SPELL_BONE_SLICE);
if (_boneSlice && me->isAttackReady() && me->GetVictim() && !me->HasUnitState(UNIT_STATE_CASTING) && me->IsWithinMeleeRange(me->GetVictim()))
memset(_lastBoneSliceTargets, 0, 3 * sizeof(uint64));
DoMeleeAttackIfReady();
}
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE || id != 1337)
return;
events.ScheduleEvent(EVENT_SPELL_COLDFLAME_BONE_STORM, 0);
}
void JustDied(Unit* /*killer*/)
{
Talk(SAY_DEATH);
_JustDied();
}
void JustReachedHome()
{
_JustReachedHome();
instance->SetBossState(DATA_LORD_MARROWGAR, FAIL);
}
void KilledUnit(Unit* victim)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_KILL);
}
void MoveInLineOfSight(Unit* who)
{
if (!_introDone && me->IsAlive() && who->GetTypeId() == TYPEID_PLAYER && me->GetExactDist2dSq(who) <= 10000.0f) // 100*100, moveinlineofsight limited to 60yd anyway
{
Talk(SAY_ENTER_ZONE);
_introDone = true;
}
BossAI::MoveInLineOfSight(who);
}
bool CanAIAttack(Unit const* target) const
{
return target->GetPositionX() < -337.0f; // main gate
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<boss_lord_marrowgarAI>(creature);
}
};
class npc_coldflame : public CreatureScript
{
public:
npc_coldflame() : CreatureScript("npc_coldflame") { }
struct npc_coldflameAI : public NullCreatureAI
{
npc_coldflameAI(Creature* creature) : NullCreatureAI(creature)
{
}
EventMap events;
void IsSummonedBy(Unit* /*summoner*/)
{
events.ScheduleEvent(1, 450);
events.ScheduleEvent(2, 12000);
me->m_positionZ = 42.5f;
}
void UpdateAI(uint32 diff)
{
events.Update(diff);
switch (events.GetEvent())
{
case 0:
break;
case 1:
{
me->m_positionZ = 42.5f;
me->DisableSpline();
me->CastSpell(me, SPELL_COLDFLAME_SUMMON, true);
float nx = me->GetPositionX()+5.0f*cos(me->GetOrientation());
float ny = me->GetPositionY()+5.0f*sin(me->GetOrientation());
if (!me->IsWithinLOS(nx, ny, 42.5f))
{
events.PopEvent();
break;
}
me->NearTeleportTo(nx, ny, 42.5f, me->GetOrientation());
events.RepeatEvent(450);
}
break;
case 2:
events.Reset();
break;
}
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<npc_coldflameAI>(creature);
}
};
class npc_bone_spike : public CreatureScript
{
public:
npc_bone_spike() : CreatureScript("npc_bone_spike") { }
struct npc_bone_spikeAI : public NullCreatureAI
{
npc_bone_spikeAI(Creature* creature) : NullCreatureAI(creature), hasTrappedUnit(false)
{
}
EventMap events;
bool hasTrappedUnit;
void DoAction(int32 action)
{
if (action != -1337)
return;
if (TempSummon* summ = me->ToTempSummon())
if (Unit* trapped = summ->GetSummoner())
{
Position exitPos = {me->GetPositionX(), me->GetPositionY(), 60.0f, me->GetOrientation()};
trapped->UpdateAllowedPositionZ(exitPos.GetPositionX(), exitPos.GetPositionY(), exitPos.m_positionZ);
exitPos.m_positionZ += 1.0f;
if (Unit* vehBase = trapped->GetVehicleBase())
vehBase->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE, trapped->GetGUID());
trapped->_ExitVehicle(&exitPos);
trapped->RemoveAurasDueToSpell(SPELL_IMPALED);
trapped->GetMotionMaster()->Clear();
trapped->UpdatePosition(exitPos, true);
trapped->StopMovingOnCurrentPos();
trapped->NearTeleportTo(exitPos.GetPositionX(), exitPos.GetPositionY(), exitPos.GetPositionZ(), exitPos.GetOrientation(), false);
}
me->DespawnOrUnsummon(1);
}
void JustDied(Unit* /*killer*/)
{
DoAction(-1337);
}
void IsSummonedBy(Unit* summoner)
{
if (!summoner)
return;
if (Vehicle* v = summoner->GetVehicle())
if (Unit* u = v->GetBase())
if (u->GetEntry() == NPC_BONE_SPIKE && u->GetTypeId() == TYPEID_UNIT)
u->ToCreature()->AI()->DoAction(-1337);
uint64 petGUID = summoner->GetPetGUID();
summoner->SetPetGUID(0);
me->CastSpell(summoner, SPELL_IMPALED, true);
summoner->CastSpell(me, SPELL_RIDE_VEHICLE, true);
//summoner->ClearUnitState(UNIT_STATE_ONVEHICLE);
summoner->SetPetGUID(petGUID);
summoner->GetMotionMaster()->Clear();
summoner->StopMoving();
events.ScheduleEvent(1, 8000);
hasTrappedUnit = true;
}
void UpdateAI(uint32 diff)
{
if (!hasTrappedUnit || !me->IsAlive())
return;
if (TempSummon* summ = me->ToTempSummon())
{
if (Unit* trapped = summ->GetSummoner())
{
if (!trapped->IsOnVehicle(me) || !trapped->IsAlive() || !me->GetInstanceScript() || me->GetInstanceScript()->GetBossState(DATA_LORD_MARROWGAR) != IN_PROGRESS || trapped->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
{
DoAction(-1337);
return;
}
}
else
{
me->DespawnOrUnsummon(1);
return;
}
}
else
{
me->DespawnOrUnsummon(1);
return;
}
events.Update(diff);
if (events.ExecuteEvent() == 1)
if (InstanceScript* instance = me->GetInstanceScript())
instance->SetData(DATA_BONED_ACHIEVEMENT, uint32(false));
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<npc_bone_spikeAI>(creature);
}
};
class spell_marrowgar_coldflame : public SpellScriptLoader
{
public:
spell_marrowgar_coldflame() : SpellScriptLoader("spell_marrowgar_coldflame") { }
class spell_marrowgar_coldflame_SpellScript : public SpellScript
{
PrepareSpellScript(spell_marrowgar_coldflame_SpellScript);
void SelectTarget(std::list<WorldObject*>& targets)
{
targets.clear();
Unit* target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 1, -1.0f, true, -SPELL_IMPALED); // -1.0f as it takes into account object size
if (!target)
target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); // if only tank or noone outside of boss' model
if (!target)
return;
targets.push_back(target);
}
void HandleScriptEffect(SpellEffIndex effIndex)
{
Unit* caster = GetCaster();
float angle = caster->GetAngle(GetHitUnit());
float dist = caster->GetObjectSize()/2.0f;
float z = caster->GetPositionZ()+2.5f;
float nx = caster->GetPositionX()+dist*cos(angle);
float ny = caster->GetPositionY()+dist*sin(angle);
if (!caster->IsWithinLOS(nx, ny, z))
{
nx = caster->GetPositionX()+0.5f*cos(angle);
ny = caster->GetPositionY()+0.5f*sin(angle);
}
if (caster->IsWithinLOS(nx, ny, z))
{
caster->m_orientation = angle;
caster->CastSpell(nx, ny, z, uint32(GetEffectValue()), true);
}
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_marrowgar_coldflame_SpellScript();
}
};
class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader
{
public:
spell_marrowgar_bone_spike_graveyard() : SpellScriptLoader("spell_marrowgar_bone_spike_graveyard") { }
class spell_marrowgar_bone_spike_graveyard_SpellScript : public SpellScript
{
PrepareSpellScript(spell_marrowgar_bone_spike_graveyard_SpellScript);
void HandleSpikes(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Creature* marrowgar = GetCaster()->ToCreature())
{
bool didHit = false;
CreatureAI* marrowgarAI = marrowgar->AI();
uint8 boneSpikeCount = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 3 : 1);
std::vector<Player*> validPlayers;
Map::PlayerList const &pList = marrowgar->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
if (Player* plr = itr->GetSource())
if (plr->IsAlive() && !plr->IsGameMaster() && plr->GetExactDist2dSq(marrowgar) < (150.0f * 150.0f) && !plr->HasAura(SPELL_IMPALED))
if (!marrowgar->GetVictim() || marrowgar->GetVictim()->GetGUID() != plr->GetGUID())
if (plr->GetGUID() != marrowgarAI->GetGUID(0) && plr->GetGUID() != marrowgarAI->GetGUID(1) && plr->GetGUID() != marrowgarAI->GetGUID(2)) // not a bone slice target
validPlayers.push_back(plr);
std::vector<Player*>::iterator begin=validPlayers.begin(), end=validPlayers.end();
std::random_shuffle(begin, end);
for (uint8 i = 0; i < boneSpikeCount && i < validPlayers.size(); ++i)
{
Unit* target = validPlayers[i];
didHit = true;
//target->CastCustomSpell(boneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true);
target->CastSpell(target, boneSpikeSummonId[i], true);
}
if (didHit)
marrowgarAI->Talk(SAY_BONESPIKE);
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_marrowgar_bone_spike_graveyard_SpellScript::HandleSpikes, EFFECT_1, SPELL_EFFECT_APPLY_AURA);
}
};
SpellScript* GetSpellScript() const
{
return new spell_marrowgar_bone_spike_graveyard_SpellScript();
}
};
class spell_marrowgar_coldflame_bonestorm : public SpellScriptLoader
{
public:
spell_marrowgar_coldflame_bonestorm() : SpellScriptLoader("spell_marrowgar_coldflame_bonestorm") { }
class spell_marrowgar_coldflame_SpellScript : public SpellScript
{
PrepareSpellScript(spell_marrowgar_coldflame_SpellScript);
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
Unit* caster = GetCaster();
float x = caster->GetPositionX();
float y = caster->GetPositionY();
float z = caster->GetPositionZ()+2.5f;
for (uint8 i = 0; i < 4; ++i)
{
float nx = x+2.5f*cos((M_PI/4)+(i*(M_PI/2)));
float ny = y+2.5f*sin((M_PI/4)+(i*(M_PI/2)));
if (caster->IsWithinLOS(nx, ny, z))
{
caster->m_orientation = (M_PI/4)+(i*(M_PI/2));
caster->CastSpell(nx, ny, z, uint32(GetEffectValue() + i), true);
}
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_marrowgar_coldflame_SpellScript();
}
};
class spell_marrowgar_bone_storm : public SpellScriptLoader
{
public:
spell_marrowgar_bone_storm() : SpellScriptLoader("spell_marrowgar_bone_storm") { }
class spell_marrowgar_bone_storm_SpellScript : public SpellScript
{
PrepareSpellScript(spell_marrowgar_bone_storm_SpellScript);
void RecalculateDamage()
{
float dist = GetHitUnit()->GetExactDist2d(GetCaster());
if (dist >= 9.0f) dist -= 9.0f;
else dist = 0.0f;
SetHitDamage(int32(GetHitDamage() / std::max(sqrtf(dist), 1.0f)));
}
void Register()
{
OnHit += SpellHitFn(spell_marrowgar_bone_storm_SpellScript::RecalculateDamage);
}
};
SpellScript* GetSpellScript() const
{
return new spell_marrowgar_bone_storm_SpellScript();
}
};
class spell_marrowgar_bone_slice : public SpellScriptLoader
{
public:
spell_marrowgar_bone_slice() : SpellScriptLoader("spell_marrowgar_bone_slice") { }
class spell_marrowgar_bone_slice_SpellScript : public SpellScript
{
PrepareSpellScript(spell_marrowgar_bone_slice_SpellScript);
bool Load()
{
_targetCount = 0;
return true;
}
void CountTargets(std::list<WorldObject*>& targets)
{
_targetCount = std::min<uint32>(targets.size(), GetSpellInfo()->MaxAffectedTargets);
}
void SplitDamage()
{
if (!_targetCount)
return; // This spell can miss all targets
SetHitDamage(GetHitDamage() / _targetCount);
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_marrowgar_bone_slice_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnHit += SpellHitFn(spell_marrowgar_bone_slice_SpellScript::SplitDamage);
}
uint32 _targetCount;
};
SpellScript* GetSpellScript() const
{
return new spell_marrowgar_bone_slice_SpellScript();
}
};
void AddSC_boss_lord_marrowgar()
{
new boss_lord_marrowgar();
new npc_coldflame();
new npc_bone_spike();
new spell_marrowgar_coldflame();
new spell_marrowgar_coldflame_bonestorm();
new spell_marrowgar_bone_spike_graveyard();
new spell_marrowgar_bone_storm();
new spell_marrowgar_bone_slice();
}

View File

@@ -1,961 +0,0 @@
/*
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
*/
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuras.h"
#include "GridNotifiers.h"
#include "icecrown_citadel.h"
enum Texts
{
SAY_PRECIOUS_DIES = 0,
SAY_AGGRO = 1,
EMOTE_SLIME_SPRAY = 2,
SAY_SLIME_SPRAY = 3,
EMOTE_UNSTABLE_EXPLOSION = 4,
SAY_UNSTABLE_EXPLOSION = 5,
SAY_KILL = 6,
SAY_BERSERK = 7,
SAY_DEATH = 8,
EMOTE_MUTATED_INFECTION = 9,
SAY_ROTFACE_OOZE_FLOOD = 2, // professor
EMOTE_PRECIOUS_ZOMBIES = 0,
};
enum Spells
{
// Rotface
SPELL_SLIME_SPRAY = 69508, // every 20 seconds
SPELL_MUTATED_INFECTION = 69674, // hastens every 1:30
SPELL_VILE_GAS_H = 69240,
// Ooze Flood
SPELL_OOZE_FLOOD_VISUAL = 69785,
SPELL_OOZE_FLOOD_PERIODIC = 69788,
// 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,
SPELL_AWAKEN_PLAGUED_ZOMBIES = 71159,
};
#define MUTATED_INFECTION RAID_MODE<int32>(69674, 71224, 73022, 73023)
enum Events
{
EVENT_NONE,
// Rotface
EVENT_UNROOT,
EVENT_SLIME_SPRAY,
EVENT_HASTEN_INFECTIONS,
EVENT_MUTATED_INFECTION,
EVENT_ROTFACE_OOZE_FLOOD,
EVENT_ROTFACE_VILE_GAS,
EVENT_STICKY_OOZE,
// Precious
EVENT_DECIMATE,
EVENT_MORTAL_WOUND,
EVENT_SUMMON_ZOMBIES,
};
uint32 const oozeFloodSpells[4] = {69782, 69796, 69798, 69801};
uint32 getOozeFloodSpellIndex(uint32 id)
{
switch (id)
{
case 69782: return 0;
case 69796: return 1;
case 69798: return 2;
case 69801: return 3;
}
return 0;
}
struct RotfaceHeightCheck
{
RotfaceHeightCheck() {}
bool operator()(Creature* stalker) const
{
return stalker->GetPositionZ() < 365.0f;
}
};
class boss_rotface : public CreatureScript
{
public:
boss_rotface() : CreatureScript("boss_rotface") { }
struct boss_rotfaceAI : public BossAI
{
boss_rotfaceAI(Creature* creature) : BossAI(creature, DATA_ROTFACE)
{
}
uint32 infectionCooldown;
uint64 _oozeFloodDummyGUIDs[4][2];
uint8 _oozeFloodStage;
void Reset()
{
infectionCooldown = 14000;
memset(&_oozeFloodDummyGUIDs, 0, sizeof(_oozeFloodDummyGUIDs));
_oozeFloodStage = 0;
_Reset();
events.Reset();
}
void EnterCombat(Unit* who)
{
if (!instance->CheckRequiredBosses(DATA_ROTFACE, who->ToPlayer()))
{
EnterEvadeMode();
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
// schedule events
events.Reset();
events.ScheduleEvent(EVENT_SLIME_SPRAY, 20000);
events.ScheduleEvent(EVENT_HASTEN_INFECTIONS, 90000);
events.ScheduleEvent(EVENT_MUTATED_INFECTION, 14000);
events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 8000);
if (IsHeroic())
events.ScheduleEvent(EVENT_ROTFACE_VILE_GAS, urand(15000, 20000));
me->setActive(true);
Talk(SAY_AGGRO);
DoZoneInCombat();
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->DoAction(ACTION_ROTFACE_COMBAT);
instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(true)); // reset
// randomize ooze flood
_oozeFloodStage = urand(0,3);
std::list<Creature*> list;
GetCreatureListWithEntryInGrid(list, me, NPC_PUDDLE_STALKER, 60.0f);
list.remove_if(RotfaceHeightCheck()); // remove from the list all on the ground
for (std::list<Creature*>::const_iterator itr = list.begin(); itr != list.end(); ++itr)
{
uint32 index = me->GetHomePosition().GetAngle(*itr)/(M_PI/2.0f);
if (index>3) index = 3;
if (_oozeFloodDummyGUIDs[index][0])
_oozeFloodDummyGUIDs[index][1] = (*itr)->GetGUID();
else
_oozeFloodDummyGUIDs[index][0] = (*itr)->GetGUID();
}
}
void JustDied(Unit* /*killer*/)
{
instance->DoRemoveAurasDueToSpellOnPlayers(MUTATED_INFECTION);
_JustDied();
Talk(SAY_DEATH);
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->DoAction(ACTION_ROTFACE_DEATH);
}
void JustReachedHome()
{
_JustReachedHome();
instance->SetBossState(DATA_ROTFACE, FAIL);
}
void JustSummoned(Creature* summon)
{
if (me->IsAlive() && me->IsInCombat() && !me->IsInEvadeMode())
summons.Summon(summon);
else
summon->DespawnOrUnsummon(1);
}
void KilledUnit(Unit* victim)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_KILL);
}
void EnterEvadeMode()
{
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
ScriptedAI::EnterEvadeMode();
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->EnterEvadeMode();
}
void SpellHitTarget(Unit* target, SpellInfo const* spell)
{
switch (spell->Id)
{
case SPELL_SLIME_SPRAY:
Talk(SAY_SLIME_SPRAY);
break;
case 69507: // Slime Spray damage
case 71213:
case 73189:
case 73190:
if (Player* p = target->ToPlayer())
if (p->GetQuestStatus(QUEST_RESIDUE_RENDEZVOUS_10) == QUEST_STATUS_INCOMPLETE || p->GetQuestStatus(QUEST_RESIDUE_RENDEZVOUS_25) == QUEST_STATUS_INCOMPLETE)
p->CastSpell(p, SPELL_GREEN_BLIGHT_RESIDUE, true);
break;
case 69782:
case 69796:
case 69798:
case 69801:
{
uint32 index = getOozeFloodSpellIndex(spell->Id);
if (target->GetGUID() == _oozeFloodDummyGUIDs[index][0] || target->GetGUID() == _oozeFloodDummyGUIDs[index][1])
target->CastSpell((Unit*)NULL, spell->Effects[0].CalcValue(), false);
}
break;
}
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_UNROOT:
me->SetControlled(false, UNIT_STATE_ROOT);
me->DisableRotate(false);
break;
case EVENT_SLIME_SPRAY:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
{
if (Creature* c = me->SummonCreature(NPC_OOZE_SPRAY_STALKER, *target, TEMPSUMMON_TIMED_DESPAWN, 8000))
{
me->SetOrientation(me->GetAngle(c));
me->SetControlled(true, UNIT_STATE_ROOT);
me->DisableRotate(true);
me->SetFacingTo(me->GetAngle(c));
me->SendMovementFlagUpdate();
Talk(EMOTE_SLIME_SPRAY);
me->CastSpell(c, SPELL_SLIME_SPRAY, false);
}
}
events.DelayEvents(1);
events.ScheduleEvent(EVENT_SLIME_SPRAY, 20000);
events.ScheduleEvent(EVENT_UNROOT, 0);
break;
case EVENT_HASTEN_INFECTIONS:
if (infectionCooldown >= 8000)
{
infectionCooldown -= 2000;
events.ScheduleEvent(EVENT_HASTEN_INFECTIONS, 90000);
}
break;
case EVENT_MUTATED_INFECTION:
me->CastCustomSpell(SPELL_MUTATED_INFECTION, SPELLVALUE_MAX_TARGETS, 1, NULL, false);
events.ScheduleEvent(EVENT_MUTATED_INFECTION, infectionCooldown);
break;
case EVENT_ROTFACE_OOZE_FLOOD:
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
{
professor->AI()->Talk(SAY_ROTFACE_OOZE_FLOOD);
me->CastSpell((Unit*)NULL, oozeFloodSpells[_oozeFloodStage], true);
if (++_oozeFloodStage == 4)
_oozeFloodStage = 0;
}
events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000);
break;
case EVENT_ROTFACE_VILE_GAS:
{
std::list<Unit*> targets;
uint32 minTargets = RAID_MODE<uint32>(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))
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
professor->CastSpell(target, SPELL_VILE_GAS_H, true); // triggered, to skip LoS check
}
events.ScheduleEvent(EVENT_ROTFACE_VILE_GAS, urand(15000, 20000));
break;
default:
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<boss_rotfaceAI>(creature);
}
};
class npc_little_ooze : public CreatureScript
{
public:
npc_little_ooze() : CreatureScript("npc_little_ooze") { }
struct npc_little_oozeAI : public ScriptedAI
{
npc_little_oozeAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript())
{
firstUpdate = true;
if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
rotface->AI()->JustSummoned(me);
}
bool firstUpdate;
EventMap events;
InstanceScript* instance;
void IsSummonedBy(Unit* summoner)
{
if (!summoner)
return;
me->AddThreat(summoner, 500000.0f);
AttackStart(summoner);
}
void JustDied(Unit* /*killer*/)
{
if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
rotface->AI()->SummonedCreatureDespawn(me);
me->DespawnOrUnsummon(0);
}
void UpdateAI(uint32 diff)
{
if (firstUpdate)
{
firstUpdate = false;
me->CastSpell(me, SPELL_LITTLE_OOZE_COMBINE, true);
me->CastSpell(me, SPELL_WEAK_RADIATING_OOZE, true);
events.Reset();
events.ScheduleEvent(EVENT_STICKY_OOZE, 5000);
DoResetThreat();
me->SetInCombatWithZone();
if (TempSummon* ts = me->ToTempSummon())
if (Unit* summoner = ts->GetSummoner())
{
me->AddThreat(summoner, 500000.0f);
AttackStart(summoner);
}
}
if (!UpdateVictim())
return;
events.Update(diff);
if (events.ExecuteEvent() == EVENT_STICKY_OOZE)
{
me->CastSpell(me->GetVictim(), SPELL_STICKY_OOZE, false);
events.ScheduleEvent(EVENT_STICKY_OOZE, 15000);
}
DoMeleeAttackIfReady();
}
void EnterEvadeMode()
{
me->SetInCombatWithZone();
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<npc_little_oozeAI>(creature);
}
};
class npc_big_ooze : public CreatureScript
{
public:
npc_big_ooze() : CreatureScript("npc_big_ooze") { }
struct npc_big_oozeAI : public ScriptedAI
{
npc_big_oozeAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript())
{
firstUpdate = true;
if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
rotface->AI()->JustSummoned(me);
}
bool firstUpdate;
EventMap events;
InstanceScript* instance;
void IsSummonedBy(Unit* /*summoner*/)
{
if (Player* p = me->SelectNearestPlayer(100.0f))
AttackStart(p);
}
void JustDied(Unit* /*killer*/)
{
if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
rotface->AI()->SummonedCreatureDespawn(me);
me->DespawnOrUnsummon();
}
void DoAction(int32 action)
{
if (action == EVENT_STICKY_OOZE)
events.CancelEvent(EVENT_STICKY_OOZE);
}
void UpdateAI(uint32 diff)
{
if (firstUpdate)
{
firstUpdate = false;
me->CastSpell(me, SPELL_LARGE_OOZE_COMBINE, true);
me->CastSpell(me, SPELL_LARGE_OOZE_BUFF_COMBINE, true);
me->CastSpell(me, SPELL_RADIATING_OOZE, true);
me->CastSpell(me, SPELL_UNSTABLE_OOZE, true);
me->CastSpell(me, SPELL_GREEN_ABOMINATION_HITTIN__YA_PROC, true);
events.Reset();
events.ScheduleEvent(EVENT_STICKY_OOZE, 5000);
DoResetThreat();
me->SetInCombatWithZone();
if (Player* p = me->SelectNearestPlayer(100.0f))
AttackStart(p);
}
if (!UpdateVictim())
return;
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_STICKY_OOZE:
me->CastSpell(me->GetVictim(), SPELL_STICKY_OOZE, false);
events.ScheduleEvent(EVENT_STICKY_OOZE, 15000);
default:
break;
}
if (me->IsVisible())
DoMeleeAttackIfReady();
}
void EnterEvadeMode()
{
me->SetInCombatWithZone();
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<npc_big_oozeAI>(creature);
}
};
class spell_rotface_mutated_infection : public SpellScriptLoader
{
public:
spell_rotface_mutated_infection() : SpellScriptLoader("spell_rotface_mutated_infection") { }
class spell_rotface_mutated_infection_SpellScript : public SpellScript
{
PrepareSpellScript(spell_rotface_mutated_infection_SpellScript);
bool Load()
{
_target = NULL;
return true;
}
void FilterTargets(std::list<WorldObject*>& targets)
{
// remove targets with this aura already
// tank is not on this list
targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
targets.remove(GetCaster()->GetVictim());
if (targets.empty())
return;
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
_target = target;
}
void ReplaceTargets(std::list<WorldObject*>& targets)
{
targets.clear();
if (_target)
targets.push_back(_target);
}
void NotifyTargets()
{
if (Creature* caster = GetCaster()->ToCreature())
if (Unit* target = GetHitUnit())
caster->AI()->Talk(EMOTE_MUTATED_INFECTION, target);
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
AfterHit += SpellHitFn(spell_rotface_mutated_infection_SpellScript::NotifyTargets);
}
WorldObject* _target;
};
class spell_rotface_mutated_infection_AuraScript : public AuraScript
{
PrepareAuraScript(spell_rotface_mutated_infection_AuraScript);
void ExtraRemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[2].CalcValue(), true);
}
void Register()
{
AfterEffectRemove += AuraEffectRemoveFn(spell_rotface_mutated_infection_AuraScript::ExtraRemoveEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
}
};
SpellScript* GetSpellScript() const
{
return new spell_rotface_mutated_infection_SpellScript();
}
AuraScript* GetAuraScript() const
{
return new spell_rotface_mutated_infection_AuraScript();
}
};
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*/)
{
// little targetting little
if (!GetHitCreature() || !GetHitCreature()->IsAlive())
return;
GetCaster()->RemoveAurasDueToSpell(SPELL_LITTLE_OOZE_COMBINE);
GetHitCreature()->RemoveAurasDueToSpell(SPELL_LITTLE_OOZE_COMBINE);
GetHitCreature()->CastSpell(GetCaster(), SPELL_OOZE_MERGE, true);
GetHitCreature()->DespawnOrUnsummon();
if (GetCaster()->ToCreature())
GetCaster()->ToCreature()->DespawnOrUnsummon();
}
void Register()
{
OnEffectHitTarget += 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*/)
{
// large targetting large
if (!GetHitCreature() || !GetHitCreature()->IsAlive())
return;
uint8 casterStack = 1;
uint8 targetStack = 1;
Aura* casterAura = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE);
if (casterAura)
casterStack = casterAura->GetStackAmount();
Aura* targetAura = GetHitCreature()->GetAura(SPELL_UNSTABLE_OOZE);
if (targetAura)
targetStack = targetAura->GetStackAmount();
uint8 newStack = casterStack+targetStack;
if (newStack > 5)
newStack = 5;
if (casterAura)
casterAura->SetStackAmount(newStack);
else
{
GetCaster()->CastSpell(GetCaster(), SPELL_UNSTABLE_OOZE, true);
if (Aura* aur = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE))
aur->SetStackAmount(newStack);
}
// red color!
if (newStack >= 4)
GetCaster()->CastSpell(GetCaster(), 69844, true);
// explode!
if (newStack >= 5)
{
GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
if (Creature* rotface = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_ROTFACE)))
if (rotface->IsAlive())
{
if (GetCaster()->GetTypeId() == TYPEID_UNIT)
GetCaster()->ToCreature()->AI()->Talk(EMOTE_UNSTABLE_EXPLOSION);
rotface->AI()->Talk(SAY_UNSTABLE_EXPLOSION);
}
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));
}
GetHitCreature()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
GetHitCreature()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
GetHitCreature()->DespawnOrUnsummon();
}
void Register()
{
OnEffectHitTarget += 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*/)
{
// large targetting little
if (!GetHitCreature() || !GetHitCreature()->IsAlive())
return;
if (Aura* unstable = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE))
{
uint8 newStack = uint8(unstable->GetStackAmount()+1);
unstable->SetStackAmount(newStack);
// red color!
if (newStack >= 4)
GetCaster()->CastSpell(GetCaster(), 69844, true);
// explode!
if (newStack >= 5)
{
GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
if (Creature* rotface = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_ROTFACE)))
if (rotface->IsAlive())
{
if (GetCaster()->GetTypeId() == TYPEID_UNIT)
GetCaster()->ToCreature()->AI()->Talk(EMOTE_UNSTABLE_EXPLOSION);
rotface->AI()->Talk(SAY_UNSTABLE_EXPLOSION);
}
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));
}
}
GetHitCreature()->RemoveAurasDueToSpell(SPELL_LITTLE_OOZE_COMBINE);
GetHitCreature()->DespawnOrUnsummon();
}
void Register()
{
OnEffectHitTarget += 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(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(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()
{
OnEffectHitTarget += 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 (!GetExplTargetDest())
return;
uint32 triggered_spell_id = GetSpellInfo()->Effects[effIndex].TriggerSpell;
float x, y, z;
GetExplTargetDest()->GetPosition(x, y, z);
// let Rotface handle the cast - caster dies before this executes
if (InstanceScript* script = GetCaster()->GetInstanceScript())
if (Creature* rotface = script->instance->GetCreature(script->GetData64(DATA_ROTFACE)))
rotface->CastSpell(x, y, z, triggered_spell_id, true/*, NULL, NULL, GetCaster()->GetGUID()*/); // caster not available on clientside, no log in such case
}
void Register()
{
OnEffectHit += 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*/)
{
PreventDefaultAction();
Unit* target = GetTarget();
if (target->GetTypeId() != TYPEID_UNIT)
return;
target->SetVisible(false);
target->RemoveAllAuras();
//target->ToCreature()->DespawnOrUnsummon();
target->ToCreature()->DespawnOrUnsummon(60000);
}
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();
}
};
class npc_precious_icc : public CreatureScript
{
public:
npc_precious_icc() : CreatureScript("npc_precious_icc") { }
struct npc_precious_iccAI : public ScriptedAI
{
npc_precious_iccAI(Creature* creature) : ScriptedAI(creature), summons(me){}
void Reset()
{
events.Reset();
summons.DespawnAll();
}
void EnterCombat(Unit* /*target*/)
{
me->setActive(true);
events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000));
events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(1500, 2500));
events.ScheduleEvent(EVENT_SUMMON_ZOMBIES, urand(25000, 30000));
}
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
summon->AI()->AttackStart(target);
}
void SummonedCreatureDespawn(Creature* summon)
{
summons.Despawn(summon);
}
void JustDied(Unit* /*killer*/)
{
summons.DespawnAll();
if (InstanceScript* _instance = me->GetInstanceScript())
if (Creature* rotface = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ROTFACE)))
if (rotface->IsAlive())
rotface->AI()->Talk(SAY_PRECIOUS_DIES);
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_DECIMATE:
me->CastSpell(me->GetVictim(), SPELL_DECIMATE, false);
events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000));
break;
case EVENT_MORTAL_WOUND:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(1500, 2500));
break;
case EVENT_SUMMON_ZOMBIES:
Talk(EMOTE_PRECIOUS_ZOMBIES);
for (uint32 i = 0; i < 11; ++i)
me->CastSpell(me, SPELL_AWAKEN_PLAGUED_ZOMBIES, true);
events.ScheduleEvent(EVENT_SUMMON_ZOMBIES, urand(20000, 25000));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap events;
SummonList summons;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetIcecrownCitadelAI<npc_precious_iccAI>(creature);
}
};
void AddSC_boss_rotface()
{
new boss_rotface();
new npc_little_ooze();
new npc_big_ooze();
new spell_rotface_mutated_infection();
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();
new npc_precious_icc();
}

View File

@@ -1,608 +0,0 @@
/*
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
*/
#ifndef ICECROWN_CITADEL_H_
#define ICECROWN_CITADEL_H_
#include "SpellScript.h"
#include "Map.h"
#include "Creature.h"
#include "SpellMgr.h"
#define ICCScriptName "instance_icecrown_citadel"
uint32 const WeeklyNPCs = 9;
uint32 const MaxHeroicAttempts = 25;
// Defined in boss_valithria_dreamwalker.cpp
extern Position const ValithriaSpawnPos;
// Defined in boss_sindragosa.cpp
extern Position const SindragosaSpawnPos;
// Defined in boss_the_lich_king.cpp
extern Position const TerenasSpawn;
extern Position const TerenasSpawnHeroic;
extern Position const SpiritWardenSpawn;
// Shared spells used by more than one script
enum SharedSpells
{
SPELL_BERSERK = 26662,
SPELL_BERSERK2 = 47008,
// Deathbound Ward
SPELL_STONEFORM = 70733,
// Residue Rendezvous
SPELL_ORANGE_BLIGHT_RESIDUE = 72144,
SPELL_GREEN_BLIGHT_RESIDUE = 72145,
// The Lich King
SPELL_ARTHAS_TELEPORTER_CEREMONY = 72915,
SPELL_FROSTMOURNE_TELEPORT_VISUAL = 73078,
// Shadowmourne questline
SPELL_UNSATED_CRAVING = 71168,
SPELL_SHADOWS_FATE = 71169,
// Misc
SPELL_WEB_BEAM = 69887,
SPELL_WEB_BEAM2 = 69986,
SPELL_GIANT_INSECT_SWARM = 70475,
SPELL_LEAP_TO_A_RANDOM_LOCATION = 70485
};
enum TeleporterSpells
{
LIGHT_S_HAMMER_TELEPORT = 70781,
ORATORY_OF_THE_DAMNED_TELEPORT = 70856,
RAMPART_OF_SKULLS_TELEPORT = 70857,
DEATHBRINGER_S_RISE_TELEPORT = 70858,
UPPER_SPIRE_TELEPORT = 70859,
FROZEN_THRONE_TELEPORT = 70860,
SINDRAGOSA_S_LAIR_TELEPORT = 70861,
};
enum DataTypes
{
// Encounter States/Boss GUIDs
DATA_LORD_MARROWGAR = 0,
DATA_LADY_DEATHWHISPER = 1,
DATA_ICECROWN_GUNSHIP_BATTLE = 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_SISTER_SVALNA = 9,
DATA_VALITHRIA_DREAMWALKER = 10,
DATA_SINDRAGOSA = 11,
DATA_THE_LICH_KING = 12,
DATA_SINDRAGOSA_GAUNTLET = 13,
DATA_BLOOD_PRINCE_TRASH = 14,
MAX_ENCOUNTERS = 15,
// Additional data
DATA_SAURFANG_EVENT_NPC = 13,
DATA_BONED_ACHIEVEMENT = 14,
DATA_OOZE_DANCE_ACHIEVEMENT = 15,
DATA_PUTRICIDE_TABLE = 16,
DATA_NAUSEA_ACHIEVEMENT = 17,
DATA_ORB_WHISPERER_ACHIEVEMENT = 18,
DATA_PRINCE_KELESETH_GUID = 19,
DATA_PRINCE_TALDARAM_GUID = 20,
DATA_PRINCE_VALANAR_GUID = 21,
DATA_BLOOD_PRINCES_CONTROL = 22,
DATA_SINDRAGOSA_FROSTWYRMS = 23,
DATA_SPINESTALKER = 24,
DATA_RIMEFANG = 25,
DATA_COLDFLAME_JETS = 26,
DATA_TEAMID_IN_INSTANCE = 27,
DATA_BLOOD_QUICKENING_STATE = 28,
DATA_HEROIC_ATTEMPTS = 29,
DATA_CROK_SCOURGEBANE = 30,
DATA_CAPTAIN_ARNATH = 31,
DATA_CAPTAIN_BRANDON = 32,
DATA_CAPTAIN_GRONDEL = 33,
DATA_CAPTAIN_RUPERT = 34,
DATA_VALITHRIA_TRIGGER = 35,
DATA_VALITHRIA_LICH_KING = 36,
DATA_HIGHLORD_TIRION_FORDRING = 37,
DATA_ARTHAS_PLATFORM = 38,
DATA_TERENAS_MENETHIL = 39,
DATA_ENEMY_GUNSHIP = 40,
// pussywizard:
DATA_BUFF_AVAILABLE = 251,
DATA_WEEKLY_QUEST_ID = 252,
// NONE = 253,
DATA_PUTRICIDE_TRAP_STATE = 254,
DATA_HAS_LIMITED_ATTEMPTS = 255,
DATA_LK_HC_AVAILABLE = 256,
DATA_BPC_TRASH_DIED = 300,
};
enum CreaturesIds
{
// At Light's Hammer
NPC_HIGHLORD_TIRION_FORDRING_LH = 37119,
NPC_THE_LICH_KING_LH = 37181,
NPC_HIGHLORD_BOLVAR_FORDRAGON_LH = 37183,
NPC_KOR_KRON_GENERAL = 37189,
NPC_ALLIANCE_COMMANDER = 37190,
NPC_TORTUNOK = 37992, // Druid Armor H
NPC_ALANA_MOONSTRIKE = 37999, // Druid Armor A
NPC_GERARDO_THE_SUAVE = 37993, // Hunter Armor H
NPC_TALAN_MOONSTRIKE = 37998, // Hunter Armor A
NPC_UVLUS_BANEFIRE = 38284, // Mage Armor H
NPC_MALFUS_GRIMFROST = 38283, // Mage Armor A
NPC_IKFIRUS_THE_VILE = 37991, // Rogue Armor H
NPC_YILI = 37997, // Rogue Armor A
NPC_VOL_GUK = 38841, // Shaman Armor H
NPC_JEDEBIA = 38840, // Shaman Armor A
NPC_HARAGG_THE_UNSEEN = 38181, // Warlock Armor H
NPC_NIBY_THE_ALMIGHTY = 38182, // Warlock Armor N
NPC_GARROSH_HELLSCREAM = 39372,
NPC_KING_VARIAN_WRYNN = 39371,
NPC_DEATHBOUND_WARD = 37007,
NPC_HIGH_OVERLORD_SAURFANG_DUMMY = 32315,
NPC_MURADIN_BRONZEBEARD_DUMMY = 38607,
NPC_LADY_JAINA_PROUDMOORE_QUEST = 38606,
NPC_MURADIN_BRONZEBEARD_QUEST = 38607,
NPC_UTHER_THE_LIGHTBRINGER_QUEST = 38608,
NPC_LADY_SYLVANAS_WINDRUNNER_QUEST = 38609,
// Weekly quests
NPC_INFILTRATOR_MINCHAR = 38471,
NPC_KOR_KRON_LIEUTENANT = 38491,
NPC_SKYBREAKER_LIEUTENANT = 38492,
NPC_ROTTING_FROST_GIANT_10 = 38490,
NPC_ROTTING_FROST_GIANT_25 = 38494,
NPC_ALCHEMIST_ADRIANNA = 38501,
NPC_ALRIN_THE_AGILE = 38551,
NPC_INFILTRATOR_MINCHAR_BQ = 38558,
NPC_BLOOD_QUICKENING_CREDIT_25 = 39123,
NPC_MINCHAR_BEAM_STALKER = 38557,
NPC_VALITHRIA_DREAMWALKER_QUEST = 38589,
// Lord Marrowgar
NPC_LORD_MARROWGAR = 36612,
NPC_COLDFLAME = 36672,
NPC_BONE_SPIKE = 36619,
// Lady Deathwhisper
NPC_LADY_DEATHWHISPER = 36855,
NPC_CULT_FANATIC = 37890,
NPC_DEFORMED_FANATIC = 38135,
NPC_REANIMATED_FANATIC = 38009,
NPC_CULT_ADHERENT = 37949,
NPC_EMPOWERED_ADHERENT = 38136,
NPC_REANIMATED_ADHERENT = 38010,
NPC_VENGEFUL_SHADE = 38222,
NPC_DEATHSPEAKER_SERVANT = 36805,
NPC_RISEN_DEATHSPEAKER_SERVANT = 36844,
// Icecrown Gunship Battle
NPC_MARTYR_STALKER_IGB_SAURFANG = 38569,
NPC_ALLIANCE_GUNSHIP_CANNON = 36838,
NPC_HORDE_GUNSHIP_CANNON = 36839,
NPC_SKYBREAKER_DECKHAND = 36970,
NPC_ORGRIMS_HAMMER_CREW = 36971,
NPC_IGB_HIGH_OVERLORD_SAURFANG = 36939,
NPC_IGB_MURADIN_BRONZEBEARD = 36948,
NPC_THE_SKYBREAKER = 37540,
NPC_ORGRIMS_HAMMER = 37215,
NPC_GUNSHIP_HULL = 37547,
NPC_TELEPORT_PORTAL = 37227,
NPC_TELEPORT_EXIT = 37488,
NPC_SKYBREAKER_SORCERER = 37116,
NPC_SKYBREAKER_RIFLEMAN = 36969,
NPC_SKYBREAKER_MORTAR_SOLDIER = 36978,
NPC_SKYBREAKER_MARINE = 36950,
NPC_SKYBREAKER_SERGEANT = 36961,
NPC_KOR_KRON_BATTLE_MAGE = 37117,
NPC_KOR_KRON_AXETHROWER = 36968,
NPC_KOR_KRON_ROCKETEER = 36982,
NPC_KOR_KRON_REAVER = 36957,
NPC_KOR_KRON_SERGEANT = 36960,
NPC_ZAFOD_BOOMBOX = 37184,
NPC_HIGH_CAPTAIN_JUSTIN_BARTLETT = 37182,
NPC_SKY_REAVER_KORM_BLACKSCAR = 37833,
// Deathbringer Saurfang
NPC_DEATHBRINGER_SAURFANG = 37813,
NPC_BLOOD_BEAST = 38508,
NPC_SE_JAINA_PROUDMOORE = 37188, // SE means Saurfang Event
NPC_SE_MURADIN_BRONZEBEARD = 37200,
NPC_SE_KING_VARIAN_WRYNN = 37879,
NPC_SE_HIGH_OVERLORD_SAURFANG = 37187,
NPC_SE_KOR_KRON_REAVER = 37920,
NPC_SE_SKYBREAKER_MARINE = 37830,
NPC_FROST_FREEZE_TRAP = 37744,
// Festergut
NPC_FESTERGUT = 36626,
NPC_GAS_DUMMY = 36659,
// Rotface
NPC_ROTFACE = 36627,
NPC_OOZE_SPRAY_STALKER = 37986,
NPC_PUDDLE_STALKER = 37013,
NPC_UNSTABLE_EXPLOSION_STALKER = 38107,
// Professor Putricide
NPC_PROFESSOR_PUTRICIDE = 36678,
NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER = 37824,
NPC_GROWING_OOZE_PUDDLE = 37690,
NPC_GAS_CLOUD = 37562,
NPC_VOLATILE_OOZE = 37697,
NPC_CHOKING_GAS_BOMB = 38159,
NPC_TEAR_GAS_TARGET_STALKER = 38317,
NPC_MUTATED_ABOMINATION_10 = 37672,
NPC_MUTATED_ABOMINATION_25 = 38285,
// 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,
// Blood-Queen Lana'thel
NPC_BLOOD_QUEEN_LANA_THEL = 37955,
// Frostwing Halls gauntlet event
NPC_CROK_SCOURGEBANE = 37129,
NPC_CAPTAIN_ARNATH = 37122,
NPC_CAPTAIN_BRANDON = 37123,
NPC_CAPTAIN_GRONDEL = 37124,
NPC_CAPTAIN_RUPERT = 37125,
NPC_CAPTAIN_ARNATH_UNDEAD = 37491,
NPC_CAPTAIN_BRANDON_UNDEAD = 37493,
NPC_CAPTAIN_GRONDEL_UNDEAD = 37494,
NPC_CAPTAIN_RUPERT_UNDEAD = 37495,
NPC_YMIRJAR_BATTLE_MAIDEN = 37132,
NPC_YMIRJAR_DEATHBRINGER = 38125,
NPC_YMIRJAR_FROSTBINDER = 37127,
NPC_YMIRJAR_HUNTRESS = 37134,
NPC_YMIRJAR_WARLORD = 37133,
NPC_SISTER_SVALNA = 37126,
NPC_IMPALING_SPEAR = 38248,
// Valithria Dreamwalker
NPC_VALITHRIA_DREAMWALKER = 36789,
NPC_GREEN_DRAGON_COMBAT_TRIGGER = 38752,
NPC_RISEN_ARCHMAGE = 37868,
NPC_BLAZING_SKELETON = 36791,
NPC_SUPPRESSER = 37863,
NPC_BLISTERING_ZOMBIE = 37934,
NPC_GLUTTONOUS_ABOMINATION = 37886,
NPC_MANA_VOID = 38068,
NPC_COLUMN_OF_FROST = 37918,
NPC_ROT_WORM = 37907,
NPC_THE_LICH_KING_VALITHRIA = 38153,
NPC_DREAM_PORTAL_PRE_EFFECT = 38186,
NPC_NIGHTMARE_PORTAL_PRE_EFFECT = 38429,
NPC_DREAM_PORTAL = 37945,
NPC_NIGHTMARE_PORTAL = 38430,
// Sindragosa
NPC_SINDRAGOSA = 36853,
NPC_SPINESTALKER = 37534,
NPC_RIMEFANG = 37533,
NPC_FROSTWARDEN_HANDLER = 37531,
NPC_FROSTWING_WHELP = 37532,
NPC_ICY_BLAST = 38223,
NPC_FROST_BOMB = 37186,
NPC_ICE_TOMB = 36980,
// Sindragosa Gauntlet
NPC_SINDRAGOSA_GAUNTLET = 37503,
NPC_NERUBAR_CHAMPION = 37501,
NPC_NERUBAR_WEBWEAVER = 37502,
NPC_NERUBAR_BROODLING = 37232,
NPC_FROSTWARDEN_SORCERESS = 37229,
NPC_FROSTWARDEN_WARRIOR = 37228,
// Putricade Trap
NPC_PUTRICADES_TRAP = 38879,
NPC_FLASH_EATING_INSECT = 37782,
// The Lich King
NPC_THE_LICH_KING = 36597,
NPC_HIGHLORD_TIRION_FORDRING_LK = 38995,
NPC_TERENAS_MENETHIL_FROSTMOURNE = 36823,
NPC_SPIRIT_WARDEN = 36824,
NPC_TERENAS_MENETHIL_FROSTMOURNE_H = 39217,
NPC_SHAMBLING_HORROR = 37698,
NPC_DRUDGE_GHOUL = 37695,
NPC_ICE_SPHERE = 36633,
NPC_RAGING_SPIRIT = 36701,
NPC_DEFILE = 38757,
NPC_SHADOW_TRAP_TRIGGER = 39137,
NPC_VALKYR_SHADOWGUARD = 36609,
NPC_VILE_SPIRIT = 37799,
NPC_WICKED_SPIRIT = 39190,
NPC_STRANGULATE_VEHICLE = 36598,
NPC_WORLD_TRIGGER = 22515,
NPC_WORLD_TRIGGER_INFINITE_AOI = 36171,
NPC_SPIRIT_BOMB = 39189,
NPC_FROSTMOURNE_TRIGGER = 38584,
NPC_TERENAS_MENETHIL_OUTRO = 38579,
// Generic
NPC_INVISIBLE_STALKER = 30298,
NPC_SPIRE_FROSTWYRM = 37230,
NPC_VENGEFUL_FLESHREAPER = 37038,
};
enum GameObjectsIds
{
GO_SCOURGE_TRANSPORTER_FIRST = 202242,
// Traps
GO_SPIRIT_ALARM_1 = 201814,
GO_SPIRIT_ALARM_2 = 201815,
GO_SPIRIT_ALARM_3 = 201816,
GO_SPIRIT_ALARM_4 = 201817,
GO_GEIST_ALARM_1 = 201888,
GO_GEIST_ALARM_2 = 201889,
// Lord Marrogar
GO_DOODAD_ICECROWN_ICEWALL02 = 201910,
GO_ICEWALL = 201911,
GO_LORD_MARROWGAR_S_ENTRANCE = 201857,
// Lady Deathwhisper
GO_ORATORY_OF_THE_DAMNED_ENTRANCE = 201563,
GO_LADY_DEATHWHISPER_ELEVATOR = 202220,
// Icecrown Gunship Battle - Horde raid
GO_ORGRIMS_HAMMER_H = 201812,
GO_THE_SKYBREAKER_H = 201811,
GO_GUNSHIP_ARMORY_H_10N = 202178,
GO_GUNSHIP_ARMORY_H_25N = 202180,
GO_GUNSHIP_ARMORY_H_10H = 202177,
GO_GUNSHIP_ARMORY_H_25H = 202179,
// Icecrown Gunship Battle - Alliance raid
GO_ORGRIMS_HAMMER_A = 201581,
GO_THE_SKYBREAKER_A = 201580,
GO_GUNSHIP_ARMORY_A_10N = 201873,
GO_GUNSHIP_ARMORY_A_25N = 201874,
GO_GUNSHIP_ARMORY_A_10H = 201872,
GO_GUNSHIP_ARMORY_A_25H = 201875,
// Deathbringer Saurfang
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,
// Professor Putricide
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_PLAGUE_SIGIL = 202182,
GO_GAS_RELEASE_VALVE = 201616,
GO_OOZE_RELEASE_VALVE = 201615,
// Blood Prince Council
GO_CRIMSON_HALL_DOOR = 201376,
GO_BLOOD_ELF_COUNCIL_DOOR = 201378,
GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT = 201377,
// Blood-Queen Lana'thel
GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01 = 201746,
GO_DOODAD_ICECROWN_GRATE_01 = 201755,
GO_BLOODWING_SIGIL = 202183,
// Valithria Dreamwalker
GO_GREEN_DRAGON_BOSS_ENTRANCE = 201375,
GO_GREEN_DRAGON_BOSS_EXIT = 201374,
GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01 = 201380,
GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02 = 201381,
GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03 = 201382,
GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04 = 201383,
GO_CACHE_OF_THE_DREAMWALKER_10N = 201959,
GO_CACHE_OF_THE_DREAMWALKER_25N = 202339,
GO_CACHE_OF_THE_DREAMWALKER_10H = 202338,
GO_CACHE_OF_THE_DREAMWALKER_25H = 202340,
// Sindragosa
GO_SINDRAGOSA_ENTRANCE_DOOR = 201373,
GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR = 201369,
GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR = 201379,
GO_ICE_WALL = 202396,
GO_ICE_BLOCK = 201722,
GO_SIGIL_OF_THE_FROSTWING = 202181,
// The Lich King
GO_SCOURGE_TRANSPORTER_LK = 202223,
GO_ARTHAS_PLATFORM = 202161,
GO_ARTHAS_PRECIPICE = 202078,
GO_DOODAD_ICECROWN_THRONEFROSTYWIND01 = 202188,
GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01 = 202189,
GO_DOODAD_ICESHARD_STANDING02 = 202141,
GO_DOODAD_ICESHARD_STANDING01 = 202142,
GO_DOODAD_ICESHARD_STANDING03 = 202143,
GO_DOODAD_ICESHARD_STANDING04 = 202144,
GO_DOODAD_ICECROWN_SNOWEDGEWARNING01 = 202190,
GO_FROZEN_LAVAMAN = 202436,
GO_LAVAMAN_PILLARS_CHAINED = 202437,
GO_LAVAMAN_PILLARS_UNCHAINED = 202438,
};
enum AchievementCriteriaIds
{
// Lord Marrowgar
CRITERIA_BONED_10N = 12775,
CRITERIA_BONED_25N = 12962,
CRITERIA_BONED_10H = 13393,
CRITERIA_BONED_25H = 13394,
// Rotface
CRITERIA_DANCES_WITH_OOZES_10N = 12984,
CRITERIA_DANCES_WITH_OOZES_25N = 12966,
CRITERIA_DANCES_WITH_OOZES_10H = 12985,
CRITERIA_DANCES_WITH_OOZES_25H = 12983,
// Professor Putricide
CRITERIA_NAUSEA_10N = 12987,
CRITERIA_NAUSEA_25N = 12968,
CRITERIA_NAUSEA_10H = 12988,
CRITERIA_NAUSEA_25H = 12981,
// Blood Prince Council
CRITERIA_ORB_WHISPERER_10N = 13033,
CRITERIA_ORB_WHISPERER_25N = 12969,
CRITERIA_ORB_WHISPERER_10H = 13034,
CRITERIA_ORB_WHISPERER_25H = 13032,
// Blood-Queen Lana'thel
CRITERIA_KILL_LANA_THEL_10M = 13340,
CRITERIA_KILL_LANA_THEL_25M = 13360,
};
enum SharedActions
{
// Icecrown Gunship Battle
ACTION_ENEMY_GUNSHIP_TALK = -369390,
ACTION_EXIT_SHIP = -369391,
// Festergut
ACTION_FESTERGUT_COMBAT = -366260,
ACTION_FESTERGUT_GAS = -366261,
ACTION_FESTERGUT_DEATH = -366262,
// Rotface
ACTION_ROTFACE_COMBAT = -366270,
ACTION_ROTFACE_OOZE = -366271,
ACTION_ROTFACE_DEATH = -366272,
ACTION_CHANGE_PHASE = -366780,
// Blood-Queen Lana'thel
ACTION_KILL_MINCHAR = -379550,
// Frostwing Halls gauntlet event
ACTION_VRYKUL_DEATH = 37129,
// Sindragosa
ACTION_START_FROSTWYRM = -368530,
// The Lich King
ACTION_RESTORE_LIGHT = -72262,
ACTION_FROSTMOURNE_INTRO = -36823,
};
enum WeekliesICC
{
QUEST_DEPROGRAMMING_10 = 24869,
QUEST_DEPROGRAMMING_25 = 24875,
QUEST_SECURING_THE_RAMPARTS_10 = 24870,
QUEST_SECURING_THE_RAMPARTS_25 = 24877,
QUEST_RESIDUE_RENDEZVOUS_10 = 24873,
QUEST_RESIDUE_RENDEZVOUS_25 = 24878,
QUEST_BLOOD_QUICKENING_10 = 24874,
QUEST_BLOOD_QUICKENING_25 = 24879,
QUEST_RESPITE_FOR_A_TORMENTED_SOUL_10 = 24872,
QUEST_RESPITE_FOR_A_TORMENTED_SOUL_25 = 24880,
};
enum QuestsICC
{
QUEST_A_FEAST_OF_SOULS = 24547
};
enum WorldStatesICC
{
WORLDSTATE_SHOW_TIMER = 4903,
WORLDSTATE_EXECUTION_TIME = 4904,
WORLDSTATE_SHOW_ATTEMPTS = 4940,
WORLDSTATE_ATTEMPTS_REMAINING = 4941,
WORLDSTATE_ATTEMPTS_MAX = 4942,
};
enum PutricideEventFlags
{
PUTRICIDE_EVENT_FLAG_FESTERGUT_VALVE = 1,
PUTRICIDE_EVENT_FLAG_ROTFACE_VALVE = 2,
PUTRICIDE_EVENT_FLAG_TRAP_INPROGRESS = 4,
PUTRICIDE_EVENT_FLAG_TRAP_FINISHED = 8,
};
enum AreaIds
{
AREA_ICECROWN_CITADEL = 4812,
AREA_THE_FROZEN_THRONE = 4859,
};
class spell_trigger_spell_from_caster : public SpellScriptLoader
{
public:
spell_trigger_spell_from_caster(char const* scriptName, uint32 triggerId) : SpellScriptLoader(scriptName), _triggerId(triggerId) { }
class spell_trigger_spell_from_caster_SpellScript : public SpellScript
{
PrepareSpellScript(spell_trigger_spell_from_caster_SpellScript);
public:
spell_trigger_spell_from_caster_SpellScript(uint32 triggerId) : SpellScript(), _triggerId(triggerId) { }
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(_triggerId))
return false;
return true;
}
void HandleTrigger()
{
GetCaster()->CastSpell(GetHitUnit(), _triggerId, true);
}
void Register()
{
AfterHit += SpellHitFn(spell_trigger_spell_from_caster_SpellScript::HandleTrigger);
}
uint32 _triggerId;
};
SpellScript* GetSpellScript() const
{
return new spell_trigger_spell_from_caster_SpellScript(_triggerId);
}
private:
uint32 _triggerId;
};
template<class AI>
CreatureAI* GetIcecrownCitadelAI(Creature* creature)
{
if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
if (instance->GetInstanceScript())
if (instance->GetScriptId() == sObjectMgr->GetScriptId(ICCScriptName))
return new AI(creature);
return NULL;
}
#endif // ICECROWN_CITADEL_H_

View File

@@ -1,91 +0,0 @@
/*
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
*/
#include "ScriptedGossip.h"
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "icecrown_citadel.h"
#include "Spell.h"
#include "Player.h"
#define GOSSIP_SENDER_ICC_PORT 631
class icecrown_citadel_teleport : public GameObjectScript
{
public:
icecrown_citadel_teleport() : GameObjectScript("icecrown_citadel_teleport") { }
bool OnGossipHello(Player* player, GameObject* go)
{
if (go->GetEntry() != GO_SCOURGE_TRANSPORTER_FIRST)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Light's Hammer.", GOSSIP_SENDER_ICC_PORT, LIGHT_S_HAMMER_TELEPORT); // M_PI + M_PI/6
if (InstanceScript* instance = go->GetInstanceScript())
{
if (instance->GetBossState(DATA_LORD_MARROWGAR) == DONE && go->GetEntry() != 202245)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Oratory of the Damned.", GOSSIP_SENDER_ICC_PORT, ORATORY_OF_THE_DAMNED_TELEPORT); // M_PI + M_PI/6
if (instance->GetBossState(DATA_LADY_DEATHWHISPER) == DONE && go->GetEntry() != 202243)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Rampart of Skulls.", GOSSIP_SENDER_ICC_PORT, RAMPART_OF_SKULLS_TELEPORT); // M_PI/6
if (instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE && go->GetEntry() != 202244)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Deathbringer's Rise.", GOSSIP_SENDER_ICC_PORT, DEATHBRINGER_S_RISE_TELEPORT); // M_PI/6
if (instance->GetData(DATA_COLDFLAME_JETS) == DONE && go->GetEntry() != 202235)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Upper Spire.", GOSSIP_SENDER_ICC_PORT, UPPER_SPIRE_TELEPORT); // M_PI/6
if (instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == DONE && instance->GetBossState(DATA_SINDRAGOSA_GAUNTLET) == DONE && go->GetEntry() != 202246)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Sindragosa's Lair", GOSSIP_SENDER_ICC_PORT, SINDRAGOSA_S_LAIR_TELEPORT); // M_PI*3/2 + M_PI/6
}
player->SEND_GOSSIP_MENU(player->GetGossipTextId(go), go->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, GameObject* /*go*/, uint32 sender, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
player->CLOSE_GOSSIP_MENU();
SpellInfo const* spell = sSpellMgr->GetSpellInfo(action);
if (!spell)
return false;
if (player->IsInCombat())
{
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_AFFECTING_COMBAT);
return true;
}
if (sender == GOSSIP_SENDER_ICC_PORT)
player->CastSpell(player, spell, false);
return true;
}
};
class at_frozen_throne_teleport : public AreaTriggerScript
{
public:
at_frozen_throne_teleport() : AreaTriggerScript("at_frozen_throne_teleport") { }
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/)
{
if (player->IsInCombat())
{
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(FROZEN_THRONE_TELEPORT))
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_AFFECTING_COMBAT);
return true;
}
if (InstanceScript* instance = player->GetInstanceScript())
if (instance->GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE &&
instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE &&
instance->GetBossState(DATA_SINDRAGOSA) == DONE &&
instance->GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS)
player->CastSpell(player, FROZEN_THRONE_TELEPORT, false);
return true;
}
};
void AddSC_icecrown_citadel_teleport()
{
new icecrown_citadel_teleport();
new at_frozen_throne_teleport();
}