Scripts/Icecrown Citadel: Added script for Blood Queen Lana'Thel

Scripts/Icecrown Citadel: Fixed Invocation of Blood announcement emote for Blood Prince Council
Scripts/Icecrown Citadel: Fixed intro for Lady Deathwhisper
Scripts/Icecrown Citadel: Fixed Bone Spike for Lord Marrowgar

--HG--
branch : trunk
This commit is contained in:
Shauren
2010-12-03 17:47:33 +01:00
parent 892f56c37d
commit e0c992a8ba
17 changed files with 782 additions and 42 deletions
+7
View File
@@ -5758,6 +5758,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
triggered_spell_id = 70701;
break;
}
case 70871:
{
target = this;
triggered_spell_id = 70872;
basepoints0 = int32(damage) * triggerAmount / 100;
break;
}
}
break;
}
@@ -470,6 +470,7 @@ void AddSC_boss_festergut();
void AddSC_boss_rotface();
void AddSC_boss_professor_putricide();
void AddSC_boss_blood_prince_council();
void AddSC_boss_blood_queen_lana_thel();
void AddSC_icecrown_citadel_teleport();
void AddSC_instance_icecrown_citadel();
@@ -1155,6 +1156,7 @@ void AddNorthrendScripts()
AddSC_boss_rotface();
AddSC_boss_professor_putricide();
AddSC_boss_blood_prince_council();
AddSC_boss_blood_queen_lana_thel();
AddSC_icecrown_citadel_teleport();
AddSC_instance_icecrown_citadel();
+26
View File
@@ -2800,6 +2800,32 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
++itr;
}
break;
case 71390: // Pact of the Darkfallen
{
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end();)
{
if (!(*itr)->HasAura(71340))
itr = unitList.erase(itr);
else
++itr;
}
bool remove = true;
// we can do this, unitList is MAX 4 in size
for (std::list<Unit*>::const_iterator itr = unitList.begin(); itr != unitList.end() && remove; ++itr)
{
if (!m_caster->IsWithinDist(*itr, 5.0f, false))
remove = false;
for (std::list<Unit*>::const_iterator itr2 = unitList.begin(); itr2 != unitList.end() && remove; ++itr2)
if (itr != itr2 && !(*itr2)->IsWithinDist(*itr, 5.0f, false))
remove = false;
}
if (remove)
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
(*itr)->RemoveAura(71340);
break;
}
}
// Death Pact
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000)
+6
View File
@@ -3624,6 +3624,8 @@ void SpellMgr::LoadSpellCustomAttr()
case 69782: case 69796: // Ooze Flood
case 69798: case 69801: // Ooze Flood
case 69538: case 69553: case 69610: // Ooze Combine
case 71447: case 71481: // Bloodbolt Splash
case 71482: case 71483: // Bloodbolt Splash
mSpellCustomAttr[i] |= SPELL_ATTR_CU_EXCLUDE_SELF;
count++;
break;
@@ -3951,6 +3953,10 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->AttributesEx3 |= SPELL_ATTR_EX3_NO_DONE_BONUS;
count++;
break;
case 71340: // Pact of the Darkfallen
spellInfo->DurationIndex = 21;
count++;
break;
default:
break;
}
@@ -152,6 +152,7 @@ set(scripts_STAT_SRCS
Northrend/IcecrownCitadel/boss_rotface.cpp
Northrend/IcecrownCitadel/boss_professor_putricide.cpp
Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
Northrend/zuldrak.cpp
Northrend/icecrown.cpp
Northrend/Gundrak/boss_slad_ran.cpp
@@ -299,10 +299,12 @@ class boss_blood_council_controller : public CreatureScript
}
if (newPrince)
{
newPrince->SetHealth(me->GetHealth());
newPrince->AI()->Talk(invocationOrder[invocationStage].textId);
}
DoCast(me, invocationOrder[invocationStage].spellId);
Talk(invocationOrder[invocationStage].textId);
events.ScheduleEvent(EVENT_INVOCATION_OF_BLOOD, 30000);
break;
}
@@ -0,0 +1,576 @@
/*
* Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
#include "icecrown_citadel.h"
enum eTexts
{
SAY_AGGRO = 0,
SAY_VAMPIRIC_BITE = 1,
SAY_MIND_CONTROL = 2,
EMOTE_BLOODTHIRST = 3,
SAY_SWARMING_SHADOWS = 4,
EMOTE_SWARMING_SHADOWS = 5,
SAY_PACT_OF_THE_DARKFALLEN = 6,
SAY_AIR_PHASE = 7,
SAY_KILL = 8,
SAY_WIPE = 9,
SAY_BERSERK = 10,
SAY_DEATH = 11,
};
enum eSpells
{
SPELL_SHROUD_OF_SORROW = 70986,
SPELL_FRENZIED_BLOODTHIRST_VISUAL = 71949,
SPELL_VAMPIRIC_BITE = 71726,
SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR = 70879,
SPELL_FRENZIED_BLOODTHIRST = 70877,
SPELL_UNCONTROLLABLE_FRENZY = 70923,
SPELL_PRESENCE_OF_THE_DARKFALLEN = 71952,
SPELL_BLOOD_MIRROR_DAMAGE = 70821,
SPELL_BLOOD_MIRROR_VISUAL = 71510,
SPELL_BLOOD_MIRROR_DUMMY = 70838,
SPELL_DELIRIOUS_SLASH = 71623,
SPELL_PACT_OF_THE_DARKFALLEN_TARGET = 71336,
SPELL_PACT_OF_THE_DARKFALLEN = 71340,
SPELL_SWARMING_SHADOWS = 71264,
SPELL_TWILIGHT_BLOODBOLT_TARGET = 71445,
SPELL_TWILIGHT_BLOODBOLT = 71446,
SPELL_INCITE_TERROR = 73070,
SPELL_BLOODBOLT_WHIRL = 71772,
};
static const uint32 vampireAuras[3][MAX_DIFFICULTY] =
{
{70867, 71473, 71532, 71533},
{70879, 71525, 71530, 71531},
{70877, 71474, 70877, 71474},
};
#define ESSENCE_OF_BLOOD_QUEEN RAID_MODE<uint32>(70867,71473,71532,71533)
#define ESSENCE_OF_BLOOD_QUEEN_PLR RAID_MODE<uint32>(70879,71525,71530,71531)
#define FRENZIED_BLOODTHIRST RAID_MODE<uint32>(70877,71474,70877,71474)
enum eEvents
{
EVENT_BERSERK = 1,
EVENT_VAMPIRIC_BITE = 2,
EVENT_BLOOD_MIRROR = 3,
EVENT_DELIRIOUS_SLASH = 4,
EVENT_PACT_OF_THE_DARKFALLEN = 5,
EVENT_SWARMING_SHADOWS = 6,
EVENT_TWILIGHT_BLOODBOLT = 7,
EVENT_AIR_PHASE = 8,
EVENT_AIR_START_FLYING = 9,
EVENT_AIR_FLY_DOWN = 10,
EVENT_GROUP_NORMAL = 1,
EVENT_GROUP_CANCELLABLE = 2,
};
#define GUID_VAMPIRE 1
enum ePoints
{
POINT_CENTER = 1,
POINT_AIR = 2,
POINT_GROUND = 3,
};
static const Position centerPos = {4595.7090f, 2769.4190f, 400.6368f, 0.0000f};
static const Position airPos = {4595.7090f, 2769.4190f, 422.3893f, 0.0000f};
bool IsVampire(Unit const* unit)
{
for (uint8 i = 0; i < 3; ++i)
if (unit->HasAura(vampireAuras[i][unit->GetMap()->GetSpawnMode()]))
return true;
return false;
}
class VampiricBiteTargetSelector : public std::unary_function<Unit*, bool>
{
public:
VampiricBiteTargetSelector() { }
bool operator() (Unit const* target)
{
if (!target)
return false;
if (target->GetTypeId() != TYPEID_PLAYER)
return false;
if (IsVampire(target))
return false;
return true;
}
};
class boss_blood_queen_lana_thel : public CreatureScript
{
public:
boss_blood_queen_lana_thel() : CreatureScript("boss_blood_queen_lana_thel") { }
struct boss_blood_queen_lana_thelAI : public BossAI
{
boss_blood_queen_lana_thelAI(Creature* creature) : BossAI(creature, DATA_BLOOD_QUEEN_LANA_THEL)
{
}
void InitializeAI()
{
if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(ICCScriptName))
me->IsAIEnabled = false;
else if (!me->isDead())
Reset();
}
void Reset()
{
events.Reset();
events.ScheduleEvent(EVENT_BERSERK, 330000);
events.ScheduleEvent(EVENT_VAMPIRIC_BITE, 15000);
events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500, EVENT_GROUP_CANCELLABLE);
events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, urand(20000, 24000), EVENT_GROUP_NORMAL);
events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 15000, EVENT_GROUP_NORMAL);
events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500, EVENT_GROUP_NORMAL);
events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, urand(20000, 25000), EVENT_GROUP_NORMAL);
events.ScheduleEvent(EVENT_AIR_PHASE, 124000 + (Is25ManRaid() ? 3000 : 0));
me->SetSpeed(MOVE_FLIGHT, 0.642857f, true);
offtank = NULL;
vampires.clear();
instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/)
{
DoZoneInCombat();
Talk(SAY_AGGRO);
instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, IN_PROGRESS);
DoCast(me, SPELL_SHROUD_OF_SORROW, true);
DoCast(me, SPELL_FRENZIED_BLOODTHIRST_VISUAL, true);
}
void JustDied(Unit* /*killer*/)
{
Talk(SAY_DEATH);
instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN);
instance->DoRemoveAurasDueToSpellOnPlayers(ESSENCE_OF_BLOOD_QUEEN_PLR);
instance->DoRemoveAurasDueToSpellOnPlayers(FRENZIED_BLOODTHIRST);
instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, DONE);
}
void JustReachedHome()
{
Talk(SAY_WIPE);
instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, FAIL);
}
void KilledUnit(Unit* victim)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_KILL);
}
void SetGUID(const uint64& guid, int32 type = 0)
{
if (type == GUID_VAMPIRE)
vampires.insert(guid);
}
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE)
return;
switch (id)
{
case POINT_CENTER:
DoCast(me, SPELL_INCITE_TERROR);
events.ScheduleEvent(EVENT_AIR_PHASE, 100000 + (Is25ManRaid() ? 0 : 20000));
events.RescheduleEvent(EVENT_SWARMING_SHADOWS, 30500, EVENT_GROUP_NORMAL);
events.RescheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 25500, EVENT_GROUP_NORMAL);
events.ScheduleEvent(EVENT_AIR_START_FLYING, 5000);
break;
case POINT_AIR:
DoCast(me, SPELL_BLOODBOLT_WHIRL);
Talk(SAY_AIR_PHASE);
events.ScheduleEvent(EVENT_AIR_FLY_DOWN, 10000);
break;
case POINT_GROUND:
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
me->SetFlying(false);
me->SetReactState(REACT_AGGRESSIVE);
AttackStart(me->getVictim());
events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500, EVENT_GROUP_CANCELLABLE);
break;
default:
break;
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_BERSERK:
DoScriptText(EMOTE_GENERIC_BERSERK_RAID, me);
Talk(SAY_BERSERK);
DoCast(me, SPELL_BERSERK);
break;
case EVENT_VAMPIRIC_BITE:
if (Player* target = SelectRandomTarget(false))
{
DoCast(target, SPELL_VAMPIRIC_BITE);
Talk(SAY_VAMPIRIC_BITE);
vampires.insert(target->GetGUID());
}
break;
case EVENT_BLOOD_MIRROR:
{
Player* newOfftank = SelectRandomTarget(true);
if (offtank != newOfftank)
{
offtank = newOfftank;
offtank->CastSpell(me->getVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true);
me->getVictim()->CastSpell(offtank, SPELL_BLOOD_MIRROR_DUMMY, true);
DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL);
}
events.ScheduleEvent(EVENT_BLOOD_MIRROR, 2500, EVENT_GROUP_CANCELLABLE);
break;
}
case EVENT_DELIRIOUS_SLASH:
if (offtank && !me->HasByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03))
DoCast(offtank, SPELL_DELIRIOUS_SLASH);
events.ScheduleEvent(EVENT_DELIRIOUS_SLASH, urand(20000, 24000), EVENT_GROUP_NORMAL);
break;
case EVENT_PACT_OF_THE_DARKFALLEN:
{
std::list<Player*> targets;
SelectRandomTarget(false, &targets);
uint32 targetCount = 2;
if (IsHeroic())
++targetCount;
if (Is25ManRaid())
++targetCount;
Trinity::RandomResizeList<Player*>(targets, targetCount);
if (targets.size() > 1)
{
Talk(SAY_PACT_OF_THE_DARKFALLEN);
for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
DoCast(*itr, SPELL_PACT_OF_THE_DARKFALLEN);
}
events.ScheduleEvent(EVENT_PACT_OF_THE_DARKFALLEN, 30500, EVENT_GROUP_NORMAL);
break;
}
case EVENT_SWARMING_SHADOWS:
if (Player* target = SelectRandomTarget(false))
{
Talk(EMOTE_SWARMING_SHADOWS, target->GetGUID());
Talk(SAY_SWARMING_SHADOWS);
DoCast(target, SPELL_SWARMING_SHADOWS);
}
events.ScheduleEvent(EVENT_SWARMING_SHADOWS, 30500, EVENT_GROUP_NORMAL);
break;
case EVENT_TWILIGHT_BLOODBOLT:
{
std::list<Player*> targets;
SelectRandomTarget(false, &targets);
Trinity::RandomResizeList<Player*>(targets, Is25ManRaid() ? 4 : 2);
for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT);
DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET);
events.ScheduleEvent(EVENT_TWILIGHT_BLOODBOLT, urand(10000, 15000), EVENT_GROUP_NORMAL);
break;
}
case EVENT_AIR_PHASE:
DoStopAttack();
me->SetReactState(REACT_PASSIVE);
events.DelayEvents(7000, EVENT_GROUP_NORMAL);
events.CancelEventsByGCD(EVENT_GROUP_CANCELLABLE);
me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos);
break;
case EVENT_AIR_START_FLYING:
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
me->SetFlying(true);
me->GetMotionMaster()->MovePoint(POINT_AIR, airPos);
break;
case EVENT_AIR_FLY_DOWN:
me->GetMotionMaster()->MovePoint(POINT_GROUND, centerPos);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
bool WasVampire(uint64 guid)
{
return vampires.count(guid) != 0;
}
private:
// offtank for this encounter is the player standing closest to main tank
Player* SelectRandomTarget(bool includeOfftank, std::list<Player*>* targetList = NULL)
{
const std::list<HostileReference*> &threatlist = me->getThreatManager().getThreatList();
std::list<Player*> tempTargets;
if (threatlist.empty())
return NULL;
for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
if (Unit* refTarget = (*itr)->getTarget())
if (refTarget != me->getVictim() && refTarget->GetTypeId() == TYPEID_PLAYER && (includeOfftank ? true : (refTarget != offtank)))
tempTargets.push_back(refTarget->ToPlayer());
if (tempTargets.empty())
return NULL;
if (targetList)
{
*targetList = tempTargets;
return NULL;
}
if (includeOfftank)
{
tempTargets.sort(Trinity::ObjectDistanceOrderPred(me->getVictim()));
return tempTargets.front();
}
std::list<Player*>::iterator itr = tempTargets.begin();
std::advance(itr, urand(1, tempTargets.size()-1));
return *itr;
}
Player* offtank;
std::set<uint64> vampires;
};
CreatureAI* GetAI(Creature* creature) const
{
return new boss_blood_queen_lana_thelAI(creature);
}
};
// helper for shortened code
typedef boss_blood_queen_lana_thel::boss_blood_queen_lana_thelAI LanaThelAI;
class spell_blood_queen_vampiric_bite : public SpellScriptLoader
{
public:
spell_blood_queen_vampiric_bite() : SpellScriptLoader("spell_blood_queen_vampiric_bite") { }
class spell_blood_queen_vampiric_bite_SpellScript : public SpellScript
{
PrepareSpellScript(spell_blood_queen_vampiric_bite_SpellScript);
bool Validate(SpellEntry const* /*spell*/)
{
if (!sSpellStore.LookupEntry(SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR))
return false;
if (!sSpellStore.LookupEntry(SPELL_FRENZIED_BLOODTHIRST))
return false;
if (!sSpellStore.LookupEntry(SPELL_PRESENCE_OF_THE_DARKFALLEN))
return false;
return true;
}
void OnCast()
{
if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
return;
if (IsVampire(GetHitUnit()))
{
PreventHitDamage();
PreventHitDefaultEffect(EFFECT_1);
Spell::SendCastResult(GetCaster()->ToPlayer(), GetSpellInfo(), 0, SPELL_FAILED_BAD_TARGETS);
return;
}
SpellEntry const* spell = sSpellStore.LookupEntry(SPELL_FRENZIED_BLOODTHIRST);
spell = sSpellMgr.GetSpellForDifficultyFromSpell(spell, GetCaster());
GetCaster()->RemoveAura(spell->Id, 0, 0, AURA_REMOVE_BY_ENEMY_SPELL);
GetCaster()->CastSpell(GetCaster(), SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR, true);
if (GetCaster()->GetMap()->IsHeroic())
GetCaster()->CastSpell(GetCaster(), SPELL_PRESENCE_OF_THE_DARKFALLEN, true);
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
if (Creature* bloodQueen = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_BLOOD_QUEEN_LANA_THEL)))
bloodQueen->AI()->SetGUID(GetHitUnit()->GetGUID(), GUID_VAMPIRE);
}
void Register()
{
BeforeHit += SpellHitFn(spell_blood_queen_vampiric_bite_SpellScript::OnCast);
}
};
SpellScript* GetSpellScript() const
{
return new spell_blood_queen_vampiric_bite_SpellScript();
}
};
class spell_blood_queen_frenzied_bloodthirst : public SpellScriptLoader
{
public:
spell_blood_queen_frenzied_bloodthirst() : SpellScriptLoader("spell_blood_queen_frenzied_bloodthirst") { }
class spell_blood_queen_frenzied_bloodthirst_AuraScript : public AuraScript
{
PrepareAuraScript(spell_blood_queen_frenzied_bloodthirst_AuraScript);
void OnApply(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/)
{
if (InstanceScript* instance = aurApp->GetTarget()->GetInstanceScript())
if (Creature* bloodQueen = ObjectAccessor::GetCreature(*aurApp->GetTarget(), instance->GetData64(DATA_BLOOD_QUEEN_LANA_THEL)))
bloodQueen->AI()->Talk(EMOTE_BLOODTHIRST);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/)
{
if (!aurApp)
return;
Unit* target = aurApp->GetTarget();
if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
if (InstanceScript* instance = target->GetInstanceScript())
if (Creature* bloodQueen = ObjectAccessor::GetCreature(*target, instance->GetData64(DATA_BLOOD_QUEEN_LANA_THEL)))
{
// this needs to be done BEFORE charm aura or we hit an assert in Unit::SetCharmedBy
if (target->GetVehicleKit())
target->RemoveVehicleKit();
bloodQueen->AI()->Talk(SAY_MIND_CONTROL);
bloodQueen->CastSpell(target, SPELL_UNCONTROLLABLE_FRENZY, true);
}
}
void Register()
{
OnEffectRemove += AuraEffectRemoveFn(spell_blood_queen_frenzied_bloodthirst_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_OVERRIDE_SPELLS, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_blood_queen_frenzied_bloodthirst_AuraScript();
}
};
class spell_blood_queen_bloodbolt : public SpellScriptLoader
{
public:
spell_blood_queen_bloodbolt() : SpellScriptLoader("spell_blood_queen_bloodbolt") { }
class spell_blood_queen_bloodbolt_SpellScript : public SpellScript
{
PrepareSpellScript(spell_blood_queen_bloodbolt_SpellScript);
bool Validate(SpellEntry const* /*spell*/)
{
if (!sSpellStore.LookupEntry(SPELL_TWILIGHT_BLOODBOLT))
return false;
return true;
}
void HandleDummy()
{
if (GetHitUnit()->GetTypeId() == TYPEID_PLAYER)
GetCaster()->CastSpell(GetHitUnit(), SPELL_TWILIGHT_BLOODBOLT, true);
}
void Register()
{
AfterHit += SpellHitFn(spell_blood_queen_bloodbolt_SpellScript::HandleDummy);
}
};
SpellScript* GetSpellScript() const
{
return new spell_blood_queen_bloodbolt_SpellScript();
}
};
class achievement_once_bitten_twice_shy_n : public AchievementCriteriaScript
{
public:
achievement_once_bitten_twice_shy_n() : AchievementCriteriaScript("achievement_once_bitten_twice_shy_n") { }
bool OnCheck(Player* source, Unit* target)
{
if (!target)
return false;
if (LanaThelAI* lanaThelAI = CAST_AI(LanaThelAI, target->GetAI()))
return !lanaThelAI->WasVampire(source->GetGUID());
return false;
}
};
class achievement_once_bitten_twice_shy_v : public AchievementCriteriaScript
{
public:
achievement_once_bitten_twice_shy_v() : AchievementCriteriaScript("achievement_once_bitten_twice_shy_v") { }
bool OnCheck(Player* source, Unit* target)
{
if (!target)
return false;
if (LanaThelAI* lanaThelAI = CAST_AI(LanaThelAI, target->GetAI()))
return lanaThelAI->WasVampire(source->GetGUID());
return false;
}
};
void AddSC_boss_blood_queen_lana_thel()
{
new boss_blood_queen_lana_thel();
new spell_blood_queen_vampiric_bite();
new spell_blood_queen_frenzied_bloodthirst();
new spell_blood_queen_bloodbolt();
new achievement_once_bitten_twice_shy_n();
new achievement_once_bitten_twice_shy_v();
}
@@ -180,7 +180,6 @@ class boss_lady_deathwhisper : public CreatureScript
void Reset()
{
me->SetReactState(REACT_DEFENSIVE);
me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA));
me->SetLastManaUse(0xFFFFFFFF); // hacky, but no other way atm to prevent mana regen
events.Reset();
@@ -211,8 +210,6 @@ class boss_lady_deathwhisper : public CreatureScript
events.ScheduleEvent(EVENT_INTRO_7, 58000, 0, PHASE_INTRO);
events.ScheduleEvent(EVENT_INTRO_FINISH, 76000, 0, PHASE_INTRO);
}
BossAI::MoveInLineOfSight(who);
}
void AttackStart(Unit* victim)
@@ -367,6 +367,12 @@ class npc_bone_spike : public CreatureScript
trappedGUID = 0;
}
void KilledUnit(Unit* victim)
{
if (TempSummon* summ = me->ToTempSummon())
summ->UnSummon();
}
void IsSummonedBy(Unit* summoner)
{
trappedGUID = summoner->GetGUID();
@@ -375,11 +381,13 @@ class npc_bone_spike : public CreatureScript
events.ScheduleEvent(EVENT_FAIL_BONED, 8000);
}
void UpdateAI(const uint32 /*diff*/)
void UpdateAI(const uint32 diff)
{
if (!trappedGUID)
return;
events.Update(diff);
if (events.ExecuteEvent() == EVENT_FAIL_BONED)
if (InstanceScript* instance = me->GetInstanceScript())
instance->SetData(DATA_BONED_ACHIEVEMENT, uint32(false));
@@ -439,7 +447,7 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader
{
PrepareSpellScript(spell_marrowgar_bone_spike_graveyard_SpellScript);
void HandleScript(SpellEffIndex effIndex)
void HandleSpikes(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Creature* marrowgar = GetCaster()->ToCreature())
@@ -466,7 +474,7 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader
void Register()
{
OnEffect += SpellEffectFn(spell_marrowgar_bone_spike_graveyard_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
OnEffect += SpellEffectFn(spell_marrowgar_bone_spike_graveyard_SpellScript::HandleSpikes, EFFECT_1, SPELL_EFFECT_APPLY_AURA);
}
};
@@ -136,6 +136,9 @@ enum eCreatures
NPC_KINETIC_BOMB_TARGET = 38458,
NPC_KINETIC_BOMB = 38454,
NPC_SHOCK_VORTEX = 38422,
// Blood-Queen Lana'thel
NPC_BLOOD_QUEEN_LANA_THEL = 37955,
};
enum eGameobjects
@@ -190,28 +193,36 @@ enum eGameobjects
enum eAchievementCriteria
{
// Lord Marrowgar
CRITERIA_BONED_10N = 12775,
CRITERIA_BONED_25N = 12962,
CRITERIA_BONED_10H = 13393,
CRITERIA_BONED_25H = 13394,
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,
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,
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,
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,
CRITERIA_ONCE_BITTEN_TWICE_SHY_10N = 12780,
CRITERIA_ONCE_BITTEN_TWICE_SHY_25N = 13012,
CRITERIA_ONCE_BITTEN_TWICE_SHY_10V = 13011,
CRITERIA_ONCE_BITTEN_TWICE_SHY_25V = 13013,
};
enum eSharedActions
@@ -18,6 +18,8 @@
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
#include "Map.h"
#include "icecrown_citadel.h"
static const DoorData doorData[] =
@@ -53,6 +55,7 @@ class instance_icecrown_citadel : public InstanceMapScript
{
SetBossNumber(MAX_ENCOUNTER);
LoadDoorData(doorData);
teamInInstance = 0;
ladyDeathwisperElevator = 0;
deathbringerSaurfang = 0;
saurfangDoor = 0;
@@ -68,73 +71,82 @@ class instance_icecrown_citadel : public InstanceMapScript
putricideTable = 0;
memset(bloodCouncil, 0, 3*sizeof(uint64));
bloodCouncilController = 0;
bloodQueenLanaThel = 0;
isBonedEligible = true;
isOozeDanceEligible = true;
isNauseaEligible = true;
isOrbWhispererEligible = true;
}
void OnCreatureCreate(Creature* creature, bool /*add*/)
void OnPlayerEnter(Player* player)
{
Map::PlayerList const &players = instance->GetPlayers();
uint32 TeamInInstance = 0;
if (!teamInInstance)
teamInInstance = player->GetTeam();
}
if (!players.isEmpty())
void OnCreatureCreate(Creature* creature, bool add)
{
if (!add)
return;
if (!teamInInstance)
{
if (Player* pPlayer = players.begin()->getSource())
TeamInInstance = pPlayer->GetTeam();
Map::PlayerList const &players = instance->GetPlayers();
if (!players.isEmpty())
if (Player* player = players.begin()->getSource())
teamInInstance = player->GetTeam();
}
switch (creature->GetEntry())
{
case NPC_KOR_KRON_GENERAL:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_ALLIANCE_COMMANDER, ALLIANCE);
break;
case NPC_KOR_KRON_LIEUTENANT:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_SKYBREAKER_LIEUTENANT, ALLIANCE);
break;
case NPC_TORTUNOK:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_ALANA_MOONSTRIKE, ALLIANCE);
break;
case NPC_GERARDO_THE_SUAVE:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_TALAN_MOONSTRIKE, ALLIANCE);
break;
case NPC_UVLUS_BANEFIRE:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_MALFUS_GRIMFROST, ALLIANCE);
break;
case NPC_IKFIRUS_THE_VILE:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_YILI, ALLIANCE);
break;
case NPC_VOL_GUK:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_JEDEBIA, ALLIANCE);
break;
case NPC_HARAGG_THE_UNSEEN:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_NIBY_THE_ALMIGHTY, ALLIANCE);
break;
case NPC_GARROSH_HELLSCREAM:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_KING_VARIAN_WRYNN, ALLIANCE);
break;
case NPC_DEATHBRINGER_SAURFANG:
deathbringerSaurfang = creature->GetGUID();
break;
case NPC_SE_HIGH_OVERLORD_SAURFANG:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_SE_MURADIN_BRONZEBEARD, ALLIANCE);
case NPC_SE_MURADIN_BRONZEBEARD:
saurfangEventNPC = creature->GetGUID();
creature->LastUsedScriptID = creature->GetScriptId();
break;
case NPC_SE_KOR_KRON_REAVER:
if (TeamInInstance == ALLIANCE)
if (teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_SE_SKYBREAKER_MARINE, ALLIANCE);
break;
case NPC_FESTERGUT:
@@ -158,6 +170,9 @@ class instance_icecrown_citadel : public InstanceMapScript
case NPC_BLOOD_ORB_CONTROLLER:
bloodCouncilController = creature->GetGUID();
break;
case NPC_BLOOD_QUEEN_LANA_THEL:
bloodQueenLanaThel = creature->GetGUID();
break;
default:
break;
}
@@ -271,6 +286,8 @@ class instance_icecrown_citadel : public InstanceMapScript
return bloodCouncil[2];
case DATA_BLOOD_PRINCES_CONTROL:
return bloodCouncilController;
case DATA_BLOOD_QUEEN_LANA_THEL:
return bloodQueenLanaThel;
default:
break;
}
@@ -400,6 +417,15 @@ class instance_icecrown_citadel : public InstanceMapScript
case CRITERIA_ORB_WHISPERER_10H:
case CRITERIA_ORB_WHISPERER_25H:
return isOrbWhispererEligible;
// Only one criteria for both modes, need to do it like this
case CRITERIA_KILL_LANA_THEL_10M:
case CRITERIA_ONCE_BITTEN_TWICE_SHY_10N:
case CRITERIA_ONCE_BITTEN_TWICE_SHY_10V:
return CAST_INST(InstanceMap, instance)->GetMaxPlayers() == 10;
case CRITERIA_KILL_LANA_THEL_25M:
case CRITERIA_ONCE_BITTEN_TWICE_SHY_25N:
case CRITERIA_ONCE_BITTEN_TWICE_SHY_25V:
return CAST_INST(InstanceMap, instance)->GetMaxPlayers() == 25;
default:
break;
}
@@ -449,6 +475,7 @@ class instance_icecrown_citadel : public InstanceMapScript
}
private:
uint32 teamInInstance;
uint64 ladyDeathwisperElevator;
uint64 deathbringerSaurfang;
uint64 saurfangDoor;
@@ -464,6 +491,7 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 putricideTable;
uint64 bloodCouncil[3];
uint64 bloodCouncilController;
uint64 bloodQueenLanaThel;
bool isBonedEligible;
bool isOozeDanceEligible;
bool isNauseaEligible;