diff options
author | Vincent-Michael <Vincent_Michael@gmx.de> | 2013-08-06 20:25:36 +0200 |
---|---|---|
committer | Vincent-Michael <Vincent_Michael@gmx.de> | 2013-08-06 20:25:36 +0200 |
commit | 5af90560500dc678662e453471254e03ddb17c95 (patch) | |
tree | 61666c6b5298d26c85865ad9a09baba44aedf211 /src | |
parent | a090c82fb759add3c97c458821d7c0df8cffcfd0 (diff) | |
parent | 75b4b0594f34fb29318ae78725178c54486cf135 (diff) |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Diffstat (limited to 'src')
14 files changed, 1335 insertions, 306 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 86c246ff387..0c80945e357 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -897,13 +897,19 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } case SMART_ACTION_CALL_KILLEDMONSTER: { - Player* player = NULL; - if (me) - player = me->GetLootRecipient(); + if (e.target.type == SMART_TARGET_NONE) // Loot recipient and his group members + { + if (!me) + break; - if (me && player) - player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); - else if (GetBaseObject()) + if (Player* player = me->GetLootRecipient()) + { + player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); + TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", + player->GetGUIDLow(), e.action.killedMonster.creature); + } + } + else // Specific target type { ObjectList* targets = GetTargets(e, unit); if (!targets) @@ -911,29 +917,21 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - // Special handling for vehicles - if (IsUnit(*itr)) + if (IsPlayer(*itr)) + { + (*itr)->ToPlayer()->KilledMonsterCredit(e.action.killedMonster.creature); + TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", + (*itr)->GetGUIDLow(), e.action.killedMonster.creature); + } + else if (IsUnit(*itr)) // Special handling for vehicles if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit()) - for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it) - if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger.Guid)) - player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); - - if (!IsPlayer(*itr)) - continue; - - (*itr)->ToPlayer()->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, (*itr)->ToPlayer()); - TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", - (*itr)->GetGUIDLow(), e.action.killedMonster.creature); + for (SeatMap::iterator itr = vehicle->Seats.begin(); itr != vehicle->Seats.end(); ++itr) + if (Player* player = ObjectAccessor::FindPlayer(itr->second.Passenger.Guid)) + player->KilledMonsterCredit(e.action.killedMonster.creature); } delete targets; } - else if (trigger && IsPlayer(unit)) - { - unit->ToPlayer()->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, unit); - TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: (trigger == true) Player %u, Killcredit: %u", - unit->GetGUIDLow(), e.action.killedMonster.creature); - } break; } case SMART_ACTION_SET_INST_DATA: @@ -1300,10 +1298,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - if (!IsPlayer(*itr)) - continue; - - (*itr)->ToPlayer()->TeleportTo(e.action.teleport.mapID, e.target.x, e.target.y, e.target.z, e.target.o); + if (IsPlayer(*itr)) + (*itr)->ToPlayer()->TeleportTo(e.action.teleport.mapID, e.target.x, e.target.y, e.target.z, e.target.o); + else if (IsCreature(*itr)) + (*itr)->ToCreature()->NearTeleportTo(e.target.x, e.target.y, e.target.z, e.target.o); } delete targets; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 8fe67f7b384..3c6be82c28b 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -761,6 +761,11 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_CALL_KILLEDMONSTER: if (!IsCreatureValid(e, e.action.killedMonster.creature)) return false; + if (e.GetTargetType() == SMART_TARGET_POSITION) + { + TC_LOG_ERROR(LOG_FILTER_SQL, "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses incorrect TargetType %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType()); + return false; + } break; case SMART_ACTION_UPDATE_TEMPLATE: if (e.action.updateTemplate.creature && !IsCreatureValid(e, e.action.updateTemplate.creature)) diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index e52f08caa3b..0a8d5075cc9 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -29,6 +29,17 @@ class Group; class Player; class WorldPacket; class BattlegroundMap; +class BattlegroundAV; +class BattlegroundWS; +class BattlegroundAB; +class BattlegroundNA; +class BattlegroundBE; +class BattlegroundEY; +class BattlegroundRL; +class BattlegroundSA; +class BattlegroundDS; +class BattlegroundRV; +class BattlegroundIC; struct PvPDifficultyEntry; struct WorldSafeLocsEntry; @@ -539,6 +550,39 @@ class Battleground virtual uint32 GetPrematureWinner(); + BattlegroundAV* ToBattlegroundAV() { if (GetTypeID() == BATTLEGROUND_AV) return reinterpret_cast<BattlegroundAV*>(this); else return NULL; } + BattlegroundAV const* ToBattlegroundAV() const { if (GetTypeID() == BATTLEGROUND_AV) return reinterpret_cast<const BattlegroundAV*>(this); else return NULL; } + + BattlegroundWS* ToBattlegroundWS() { if (GetTypeID() == BATTLEGROUND_WS) return reinterpret_cast<BattlegroundWS*>(this); else return NULL; } + BattlegroundWS const* ToBattlegroundWS() const { if (GetTypeID() == BATTLEGROUND_WS) return reinterpret_cast<const BattlegroundWS*>(this); else return NULL; } + + BattlegroundAB* ToBattlegroundAB() { if (GetTypeID() == BATTLEGROUND_AB) return reinterpret_cast<BattlegroundAB*>(this); else return NULL; } + BattlegroundAB const* ToBattlegroundAB() const { if (GetTypeID() == BATTLEGROUND_AB) return reinterpret_cast<const BattlegroundAB*>(this); else return NULL; } + + BattlegroundNA* ToBattlegroundNA() { if (GetTypeID() == BATTLEGROUND_NA) return reinterpret_cast<BattlegroundNA*>(this); else return NULL; } + BattlegroundNA const* ToBattlegroundNA() const { if (GetTypeID() == BATTLEGROUND_NA) return reinterpret_cast<const BattlegroundNA*>(this); else return NULL; } + + BattlegroundBE* ToBattlegroundBE() { if (GetTypeID() == BATTLEGROUND_BE) return reinterpret_cast<BattlegroundBE*>(this); else return NULL; } + BattlegroundBE const* ToBattlegroundBE() const { if (GetTypeID() == BATTLEGROUND_BE) return reinterpret_cast<const BattlegroundBE*>(this); else return NULL; } + + BattlegroundEY* ToBattlegroundEY() { if (GetTypeID() == BATTLEGROUND_EY) return reinterpret_cast<BattlegroundEY*>(this); else return NULL; } + BattlegroundEY const* ToBattlegroundEY() const { if (GetTypeID() == BATTLEGROUND_EY) return reinterpret_cast<const BattlegroundEY*>(this); else return NULL; } + + BattlegroundRL* ToBattlegroundRL() { if (GetTypeID() == BATTLEGROUND_RL) return reinterpret_cast<BattlegroundRL*>(this); else return NULL; } + BattlegroundRL const* ToBattlegroundRL() const { if (GetTypeID() == BATTLEGROUND_RL) return reinterpret_cast<const BattlegroundRL*>(this); else return NULL; } + + BattlegroundSA* ToBattlegroundSA() { if (GetTypeID() == BATTLEGROUND_SA) return reinterpret_cast<BattlegroundSA*>(this); else return NULL; } + BattlegroundSA const* ToBattlegroundSA() const { if (GetTypeID() == BATTLEGROUND_SA) return reinterpret_cast<const BattlegroundSA*>(this); else return NULL; } + + BattlegroundDS* ToBattlegroundDS() { if (GetTypeID() == BATTLEGROUND_DS) return reinterpret_cast<BattlegroundDS*>(this); else return NULL; } + BattlegroundDS const* ToBattlegroundDS() const { if (GetTypeID() == BATTLEGROUND_DS) return reinterpret_cast<const BattlegroundDS*>(this); else return NULL; } + + BattlegroundRV* ToBattlegroundRV() { if (GetTypeID() == BATTLEGROUND_RV) return reinterpret_cast<BattlegroundRV*>(this); else return NULL; } + BattlegroundRV const* ToBattlegroundRV() const { if (GetTypeID() == BATTLEGROUND_RV) return reinterpret_cast<const BattlegroundRV*>(this); else return NULL; } + + BattlegroundIC* ToBattlegroundIC() { if (GetTypeID() == BATTLEGROUND_IC) return reinterpret_cast<BattlegroundIC*>(this); else return NULL; } + BattlegroundIC const* ToBattlegroundIC() const { if (GetTypeID() == BATTLEGROUND_IC) return reinterpret_cast<const BattlegroundIC*>(this); else return NULL; } + protected: // this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends Battleground void EndNow(); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index 0b32072d583..7e0034eca6e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -326,11 +326,27 @@ void BattlegroundIC::RemovePlayer(Player* player, uint64 /*guid*/, uint32 /*team } } -void BattlegroundIC::HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) +void BattlegroundIC::HandleAreaTrigger(Player* player, uint32 trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; + + /// @hack: this spell should be cast by npc 22515 (World Trigger) and not by the player + if (trigger == 5555 && player->GetTeamId() == TEAM_HORDE) + { + if (GateStatus[BG_IC_A_FRONT] != BG_IC_GATE_DESTROYED + && GateStatus[BG_IC_A_WEST] != BG_IC_GATE_DESTROYED + && GateStatus[BG_IC_A_EAST] != BG_IC_GATE_DESTROYED) + player->CastSpell(player, SPELL_BACK_DOOR_JOB_ACHIEVEMENT, true); + } + else if (trigger == 5535 && player->GetTeamId() == TEAM_ALLIANCE) + { + if (GateStatus[BG_IC_H_FRONT] != BG_IC_GATE_DESTROYED + && GateStatus[BG_IC_H_WEST] != BG_IC_GATE_DESTROYED + && GateStatus[BG_IC_H_EAST] != BG_IC_GATE_DESTROYED) + player->CastSpell(player, SPELL_BACK_DOOR_JOB_ACHIEVEMENT, true); + } } void BattlegroundIC::UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h index f25fbe297b3..e8249dc777a 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h @@ -661,6 +661,7 @@ enum Spells SPELL_PARACHUTE = 66656, SPELL_SLOW_FALL = 12438, SPELL_DESTROYED_VEHICLE_ACHIEVEMENT = 68357, + SPELL_BACK_DOOR_JOB_ACHIEVEMENT = 68502, SPELL_DRIVING_CREDIT_DEMOLISHER = 68365, SPELL_DRIVING_CREDIT_GLAIVE = 68363, SPELL_DRIVING_CREDIT_SIEGE = 68364, diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 3704530589e..9aaf45737ce 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -953,7 +953,7 @@ bool GameObject::ActivateToQuest(Player* target) const //look for battlegroundAV for some objects which are only activated after mine gots captured by own team if (GetEntry() == BG_AV_OBJECTID_MINE_N || GetEntry() == BG_AV_OBJECTID_MINE_S) if (Battleground* bg = target->GetBattleground()) - if (bg->GetTypeID(true) == BATTLEGROUND_AV && !(((BattlegroundAV*)bg)->PlayerCanDoMineQuest(GetEntry(), target->GetTeam()))) + if (bg->GetTypeID(true) == BATTLEGROUND_AV && !bg->ToBattlegroundAV()->PlayerCanDoMineQuest(GetEntry(), target->GetTeam())) return false; return true; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5653c738c4d..f8390cecbe9 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -9006,13 +9006,19 @@ void Player::SendLoot(uint64 guid, LootType loot_type) /// @todo fix this big hack if ((go->GetEntry() == BG_AV_OBJECTID_MINE_N || go->GetEntry() == BG_AV_OBJECTID_MINE_S)) + { if (Battleground* bg = GetBattleground()) + { if (bg->GetTypeID(true) == BATTLEGROUND_AV) - if (!(((BattlegroundAV*)bg)->PlayerCanDoMineQuest(go->GetEntry(), GetTeam()))) + { + if (!bg->ToBattlegroundAV()->PlayerCanDoMineQuest(go->GetEntry(), GetTeam())) { SendLootRelease(guid); return; } + } + } + } if (lootid) { @@ -16280,7 +16286,7 @@ void Player::KilledMonster(CreatureTemplate const* cInfo, uint64 guid) KilledMonsterCredit(cInfo->KillCredit[i], 0); } -void Player::KilledMonsterCredit(uint32 entry, uint64 guid) +void Player::KilledMonsterCredit(uint32 entry, uint64 guid /*= 0*/) { uint16 addkillcount = 1; uint32 real_entry = entry; @@ -23279,6 +23285,11 @@ void Player::ApplyEquipCooldown(Item* pItem) if (spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) continue; + // Don't replace longer cooldowns by equip cooldown if we have any. + SpellCooldowns::iterator itr = m_spellCooldowns.find(spellData.SpellId); + if (itr != m_spellCooldowns.end() && itr->second.itemid == pItem->GetEntry() && itr->second.end > time(NULL) + 30) + continue; + AddSpellCooldown(spellData.SpellId, pItem->GetEntry(), time(NULL) + 30); WorldPacket data(SMSG_ITEM_COOLDOWN, 12); diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 31adc0ac72c..c7bc141dd7f 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -553,7 +553,7 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) if (_player->InBattleground()) if (Battleground* bg = _player->GetBattleground()) if (bg->GetTypeID() == BATTLEGROUND_AV) - ((BattlegroundAV*)bg)->HandleQuestComplete(questId, _player); + bg->ToBattlegroundAV()->HandleQuestComplete(questId, _player); if (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE) { diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index fb0f6d0c461..56330c503de 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -820,6 +820,8 @@ void Map::MoveAllCreaturesInMoveList() { // update pos c->Relocate(c->_newPosition); + if (c->IsVehicle()) + c->GetVehicleKit()->RelocatePassengers(); //CreatureRelocationNotify(c, new_cell, new_cell.cellCoord()); c->UpdateObjectVisibility(false); } diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 95e25e2b03a..5643b7d8449 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1124,7 +1124,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 uint8 nodeType = spellId == 68719 ? NODE_TYPE_REFINERY : NODE_TYPE_QUARRY; uint8 nodeState = player->GetTeamId() == TEAM_ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H; - BattlegroundIC* pIC = static_cast<BattlegroundIC*>(player->GetBattleground()); + BattlegroundIC* pIC = player->GetBattleground()->ToBattlegroundIC(); if (pIC->GetNodeState(nodeType) == nodeState) return true; diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index e291ee0de70..7fddfd861c2 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -36,6 +36,17 @@ enum Text SAY_JAINA_INTRO_11 = 10, SAY_JAINA_INTRO_END = 11, + SAY_JAINA_ESCAPE_1 = 0, + SAY_JAINA_ESCAPE_2 = 1, + SAY_JAINA_ESCAPE_3 = 2, + SAY_JAINA_ESCAPE_4 = 3, + SAY_JAINA_ESCAPE_5 = 4, + SAY_JAINA_ESCAPE_6 = 5, + SAY_JAINA_ESCAPE_7 = 6, + SAY_JAINA_ESCAPE_8 = 7, + SAY_JAINA_ESCAPE_9 = 8, + SAY_JAINA_ESCAPE_10 = 9, + SAY_SYLVANAS_INTRO_1 = 0, SAY_SYLVANAS_INTRO_2 = 1, SAY_SYLVANAS_INTRO_3 = 2, @@ -46,6 +57,16 @@ enum Text SAY_SYLVANAS_INTRO_8 = 7, SAY_SYLVANAS_INTRO_END = 8, + SAY_SYLVANAS_ESCAPE_1 = 0, + SAY_SYLVANAS_ESCAPE_2 = 1, + SAY_SYLVANAS_ESCAPE_3 = 2, + SAY_SYLVANAS_ESCAPE_4 = 3, + SAY_SYLVANAS_ESCAPE_5 = 4, + SAY_SYLVANAS_ESCAPE_6 = 5, + SAY_SYLVANAS_ESCAPE_7 = 6, + SAY_SYLVANAS_ESCAPE_8 = 7, + SAY_SYLVANAS_ESCAPE_9 = 8, + SAY_UTHER_INTRO_A2_1 = 0, SAY_UTHER_INTRO_A2_2 = 1, SAY_UTHER_INTRO_A2_3 = 2, @@ -69,6 +90,18 @@ enum Text SAY_LK_JAINA_INTRO_END = 3, SAY_LK_SYLVANAS_INTRO_END = 4, + SAY_LK_ESCAPE_1 = 0, + SAY_LK_ESCAPE_2 = 1, + SAY_LK_ESCAPE_3 = 2, + SAY_LK_ESCAPE_4 = 3, + SAY_LK_ESCAPE_5 = 4, + SAY_LK_ESCAPE_6 = 5, + SAY_LK_ESCAPE_7 = 6, + SAY_LK_ESCAPE_8 = 7, + SAY_LK_ESCAPE_9 = 8, + SAY_LK_ESCAPE_10 = 9, + SAY_LK_ESCAPE_11 = 10, + SAY_FALRIC_INTRO_1 = 5, SAY_FALRIC_INTRO_2 = 6, @@ -132,11 +165,40 @@ enum Events EVENT_INTRO_END, + EVENT_ESCAPE, + EVENT_ESCAPE_1, + EVENT_ESCAPE_2, + EVENT_ESCAPE_3, + EVENT_ESCAPE_4, + EVENT_ESCAPE_5, + EVENT_ESCAPE_6, + EVENT_ESCAPE_7, + EVENT_ESCAPE_8, + EVENT_ESCAPE_9, + EVENT_ESCAPE_10, + EVENT_ESCAPE_11, + EVENT_ESCAPE_12, + EVENT_ESCAPE_13, + EVENT_ESCAPE_14, + EVENT_ESCAPE_15, + EVENT_ESCAPE_16, + EVENT_ESCAPE_17, + EVENT_ESCAPE_18, + EVENT_ESCAPE_19, + EVENT_ESCAPE_20, + EVENT_ESCAPE_21, + EVENT_ESCAPE_22, + EVENT_ESCAPE_23, + EVENT_ESCAPE_24, + EVENT_ESCAPE_25, + EVENT_ESCAPE_26, + EVENT_ESCAPE_27, + EVENT_OPEN_FROSTWORN_DOOR, EVENT_CLOSE_FROSTWORN_DOOR, }; -enum Misc +enum Enum { ACTION_START_INTRO, ACTION_SKIP_INTRO, @@ -156,21 +218,79 @@ enum Spells SPELL_FROSTMOURNE_DESPAWN = 72726, SPELL_FROSTMOURNE_VISUAL = 73220, SPELL_FROSTMOURNE_SOUNDS = 70667, + SPELL_JAINA_ICEBARRIER = 69787, // Jaina Ice Barrier + SPELL_JAINA_ICEPRISON = 69708, // Jaina Ice Prison + SPELL_SYLVANAS_CLOAKOFDARKNESS = 70188, // Sylvanas Cloak of Darkness + SPELL_SYLVANAS_DARKBINDING = 70194, // Sylvanas Dark Binding + SPELL_REMORSELESS_WINTER = 69780, // Lich King Remorseless Winter + SPELL_SOUL_REAPER = 69409, // Lich King Soul Reaper + SPELL_FURY_OF_FROSTMOURNE = 70063, // Lich King Fury of FrostMourne + SPELL_JAINA_DESTROY_ICE_WALL = 69784, // Jaina + SPELL_SYLVANAS_DESTROY_ICE_WALL = 70225, // Sylvanas + SPELL_SYLVANAS_JUMP = 68339, // Sylvanas Jump + SPELL_RAISE_DEAD = 69818, + SPELL_HARVEST_SOUL = 70070, + SPELL_SUMMON_RISE_WITCH_DOCTOR = 69836, + SPELL_SUMMON_LUMBERING_ABOMINATION = 69835, + SPELL_SUMMON_ICE_WALL = 69768, // Visual effect and icewall summoning + + //Raging gnoul + SPELL_EMERGE_VISUAL = 50142, + SPELL_GHOUL_JUMP = 70150, + + //Witch Doctor + SPELL_COURSE_OF_DOOM = 70144, + SPELL_SHADOW_BOLT_VOLLEY = 70145, + SPELL_SHADOW_BOLT = 70080, + + //Lumbering Abomination + SPELL_ABON_STRIKE = 40505, + SPELL_VOMIT_SPRAY = 70176, }; -const Position HallsofReflectionLocs[]= +const Position HallsofReflectionLocs[] = { {5283.234863f, 1990.946777f, 707.695679f, 0.929097f}, // 2 Loralen Follows {5408.031250f, 2102.918213f, 707.695251f, 0.792756f}, // 9 Sylvanas Follows {5401.866699f, 2110.837402f, 707.695251f, 0.800610f}, // 10 Loralen follows }; -const Position IntroPos = {5265.89f, 1952.98f, 707.6978f, 0.0f}; // Jaina/Sylvanas Intro Start Position -const Position MoveThronePos = {5306.952148f, 1998.499023f, 709.341431f, 1.277278f}; // Jaina/Sylvanas walks to throne -const Position UtherSpawnPos = {5308.310059f, 2003.857178f, 709.341431f, 4.650315f}; -const Position LichKingSpawnPos = {5362.917480f, 2062.307129f, 707.695374f, 3.945812f}; -const Position LichKingMoveThronePos = {5312.080566f, 2009.172119f, 709.341431f, 3.973301f}; // Lich King walks to throne -const Position LichKingMoveAwayPos = {5400.069824f, 2102.7131689f, 707.69525f, 0.843803f}; // Lich King walks away +const Position NpcJainaOrSylvanasEscapeRoute[] = +{ + {5601.217285f, 2207.652832f, 731.541931f, 5.223304f}, // leave the throne room + {5607.224375f, 2173.913330f, 731.126038f, 2.608723f}, // adjust route + {5583.427246f, 2138.784180f, 731.150391f, 4.260901f}, // stop for talking + {5560.281738f, 2104.025635f, 731.410889f, 4.058383f}, // attack the first icewall + {5510.990723f, 2000.772217f, 734.716064f, 3.973213f}, // attack the second icewall + {5452.641113f, 1905.762329f, 746.530579f, 4.118834f}, // attack the third icewall + {5338.126953f, 1768.429810f, 767.237244f, 3.855189f}, // attack the fourth icewall + {5257.712402f, 1669.379395f, 784.300110f, 0.908373f}, // face the Lich king + {5261.191895f, 1681.901611f, 784.285278f, 4.410465f}, // final position +}; + +const Position IceWalls[] = +{ + {5547.833f, 2083.701f,731.4332f,4.24115f}, // first icewall + {5503.213f, 1969.547f,737.0245f,4.293779f},// second icewall + {5439.976f, 1879.005f,752.7048f,4.207591f},// third icewall + {5318.289f, 1749.184f,771.9423f,4.054276f},// fourth icewall +}; + +const Position IntroPos = {5265.89f, 1952.98f, 707.6978f, 0.0f}; // Jaina/Sylvanas Intro Start Position +const Position MoveThronePos = {5306.952148f, 1998.499023f, 709.341431f, 1.277278f}; // Jaina/Sylvanas walks to throne +const Position UtherSpawnPos = {5308.310059f, 2003.857178f, 709.341431f, 4.650315f}; +const Position LichKingSpawnPos = {5362.917480f, 2062.307129f, 707.695374f, 3.945812f}; +const Position LichKingMoveThronePos = {5312.080566f, 2009.172119f, 709.341431f, 3.973301f}; // Lich King walks to throne +const Position LichKingMoveAwayPos = {5400.069824f, 2102.7131689f, 707.69525f, 0.843803f}; // Lich King walks away +const Position LichKingSpawnPos2 = {5552.733398f, 2262.718506f, 733.011047f, 4.009696f}; // Lich King Spawn Position 2 +const Position LichKingFirstSummon = {5600.076172f, 2192.270996f, 731.750488f, 4.330935f}; // Lich King First summons +const Position JainaShadowThroneDoor = {5577.243f, 2235.852f, 733.0128f, 2.209562f}; // Jaina Spawn Position 2 +const Position SylvanasShadowThroneDoor = {5577.243f, 2235.852f, 733.0128f, 2.209562f}; // Sylvanas Spawn Position 2 +const Position FalricStartPos = {5283.878906f, 2030.459595f, 709.319641f, 5.506670f}; // Falric start position +const Position MarwynStartPos = {5334.979980f, 1982.399536f, 709.320129f, 2.347014f}; // Marwyn start position +const Position LichKingFinalPos = {5283.742188f, 1706.335693f, 783.293518f, 4.138510f}; // Lich King Final Pos +const Position ChestPos = {5246.187500f, 1649.079468f, 784.301758f, 0.901268f}; // Chest position +const Position FinalPortalPos = {5270.634277f ,1639.101196f, 784.303040f, 1.682743f}; // Final portal position class npc_jaina_or_sylvanas_hor : public CreatureScript { @@ -182,14 +302,14 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript { npc_jaina_or_sylvanas_horAI(Creature* creature) : ScriptedAI(creature) { - instance = me->GetInstanceScript(); + _instance = me->GetInstanceScript(); } - InstanceScript* instance; - uint64 utherGUID; - uint64 lichkingGUID; + InstanceScript* _instance; + uint64 _utherGUID; + uint64 _lichkingGUID; - EventMap events; + EventMap _events; void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) OVERRIDE { @@ -198,12 +318,12 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript { case 0: player->CLOSE_GOSSIP_MENU(); - events.ScheduleEvent(EVENT_START_INTRO, 1000); + _events.ScheduleEvent(EVENT_START_INTRO, 1000); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); break; case 1: player->CLOSE_GOSSIP_MENU(); - events.ScheduleEvent(EVENT_SKIP_INTRO, 1000); + _events.ScheduleEvent(EVENT_SKIP_INTRO, 1000); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); break; } @@ -211,36 +331,36 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript void Reset() OVERRIDE { - events.Reset(); + _events.Reset(); - utherGUID = 0; - lichkingGUID = 0; + _utherGUID = 0; + _lichkingGUID = 0; me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); me->SetStandState(UNIT_STAND_STATE_STAND); - events.ScheduleEvent(EVENT_WALK_INTRO1, 3000); + _events.ScheduleEvent(EVENT_WALK_INTRO1, 3000); } void UpdateAI(uint32 diff) OVERRIDE { - events.Update(diff); - switch (events.ExecuteEvent()) + _events.Update(diff); + switch (_events.ExecuteEvent()) { case EVENT_WALK_INTRO1: me->GetMotionMaster()->MovePoint(0, IntroPos); - if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) { Talk(SAY_JAINA_INTRO_1); - events.ScheduleEvent(EVENT_WALK_INTRO2, 7000); + _events.ScheduleEvent(EVENT_WALK_INTRO2, 7000); } else { Talk(SAY_SYLVANAS_INTRO_1); - events.ScheduleEvent(EVENT_WALK_INTRO2, 9000); + _events.ScheduleEvent(EVENT_WALK_INTRO2, 9000); } break; case EVENT_WALK_INTRO2: - if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) Talk(SAY_JAINA_INTRO_2); else Talk(SAY_SYLVANAS_INTRO_2); @@ -249,182 +369,182 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript case EVENT_START_INTRO: me->GetMotionMaster()->MovePoint(0, MoveThronePos); // Begining of intro is differents between fActions as the speech sequence and timers are differents. - if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - events.ScheduleEvent(EVENT_INTRO_A2_1, 0); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + _events.ScheduleEvent(EVENT_INTRO_A2_1, 0); else - events.ScheduleEvent(EVENT_INTRO_H2_1, 0); + _events.ScheduleEvent(EVENT_INTRO_H2_1, 0); break; // A2 Intro Events case EVENT_INTRO_A2_1: Talk(SAY_JAINA_INTRO_3); - events.ScheduleEvent(EVENT_INTRO_A2_2, 7000); + _events.ScheduleEvent(EVENT_INTRO_A2_2, 7000); break; case EVENT_INTRO_A2_2: Talk(SAY_JAINA_INTRO_4); - events.ScheduleEvent(EVENT_INTRO_A2_3, 10000); + _events.ScheduleEvent(EVENT_INTRO_A2_3, 10000); break; case EVENT_INTRO_A2_3: me->CastSpell(me, SPELL_CAST_VISUAL, false); me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true); - instance->HandleGameObject(instance->GetData64(DATA_FROSTMOURNE), true); - events.ScheduleEvent(EVENT_INTRO_A2_4, 10000); + _instance->HandleGameObject(_instance->GetData64(DATA_FROSTMOURNE), true); + _events.ScheduleEvent(EVENT_INTRO_A2_4, 10000); break; case EVENT_INTRO_A2_4: if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) { uther->GetMotionMaster()->MoveIdle(); - utherGUID = uther->GetGUID(); + _utherGUID = uther->GetGUID(); } - events.ScheduleEvent(EVENT_INTRO_A2_5, 2000); + _events.ScheduleEvent(EVENT_INTRO_A2_5, 2000); break; case EVENT_INTRO_A2_5: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_1); - events.ScheduleEvent(EVENT_INTRO_A2_6, 3000); + _events.ScheduleEvent(EVENT_INTRO_A2_6, 3000); break; case EVENT_INTRO_A2_6: Talk(SAY_JAINA_INTRO_5); - events.ScheduleEvent(EVENT_INTRO_A2_7, 7000); + _events.ScheduleEvent(EVENT_INTRO_A2_7, 7000); break; case EVENT_INTRO_A2_7: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_2); - events.ScheduleEvent(EVENT_INTRO_A2_8, 7000); + _events.ScheduleEvent(EVENT_INTRO_A2_8, 7000); break; case EVENT_INTRO_A2_8: Talk(SAY_JAINA_INTRO_6); - events.ScheduleEvent(EVENT_INTRO_A2_9, 1200); + _events.ScheduleEvent(EVENT_INTRO_A2_9, 1200); break; case EVENT_INTRO_A2_9: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_3); - events.ScheduleEvent(EVENT_INTRO_A2_10, 11000); + _events.ScheduleEvent(EVENT_INTRO_A2_10, 11000); break; case EVENT_INTRO_A2_10: Talk(SAY_JAINA_INTRO_7); - events.ScheduleEvent(EVENT_INTRO_A2_11, 6000); + _events.ScheduleEvent(EVENT_INTRO_A2_11, 6000); break; case EVENT_INTRO_A2_11: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_4); - events.ScheduleEvent(EVENT_INTRO_A2_12, 12000); + _events.ScheduleEvent(EVENT_INTRO_A2_12, 12000); break; case EVENT_INTRO_A2_12: Talk(SAY_JAINA_INTRO_8); - events.ScheduleEvent(EVENT_INTRO_A2_13, 6000); + _events.ScheduleEvent(EVENT_INTRO_A2_13, 6000); break; case EVENT_INTRO_A2_13: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_5); - events.ScheduleEvent(EVENT_INTRO_A2_14, 13000); + _events.ScheduleEvent(EVENT_INTRO_A2_14, 13000); break; case EVENT_INTRO_A2_14: Talk(SAY_JAINA_INTRO_9); - events.ScheduleEvent(EVENT_INTRO_A2_15, 12000); + _events.ScheduleEvent(EVENT_INTRO_A2_15, 12000); break; case EVENT_INTRO_A2_15: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_6); - events.ScheduleEvent(EVENT_INTRO_A2_16, 25000); + _events.ScheduleEvent(EVENT_INTRO_A2_16, 25000); break; case EVENT_INTRO_A2_16: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_7); - events.ScheduleEvent(EVENT_INTRO_A2_17, 6000); + _events.ScheduleEvent(EVENT_INTRO_A2_17, 6000); break; case EVENT_INTRO_A2_17: Talk(SAY_JAINA_INTRO_10); - events.ScheduleEvent(EVENT_INTRO_A2_18, 5000); + _events.ScheduleEvent(EVENT_INTRO_A2_18, 5000); break; case EVENT_INTRO_A2_18: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) { uther->HandleEmoteCommand(EMOTE_ONESHOT_NO); uther->AI()->Talk(SAY_UTHER_INTRO_A2_8); } - events.ScheduleEvent(EVENT_INTRO_A2_19, 12000); + _events.ScheduleEvent(EVENT_INTRO_A2_19, 12000); break; case EVENT_INTRO_A2_19: Talk(SAY_JAINA_INTRO_11); - events.ScheduleEvent(EVENT_INTRO_LK_1, 3000); + _events.ScheduleEvent(EVENT_INTRO_LK_1, 3000); break; // H2 Intro Events case EVENT_INTRO_H2_1: Talk(SAY_SYLVANAS_INTRO_1); - events.ScheduleEvent(EVENT_INTRO_H2_2, 8000); + _events.ScheduleEvent(EVENT_INTRO_H2_2, 8000); break; case EVENT_INTRO_H2_2: Talk(SAY_SYLVANAS_INTRO_2); - events.ScheduleEvent(EVENT_INTRO_H2_3, 6000); + _events.ScheduleEvent(EVENT_INTRO_H2_3, 6000); break; case EVENT_INTRO_H2_3: Talk(SAY_SYLVANAS_INTRO_3); me->CastSpell(me, SPELL_CAST_VISUAL, false); me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true); - instance->HandleGameObject(instance->GetData64(DATA_FROSTMOURNE), true); - events.ScheduleEvent(EVENT_INTRO_H2_4, 6000); + _instance->HandleGameObject(_instance->GetData64(DATA_FROSTMOURNE), true); + _events.ScheduleEvent(EVENT_INTRO_H2_4, 6000); break; case EVENT_INTRO_H2_4: // spawn UTHER during speach 2 if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) { uther->GetMotionMaster()->MoveIdle(); - utherGUID = uther->GetGUID(); + _utherGUID = uther->GetGUID(); } - events.ScheduleEvent(EVENT_INTRO_H2_5, 2000); + _events.ScheduleEvent(EVENT_INTRO_H2_5, 2000); break; case EVENT_INTRO_H2_5: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_H2_1); - events.ScheduleEvent(EVENT_INTRO_H2_6, 11000); + _events.ScheduleEvent(EVENT_INTRO_H2_6, 11000); break; case EVENT_INTRO_H2_6: Talk(SAY_SYLVANAS_INTRO_4); - events.ScheduleEvent(EVENT_INTRO_H2_7, 3000); + _events.ScheduleEvent(EVENT_INTRO_H2_7, 3000); break; case EVENT_INTRO_H2_7: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_H2_2); - events.ScheduleEvent(EVENT_INTRO_H2_8, 6000); + _events.ScheduleEvent(EVENT_INTRO_H2_8, 6000); break; case EVENT_INTRO_H2_8: Talk(SAY_SYLVANAS_INTRO_5); - events.ScheduleEvent(EVENT_INTRO_H2_9, 5000); + _events.ScheduleEvent(EVENT_INTRO_H2_9, 5000); break; case EVENT_INTRO_H2_9: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_H2_3); - events.ScheduleEvent(EVENT_INTRO_H2_10, 19000); + _events.ScheduleEvent(EVENT_INTRO_H2_10, 19000); break; case EVENT_INTRO_H2_10: Talk(SAY_SYLVANAS_INTRO_6); - events.ScheduleEvent(EVENT_INTRO_H2_11, 1500); + _events.ScheduleEvent(EVENT_INTRO_H2_11, 1500); break; case EVENT_INTRO_H2_11: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_H2_4); - events.ScheduleEvent(EVENT_INTRO_H2_12, 19500); + _events.ScheduleEvent(EVENT_INTRO_H2_12, 19500); break; case EVENT_INTRO_H2_12: Talk(SAY_SYLVANAS_INTRO_7); - events.ScheduleEvent(EVENT_INTRO_H2_13, 2000); + _events.ScheduleEvent(EVENT_INTRO_H2_13, 2000); break; case EVENT_INTRO_H2_13: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) { uther->HandleEmoteCommand(EMOTE_ONESHOT_NO); uther->AI()->Talk(SAY_UTHER_INTRO_H2_5); } - events.ScheduleEvent(EVENT_INTRO_H2_14, 12000); + _events.ScheduleEvent(EVENT_INTRO_H2_14, 12000); break; case EVENT_INTRO_H2_14: - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_H2_6); - events.ScheduleEvent(EVENT_INTRO_H2_15, 8000); + _events.ScheduleEvent(EVENT_INTRO_H2_15, 8000); break; case EVENT_INTRO_H2_15: Talk(SAY_SYLVANAS_INTRO_8); - events.ScheduleEvent(EVENT_INTRO_LK_1, 2000); + _events.ScheduleEvent(EVENT_INTRO_LK_1, 2000); break; // Remaining Intro Events common for both faction case EVENT_INTRO_LK_1: @@ -433,121 +553,126 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript { lichking->SetWalk(true); lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos); - //lichking->SetReactState(REACT_PASSIVE); - lichkingGUID = lichking->GetGUID(); - events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0); - events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000); + _lichkingGUID = lichking->GetGUID(); + _events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0); + _events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000); } - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) { uther->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER); - if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) uther->AI()->Talk(SAY_UTHER_INTRO_A2_9); else uther->AI()->Talk(SAY_UTHER_INTRO_H2_7); } - events.ScheduleEvent(EVENT_INTRO_LK_2, 10000); + _events.ScheduleEvent(EVENT_INTRO_LK_2, 10000); break; case EVENT_INTRO_LK_2: - if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) lichking->AI()->Talk(SAY_LK_INTRO_1); - events.ScheduleEvent(EVENT_INTRO_LK_3, 1000); + _events.ScheduleEvent(EVENT_INTRO_LK_3, 1000); break; case EVENT_INTRO_LK_3: // The Lich King banishes Uther to the abyss. - if (Creature* uther = me->GetCreature(*me, utherGUID)) + if (Creature* uther = me->GetCreature(*me, _utherGUID)) { uther->CastSpell(uther, SPELL_UTHER_DESPAWN, true); uther->DespawnOrUnsummon(5000); - utherGUID = 0; + _utherGUID = 0; } - events.ScheduleEvent(EVENT_INTRO_LK_4, 9000); + _events.ScheduleEvent(EVENT_INTRO_LK_4, 9000); break; case EVENT_INTRO_LK_4: // He steps forward and removes the runeblade from the heap of skulls. - if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) { - if (GameObject* frostmourne = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTMOURNE))) + if (GameObject* frostmourne = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTMOURNE))) frostmourne->SetPhaseMask(2, true); lichking->CastSpell(lichking, SPELL_TAKE_FROSTMOURNE, true); lichking->CastSpell(lichking, SPELL_FROSTMOURNE_VISUAL, true); } - events.ScheduleEvent(EVENT_INTRO_LK_5, 8000); + _events.ScheduleEvent(EVENT_INTRO_LK_5, 8000); break; case EVENT_INTRO_LK_5: - if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) lichking->AI()->Talk(SAY_LK_INTRO_2); - events.ScheduleEvent(EVENT_INTRO_LK_6, 8000); + _events.ScheduleEvent(EVENT_INTRO_LK_6, 10000); break; case EVENT_INTRO_LK_6: // summon Falric and Marwyn. then go back to the door - if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT))) + if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC_EVENT))) { falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true); falric->SetVisible(true); } - if (Creature* marwyn = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MARWYN_EVENT))) + if (Creature* marwyn = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MARWYN_EVENT))) { marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true); marwyn->SetVisible(true); } - if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) { lichking->AI()->Talk(SAY_LK_INTRO_3); lichking->SetWalk(true); lichking->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos); } - events.ScheduleEvent(EVENT_INTRO_LK_7, 10000); - events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 5000); + _events.ScheduleEvent(EVENT_INTRO_LK_7, 10000); + _events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 5000); break; case EVENT_INTRO_LK_7: - if (Creature* marwyn = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MARWYN_EVENT))) + if (Creature* marwyn = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MARWYN_EVENT))) + { marwyn->AI()->Talk(SAY_MARWYN_INTRO_1); - events.ScheduleEvent(EVENT_INTRO_LK_8, 1000); + marwyn->SetWalk(true); + marwyn->GetMotionMaster()->MovePoint(0, MarwynStartPos); + } + _events.ScheduleEvent(EVENT_INTRO_LK_8, 1000); break; case EVENT_INTRO_LK_8: - if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT))) + if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC_EVENT))) + { falric->AI()->Talk(SAY_FALRIC_INTRO_1); - events.ScheduleEvent(EVENT_INTRO_LK_9, 5000); + falric->SetWalk(true); + falric->GetMotionMaster()->MovePoint(0, FalricStartPos); + } + _events.ScheduleEvent(EVENT_INTRO_LK_9, 5000); break; case EVENT_INTRO_LK_9: - if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT))) + if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC_EVENT))) falric->AI()->Talk(SAY_FALRIC_INTRO_2); - events.ScheduleEvent(EVENT_INTRO_LK_10, 7000); + _instance->ProcessEvent(0, EVENT_SPAWN_WAVES); + _events.ScheduleEvent(EVENT_INTRO_LK_10, 4000); break; case EVENT_INTRO_LK_10: - if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) Talk(SAY_JAINA_INTRO_END); else Talk(SAY_SYLVANAS_INTRO_END); me->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos); /// @todo Loralen/Koreln shall run also - events.ScheduleEvent(EVENT_INTRO_LK_11, 5000); + _events.ScheduleEvent(EVENT_INTRO_LK_11, 5000); break; case EVENT_INTRO_LK_11: - if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) { - if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) lichking->AI()->Talk(SAY_LK_JAINA_INTRO_END); else lichking->AI()->Talk(SAY_LK_SYLVANAS_INTRO_END); } - events.ScheduleEvent(EVENT_INTRO_END, 5000); + _events.ScheduleEvent(EVENT_INTRO_END, 5000); break; case EVENT_INTRO_END: - if (instance) - { - instance->SetData(DATA_INTRO_EVENT, DONE); - instance->ProcessEvent(0, EVENT_SPAWN_WAVES); - } + if (_instance) + _instance->SetData(DATA_INTRO_EVENT, DONE); // Loralen or Koreln disappearAndDie() - if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) { lichking->DespawnOrUnsummon(5000); - lichkingGUID = 0; + _lichkingGUID = 0; } me->DespawnOrUnsummon(10000); - events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 7000); + _events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 7000); break; case EVENT_SKIP_INTRO: me->GetMotionMaster()->MovePoint(0, MoveThronePos); @@ -557,19 +682,19 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript lichking->SetWalk(true); lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos); lichking->SetReactState(REACT_PASSIVE); - lichkingGUID = lichking->GetGUID(); - events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0); - events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000); + _lichkingGUID = lichking->GetGUID(); + _events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0); + _events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000); } - events.ScheduleEvent(EVENT_INTRO_LK_4, 15000); + _events.ScheduleEvent(EVENT_INTRO_LK_4, 15000); break; case EVENT_OPEN_FROSTWORN_DOOR: - if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTWORN_DOOR))) - instance->HandleGameObject(0 ,true, gate); + if (GameObject* gate = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTWORN_DOOR))) + _instance->HandleGameObject(0, true, gate); break; case EVENT_CLOSE_FROSTWORN_DOOR: - if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTWORN_DOOR))) - instance->HandleGameObject(0 ,false, gate); + if (GameObject* gate = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTWORN_DOOR))) + _instance->HandleGameObject(0, false, gate); break; } } @@ -581,6 +706,432 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript } }; +class npc_jaina_or_sylvanas_escape_hor : public CreatureScript +{ + public: + npc_jaina_or_sylvanas_escape_hor() : CreatureScript("npc_jaina_or_sylvanas_escape_hor") { } + + // AI of Part2 + struct npc_jaina_or_sylvanas_escape_horAI : public ScriptedAI + { + npc_jaina_or_sylvanas_escape_horAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } + + InstanceScript* _instance; + uint64 _lichkingGUID; + uint64 _walltargetGUID; // dummy + uint64 _icewallGUID; // object + uint32 _icewall; // icewall number + uint32 _isattackingwall; //sylvannas attacking icewall + + EventMap _events; + + + void Reset() OVERRIDE + { + _events.Reset(); + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + lichking->DespawnOrUnsummon(1); + _lichkingGUID = 0; + _walltargetGUID = 0; + _icewallGUID = 0; + _icewall = 0; + _isattackingwall = false; + _events.ScheduleEvent(EVENT_ESCAPE, 0); + } + + void JustDied(Unit* /*Killer*/) OVERRIDE + { + if (_instance) + _instance->SetData(DATA_ESCAPE_EVENT, FAIL); + } + + void DoAction(int32 actionID) OVERRIDE + { + switch (actionID) + { + case ACTION_START_ESCAPING: // called by InstanceScript when we need to start the escaping event + _events.ScheduleEvent(EVENT_ESCAPE_1, 1000); + break; + case ACTION_WALL_BROKEN: + _icewall++; + if (_icewall != 4) + _events.ScheduleEvent(EVENT_ESCAPE_17,3000); + else + _events.ScheduleEvent(EVENT_ESCAPE_23,3000); + _isattackingwall = false; + break; + } + } + + void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) OVERRIDE + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case 0: + player->CLOSE_GOSSIP_MENU(); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); + _events.ScheduleEvent(EVENT_ESCAPE_7, 0); + break; + } + } + + void UpdateAI(uint32 diff) OVERRIDE + { + _events.Update(diff); + + while (uint32 event = _events.ExecuteEvent()) + { + switch (event) + { + case EVENT_ESCAPE: + if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART2, LichKingSpawnPos2, TEMPSUMMON_MANUAL_DESPAWN)) + { + me->Attack(lichking,true); + lichking->Attack(me,true); + me->SetReactState(REACT_PASSIVE); + lichking->SetReactState(REACT_PASSIVE); + _lichkingGUID = lichking->GetGUID(); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->AI()->DoCast(me, SPELL_JAINA_ICEBARRIER); + else + me->AI()->DoCast(me, SPELL_SYLVANAS_CLOAKOFDARKNESS); + } + me->SetHealth(252000); + break; + case EVENT_ESCAPE_1: + _instance->SetData(DATA_ESCAPE_EVENT, IN_PROGRESS); + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + lichking->AI()->Talk(SAY_LK_ESCAPE_1); + else + lichking->AI()->Talk(SAY_LK_ESCAPE_2); + _events.ScheduleEvent(EVENT_ESCAPE_2, 8000); + } + break; + case EVENT_ESCAPE_2: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->AI()->DoCast(me,SPELL_CAST_VISUAL,true); + else + me->AI()->DoCast(me,SPELL_SYLVANAS_JUMP,true); + _events.ScheduleEvent(EVENT_ESCAPE_3, 1000); + break; + case EVENT_ESCAPE_3: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + lichking->AI()->DoCast(lichking, SPELL_JAINA_ICEPRISON, true); + else + lichking->AI()->DoCast(lichking, SPELL_SYLVANAS_DARKBINDING, true); + } + _events.ScheduleEvent(EVENT_ESCAPE_4, 2000); + break; + case EVENT_ESCAPE_4: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->AI()->Talk(SAY_JAINA_ESCAPE_1); + else + me->AI()->Talk(SAY_SYLVANAS_ESCAPE_1); + _events.ScheduleEvent(EVENT_ESCAPE_5, 2000); + break; + case EVENT_ESCAPE_5: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + lichking->CombatStop(); + me->GetMotionMaster()->MovePoint(0, JainaShadowThroneDoor); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->RemoveAurasDueToSpell(SPELL_JAINA_ICEBARRIER); + else + me->RemoveAurasDueToSpell(SPELL_SYLVANAS_CLOAKOFDARKNESS); + _events.ScheduleEvent(EVENT_ESCAPE_6, 5000); + break; + case EVENT_ESCAPE_6: + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); + break; + case EVENT_ESCAPE_7: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + lichking->RemoveAurasDueToSpell(SPELL_JAINA_ICEPRISON); + else + lichking->RemoveAurasDueToSpell(SPELL_SYLVANAS_DARKBINDING); + } + _events.ScheduleEvent(EVENT_ESCAPE_8, 1000); + break; + case EVENT_ESCAPE_8: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + lichking->HandleEmoteCommand(TEXT_EMOTE_ROAR); + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[0]); + _events.ScheduleEvent(EVENT_ESCAPE_9, 3000); + break; + case EVENT_ESCAPE_9: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + lichking->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[0]); + _events.ScheduleEvent(EVENT_ESCAPE_10, 1000); + break; + case EVENT_ESCAPE_10: + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[1]); + _events.ScheduleEvent(EVENT_ESCAPE_11, 5000); + break; + case EVENT_ESCAPE_11: + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[2]); + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + lichking->GetMotionMaster()->MovePoint(0, LichKingFirstSummon); + _events.ScheduleEvent(EVENT_ESCAPE_12, 6000); + break; + case EVENT_ESCAPE_12: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + lichking->AI()->Talk(SAY_LK_ESCAPE_3); + lichking->AI()->DoCast(me, SPELL_RAISE_DEAD); + lichking->Attack(me,true); + } + _events.ScheduleEvent(EVENT_ESCAPE_13, 4000); + break; + case EVENT_ESCAPE_13: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + lichking->AI()->DoCast(lichking, SPELL_REMORSELESS_WINTER, true); + lichking->AI()->DoCast(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); + lichking->GetMotionMaster()->MoveIdle(); + lichking->GetMotionMaster()->MoveChase(me); + } + if (Creature* walltarget = me->SummonCreature(NPC_ICE_WALL,IceWalls[0].GetPositionX(), IceWalls[0].GetPositionY(), IceWalls[0].GetPositionZ(), IceWalls[0].GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN, 720000)) + { + _walltargetGUID = walltarget->GetGUID(); + walltarget->AI()->DoCast(walltarget, SPELL_SUMMON_ICE_WALL); + walltarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->Attack(walltarget,false); + } + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[3]); + _events.ScheduleEvent(EVENT_ESCAPE_14, 8000); + break; + case EVENT_ESCAPE_14: + if (Creature* walltarget = me->GetCreature(*me, _walltargetGUID)) + { + if (GameObject* icewall = walltarget->FindNearestGameObject(GO_ICE_WALL, 50.00f)) + { + _icewallGUID = icewall->GetGUID(); + icewall->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + _instance->HandleGameObject(0, false, icewall); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->AI()->Talk(SAY_JAINA_ESCAPE_2); + else + me->AI()->Talk(SAY_SYLVANAS_ESCAPE_2); + } + } + _events.ScheduleEvent(EVENT_ESCAPE_15, 1000); + break; + case EVENT_ESCAPE_15: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + lichking->GetMotionMaster()->MoveIdle(); + lichking->GetMotionMaster()->MoveChase(me); + lichking->SetReactState(REACT_PASSIVE); + } + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->AI()->DoCast(me, SPELL_JAINA_DESTROY_ICE_WALL, false); + else + { + _isattackingwall = true; + me->AI()->DoCast(me, SPELL_SYLVANAS_DESTROY_ICE_WALL, false); + _events.ScheduleEvent(EVENT_ESCAPE_16, 1000); + } + break; + case EVENT_ESCAPE_16: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) + { + me->AI()->DoCast(me, SPELL_SYLVANAS_DESTROY_ICE_WALL, false); + if (_isattackingwall) + _events.ScheduleEvent(EVENT_ESCAPE_16, 1000); + } + break; + case EVENT_ESCAPE_17:// ICEWALL BROKEN + me->GetMotionMaster()->MoveIdle(); + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + lichking->StopMoving(); + lichking->AI()->Talk(SAY_LK_ESCAPE_3); + lichking->AI()->DoCast(me, SPELL_RAISE_DEAD); + } + if (Creature* walltarget = me->GetCreature(*me, _walltargetGUID)) + walltarget->DespawnOrUnsummon(0); + if (GameObject* icewall = ObjectAccessor::GetGameObject(*me, _icewallGUID)) + { + _instance->HandleGameObject(0 ,true, icewall); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->RemoveAurasDueToSpell(SPELL_JAINA_DESTROY_ICE_WALL); + else + me->RemoveAurasDueToSpell(SPELL_SYLVANAS_DESTROY_ICE_WALL); + } + if (_icewall && _icewall < 4) + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[_icewall + 3]); + _events.ScheduleEvent(EVENT_ESCAPE_18, 2000); + break; + case EVENT_ESCAPE_18: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + lichking->GetMotionMaster()->MoveIdle(); + lichking->GetMotionMaster()->MoveChase(me); + } + _events.ScheduleEvent(EVENT_ESCAPE_19, 6000); + break; + case EVENT_ESCAPE_19: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + if (_icewall && _icewall < 4) + lichking->AI()->DoCast(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); + lichking->GetMotionMaster()->MoveIdle(); + lichking->GetMotionMaster()->MoveChase(me); + lichking->SetReactState(REACT_PASSIVE); + lichking->Attack(me,true); + } + if (Creature* walltarget = me->SummonCreature(NPC_ICE_WALL, IceWalls[_icewall].GetPositionX(), IceWalls[_icewall].GetPositionY(), IceWalls[_icewall].GetPositionZ(), IceWalls[_icewall].GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN, 720000)) + { + _walltargetGUID = walltarget->GetGUID(); + walltarget->AI()->DoCast(walltarget, SPELL_SUMMON_ICE_WALL); + walltarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->Attack(walltarget,false); + } + _events.ScheduleEvent(EVENT_ESCAPE_20, 3000); + break; + case EVENT_ESCAPE_20: + if (Creature* walltarget = me->GetCreature(*me, _walltargetGUID)) + { + if (GameObject* icewall = walltarget->FindNearestGameObject(GO_ICE_WALL, 50.00f)) + { + _icewallGUID = icewall->GetGUID(); + _instance->HandleGameObject(0, false, icewall); + icewall->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + { + if (_icewall == 1) + me->AI()->Talk(SAY_JAINA_ESCAPE_3); + else if (_icewall == 2) + me->AI()->Talk(SAY_JAINA_ESCAPE_4); + else if (_icewall == 3) + me->AI()->Talk(SAY_JAINA_ESCAPE_5); + } + else if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + { + if (_icewall == 1) + me->AI()->Talk(SAY_SYLVANAS_ESCAPE_3); + else if (_icewall == 2) + me->AI()->Talk(SAY_SYLVANAS_ESCAPE_4); + else if (_icewall == 3) + me->AI()->Talk(SAY_SYLVANAS_ESCAPE_5); + } + } + } + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + if (_icewall && _icewall < 3) + lichking->AI()->DoCast(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); + else + lichking->AI()->DoCast(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); + } + if (_icewall == 3) + _events.ScheduleEvent(EVENT_ESCAPE_21, 16000); // last wall, really far + else + _events.ScheduleEvent(EVENT_ESCAPE_21, 9000); + break; + case EVENT_ESCAPE_21: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->AI()->DoCast(me, SPELL_JAINA_DESTROY_ICE_WALL, false); + else + { + me->AI()->DoCast(me, SPELL_SYLVANAS_DESTROY_ICE_WALL, false); + _isattackingwall = true; + _events.ScheduleEvent(EVENT_ESCAPE_22, 1000); + } + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + if (_icewall == 1) + lichking->AI()->DoCast(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); + else if (_icewall > 1 && _icewall < 4) + lichking->AI()->DoCast(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); + } + break; + case EVENT_ESCAPE_22: + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + if (_icewall >= 2 && _icewall < 4) + lichking->AI()->DoCast(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); + } + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) + { + me->AI()->DoCast(me, SPELL_SYLVANAS_DESTROY_ICE_WALL, false); + if (_isattackingwall) + _events.ScheduleEvent(EVENT_ESCAPE_22, 1000); + } + break; + + case EVENT_ESCAPE_23:// FINAL PART + if (Creature* walltarget = me->GetCreature(*me, _walltargetGUID)) + walltarget->DespawnOrUnsummon(0); + if (GameObject* icewall = ObjectAccessor::GetGameObject(*me, _icewallGUID)) + { + _instance->HandleGameObject(0 ,true, icewall); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + { + me->RemoveAurasDueToSpell(SPELL_JAINA_DESTROY_ICE_WALL); + me->AI()->Talk(SAY_JAINA_ESCAPE_6); + } + else + { + me->RemoveAurasDueToSpell(SPELL_SYLVANAS_DESTROY_ICE_WALL); + me->AI()->Talk(SAY_SYLVANAS_ESCAPE_6); + } + } + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + { + lichking->GetMotionMaster()->MovePoint(0, LichKingFinalPos); + lichking->AI()->Talk(SAY_LK_ESCAPE_11); + } + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[8]); + _events.ScheduleEvent(EVENT_ESCAPE_24, 10000); + break; + case EVENT_ESCAPE_24: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->AI()->Talk(SAY_JAINA_ESCAPE_8); + else + me->AI()->Talk(SAY_SYLVANAS_ESCAPE_8); + _events.ScheduleEvent(EVENT_ESCAPE_25, 5000); + break; + case EVENT_ESCAPE_25: + if (GameObject* cave = _instance->instance->GetGameObject(_instance->GetData64(DATA_CAVE_IN))) + cave->SetGoState(GO_STATE_READY); + _events.ScheduleEvent(EVENT_ESCAPE_26, 4000); + break; + case EVENT_ESCAPE_26: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->AI()->Talk(SAY_JAINA_ESCAPE_10); + else + me->AI()->Talk(SAY_SYLVANAS_ESCAPE_9); + _events.ScheduleEvent(EVENT_ESCAPE_27, 4000); + break; + case EVENT_ESCAPE_27: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->SummonGameObject(GO_CAPTAIN_CHEST_1, ChestPos.GetPositionX(), ChestPos.GetPositionY(), ChestPos.GetPositionZ(), ChestPos.GetOrientation(), 0, 0, 0, 0, 720000); + else + me->SummonGameObject(GO_CAPTAIN_CHEST_3, ChestPos.GetPositionX(), ChestPos.GetPositionY(), ChestPos.GetPositionZ(), ChestPos.GetOrientation(), 0, 0, 0, 0, 720000); + me->SummonGameObject(GO_PORTAL, FinalPortalPos.GetPositionX(), FinalPortalPos.GetPositionY(), FinalPortalPos.GetPositionZ(), FinalPortalPos.GetOrientation(), 0, 0, 0, 0, 720000); + if (Creature* lichking = me->GetCreature(*me, _lichkingGUID)) + lichking->DespawnOrUnsummon(1); + break; + } + } + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_jaina_or_sylvanas_escape_horAI(creature); + } +}; + enum TrashSpells { // Ghostly Priest @@ -655,20 +1206,20 @@ enum TrashEvents struct npc_gauntlet_trash : public ScriptedAI { npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature), - instance(creature->GetInstanceScript()) + _instance(creature->GetInstanceScript()) { } void Reset() OVERRIDE { me->CastSpell(me, SPELL_WELL_OF_SOULS, true); - events.Reset(); + _events.Reset(); } void EnterEvadeMode() OVERRIDE { - if (instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED) - instance->SetData(DATA_WAVE_COUNT, NOT_STARTED); + if (_instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED) + _instance->SetData(DATA_WAVE_COUNT, NOT_STARTED); } void SetData(uint32 type, uint32 value) OVERRIDE @@ -688,8 +1239,8 @@ struct npc_gauntlet_trash : public ScriptedAI } protected: - EventMap events; - InstanceScript* instance; + EventMap _events; + InstanceScript* _instance; uint32 InternalWaveId; }; @@ -706,10 +1257,10 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); /// @todo adjust timers - events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); - events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); - events.ScheduleEvent(EVENT_DARK_MENDING, 20000); + _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); /// @todo adjust timers + _events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); + _events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); + _events.ScheduleEvent(EVENT_DARK_MENDING, 20000); } void UpdateAI(uint32 diff) OVERRIDE @@ -717,39 +1268,39 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (events.ExecuteEvent()) + switch (_events.ExecuteEvent()) { case EVENT_SHADOW_WORD_PAIN: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_SHADOW_WORD_PAIN); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); + _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); break; case EVENT_CIRCLE_OF_DESTRUCTION: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_CIRCLE_OF_DESTRUCTION); - events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); + _events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); break; case EVENT_COWER_IN_FEAR: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_COWER_IN_FEAR); - events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); + _events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); break; case EVENT_DARK_MENDING: // find an ally with missing HP if (Unit* target = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000, 50000))) { DoCast(target, SPELL_DARK_MENDING); - events.ScheduleEvent(EVENT_DARK_MENDING, 20000); + _events.ScheduleEvent(EVENT_DARK_MENDING, 20000); } else { // no friendly unit with missing hp. re-check in just 5 sec. - events.ScheduleEvent(EVENT_DARK_MENDING, 5000); + _events.ScheduleEvent(EVENT_DARK_MENDING, 5000); } break; } @@ -777,11 +1328,11 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - events.ScheduleEvent(EVENT_FIREBALL, 3000); /// @todo adjust timers - events.ScheduleEvent(EVENT_FLAMESTRIKE, 6000); - events.ScheduleEvent(EVENT_FROSTBOLT, 9000); - events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 12000); - events.ScheduleEvent(EVENT_HALLUCINATION, 40000); + _events.ScheduleEvent(EVENT_FIREBALL, 3000); /// @todo adjust timers + _events.ScheduleEvent(EVENT_FLAMESTRIKE, 6000); + _events.ScheduleEvent(EVENT_FROSTBOLT, 9000); + _events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 12000); + _events.ScheduleEvent(EVENT_HALLUCINATION, 40000); } void UpdateAI(uint32 diff) OVERRIDE @@ -789,31 +1340,31 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (events.ExecuteEvent()) + switch (_events.ExecuteEvent()) { case EVENT_FIREBALL: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_FIREBALL); - events.ScheduleEvent(EVENT_FIREBALL, 15000); + _events.ScheduleEvent(EVENT_FIREBALL, 15000); break; case EVENT_FLAMESTRIKE: DoCast(SPELL_FLAMESTRIKE); - events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000); + _events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000); break; case EVENT_FROSTBOLT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_FROSTBOLT); - events.ScheduleEvent(EVENT_FROSTBOLT, 15000); + _events.ScheduleEvent(EVENT_FROSTBOLT, 15000); break; case EVENT_CHAINS_OF_ICE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_CHAINS_OF_ICE); - events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000); + _events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000); break; case EVENT_HALLUCINATION: DoCast(SPELL_HALLUCINATION); @@ -864,10 +1415,10 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); /// @todo adjust timers - events.ScheduleEvent(EVENT_DEADLY_POISON, 5000); - events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); - events.ScheduleEvent(EVENT_KIDNEY_SHOT, 12000); + _events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); /// @todo adjust timers + _events.ScheduleEvent(EVENT_DEADLY_POISON, 5000); + _events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); + _events.ScheduleEvent(EVENT_KIDNEY_SHOT, 12000); } void UpdateAI(uint32 diff) OVERRIDE @@ -875,29 +1426,29 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (events.ExecuteEvent()) + switch (_events.ExecuteEvent()) { case EVENT_SHADOW_STEP: DoCast(SPELL_SHADOW_STEP); - events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); + _events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); break; case EVENT_DEADLY_POISON: DoCastVictim(SPELL_DEADLY_POISON); - events.ScheduleEvent(EVENT_DEADLY_POISON, 10000); + _events.ScheduleEvent(EVENT_DEADLY_POISON, 10000); break; case EVENT_ENVENOMED_DAGGER_THROW: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_ENVENOMED_DAGGER_THROW); - events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); + _events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); break; case EVENT_KIDNEY_SHOT: DoCastVictim(SPELL_KIDNEY_SHOT); - events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000); + _events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000); break; } @@ -924,9 +1475,9 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); /// @todo adjust timers - events.ScheduleEvent(EVENT_SHIELD_BASH, 10000); - events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); + _events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); /// @todo adjust timers + _events.ScheduleEvent(EVENT_SHIELD_BASH, 10000); + _events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); } void UpdateAI(uint32 diff) OVERRIDE @@ -934,24 +1485,24 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (events.ExecuteEvent()) + switch (_events.ExecuteEvent()) { case EVENT_SPECTRAL_STRIKE: DoCastVictim(SPELL_SPECTRAL_STRIKE); - events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); + _events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); break; case EVENT_SHIELD_BASH: DoCastVictim(SPELL_SHIELD_BASH); - events.ScheduleEvent(EVENT_SHIELD_BASH, 5000); + _events.ScheduleEvent(EVENT_SHIELD_BASH, 5000); break; case EVENT_TORTURED_ENRAGE: DoCast(SPELL_TORTURED_ENRAGE); - events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); + _events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); break; } @@ -978,10 +1529,10 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - events.ScheduleEvent(EVENT_SHOOT, 2000); /// @todo adjust timers - events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); - events.ScheduleEvent(EVENT_FROST_TRAP, 1000); - events.ScheduleEvent(EVENT_ICE_SHOT, 15000); + _events.ScheduleEvent(EVENT_SHOOT, 1); /// @todo adjust timers + _events.ScheduleEvent(EVENT_CURSED_ARROW, 7000); + _events.ScheduleEvent(EVENT_FROST_TRAP, 10000); + _events.ScheduleEvent(EVENT_ICE_SHOT, 15000); } void UpdateAI(uint32 diff) OVERRIDE @@ -989,34 +1540,33 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (events.ExecuteEvent()) + switch (_events.ExecuteEvent()) { case EVENT_SHOOT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_SHOOT); - events.ScheduleEvent(EVENT_SHOOT, 2000); + _events.ScheduleEvent(EVENT_SHOOT, 2000); break; case EVENT_CURSED_ARROW: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_CURSED_ARROW); - events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); + _events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); break; case EVENT_FROST_TRAP: DoCast(SPELL_FROST_TRAP); - events.ScheduleEvent(EVENT_FROST_TRAP, 30000); + _events.ScheduleEvent(EVENT_FROST_TRAP, 30000); break; case EVENT_ICE_SHOT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) DoCast(target, SPELL_ICE_SHOT); - events.ScheduleEvent(EVENT_ICE_SHOT, 15000); + _events.ScheduleEvent(EVENT_ICE_SHOT, 15000); break; } - DoMeleeAttackIfReady(); } }; @@ -1031,9 +1581,9 @@ public: enum GeneralEvents { //General - EVENT_SHIELD = 0, - EVENT_SPIKE = 1, - EVENT_CLONE = 2, + EVENT_SHIELD = 1, + EVENT_SPIKE = 2, + EVENT_CLONE = 3, SAY_AGGRO = 0, SAY_DEATH = 1, @@ -1044,7 +1594,7 @@ enum GeneralEvents SPELL_CLONE_MODEL = 45204, // Reflection - EVENT_BALEFUL_STRIKE = 0, + EVENT_BALEFUL_STRIKE = 1, SPELL_BALEFUL_STRIKE = 69933, // 70400 on hc SPELL_SPIRIT_BURST = 69900, // 73046 on hc @@ -1059,33 +1609,32 @@ public: { npc_frostworn_generalAI(Creature* creature) : ScriptedAI(creature) { - instance = me->GetInstanceScript(); + _instance = me->GetInstanceScript(); Reset(); } - InstanceScript* instance; - - EventMap events; + InstanceScript* _instance; + EventMap _events; void Reset() OVERRIDE { - events.Reset(); - instance->SetData(DATA_FROSWORN_EVENT, NOT_STARTED); + _events.Reset(); + _instance->SetData(DATA_FROSWORN_EVENT, NOT_STARTED); } void JustDied(Unit* /*killer*/) OVERRIDE { Talk(SAY_DEATH); - instance->SetData(DATA_FROSWORN_EVENT, DONE); + _instance->SetData(DATA_FROSWORN_EVENT, DONE); } void EnterCombat(Unit* /*victim*/) OVERRIDE { Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_SHIELD, 5000); - events.ScheduleEvent(EVENT_SPIKE, 14000); - events.ScheduleEvent(EVENT_CLONE, 22000); - instance->SetData(DATA_FROSWORN_EVENT, IN_PROGRESS); + _events.ScheduleEvent(EVENT_SHIELD, 5000); + _events.ScheduleEvent(EVENT_SPIKE, 14000); + _events.ScheduleEvent(EVENT_CLONE, 22000); + _instance->SetData(DATA_FROSWORN_EVENT, IN_PROGRESS); } void UpdateAI(uint32 diff) OVERRIDE @@ -1093,29 +1642,31 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (events.ExecuteEvent()) + while (uint32 event = _events.ExecuteEvent()) { - case EVENT_SHIELD: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHIELD_THROWN); - events.ScheduleEvent(EVENT_SHIELD, urand(8000, 12000)); - break; - case EVENT_SPIKE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SPIKE); - events.ScheduleEvent(EVENT_SPIKE, urand(15000, 20000)); - break; - case EVENT_CLONE: - SummonClones(); - events.ScheduleEvent(EVENT_CLONE, 60000); - break; + switch (event) + { + case EVENT_SHIELD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SHIELD_THROWN); + _events.ScheduleEvent(EVENT_SHIELD, urand(8000, 12000)); + break; + case EVENT_SPIKE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SPIKE); + _events.ScheduleEvent(EVENT_SPIKE, urand(15000, 20000)); + break; + case EVENT_CLONE: + SummonClones(); + _events.ScheduleEvent(EVENT_CLONE, 60000); + break; + } } - DoMeleeAttackIfReady(); } @@ -1133,7 +1684,6 @@ public: reflection->setFaction(me->getFaction()); reflection->AI()->AttackStart(temp); } - } }; @@ -1155,16 +1705,16 @@ public: Reset(); } - EventMap events; + EventMap _events; void Reset() OVERRIDE { - events.Reset(); + _events.Reset(); } void EnterCombat(Unit* /*victim*/) OVERRIDE { - events.ScheduleEvent(EVENT_BALEFUL_STRIKE, 3000); + _events.ScheduleEvent(EVENT_BALEFUL_STRIKE, 3000); } void JustDied(Unit* killer) OVERRIDE @@ -1177,17 +1727,17 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (events.ExecuteEvent()) + switch (_events.ExecuteEvent()) { case EVENT_BALEFUL_STRIKE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_BALEFUL_STRIKE); - events.ScheduleEvent(EVENT_BALEFUL_STRIKE, urand(3000, 8000)); + _events.ScheduleEvent(EVENT_BALEFUL_STRIKE, urand(3000, 8000)); } DoMeleeAttackIfReady(); @@ -1207,15 +1757,13 @@ public: bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) OVERRIDE { - InstanceScript* instance = player->GetInstanceScript(); + InstanceScript* _instance = player->GetInstanceScript(); if (player->IsGameMaster()) return true; - if (instance->GetData(DATA_INTRO_EVENT) == NOT_STARTED) - { - instance->SetData(DATA_INTRO_EVENT, IN_PROGRESS); - } + if (_instance->GetData(DATA_INTRO_EVENT) == NOT_STARTED) + _instance->SetData(DATA_INTRO_EVENT, IN_PROGRESS); return true; } @@ -1228,24 +1776,24 @@ public: bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) OVERRIDE { - InstanceScript* instance = player->GetInstanceScript(); + InstanceScript* _instance = player->GetInstanceScript(); if (player->IsGameMaster()) return true; - if (instance->GetData(DATA_WAVE_COUNT)) + if (_instance->GetData(DATA_WAVE_COUNT)) return true; - if (instance->GetData(DATA_INTRO_EVENT) == DONE && instance->GetBossState(DATA_MARWYN_EVENT) != DONE) + if (_instance->GetData(DATA_INTRO_EVENT) == DONE && _instance->GetBossState(DATA_MARWYN_EVENT) != DONE) { - instance->ProcessEvent(0, EVENT_SPAWN_WAVES); + _instance->ProcessEvent(0, EVENT_SPAWN_WAVES); - if (Creature* falric = player->GetCreature(*player, instance->GetData64(DATA_FALRIC_EVENT))) + if (Creature* falric = player->GetCreature(*player, _instance->GetData64(DATA_FALRIC_EVENT))) { falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true); falric->SetVisible(true); } - if (Creature* marwyn = player->GetCreature(*player, instance->GetData64(DATA_MARWYN_EVENT))) + if (Creature* marwyn = player->GetCreature(*player, _instance->GetData64(DATA_MARWYN_EVENT))) { marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true); marwyn->SetVisible(true); @@ -1255,17 +1803,349 @@ public: } }; +class at_shadow_throne : public AreaTriggerScript +{ +public: + at_shadow_throne() : AreaTriggerScript("at_shadow_throne") { } + + bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) OVERRIDE + { + InstanceScript* _instance = player->GetInstanceScript(); + + if (player->IsGameMaster()) + return true; + + if (_instance->GetData(DATA_ESCAPE_EVENT) == NOT_STARTED) + _instance->SetData(DATA_ESCAPE_EVENT, IN_PROGRESS); + + return true; + } +}; + +class npc_raging_ghoul : public CreatureScript +{ +public: + npc_raging_ghoul() : CreatureScript("npc_raging_ghoul") { } + + struct npc_raging_ghoulAI : public ScriptedAI + { + npc_raging_ghoulAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } + + InstanceScript* _instance; + uint32 _emergeTimer; + bool _doEmerge; + bool _doJump; + uint64 _leaderGUID; + + void Reset() OVERRIDE + { + _emergeTimer = 4000; + _doEmerge = false; + _doJump = false; + if (_instance && _instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + _instance->SetData(DATA_SUMMONS, 1); + + } + + void IsSummonedBy(Unit*) OVERRIDE + { + DoCast(me, SPELL_EMERGE_VISUAL); + DoZoneInCombat(me, 100.00f); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + if (_instance) + _instance->SetData(DATA_SUMMONS, 0); + } + + void AttackStart(Unit* who) OVERRIDE + { + if (!who) + return; + + if (!_doEmerge) + return; + + ScriptedAI::AttackStart(who); + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!_instance) + return; + + if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + { + _leaderGUID = _instance->GetData64(DATA_ESCAPE_LEADER); + Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER)); + + if (_doEmerge != true) + { + if (_emergeTimer < diff) + { + _doEmerge = true; + if (leader) + { + DoResetThreat(); + me->GetMotionMaster()->MoveIdle(); + me->GetMotionMaster()->MoveChase(leader); + } + } + else + _emergeTimer -= diff; + } + + if (me->Attack(leader,true))/*(Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f))*/ + { + if (!_doJump && me->IsWithinDistInMap(leader, 30.0f) && !me->IsWithinDistInMap(leader, 5.0f)) + { + _doJump = true; + DoCast(leader, SPELL_GHOUL_JUMP); + } + } + } + else if (_instance->GetData(DATA_ESCAPE_EVENT) == FAIL || _instance->GetData(DATA_ESCAPE_EVENT) == NOT_STARTED) + me->DespawnOrUnsummon(); + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_raging_ghoulAI(creature); + } +}; + +class npc_risen_witch_doctor : public CreatureScript +{ +public: + npc_risen_witch_doctor() : CreatureScript("npc_risen_witch_doctor") { } + + struct npc_risen_witch_doctorAI : public ScriptedAI + { + npc_risen_witch_doctorAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } + + InstanceScript* _instance; + uint32 _emergeTimer; + bool _doEmerge; + uint64 _leaderGUID; + uint32 _boltTimer; + uint32 _boltVolleyTimer; + uint32 _curseTimer; + + void Reset() OVERRIDE + { + _emergeTimer = 5000; + _boltTimer = 6000; + _boltVolleyTimer = 15000; + _curseTimer = 7000; + _doEmerge = false; + if (_instance) + if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + _instance->SetData(DATA_SUMMONS, 1); + } + + void IsSummonedBy(Unit*) OVERRIDE + { + DoCast(me, SPELL_EMERGE_VISUAL); + DoZoneInCombat(me, 100.00f); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + if (_instance) + _instance->SetData(DATA_SUMMONS, 0); + + } + + void AttackStart(Unit* who) OVERRIDE + { + if (!who) + return; + + if (_doEmerge == false) + return; + + ScriptedAI::AttackStart(who); + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!_instance) + return; + + if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + { + if (_doEmerge != true) + { + if (_emergeTimer < diff) + { + _doEmerge = true; + _leaderGUID = _instance->GetData64(DATA_ESCAPE_LEADER); + + if (Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) + { + DoResetThreat(); + me->GetMotionMaster()->MoveIdle(); + me->GetMotionMaster()->MoveChase(leader); + } + } + else + _emergeTimer -= diff; + } + + if (_curseTimer < diff) + { + if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_COURSE_OF_DOOM); + _curseTimer = urand(10000, 15000); + } + else + _curseTimer -= diff; + + if (_boltTimer < diff) + { + if (Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO)) + DoCast(target, SPELL_SHADOW_BOLT); + _boltTimer = urand(2000, 3000); + } + else + _boltTimer -= diff; + + if (_boltVolleyTimer < diff) + { + if (Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO)) + DoCast(target, SPELL_SHADOW_BOLT_VOLLEY); + _boltVolleyTimer = urand(15000, 22000); + } + else + _boltVolleyTimer -= diff; + } + else if (_instance->GetData(DATA_ESCAPE_EVENT) == FAIL || _instance->GetData(DATA_ESCAPE_EVENT) == NOT_STARTED) + me->DespawnOrUnsummon(); + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_risen_witch_doctorAI(creature); + } +}; + + +class npc_lumbering_abomination : public CreatureScript +{ +public: + npc_lumbering_abomination() : CreatureScript("npc_lumbering_abomination") { } + + struct npc_lumbering_abominationAI : public ScriptedAI + { + npc_lumbering_abominationAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } + + InstanceScript* _instance; + uint64 _leaderGUID; + bool _doWalk; + uint32 _strikeTimer; + uint32 _vomitTimer; + + void Reset() OVERRIDE + { + _doWalk = false; + _vomitTimer = 15000; + _strikeTimer = 6000; + if (_instance) + if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + _instance->SetData(DATA_SUMMONS, 1); + } + + void IsSummonedBy(Unit*) OVERRIDE + { + DoCast(me, SPELL_EMERGE_VISUAL); + DoZoneInCombat(me, 100.00f); + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!_instance) + return; + + if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + { + if (_doWalk != true) + { + _doWalk = true; + _leaderGUID = _instance->GetData64(DATA_ESCAPE_LEADER); + if (Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) + { + DoResetThreat(); + me->GetMotionMaster()->MoveIdle(); + me->GetMotionMaster()->MoveChase(leader); + } + } + if (_strikeTimer < diff) + { + if (Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO)) + DoCast(target, SPELL_ABON_STRIKE); + _strikeTimer = urand(7000, 9000); + } + else + _strikeTimer -= diff; + + if (_vomitTimer < diff) + { + if (Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO)) + DoCast(target, SPELL_VOMIT_SPRAY); + _vomitTimer = urand(15000, 20000); + } + else + _vomitTimer -= diff; + } + else if (_instance->GetData(DATA_ESCAPE_EVENT) == FAIL || _instance->GetData(DATA_ESCAPE_EVENT) == NOT_STARTED) + me->DespawnOrUnsummon(); + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + if (_instance) + _instance->SetData(DATA_SUMMONS, 0); + } + + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_lumbering_abominationAI(creature); + } +}; + void AddSC_halls_of_reflection() { + new at_hor_intro_start(); + new at_hor_waves_restarter(); + new at_shadow_throne(); new npc_jaina_or_sylvanas_hor(); + new npc_jaina_or_sylvanas_escape_hor(); new npc_ghostly_priest(); new npc_phantom_mage(); new npc_phantom_hallucination(); new npc_shadowy_mercenary(); new npc_spectral_footman(); new npc_tortured_rifleman(); - new at_hor_intro_start(); - new at_hor_waves_restarter(); + new npc_raging_ghoul(); + new npc_risen_witch_doctor(); + new npc_lumbering_abomination(); new npc_frostworn_general(); new npc_spiritual_reflection(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h index c5fe115978f..3223ecf66a5 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h @@ -39,6 +39,11 @@ enum Data DATA_TEAM_IN_INSTANCE = 6, DATA_FROSTMOURNE = 7, DATA_FROSTWORN_DOOR = 8, + DATA_ESCAPE_EVENT = 9, + DATA_ESCAPE_LEADER = 10, + DATA_SUMMONS = 11, + DATA_ICEWALL = 12, + DATA_CAVE_IN = 13 }; enum Creatures @@ -67,6 +72,10 @@ enum Creatures NPC_BARTLETT = 37182, // High Captain Justin Bartlett NPC_KORM = 37833, // Sky-Reaver Korm Blackscar NPC_ICE_WALL = 37014, // Ice Wall Target + + NPC_RAGING_GNOUL = 36940, + NPC_RISEN_WITCH_DOCTOR = 36941, + NPC_ABON = 37069 }; enum GameObjects @@ -102,6 +111,8 @@ enum HorWorldStates enum Actions { ACTION_ENTER_COMBAT, + ACTION_START_ESCAPING, + ACTION_WALL_BROKEN }; enum TrashGeneralSpells diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index 115127b8c2f..c5c1811d30e 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -24,7 +24,9 @@ Position const JainaSpawnPos = {5236.659f, 1929.894f, 707.7781f, 0.8726646f}; // Jaina Spawn Position Position const SylvanasSpawnPos = {5236.667f, 1929.906f, 707.7781f, 0.8377581f}; // Sylvanas Spawn Position -Position const GeneralSpawnPos = {5415.538f, 2117.842f, 707.7781f, 3.944444f}; // Frostsworn General +Position const GeneralSpawnPos = {5415.538f, 2117.842f, 707.7781f, 3.944444f}; // Frostsworn General +Position const JainaSpawnPos2 = {5549.011f, 2257.041f, 733.0120f, 1.153993f}; // Jaina Spawn Position 2 +Position const SylvanasSpawnPos2 = {5549.011f, 2257.041f, 733.0120f, 1.153993f}; // Sylvanas Spawn Position 2 Position const SpawnPos[] = { @@ -73,7 +75,7 @@ public: { instance_halls_of_reflection_InstanceMapScript(Map* map) : InstanceScript(map) {} - void Initialize() + void Initialize() OVERRIDE { SetBossNumber(MAX_ENCOUNTER); events.Reset(); @@ -87,17 +89,19 @@ public: _arthasDoorGUID = 0; _teamInInstance = 0; _waveCount = 0; + _mobsaticewall = 0; _introEvent = NOT_STARTED; _frostwornGeneral = NOT_STARTED; + _escapeevent = NOT_STARTED; } - void OnPlayerEnter(Player* player) + void OnPlayerEnter(Player* player) OVERRIDE { if (!_teamInInstance) _teamInInstance = player->GetTeam(); } - void OnCreatureCreate(Creature* creature) + void OnCreatureCreate(Creature* creature) OVERRIDE { Map::PlayerList const& players = instance->GetPlayers(); if (!players.isEmpty()) @@ -122,10 +126,14 @@ public: if (Creature* general = instance->GetCreature(_frostwornGeneralGUID)) general->SetPhaseMask(1, true); break; + case NPC_JAINA_PART2: + case NPC_SYLVANAS_PART2: + _jainaOrSylvanasPart2GUID = creature->GetGUID(); + break; } } - void OnCreatureRemove(Creature* creature) + void OnCreatureRemove(Creature* creature) OVERRIDE { switch (creature->GetEntry()) { @@ -142,7 +150,7 @@ public: } } - void OnGameObjectCreate(GameObject* go) + void OnGameObjectCreate(GameObject* go) OVERRIDE { switch (go->GetEntry()) { @@ -173,17 +181,21 @@ public: HandleGameObject(0, true, go); else HandleGameObject(0, false, go); + break; + case GO_CAVE: + _caveGUID = go->GetGUID(); + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); break; } } - void FillInitialWorldStates(WorldPacket& data) + void FillInitialWorldStates(WorldPacket& data) OVERRIDE { data << uint32(WORLD_STATE_HOR_WAVES_ENABLED) << uint32(0); data << uint32(WORLD_STATE_HOR_WAVE_COUNT) << uint32(0); } - bool SetBossState(uint32 type, EncounterState state) + bool SetBossState(uint32 type, EncounterState state) OVERRIDE { if (!InstanceScript::SetBossState(type, state)) return false; @@ -202,12 +214,12 @@ public: { HandleGameObject(_entranceDoorGUID, true); HandleGameObject(_frostwornDoorGUID, true); + DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 0); if (Creature* general = instance->GetCreature(_frostwornGeneralGUID)) general->SetPhaseMask(1, true); } break; case DATA_LICHKING_EVENT: - break; default: break; } @@ -240,10 +252,44 @@ public: if (data == DONE) { HandleGameObject(_arthasDoorGUID, true); - // spawn Jaina part 2 - // spawn LK part 2 + if (_teamInInstance == ALLIANCE) + instance->SummonCreature(NPC_JAINA_PART2, JainaSpawnPos2); + else + instance->SummonCreature(NPC_SYLVANAS_PART2, SylvanasSpawnPos2); } - _frostwornGeneral = data; + _frostwornGeneral = data; + break; + case DATA_ESCAPE_EVENT: + if (data == IN_PROGRESS) + { + if (!_escapeevent) + if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID)) + jaina_or_sylvanas->AI()->DoAction(ACTION_START_ESCAPING); + } + else if (data == NOT_STARTED) + { + if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID)) + jaina_or_sylvanas->DespawnOrUnsummon(1); + if (_teamInInstance == ALLIANCE) + instance->SummonCreature(NPC_JAINA_PART2, JainaSpawnPos2); + else + instance->SummonCreature(NPC_SYLVANAS_PART2, SylvanasSpawnPos2); + SetData(DATA_ESCAPE_EVENT,IN_PROGRESS); + } + _escapeevent = data; + break; + case DATA_SUMMONS: + if (data == 0) + { + _mobsaticewall--; + if (_mobsaticewall == 0) + { + if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID)) + jaina_or_sylvanas->AI()->DoAction(ACTION_WALL_BROKEN); + } + } + else if (data == 1) + _mobsaticewall++; break; } @@ -252,7 +298,7 @@ public: // wave scheduling,checked when wave npcs die - void OnUnitDeath(Unit* unit) + void OnUnitDeath(Unit* unit) OVERRIDE { Creature* creature = unit->ToCreature(); if (!creature) @@ -274,20 +320,19 @@ public: if (!npc || !npc->IsAlive()) ++deadNpcs; } - // because the current npc returns IsAlive when OnUnitDeath happens // we check if the number of dead npcs is equal to the list-1 if (deadNpcs == waveGuidList[waveId].size() - 1) { ++_waveCount; - events.ScheduleEvent(EVENT_NEXT_WAVE, 10000); + events.ScheduleEvent(EVENT_NEXT_WAVE, 3000); } break; } } } - void Update(uint32 diff) + void Update(uint32 diff) OVERRIDE { if (!instance->HavePlayers()) return; @@ -302,7 +347,7 @@ public: } } - void ProcessEvent(WorldObject* /*go*/, uint32 eventId) + void ProcessEvent(WorldObject* /*go*/, uint32 eventId) OVERRIDE { switch (eventId) { @@ -348,7 +393,7 @@ public: } } } - events.ScheduleEvent(EVENT_NEXT_WAVE, 10000); + events.ScheduleEvent(EVENT_NEXT_WAVE, 5000); break; case EVENT_ADD_WAVE: DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); @@ -364,7 +409,7 @@ public: { temp->CastSpell(temp, SPELL_SPIRIT_ACTIVATE, true); temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC|UNIT_FLAG_NOT_SELECTABLE); - temp->AI()->DoZoneInCombat(); + temp->AI()->DoZoneInCombat(temp, 100.00f); } } } @@ -374,13 +419,12 @@ public: if (GetBossState(DATA_FALRIC_EVENT + bossIndex) != DONE) { if (Creature* boss = instance->GetCreature(bossIndex ? _marwynGUID : _falricGUID)) - if (boss->AI()) - boss->AI()->DoAction(ACTION_ENTER_COMBAT); + boss->AI()->DoAction(ACTION_ENTER_COMBAT); } else if (_waveCount != 10) { ++_waveCount; - events.ScheduleEvent(EVENT_NEXT_WAVE, 10000); + events.ScheduleEvent(EVENT_NEXT_WAVE, 5000); } } break; @@ -395,14 +439,12 @@ public: falric->SetVisible(false); if (Creature* marwyn = instance->GetCreature(_marwynGUID)) marwyn->SetVisible(false); - //despawn wave npcs for (uint8 i = 0; i < 8; ++i) { for (std::set<uint64>::const_iterator itr = waveGuidList[i].begin(); itr != waveGuidList[i].end(); ++itr) if (Creature* creature = instance->GetCreature(*itr)) creature->DespawnOrUnsummon(1); - waveGuidList[i].clear(); } break; @@ -421,6 +463,10 @@ public: return _introEvent; case DATA_FROSWORN_EVENT: return _frostwornGeneral; + case DATA_ESCAPE_EVENT: + return _escapeevent; + case DATA_SUMMONS: + return _mobsaticewall; default: break; } @@ -442,6 +488,10 @@ public: return _frostwornDoorGUID; case DATA_FROSTMOURNE: return _frostmourneGUID; + case DATA_ESCAPE_LEADER: + return _jainaOrSylvanasPart2GUID; + case DATA_CAVE_IN: + return _caveGUID; default: break; } @@ -449,18 +499,18 @@ public: return 0; } - std::string GetSaveData() + std::string GetSaveData() OVERRIDE { OUT_SAVE_INST_DATA; std::ostringstream saveStream; - saveStream << "H R " << GetBossSaveData() << _introEvent << ' ' << _frostwornGeneral; + saveStream << "H R " << GetBossSaveData() << _introEvent << ' ' << _frostwornGeneral << _escapeevent; OUT_SAVE_INST_DATA_COMPLETE; return saveStream.str(); } - void Load(char const* in) + void Load(char const* in) OVERRIDE { if (!in) { @@ -499,6 +549,12 @@ public: SetData(DATA_FROSWORN_EVENT, DONE); else SetData(DATA_FROSWORN_EVENT, NOT_STARTED); + + loadStream >> temp; + if (temp == DONE) + SetData(DATA_ESCAPE_EVENT, DONE); + else + SetData(DATA_ESCAPE_EVENT, NOT_STARTED); } else OUT_LOAD_INST_DATA_FAIL; @@ -510,6 +566,8 @@ public: uint64 _falricGUID; uint64 _marwynGUID; uint64 _jainaOrSylvanasPart1GUID; + uint64 _jainaOrSylvanasPart2GUID; + uint64 _lichkingPart1GUID; uint64 _frostwornGeneralGUID; uint64 _frostmourneGUID; @@ -517,11 +575,14 @@ public: uint64 _frostwornDoorGUID; uint64 _arthasDoorGUID; uint64 _escapeDoorGUID; + uint64 _caveGUID; uint32 _teamInInstance; uint32 _waveCount; uint32 _introEvent; uint32 _frostwornGeneral; + uint32 _escapeevent; + uint32 _mobsaticewall; EventMap events; diff --git a/src/server/scripts/World/achievement_scripts.cpp b/src/server/scripts/World/achievement_scripts.cpp index 774c4e63071..0243b08e80e 100644 --- a/src/server/scripts/World/achievement_scripts.cpp +++ b/src/server/scripts/World/achievement_scripts.cpp @@ -40,7 +40,7 @@ class achievement_resilient_victory : public AchievementCriteriaScript if (bg->GetTypeID(true) != BATTLEGROUND_AB) return false; - if (!static_cast<BattlegroundAB*>(bg)->IsTeamScores500Disadvantage(source->GetTeam())) + if (!bg->ToBattlegroundAB()->IsTeamScores500Disadvantage(source->GetTeam())) return false; return true; @@ -84,7 +84,7 @@ class achievement_save_the_day : public AchievementCriteriaScript if (bg->GetTypeID(true) != BATTLEGROUND_WS) return false; - if (static_cast<BattlegroundWS*>(bg)->GetFlagState(player->GetTeam()) == BG_WS_FLAG_STATE_ON_BASE) + if (bg->ToBattlegroundWS()->GetFlagState(player->GetTeam()) == BG_WS_FLAG_STATE_ON_BASE) return true; } return false; @@ -209,7 +209,7 @@ class achievement_everything_counts : public AchievementCriteriaScript if (bg->GetTypeID(true) != BATTLEGROUND_AV) return false; - if (static_cast<BattlegroundAV*>(bg)->IsBothMinesControlledByTeam(source->GetTeam())) + if (bg->ToBattlegroundAV()->IsBothMinesControlledByTeam(source->GetTeam())) return true; return false; @@ -230,7 +230,7 @@ class achievement_bg_av_perfection : public AchievementCriteriaScript if (bg->GetTypeID(true) != BATTLEGROUND_AV) return false; - if (static_cast<BattlegroundAV*>(bg)->IsAllTowersControlledAndCaptainAlive(source->GetTeam())) + if (bg->ToBattlegroundAV()->IsAllTowersControlledAndCaptainAlive(source->GetTeam())) return true; return false; @@ -253,10 +253,10 @@ class achievement_bg_sa_defense_of_ancients : public AchievementCriteriaScript if (!battleground) return false; - if (player->GetTeamId() == static_cast<BattlegroundSA*>(battleground)->Attackers) + if (player->GetTeamId() == battleground->ToBattlegroundSA()->Attackers) return false; - if (!static_cast<BattlegroundSA*>(battleground)->gateDestroyed) + if (!battleground->ToBattlegroundSA()->gateDestroyed) return true; return false; @@ -308,7 +308,7 @@ class achievement_not_even_a_scratch : public AchievementCriteriaScript if (!battleground) return false; - if (static_cast<BattlegroundSA*>(battleground)->notEvenAScratch(source->GetTeam())) + if (battleground->ToBattlegroundSA()->notEvenAScratch(source->GetTeam())) return true; return false; |