aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2011-02-18 19:48:47 +0100
committerShauren <shauren.trinity@gmail.com>2011-02-18 19:48:47 +0100
commit0f34df6e1a5c2272a3a1841978bcb8dfea073449 (patch)
treeb58c2384c53871b08f88ba2db77f54289fabc0cf /src
parent6a64c79d2aa169f6d6d385948af3f6737f274133 (diff)
Scripts/Icecrown Citadel: Added support for weekly quest "Deprogramming"
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp92
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp4
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp229
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp4
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h10
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp56
6 files changed, 317 insertions, 78 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 9c8e52fa81b..9a21f57f120 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -317,14 +317,10 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData *data
SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
// Load creature equipment
- if (!data || data->equipmentId == 0)
- { // use default from the template
+ if (!data || data->equipmentId == 0) // use default from the template
LoadEquipment(cinfo->equipmentId);
- }
- else if (data && data->equipmentId != -1)
- { // override, -1 means no equipment
+ else if (data && data->equipmentId != -1) // override, -1 means no equipment
LoadEquipment(data->equipmentId);
- }
SetName(normalInfo->Name); // at normal entry always
@@ -764,61 +760,59 @@ bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry,
}
//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
- const bool bResult = CreateFromProto(guidlow, Entry, vehId, team, data);
+ if (!CreateFromProto(guidlow, Entry, vehId, team, data))
+ return false;
- if (bResult)
+ switch (GetCreatureInfo()->rank)
{
- switch (GetCreatureInfo()->rank)
- {
- case CREATURE_ELITE_RARE:
- m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_RARE);
- break;
- case CREATURE_ELITE_ELITE:
- m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_ELITE);
- break;
- case CREATURE_ELITE_RAREELITE:
- m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_RAREELITE);
- break;
- case CREATURE_ELITE_WORLDBOSS:
- m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_WORLDBOSS);
- break;
- default:
- m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_NORMAL);
- break;
- }
- LoadCreaturesAddon();
- CreatureModelInfo const *minfo = sObjectMgr->GetCreatureModelRandomGender(GetNativeDisplayId());
- if (minfo && !isTotem()) // Cancel load if no model defined or if totem
- {
- uint32 display_id = minfo->modelid; // it can be different (for another gender)
+ case CREATURE_ELITE_RARE:
+ m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_RARE);
+ break;
+ case CREATURE_ELITE_ELITE:
+ m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_ELITE);
+ break;
+ case CREATURE_ELITE_RAREELITE:
+ m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_RAREELITE);
+ break;
+ case CREATURE_ELITE_WORLDBOSS:
+ m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_WORLDBOSS);
+ break;
+ default:
+ m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_NORMAL);
+ break;
+ }
- SetDisplayId(display_id);
- SetNativeDisplayId(display_id);
- SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
- }
+ LoadCreaturesAddon();
+ CreatureModelInfo const *minfo = sObjectMgr->GetCreatureModelRandomGender(GetNativeDisplayId());
+ if (minfo && !isTotem()) // Cancel load if no model defined or if totem
+ {
+ uint32 display_id = minfo->modelid; // it can be different (for another gender)
- if (GetCreatureInfo()->InhabitType & INHABIT_AIR)
- {
- if (GetDefaultMovementType() == IDLE_MOTION_TYPE)
- AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
- else
- SetFlying(true);
- }
+ SetDisplayId(display_id);
+ SetNativeDisplayId(display_id);
+ SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
+ }
- if (GetCreatureInfo()->InhabitType & INHABIT_WATER)
- {
- AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
- }
- LastUsedScriptID = GetCreatureInfo()->ScriptID;
+ if (GetCreatureInfo()->InhabitType & INHABIT_AIR)
+ {
+ if (GetDefaultMovementType() == IDLE_MOTION_TYPE)
+ AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
+ else
+ SetFlying(true);
}
+ if (GetCreatureInfo()->InhabitType & INHABIT_WATER)
+ AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+
+ LastUsedScriptID = GetCreatureInfo()->ScriptID;
+
// TODO: Replace with spell, handle from DB
if (isSpiritHealer())
{
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST);
}
- else if(isSpiritGuide())
+ else if (isSpiritGuide())
{
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST | GHOST_VISIBILITY_ALIVE);
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST | GHOST_VISIBILITY_ALIVE);
@@ -827,7 +821,7 @@ bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry,
if (Entry == VISUAL_WAYPOINT)
SetVisible(false);
- return bResult;
+ return true;
}
bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 752572151ef..3227e69771a 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1846,7 +1846,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation))
{
- sLog->outError("TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (GUID: %u, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).",
+ sLog->outError("TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (GUID: %u, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).",
mapid, x, y, z, orientation, GetGUIDLow(), GetName(), GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
return false;
}
@@ -8045,7 +8045,7 @@ void Player::CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32
SpellEntry const *spellInfo = sSpellStore.LookupEntry(pEnchant->spellid[s]);
if (!spellInfo)
{
- sLog->outError("Player::CastItemCombatSpell(GUID: %u, name: %s, enchant: %i): unknown spell %i is casted, ignoring...",
+ sLog->outError("Player::CastItemCombatSpell(GUID: %u, name: %s, enchant: %i): unknown spell %i is casted, ignoring...",
GetGUIDLow(), GetName(), pEnchant->ID, pEnchant->spellid[s]);
continue;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index 0c44d27d4e5..32578b3d9b7 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -19,11 +19,13 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
-#include "icecrown_citadel.h"
+#include "PoolMgr.h"
#include "Group.h"
+#include "icecrown_citadel.h"
enum ScriptTexts
{
+ // Lady Deathwhisper
SAY_INTRO_1 = 0,
SAY_INTRO_2 = 1,
SAY_INTRO_3 = 2,
@@ -41,6 +43,10 @@ enum ScriptTexts
SAY_KILL = 14,
SAY_BERSERK = 15,
SAY_DEATH = 16,
+
+ // Darnavan
+ SAY_DARNAVAN_AGGRO = 0,
+ SAY_DARNAVAN_RESCUED = 1,
};
enum Spells
@@ -89,6 +95,14 @@ enum Spells
SPELL_VENGEFUL_BLAST_25N = 72010,
SPELL_VENGEFUL_BLAST_10H = 72011,
SPELL_VENGEFUL_BLAST_25H = 72012,
+
+ // Darnavan
+ SPELL_BLADESTORM = 65947,
+ SPELL_CHARGE = 65927,
+ SPELL_INTIMIDATING_SHOUT = 65930,
+ SPELL_MORTAL_STRIKE = 65926,
+ SPELL_SHATTERING_THROW = 65940,
+ SPELL_SUNDER_ARMOR = 65936,
};
enum Events
@@ -131,6 +145,14 @@ enum Events
EVENT_ADHERENT_DEATHCHILL = 25,
EVENT_ADHERENT_CURSE_OF_TORPOR = 26,
EVENT_ADHERENT_SHORUD_OF_THE_OCCULT = 27,
+
+ // Darnavan
+ EVENT_DARNAVAN_BLADESTORM = 28,
+ EVENT_DARNAVAN_CHARGE = 29,
+ EVENT_DARNAVAN_INTIMIDATING_SHOUT = 30,
+ EVENT_DARNAVAN_MORTAL_STRIKE = 31,
+ EVENT_DARNAVAN_SHATTERING_THROW = 32,
+ EVENT_DARNAVAN_SUNDER_ARMOR = 33,
};
enum Phases
@@ -144,6 +166,24 @@ enum Phases
PHASE_ONE_MASK = 1 << PHASE_ONE,
};
+enum DeprogrammingData
+{
+ QUEST_DEPROGRAMMING_10 = 24869,
+ QUEST_DEPROGRAMMING_25 = 24875,
+
+ NPC_DARNAVAN_10 = 38472,
+ NPC_DARNAVAN_25 = 38485,
+ NPC_DARNAVAN_CREDIT_10 = 39091,
+ NPC_DARNAVAN_CREDIT_25 = 39092,
+
+ ACTION_COMPLETE_QUEST = -384720,
+ POINT_DESPAWN = 384721,
+};
+
+#define NPC_DARNAVAN RAID_MODE<uint32>(NPC_DARNAVAN_10,NPC_DARNAVAN_25,NPC_DARNAVAN_10,NPC_DARNAVAN_25)
+#define NPC_DARNAVAN_CREDIT RAID_MODE<uint32>(NPC_DARNAVAN_CREDIT_10,NPC_DARNAVAN_CREDIT_25,NPC_DARNAVAN_CREDIT_10,NPC_DARNAVAN_CREDIT_25)
+#define QUEST_DEPROGRAMMING RAID_MODE<uint32>(QUEST_DEPROGRAMMING_10,QUEST_DEPROGRAMMING_25,QUEST_DEPROGRAMMING_10,QUEST_DEPROGRAMMING_25)
+
static const uint32 addEntries[2] = {NPC_CULT_FANATIC, NPC_CULT_ADHERENT};
static const Position addSpawnPos[7] =
@@ -157,6 +197,20 @@ static const Position addSpawnPos[7] =
{-524.2480f, 2211.920f, 62.90960f, 3.141592f}, // 7 Upper (Random Cultist)
};
+class DaranavanMoveEvent : public BasicEvent
+{
+ public:
+ DaranavanMoveEvent(Creature& _darnavan) : darnavan(_darnavan) { }
+
+ bool Execute(uint64 , uint32 )
+ {
+ darnavan.GetMotionMaster()->MovePoint(POINT_DESPAWN, addSpawnPos[6]);
+ return true;
+ }
+
+ Creature& darnavan;
+};
+
class boss_lady_deathwhisper : public CreatureScript
{
public:
@@ -167,7 +221,7 @@ class boss_lady_deathwhisper : public CreatureScript
boss_lady_deathwhisperAI(Creature* creature) : BossAI(creature, DATA_LADY_DEATHWHISPER)
{
introDone = false;
- dominateMindCount = RAID_MODE<uint8>(0,1,1,3);
+ dominateMindCount = RAID_MODE<uint8>(0, 1, 1, 3);
}
void InitializeAI()
@@ -186,6 +240,7 @@ class boss_lady_deathwhisper : public CreatureScript
events.SetPhase(PHASE_ONE);
addWaveCounter = 0;
nextVengefulShadeTarget = 0;
+ darnavanGUID = 0;
DoCast(me, SPELL_SHADOW_CHANNELING);
me->RemoveAurasDueToSpell(SPELL_BERSERK);
me->RemoveAurasDueToSpell(SPELL_MANA_BARRIER);
@@ -264,23 +319,29 @@ class boss_lady_deathwhisper : public CreatureScript
livingAddEntries.insert(unit->GetEntry());
if (livingAddEntries.size() >= 5)
+ instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_FULL_HOUSE, 0, me);
+
+ if (Creature* darnavan = ObjectAccessor::GetCreature(*me, darnavanGUID))
{
- if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
+ if (darnavan->isAlive())
{
- if (Group* group = player->GetGroup())
+ darnavan->setFaction(35);
+ darnavan->CombatStop(true);
+ darnavan->GetMotionMaster()->MoveIdle();
+ darnavan->SetReactState(REACT_PASSIVE);
+ darnavan->m_Events.AddEvent(new DaranavanMoveEvent(*darnavan), darnavan->m_Events.CalculateTime(10000));
+ darnavan->AI()->Talk(SAY_DARNAVAN_RESCUED);
+ if (Player* owner = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
{
- for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ if (Group* group = owner->GetGroup())
{
- Player* member = itr->getSource();
- if (!member || !member->IsAtGroupRewardDistance(me))
- continue;
-
- if (member->isAlive()|| !member->GetCorpse())
- member->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_FULL_HOUSE, 0, me);
+ for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ if (Player* member = itr->getSource())
+ member->KilledMonsterCredit(NPC_DARNAVAN_CREDIT, 0);
}
+ else
+ owner->KilledMonsterCredit(NPC_DARNAVAN_CREDIT, 0);
}
- else
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_FULL_HOUSE, 0, me);
}
}
@@ -293,6 +354,11 @@ class boss_lady_deathwhisper : public CreatureScript
instance->SetBossState(DATA_LADY_DEATHWHISPER, FAIL);
summons.DespawnAll();
+ if (Creature* darnavan = ObjectAccessor::GetCreature(*me, darnavanGUID))
+ {
+ darnavan->DespawnOrUnsummon();
+ darnavanGUID = 0;
+ }
}
void KilledUnit(Unit* victim)
@@ -329,7 +395,11 @@ class boss_lady_deathwhisper : public CreatureScript
void JustSummoned(Creature* summon)
{
- summons.push_back(summon->GetGUID());
+ if (summon->GetEntry() == NPC_DARNAVAN)
+ darnavanGUID = summon->GetGUID();
+ else
+ summons.push_back(summon->GetGUID());
+
Unit* target = NULL;
if (summon->GetEntry() == NPC_VENGEFUL_SHADE)
{
@@ -452,7 +522,10 @@ class boss_lady_deathwhisper : public CreatureScript
{
uint8 addIndex = addWaveCounter & 1;
uint8 addIndexOther = uint8(addIndex ^ 1);
- _SummonAdd(addEntries[addIndex], addSpawnPos[addIndex*3]);
+ if (addWaveCounter || !sPoolMgr->IsSpawnedObject<Quest>(QUEST_DEPROGRAMMING))
+ _SummonAdd(addEntries[addIndex], addSpawnPos[addIndex*3]);
+ else
+ _SummonAdd(NPC_DARNAVAN, addSpawnPos[addIndex*3]);
_SummonAdd(addEntries[addIndexOther], addSpawnPos[addIndex*3+1]);
_SummonAdd(addEntries[addIndex], addSpawnPos[addIndex*3+2]);
if (Is25ManRaid())
@@ -550,6 +623,7 @@ class boss_lady_deathwhisper : public CreatureScript
private:
uint64 nextVengefulShadeTarget;
+ uint64 darnavanGUID;
std::deque<uint64> reanimationQueue;
uint32 addWaveCounter;
uint8 dominateMindCount;
@@ -562,6 +636,8 @@ class boss_lady_deathwhisper : public CreatureScript
}
};
+typedef boss_lady_deathwhisper::boss_lady_deathwhisperAI DeathwisperAI;
+
class npc_cult_fanatic : public CreatureScript
{
public:
@@ -765,6 +841,126 @@ class npc_vengeful_shade : public CreatureScript
}
};
+class npc_darnavan : public CreatureScript
+{
+ public:
+ npc_darnavan() : CreatureScript("npc_darnavan") { }
+
+ struct npc_darnavanAI : public ScriptedAI
+ {
+ npc_darnavanAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ void Reset()
+ {
+ events.Reset();
+ events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, 10000);
+ events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, urand(20000, 25000));
+ events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, urand(25000, 30000));
+ events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, urand(5000, 8000));
+ canCharge = true;
+ canShatter = true;
+ }
+
+ void JustDied(Unit* killer)
+ {
+ events.Reset();
+ if (Player* owner = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
+ {
+ if (Group* group = owner->GetGroup())
+ {
+ for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ if (Player* member = itr->getSource())
+ member->FailQuest(QUEST_DEPROGRAMMING);
+ }
+ else
+ owner->FailQuest(QUEST_DEPROGRAMMING);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || id != POINT_DESPAWN)
+ return;
+ me->DespawnOrUnsummon();
+ }
+
+ void EnterCombat(Unit* /*victim*/)
+ {
+ Talk(SAY_DARNAVAN_AGGRO);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ if (canShatter && me->getVictim()->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL))
+ {
+ DoCastVictim(SPELL_SHATTERING_THROW);
+ canShatter = false;
+ events.ScheduleEvent(EVENT_DARNAVAN_SHATTERING_THROW, 30000);
+ return;
+ }
+
+ if (canCharge && !me->IsWithinMeleeRange(me->getVictim()))
+ {
+ DoCastVictim(SPELL_CHARGE);
+ canCharge = false;
+ events.ScheduleEvent(EVENT_DARNAVAN_CHARGE, 20000);
+ return;
+ }
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DARNAVAN_BLADESTORM:
+ DoCast(SPELL_BLADESTORM);
+ events.ScheduleEvent(EVENT_DARNAVAN_BLADESTORM, urand(90000, 100000));
+ break;
+ case EVENT_DARNAVAN_CHARGE:
+ canCharge = true;
+ break;
+ case EVENT_DARNAVAN_INTIMIDATING_SHOUT:
+ DoCast(SPELL_INTIMIDATING_SHOUT);
+ events.ScheduleEvent(EVENT_DARNAVAN_INTIMIDATING_SHOUT, urand(90000, 120000));
+ break;
+ case EVENT_DARNAVAN_MORTAL_STRIKE:
+ DoCastVictim(SPELL_MORTAL_STRIKE);
+ events.ScheduleEvent(EVENT_DARNAVAN_MORTAL_STRIKE, urand(15000, 30000));
+ break;
+ case EVENT_DARNAVAN_SHATTERING_THROW:
+ canShatter = true;
+ break;
+ case EVENT_DARNAVAN_SUNDER_ARMOR:
+ DoCastVictim(SPELL_SUNDER_ARMOR);
+ events.ScheduleEvent(EVENT_DARNAVAN_SUNDER_ARMOR, urand(3000, 7000));
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap events;
+ bool canCharge;
+ bool canShatter;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_darnavanAI(creature);
+ }
+};
+
class spell_deathwhisper_mana_barrier : public SpellScriptLoader
{
public:
@@ -809,7 +1005,7 @@ class spell_cultist_dark_martyrdom : public SpellScriptLoader
if (GetCaster()->isSummon())
if (Unit* owner = GetCaster()->ToTempSummon()->GetSummoner())
if (owner->GetEntry() == NPC_LADY_DEATHWHISPER)
- CAST_AI(boss_lady_deathwhisper::boss_lady_deathwhisperAI, owner->ToCreature()->AI())->AddToReanimationQueue(GetCaster());
+ CAST_AI(DeathwisperAI, owner->ToCreature()->AI())->AddToReanimationQueue(GetCaster());
GetCaster()->Kill(GetCaster());
GetCaster()->SetDisplayId(uint32(GetCaster()->GetEntry() == NPC_CULT_FANATIC ? 38009 : 38010));
@@ -833,6 +1029,7 @@ void AddSC_boss_lady_deathwhisper()
new npc_cult_fanatic();
new npc_cult_adherent();
new npc_vengeful_shade();
+ new npc_darnavan();
new spell_deathwhisper_mana_barrier();
new spell_cultist_dark_martyrdom();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index 7a0dfc76fd5..826a3638a2a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -23,10 +23,10 @@
#include "icecrown_citadel.h"
// Weekly quest support
-//* Deprogramming
+//* Deprogramming (DONE)
//* Securing the Ramparts (DONE)
//* Residue Rendezvous
-//* Blood Quickening
+//* Blood Quickening // AreaTrigger 5729 starts the timer, pulling BQ before it runs out means success
//* Respite for a Tormented Soul
enum Texts
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index 5f09434064f..3624e5b916b 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -78,8 +78,6 @@ enum CreaturesIds
// At Light's Hammer
NPC_KOR_KRON_GENERAL = 37189,
NPC_ALLIANCE_COMMANDER = 37190,
- NPC_KOR_KRON_LIEUTENANT = 38491,
- NPC_SKYBREAKER_LIEUTENANT = 38492,
NPC_TORTUNOK = 37992, // Druid Armor H
NPC_ALANA_MOONSTRIKE = 37999, // Druid Armor A
NPC_GERARDO_THE_SUAVE = 37993, // Hunter Armor H
@@ -95,6 +93,14 @@ enum CreaturesIds
NPC_GARROSH_HELLSCREAM = 39372,
NPC_KING_VARIAN_WRYNN = 39371,
+ // Weekly questgivers
+ NPC_INFILTRATOR_MINCHAR = 38471,
+ NPC_KOR_KRON_LIEUTENANT = 38491,
+ NPC_SKYBREAKER_LIEUTENANT = 38492,
+ NPC_ALCHEMIST_ADRIANNA = 38501,
+ NPC_ALRIN_THE_AGILE = 38551,
+ NPC_VALITHRIA_DREAMWALKER_QUEST = 38589,
+
// Lord Marrowgar
NPC_LORD_MARROWGAR = 36612,
NPC_COLDFLAME = 36672,
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index a905fe0dd5f..9d8349c84cb 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -20,6 +20,7 @@
#include "InstanceScript.h"
#include "ScriptedCreature.h"
#include "Map.h"
+#include "PoolMgr.h"
#include "icecrown_citadel.h"
static const DoorData doorData[] =
@@ -47,6 +48,19 @@ static const DoorData doorData[] =
{0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END
};
+struct WeeklyQuest
+{
+ uint32 npcStart;
+ uint32 questId[2]; // 10 and 25 man versions
+} WeeklyQuestData[5] =
+{
+ {NPC_INFILTRATOR_MINCHAR, {24869, 24875}}, // Deprogramming
+ {NPC_KOR_KRON_LIEUTENANT, {24870, 24877}}, // Securing the Ramparts
+ {NPC_ALCHEMIST_ADRIANNA, {24873, 24878}}, // Residue Rendezvous
+ {NPC_ALRIN_THE_AGILE, {24874, 24879}}, // Blood Quickening
+ {NPC_VALITHRIA_DREAMWALKER_QUEST, {24872, 24880}}, // Respite for a Tormented Soul
+};
+
class instance_icecrown_citadel : public InstanceMapScript
{
public:
@@ -201,6 +215,35 @@ class instance_icecrown_citadel : public InstanceMapScript
}
}
+ // Weekly quest spawn prevention
+ uint32 GetCreatureEntry(uint32 /*guidLow*/, CreatureData const* data)
+ {
+ uint32 entry = data->id;
+ switch (entry)
+ {
+ case NPC_INFILTRATOR_MINCHAR:
+ case NPC_KOR_KRON_LIEUTENANT:
+ case NPC_ALCHEMIST_ADRIANNA:
+ case NPC_ALRIN_THE_AGILE:
+ case NPC_VALITHRIA_DREAMWALKER_QUEST:
+ {
+ uint8 questIndex = 0;
+ for (; questIndex < 5; ++questIndex)
+ if (WeeklyQuestData[questIndex].npcStart == entry)
+ break;
+
+ uint8 diffIndex = instance->GetSpawnMode() & 1;
+ if (!sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[questIndex].questId[diffIndex]))
+ entry = 0;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return entry;
+ }
+
void OnCreatureRemove(Creature* creature)
{
if (creature->GetEntry() == NPC_FROST_FREEZE_TRAP)
@@ -704,19 +747,19 @@ class instance_icecrown_citadel : public InstanceMapScript
return saveStream.str();
}
- void Load(const char* in)
+ void Load(const char* str)
{
- if (!in)
+ if (!str)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
- OUT_LOAD_INST_DATA(in);
+ OUT_LOAD_INST_DATA(str);
char dataHead1, dataHead2;
- std::istringstream loadStream(in);
+ std::istringstream loadStream(str);
loadStream >> dataHead1 >> dataHead2;
if (dataHead1 == 'I' && dataHead2 == 'C')
@@ -729,11 +772,10 @@ class instance_icecrown_citadel : public InstanceMapScript
tmpState = NOT_STARTED;
SetBossState(i, EncounterState(tmpState));
}
+
uint32 jets = 0;
loadStream >> jets;
- if (jets)
- jets = DONE;
- coldflameJetsState = jets;
+ coldflameJetsState = jets ? DONE : NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;