diff options
author | Shauren <shauren.trinity@gmail.com> | 2011-02-18 19:48:47 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2011-02-18 19:48:47 +0100 |
commit | 0f34df6e1a5c2272a3a1841978bcb8dfea073449 (patch) | |
tree | b58c2384c53871b08f88ba2db77f54289fabc0cf | |
parent | 6a64c79d2aa169f6d6d385948af3f6737f274133 (diff) |
Scripts/Icecrown Citadel: Added support for weekly quest "Deprogramming"
13 files changed, 363 insertions, 78 deletions
diff --git a/sql/base/world_database.sql b/sql/base/world_database.sql index 21f4032ecab..16cb1292292 100644 --- a/sql/base/world_database.sql +++ b/sql/base/world_database.sql @@ -18151,6 +18151,7 @@ INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment ( 67623,-67620, 1, 'Remove Paralytic Toxin when hit by Burning Bite'), (-66683, 68667, 0, 'Icehowl - Surge of Adrenaline'), (-67661, 68667, 0, 'Icehowl - Surge of Adrenaline'), +( 65940, 65941, 0, 'Trial of the Crusader: Shattering Throw'), -- Forge of Souls (-68839, 68846, 0, 'Bronjahm: Corrupt Soul Summon'), -- Icecrown Citadel diff --git a/sql/scripts/world_scripts_full.sql b/sql/scripts/world_scripts_full.sql index 70e87e635ce..2b5dce0e3de 100644 --- a/sql/scripts/world_scripts_full.sql +++ b/sql/scripts/world_scripts_full.sql @@ -843,6 +843,7 @@ UPDATE `creature_template` SET `ScriptName`='boss_lady_deathwhisper' WHERE `entr UPDATE `creature_template` SET `ScriptName`='npc_cult_fanatic' WHERE `entry` IN (37890,38009,38135); UPDATE `creature_template` SET `ScriptName`='npc_cult_adherent' WHERE `entry` IN(37949,38010,38136); UPDATE `creature_template` SET `ScriptName`='npc_vengeful_shade' WHERE `entry`=38222; +UPDATE `creature_template` SET `ScriptName`='npc_darnavan' WHERE `entry` IN (38472,38485); UPDATE `creature_template` SET `ScriptName`='npc_rotting_frost_giant' WHERE `entry` IN (38490,38494); UPDATE `creature_template` SET `ScriptName`='boss_deathbringer_saurfang' WHERE `entry`=37813; UPDATE `creature_template` SET `ScriptName`='npc_high_overlord_saurfang_icc' WHERE `entry`=37187; diff --git a/sql/updates/world/2011_02_18_0_world_creature.sql b/sql/updates/world/2011_02_18_0_world_creature.sql new file mode 100644 index 00000000000..4f07781a267 --- /dev/null +++ b/sql/updates/world/2011_02_18_0_world_creature.sql @@ -0,0 +1,6 @@ +SET @GUID := 137743; +DELETE FROM `creature` WHERE `id` IN (38471,38501,38551); +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`DeathState`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES +(@GUID+0,38471,631,15,1,0,0,-504.949,2184.24,62.3048,0.450047,86400,0,0,0,0,0,0,0,0,0), +(@GUID+1,38501,631,15,1,0,0,4247.040,2753.25,348.996,0.227759,86400,0,0,0,0,0,0,0,0,0), +(@GUID+2,38551,631,15,1,0,0,4466.260,2787.99,348.954,3.349720,86400,0,0,0,0,0,0,0,0,0); diff --git a/sql/updates/world/2011_02_18_0_world_creature_text.sql b/sql/updates/world/2011_02_18_0_world_creature_text.sql new file mode 100644 index 00000000000..39d46f15fef --- /dev/null +++ b/sql/updates/world/2011_02_18_0_world_creature_text.sql @@ -0,0 +1,6 @@ +DELETE FROM `creature_text` WHERE `entry` IN (38472,38485); +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(38472,0,0, 'Die, intruders! None shall interfere with the Cult''s plans!',1,0,0,0,0,0, 'Darnavan - SAY_DARNAVAN_AGGRO'), +(38472,1,0, 'Wh- where am I...? What a nightmare I have had... But this is no time to reflect, I have much information to report!',0,0,0,0,0,0, 'Darnavan - SAY_DARNAVAN_RESCUED'), +(38485,0,0, 'Die, intruders! None shall interfere with the Cult''s plans!',1,0,0,0,0,0, 'Darnavan - SAY_DARNAVAN_AGGRO'), +(38485,1,0, 'Wh- where am I...? What a nightmare I have had... But this is no time to reflect, I have much information to report!',0,0,0,0,0,0, 'Darnavan - SAY_DARNAVAN_RESCUED'); diff --git a/sql/updates/world/2011_02_18_0_world_pool_quest.sql b/sql/updates/world/2011_02_18_0_world_pool_quest.sql new file mode 100644 index 00000000000..0ea5d42026e --- /dev/null +++ b/sql/updates/world/2011_02_18_0_world_pool_quest.sql @@ -0,0 +1,28 @@ +-- ICC Quest pools (also deletes old pool data) +SET @pool := 5662; +DELETE FROM `pool_quest` WHERE `pool_entry` BETWEEN @pool+18 AND @pool+22; +INSERT INTO `pool_quest` (`entry`,`pool_entry`,`description`) VALUES +(24874,@pool+17, 'Blood Quickening (10)'), +(24869,@pool+17, 'Deprogramming (10)'), +(24873,@pool+17, 'Residue Rendezvous (10)'), +(24872,@pool+17, 'Respite for a Tormented Soul (10)'), +(24870,@pool+19, 'Securing the Ramparts HORDE (10)'), +(24871,@pool+19, 'Securing the Ramparts ALLY (10)'), +(24879,@pool+18, 'Blood Quickening (25)'), +(24875,@pool+18, 'Deprogramming (25)'), +(24878,@pool+18, 'Residue Rendezvous (25)'), +(24880,@pool+18, 'Respite for a Tormented Soul (25)'), +(24876,@pool+20, 'Securing the Ramparts ALLY (25)'), +(24877,@pool+20, 'Securing the Ramparts HORDE (25)'); + +DELETE FROM `pool_template` WHERE `entry` BETWEEN @pool+18 AND @pool+22; +INSERT INTO `pool_template` (`entry`,`max_limit`,`description`) VALUES +(@pool+17,1, 'ICC weeklies (10)'), +(@pool+18,1, 'ICC weeklies (25)'), +(@pool+19,2, 'Securing the Ramparts (10)'), +(@pool+20,2, 'Securing the Ramparts (25)'); + +DELETE FROM `pool_pool` WHERE `mother_pool` IN (@pool+17,@pool+18); +INSERT INTO `pool_pool` (`pool_id`,`mother_pool`,`chance`,`description`) VALUES +(@pool+19,@pool+17,0, 'Securing the Ramparts (10)'), +(@pool+20,@pool+18,0, 'Securing the Ramparts (25)'); diff --git a/sql/updates/world/2011_02_18_0_world_scriptname.sql b/sql/updates/world/2011_02_18_0_world_scriptname.sql new file mode 100644 index 00000000000..3588fe7ae3b --- /dev/null +++ b/sql/updates/world/2011_02_18_0_world_scriptname.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `ScriptName`='npc_darnavan' WHERE `entry` IN (38472,38485); diff --git a/sql/updates/world/2011_02_18_0_world_spell_linked_spell.sql b/sql/updates/world/2011_02_18_0_world_spell_linked_spell.sql new file mode 100644 index 00000000000..66ceb1b593c --- /dev/null +++ b/sql/updates/world/2011_02_18_0_world_spell_linked_spell.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=65940; +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(65940,65941,0, 'Trial of the Crusader: Shattering Throw'); 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; |