mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 05:06:24 +00:00
Big re-organization of repository [W.I.P]
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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_
|
||||
@@ -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();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user