From 9d914d206a5b63d5920ce488c0b5205320183e37 Mon Sep 17 00:00:00 2001 From: Butterfly69 Date: Fri, 7 Dec 2012 00:24:59 +0430 Subject: Core/Spells:Beacon of Light When holy paladin put beacon on someone and heal someone else, it shows up that the player with the beacon is being healed by himself, instead of the person who casting the Beacon. This problem Can be solved by this. --- src/server/game/Entities/Unit/Unit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c469edd1112..2569a8ccddf 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6671,7 +6671,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere if (triggered_spell_id && beaconTarget) { - victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, NULL, NULL, true, 0, triggeredByAura); + victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, NULL, NULL, true); return true; } -- cgit v1.2.3 From 9f9f797d5d587f26aac57e2f92188b5ddad58216 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Tue, 8 Jan 2013 23:00:40 +0100 Subject: Scripts/TOCR: Fix some faction champions crash Closes #8393 --- .../TrialOfTheCrusader/boss_faction_champions.cpp | 48 ++++++++++++++-------- 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp index 32d4c621450..ba554c3703d 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp @@ -29,7 +29,7 @@ enum Yells SAY_KILL_PLAYER = 6 }; -enum eAIs +enum AIs { AI_MELEE = 0, AI_RANGED = 1, @@ -1484,8 +1484,11 @@ class mob_toc_hunter : public CreatureScript events.ScheduleEvent(EVENT_STEADY_SHOT, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS)); return; case EVENT_WING_CLIP: - if (me->GetDistance2d(me->getVictim()) < 6.0f) - DoCastVictim(SPELL_WING_CLIP); + if (Unit* target = me->getVictim()) + { + if (me->GetDistance2d(target) < 6.0f) + DoCast(target, SPELL_WING_CLIP); + } events.ScheduleEvent(EVENT_WING_CLIP, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS)); return; case EVENT_WYVERN_STING: @@ -1670,13 +1673,16 @@ class mob_toc_warrior : public CreatureScript events.ScheduleEvent(EVENT_SUNDER_ARMOR, urand(2*IN_MILLISECONDS, 5*IN_MILLISECONDS)); return; case EVENT_SHATTERING_THROW: - if (me->getVictim()->HasAuraWithMechanic(1<getVictim()) { - DoCastVictim(SPELL_SHATTERING_THROW); - events.RescheduleEvent(EVENT_SHATTERING_THROW, 5*MINUTE*IN_MILLISECONDS); + if (target->HasAuraWithMechanic(1 << MECHANIC_IMMUNE_SHIELD)) + { + DoCast(target, SPELL_SHATTERING_THROW); + events.RescheduleEvent(EVENT_SHATTERING_THROW, 5*MINUTE*IN_MILLISECONDS); + return; + } } - else - events.RescheduleEvent(EVENT_SHATTERING_THROW, 3*IN_MILLISECONDS); + events.RescheduleEvent(EVENT_SHATTERING_THROW, 3*IN_MILLISECONDS); return; case EVENT_RETALIATION: if (HealthBelowPct(50)) @@ -1746,13 +1752,16 @@ class mob_toc_dk : public CreatureScript events.ScheduleEvent(EVENT_DEATH_COIL, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS)); return; case EVENT_DEATH_GRIP: - if (me->IsInRange(me->getVictim(), 5.0f, 30.0f, false)) + if (Unit* target = me->getVictim()) { - DoCast(me->getVictim(), SPELL_DEATH_GRIP); - events.RescheduleEvent(EVENT_DEATH_GRIP, 35*IN_MILLISECONDS); + if (me->IsInRange(target, 5.0f, 30.0f, false)) + { + DoCast(target, SPELL_DEATH_GRIP); + events.RescheduleEvent(EVENT_DEATH_GRIP, 35*IN_MILLISECONDS); + return; + } } - else - events.RescheduleEvent(EVENT_DEATH_GRIP, 3*IN_MILLISECONDS); + events.RescheduleEvent(EVENT_DEATH_GRIP, 3*IN_MILLISECONDS); return; case EVENT_FROST_STRIKE: DoCastVictim(SPELL_FROST_STRIKE); @@ -1862,13 +1871,16 @@ class mob_toc_rogue : public CreatureScript events.RescheduleEvent(EVENT_BLADE_FLURRY, 5*IN_MILLISECONDS); return; case EVENT_SHADOWSTEP: - if (me->IsInRange(me->getVictim(), 10.0f, 40.0f, false)) + if (Unit* target = me->getVictim()) { - DoCast(me->getVictim(), SPELL_SHADOWSTEP); - events.RescheduleEvent(EVENT_SHADOWSTEP, 30*IN_MILLISECONDS); + if (me->IsInRange(target, 10.0f, 40.0f, false)) + { + DoCast(target, SPELL_SHADOWSTEP); + events.RescheduleEvent(EVENT_SHADOWSTEP, 30*IN_MILLISECONDS); + return; + } } - else - events.RescheduleEvent(EVENT_SHADOWSTEP, 5*IN_MILLISECONDS); + events.RescheduleEvent(EVENT_SHADOWSTEP, 5*IN_MILLISECONDS); return; case EVENT_HEMORRHAGE: DoCastVictim(SPELL_HEMORRHAGE); -- cgit v1.2.3 From 677ed180802541d4bf487eeaa554c01aa3dc5ceb Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 9 Jan 2013 15:15:42 +0100 Subject: Core/Dungeon Finder: Fix group (5) unable to do new dungeon after finished last dungeon - Some optimizations here and there - Drop unused columns related to dungeon rewards - Simplify Group reward. All people inside the dungeon should get the reward, no matter how far it's from the boss --- .../2013_01_09_world_lfg_dungeon_rewards.sql | 6 + src/server/game/DungeonFinding/LFGMgr.cpp | 253 ++++++++++----------- src/server/game/DungeonFinding/LFGMgr.h | 49 ++-- src/server/game/DungeonFinding/LFGPlayerData.cpp | 4 +- src/server/game/DungeonFinding/LFGQueue.cpp | 6 +- src/server/game/DungeonFinding/LFGQueue.h | 4 +- src/server/game/DungeonFinding/LFGScripts.cpp | 10 - src/server/game/Handlers/BattleGroundHandler.cpp | 2 +- src/server/game/Handlers/LFGHandler.cpp | 91 ++++---- src/server/game/Instances/InstanceScript.cpp | 38 +++- src/server/game/Server/Protocol/Opcodes.cpp | 2 +- src/server/game/Server/WorldSession.h | 40 ++-- .../ScarletMonastery/boss_headless_horseman.cpp | 6 +- 13 files changed, 263 insertions(+), 248 deletions(-) create mode 100644 sql/updates/2013_01_09_world_lfg_dungeon_rewards.sql (limited to 'src') diff --git a/sql/updates/2013_01_09_world_lfg_dungeon_rewards.sql b/sql/updates/2013_01_09_world_lfg_dungeon_rewards.sql new file mode 100644 index 00000000000..dfc5f7cf075 --- /dev/null +++ b/sql/updates/2013_01_09_world_lfg_dungeon_rewards.sql @@ -0,0 +1,6 @@ +ALTER TABLE `lfg_dungeon_rewards` + DROP `firstMoneyVar`, + DROP `firstXPVar`, + DROP `otherMoneyVar`, + DROP `otherXPVar`; + diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 2550f909a8b..9d5d8e40b54 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -188,7 +188,7 @@ void LFGMgr::LoadRewards() RewardMapStore.clear(); // ORDER BY is very important for GetRandomDungeonReward! - QueryResult result = WorldDatabase.Query("SELECT dungeonId, maxLevel, firstQuestId, firstMoneyVar, firstXPVar, otherQuestId, otherMoneyVar, otherXPVar FROM lfg_dungeon_rewards ORDER BY dungeonId, maxLevel ASC"); + QueryResult result = WorldDatabase.Query("SELECT dungeonId, maxLevel, firstQuestId, otherQuestId FROM lfg_dungeon_rewards ORDER BY dungeonId, maxLevel ASC"); if (!result) { @@ -205,11 +205,7 @@ void LFGMgr::LoadRewards() uint32 dungeonId = fields[0].GetUInt32(); uint32 maxLevel = fields[1].GetUInt8(); uint32 firstQuestId = fields[2].GetUInt32(); - uint32 firstMoneyVar = fields[3].GetUInt32(); - uint32 firstXPVar = fields[4].GetUInt32(); - uint32 otherQuestId = fields[5].GetUInt32(); - uint32 otherMoneyVar = fields[6].GetUInt32(); - uint32 otherXPVar = fields[7].GetUInt32(); + uint32 otherQuestId = fields[3].GetUInt32(); if (!GetLFGDungeon(dungeonId)) { @@ -223,10 +219,10 @@ void LFGMgr::LoadRewards() maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); } - if (firstQuestId && !sObjectMgr->GetQuestTemplate(firstQuestId)) + if (!firstQuestId || !sObjectMgr->GetQuestTemplate(firstQuestId)) { sLog->outError(LOG_FILTER_SQL, "First quest %u specified for dungeon %u in table `lfg_dungeon_rewards` does not exist!", firstQuestId, dungeonId); - firstQuestId = 0; + continue; } if (otherQuestId && !sObjectMgr->GetQuestTemplate(otherQuestId)) @@ -235,9 +231,10 @@ void LFGMgr::LoadRewards() otherQuestId = 0; } - RewardMapStore.insert(LfgRewardContainer::value_type(dungeonId, new LfgReward(maxLevel, firstQuestId, firstMoneyVar, firstXPVar, otherQuestId, otherMoneyVar, otherXPVar))); + RewardMapStore.insert(LfgRewardContainer::value_type(dungeonId, new LfgReward(maxLevel, firstQuestId, otherQuestId))); ++count; - } while (result->NextRow()); + } + while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u lfg dungeon rewards in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } @@ -434,7 +431,7 @@ void LFGMgr::Update(uint32 diff) } else SendLfgUpdatePlayer(guid, LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid))); - SendLfgUpdateProposal(guid, m_lfgProposalId, proposal); + SendLfgUpdateProposal(guid, proposal); } if (proposal.state == LFG_PROPOSAL_SUCCESS) @@ -552,27 +549,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const LfgState state = GetState(gguid); if (state == LFG_STATE_QUEUED) { - LfgDungeonSet const& playerDungeons = GetSelectedDungeons(guid); - if (playerDungeons == dungeons) // Joining the same dungeons -- Send OK - { - player->GetSession()->SendLfgJoinResult(joinData); // Default value of joinData.result = LFG_JOIN_OK - if (grp) - { - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, comment); - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) - if (itr->getSource() && itr->getSource()->GetSession()) - itr->getSource()->GetSession()->SendLfgUpdateParty(updateData); - } - else - player->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_QUEUE, dungeons, comment)); - - return; - } - else // Remove from queue and rejoin - { - LFGQueue& queue = GetQueue(gguid); - queue.RemoveFromQueue(gguid); - } + LFGQueue& queue = GetQueue(gguid); + queue.RemoveFromQueue(gguid); } // Check player or group member restrictions @@ -620,7 +598,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const bool isDungeon = false; for (LfgDungeonSet::const_iterator it = dungeons.begin(); it != dungeons.end() && joinData.result == LFG_JOIN_OK; ++it) { - switch (GetDungeonType(*it)) + LfgType type = GetDungeonType(*it); + switch (type) { case LFG_TYPE_RANDOM: if (dungeons.size() > 1) // Only allow 1 random dungeon @@ -640,6 +619,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const isRaid = true; break; default: + sLog->outError(LOG_FILTER_LFG, "Wrong dungeon type %u for dungeon %u", type, *it); joinData.result = LFG_JOIN_DUNGEON_INVALID; break; } @@ -719,8 +699,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { LfgRolesMap rolesMap; rolesMap[guid] = roles; - LFGQueue& queue = GetQueue(gguid); - queue.AddQueueData(guid, time_t(time(NULL)), dungeons, rolesMap); + LFGQueue& queue = GetQueue(guid); + queue.AddQueueData(guid, time(NULL), dungeons, rolesMap); if (!isContinue) { @@ -873,7 +853,7 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* { uint64 pguid = it->first; - if (!sendRoleChosen) + if (sendRoleChosen) SendLfgRoleChosen(pguid, guid, roles); SendLfgRoleCheckUpdate(pguid, roleCheck); @@ -916,7 +896,7 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /* @param[in] players Set of players to check their dungeon restrictions @param[out] lockMap Map of players Lock status info of given dungeons (Empty if dungeons is not empty) */ -void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, const LfgGuidSet& players, LfgLockPartyMap& lockMap) +void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap) { lockMap.clear(); for (LfgGuidSet::const_iterator it = players.begin(); it != players.end() && !dungeons.empty(); ++it) @@ -1083,9 +1063,10 @@ void LFGMgr::MakeNewGroup(LfgProposal const& proposal) grp->SendUpdate(); } -uint32 LFGMgr::AddProposal(LfgProposal const& proposal) +uint32 LFGMgr::AddProposal(LfgProposal& proposal) { - ProposalsStore[++m_lfgProposalId] = proposal; + proposal.id = ++m_lfgProposalId; + ProposalsStore[m_lfgProposalId] = proposal; return m_lfgProposalId; } @@ -1129,16 +1110,14 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) if (!allAnswered) { for (LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it) - { - uint64 guid = it->first; - SendLfgUpdateProposal(guid, proposalId, proposal); - } + SendLfgUpdateProposal(it->first, proposal); + return; } bool sendUpdate = proposal.state != LFG_PROPOSAL_SUCCESS; proposal.state = LFG_PROPOSAL_SUCCESS; - time_t joinTime = time_t(time(NULL)); + time_t joinTime = time(NULL); LFGQueue& queue = GetQueue(guid); LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND); @@ -1149,7 +1128,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) uint32 dungeonId = (*GetSelectedDungeons(pguid).begin()); int32 waitTime = -1; if (sendUpdate) - SendLfgUpdateProposal(pguid, proposalId, proposal); + SendLfgUpdateProposal(pguid, proposal); if (gguid) { @@ -1236,7 +1215,7 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate uint64 guid = it->first; uint64 gguid = it->second.group ? it->second.group : guid; - SendLfgUpdateProposal(guid, itProposal->first, proposal); + SendLfgUpdateProposal(guid, proposal); if (toRemove.find(gguid) != toRemove.end()) // Didn't accept or in same group that someone that didn't accept { @@ -1465,106 +1444,126 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* } } - if (error == LFG_TELEPORTERROR_OK) - { - if (!player->GetMap()->IsDungeon()) - player->SetBattlegroundEntryPoint(); - - if (player->isInFlight()) - { - player->GetMotionMaster()->MovementExpired(); - player->CleanupAfterTaxiFlight(); - } + if (!player->GetMap()->IsDungeon()) + player->SetBattlegroundEntryPoint(); - if (!player->TeleportTo(mapid, x, y, z, orientation)) - { - error = LFG_TELEPORTERROR_INVALID_LOCATION; - sLog->outError(LOG_FILTER_LFG, "TeleportPlayer: Failed to teleport [" UI64FMTD "] to map %u (x: %f, y: %f, z: %f)", player->GetGUID(), mapid, x, y, z); - } + if (player->isInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->CleanupAfterTaxiFlight(); } + + if (!player->TeleportTo(mapid, x, y, z, orientation)) + error = LFG_TELEPORTERROR_INVALID_LOCATION; } + else + error = LFG_TELEPORTERROR_INVALID_LOCATION; if (error != LFG_TELEPORTERROR_OK) player->GetSession()->SendLfgTeleportError(uint8(error)); - sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported in. Result: %u", - player->GetName().c_str(), error); + sLog->outDebug(LOG_FILTER_LFG, "TeleportPlayer: Player %s is being teleported in to map %u " + "(x: %f, y: %f, z: %f) Result: %u", player->GetName().c_str(), dungeon->map, + dungeon->x, dungeon->y, dungeon->z, error); } /** - Give completion reward to player + Finish a dungeon and give reward, if any. - @param[in] dungeonId Id of the dungeon finished - @param[in] player Player to reward + @param[in] guid Group guid + @param[in] dungeonId Dungeonid */ -void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) +void LFGMgr::FinishDungeon(uint64 gguid, const uint32 dungeonId) { - Group* group = player->GetGroup(); - if (!group || !group->isLFGGroup()) - { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] is not in a group or not a LFGGroup. Ignoring", player->GetGUID()); - return; - } - - uint64 guid = player->GetGUID(); - uint64 gguid = player->GetGroup()->GetGUID(); uint32 gDungeonId = GetDungeon(gguid); if (gDungeonId != dungeonId) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] Finished dungeon %u but group queued for %u. Ignoring", guid, dungeonId, gDungeonId); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Finished dungeon %u but group queued for %u. Ignoring", gguid, dungeonId, gDungeonId); return; } - if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON) + if (GetState(gguid) == LFG_STATE_FINISHED_DUNGEON) // Shouldn't happen. Do not reward multiple times { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] Already rewarded player. Ignoring", guid); + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Already rewarded group. Ignoring", gguid); return; } - // Mark dungeon as finished SetState(gguid, LFG_STATE_FINISHED_DUNGEON); - // Clear player related lfg stuff - uint32 rDungeonId = (*GetSelectedDungeons(guid).begin()); - SetState(guid, LFG_STATE_FINISHED_DUNGEON); - - // Give rewards only if its a random or seasonal dungeon - LFGDungeonData const* dungeon = GetLFGDungeon(rDungeonId); - if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal)) + const LfgGuidSet& players = GetPlayers(gguid); + for (LfgGuidSet::const_iterator it = players.begin(); it != players.end(); ++it) { - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] dungeon %u is not random nor seasonal", guid, rDungeonId); - return; - } + uint64 guid = (*it); + if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] Already rewarded player. Ignoring", guid); + continue; + } - // Update achievements - if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); + uint32 rDungeonId = 0; + const LfgDungeonSet& dungeons = GetSelectedDungeons(guid); + if (!dungeons.empty()) + rDungeonId = (*dungeons.begin()); - LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); - if (!reward) - return; + SetState(guid, LFG_STATE_FINISHED_DUNGEON); - uint8 index = 0; - Quest const* qReward = sObjectMgr->GetQuestTemplate(reward->reward[index].questId); - if (!qReward) - return; + // Give rewards only if its a random dungeon + LFGDungeonData const* dungeon = GetLFGDungeon(rDungeonId); - // if we can take the quest, means that we haven't done this kind of "run", IE: First Heroic Random of Day. - if (player->CanRewardQuest(qReward, false)) - player->RewardQuest(qReward, 0, NULL, false); - else - { - index = 1; - qReward = sObjectMgr->GetQuestTemplate(reward->reward[index].questId); - if (!qReward) - return; - // we give reward without informing client (retail does this) - player->RewardQuest(qReward, 0, NULL, false); - } + if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal)) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] dungeon %u is not random or seasonal", guid, rDungeonId); + continue; + } + + Player* player = ObjectAccessor::FindPlayer(guid); + if (!player || !player->IsInWorld()) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] not found in world", guid); + continue; + } + + LFGDungeonData const* dungeonDone = GetLFGDungeon(dungeonId); + uint32 mapId = dungeonDone ? uint32(dungeonDone->map) : 0; - // Give rewards - sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::RewardDungeonDoneFor: [" UI64FMTD "] done dungeon %u, %s previously done.", player->GetGUID(), GetDungeon(gguid), index > 0 ? " " : " not"); - player->GetSession()->SendLfgPlayerReward(dungeon->Entry(), GetDungeon(gguid, false), index, reward, qReward); + if (player->GetMapId() != mapId) + { + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] is in map %u and should be in %u to get reward", guid, player->GetMapId(), mapId); + continue; + } + + // Update achievements + if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); + + LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); + if (!reward) + continue; + + bool done = false; + Quest const* quest = sObjectMgr->GetQuestTemplate(reward->firstQuest); + if (!quest) + continue; + + // if we can take the quest, means that we haven't done this kind of "run", IE: First Heroic Random of Day. + if (player->CanRewardQuest(quest, false)) + player->RewardQuest(quest, 0, NULL, false); + else + { + done = true; + quest = sObjectMgr->GetQuestTemplate(reward->otherQuest); + if (!quest) + continue; + // we give reward without informing client (retail does this) + player->RewardQuest(quest, 0, NULL, false); + } + + // Give rewards + sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FinishDungeon: [" UI64FMTD "] done dungeon %u, %s previously done.", player->GetGUID(), GetDungeon(gguid), done? " " : " not"); + LfgPlayerRewardData data = LfgPlayerRewardData(dungeon->Entry(), GetDungeon(gguid, false), done, quest); + player->GetSession()->SendLfgPlayerReward(data); + } + SetDungeon(gguid, 0); } // --------------------------------------------------------------------------// @@ -1577,7 +1576,7 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) @param[in] randomdungeon Random dungeon id (if value = 0 will return all dungeons) @returns Set of dungeons that can be done. */ -const LfgDungeonSet& LFGMgr::GetDungeonsByRandom(uint32 randomdungeon) +LfgDungeonSet const& LFGMgr::GetDungeonsByRandom(uint32 randomdungeon) { LFGDungeonData const* dungeon = GetLFGDungeon(randomdungeon); uint32 group = dungeon ? dungeon->group : 0; @@ -1675,13 +1674,13 @@ bool LFGMgr::IsTeleported(uint64 pguid) return false; } -const LfgDungeonSet& LFGMgr::GetSelectedDungeons(uint64 guid) +LfgDungeonSet const& LFGMgr::GetSelectedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetSelectedDungeons: [" UI64FMTD "]", guid); return PlayersStore[guid].GetSelectedDungeons(); } -const LfgLockMap& LFGMgr::GetLockedDungeons(uint64 guid) +LfgLockMap const& LFGMgr::GetLockedDungeons(uint64 guid) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::GetLockedDungeons: [" UI64FMTD "]", guid); return PlayersStore[guid].GetLockedDungeons(); @@ -1728,7 +1727,7 @@ void LFGMgr::SetState(uint64 guid, LfgState state) if (IS_GROUP_GUID(guid)) { LfgGroupData& data = GroupsStore[guid]; - if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_TRACE)) { std::string const& ns = GetStateString(state); std::string const& ps = GetStateString(data.GetState()); @@ -1741,7 +1740,7 @@ void LFGMgr::SetState(uint64 guid, LfgState state) else { LfgPlayerData& data = PlayersStore[guid]; - if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG)) + if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_TRACE)) { std::string const& ns = GetStateString(state); std::string const& ps = GetStateString(data.GetState()); @@ -1765,19 +1764,19 @@ void LFGMgr::SetRoles(uint64 guid, uint8 roles) PlayersStore[guid].SetRoles(roles); } -void LFGMgr::SetComment(uint64 guid, const std::string& comment) +void LFGMgr::SetComment(uint64 guid, std::string const& comment) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetComment: [" UI64FMTD "] comment: %s", guid, comment.c_str()); PlayersStore[guid].SetComment(comment); } -void LFGMgr::SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons) +void LFGMgr::SetSelectedDungeons(uint64 guid, LfgDungeonSet const& dungeons) { - sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetSelectedDungeons: [" UI64FMTD "]", guid); + sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetSelectedDungeons: [" UI64FMTD "] Dungeons: %s", guid, ConcatenateDungeons(dungeons).c_str()); PlayersStore[guid].SetSelectedDungeons(dungeons); } -void LFGMgr::SetLockedDungeons(uint64 guid, const LfgLockMap& lock) +void LFGMgr::SetLockedDungeons(uint64 guid, LfgLockMap const& lock) { sLog->outTrace(LOG_FILTER_LFG, "LFGMgr::SetLockedDungeons: [" UI64FMTD "]", guid); PlayersStore[guid].SetLockedDungeons(lock); @@ -1918,10 +1917,10 @@ void LFGMgr::SendLfgBootProposalUpdate(uint64 guid, LfgPlayerBoot const& boot) player->GetSession()->SendLfgBootProposalUpdate(boot); } -void LFGMgr::SendLfgUpdateProposal(uint64 guid, uint32 proposalId, LfgProposal const& proposal) +void LFGMgr::SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal) { if (Player* player = ObjectAccessor::FindPlayer(guid)) - player->GetSession()->SendLfgUpdateProposal(proposalId, proposal); + player->GetSession()->SendLfgUpdateProposal(proposal); } void LFGMgr::SendLfgQueueStatus(uint64 guid, LfgQueueStatusData const& data) @@ -1940,7 +1939,7 @@ LFGQueue& LFGMgr::GetQueue(uint64 guid) uint8 queueId = 0; if (IS_GROUP_GUID(guid)) { - const LfgGuidSet& players = GetPlayers(guid); + LfgGuidSet const& players = GetPlayers(guid); uint64 pguid = players.empty() ? 0 : (*players.begin()); if (pguid) queueId = GetTeam(pguid); diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 2041c18a081..0a1b90ee04d 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -28,6 +28,7 @@ class Group; class Player; +class Quest; enum LfgOptions { @@ -37,9 +38,9 @@ enum LfgOptions enum LFGMgrEnum { - LFG_TIME_ROLECHECK = 40 * IN_MILLISECONDS, + LFG_TIME_ROLECHECK = 45 * IN_MILLISECONDS, LFG_TIME_BOOT = 120, - LFG_TIME_PROPOSAL = 120, + LFG_TIME_PROPOSAL = 45, LFG_QUEUEUPDATE_INTERVAL = 15 * IN_MILLISECONDS, LFG_SPELL_DUNGEON_COOLDOWN = 71328, LFG_SPELL_DUNGEON_DESERTER = 71041, @@ -188,27 +189,25 @@ struct LfgQueueStatusData uint8 dps; }; +struct LfgPlayerRewardData +{ + LfgPlayerRewardData(uint32 random, uint32 current, bool _done, Quest const* _quest): + rdungeonEntry(random), sdungeonEntry(current), done(_done), quest(_quest) { } + uint32 rdungeonEntry; + uint32 sdungeonEntry; + bool done; + Quest const* quest; +}; + /// Reward info struct LfgReward { + LfgReward(uint32 _maxLevel = 0, uint32 _firstQuest = 0, uint32 _otherQuest = 0): + maxLevel(_maxLevel), firstQuest(_firstQuest), otherQuest(_otherQuest) { } + uint32 maxLevel; - struct - { - uint32 questId; - uint32 variableMoney; - uint32 variableXP; - } reward[2]; - - LfgReward(uint32 _maxLevel = 0, uint32 firstQuest = 0, uint32 firstVarMoney = 0, uint32 firstVarXp = 0, uint32 otherQuest = 0, uint32 otherVarMoney = 0, uint32 otherVarXp = 0) - : maxLevel(_maxLevel) - { - reward[0].questId = firstQuest; - reward[0].variableMoney = firstVarMoney; - reward[0].variableXP = firstVarXp; - reward[1].questId = otherQuest; - reward[1].variableMoney = otherVarMoney; - reward[1].variableXP = otherVarXp; - } + uint32 firstQuest; + uint32 otherQuest; }; /// Stores player data related to proposal to join @@ -223,10 +222,11 @@ struct LfgProposalPlayer /// Stores group data related to proposal to join struct LfgProposal { - LfgProposal(uint32 dungeon = 0): dungeonId(dungeon), state(LFG_PROPOSAL_INITIATING), + LfgProposal(uint32 dungeon = 0): id(0), dungeonId(dungeon), state(LFG_PROPOSAL_INITIATING), group(0), leader(0), cancelTime(0), encounters(0), isNew(true) { } + uint32 id; ///< Proposal Id uint32 dungeonId; ///< Dungeon to join LfgProposalState state; ///< State of the proposal uint64 group; ///< Proposal group (0 if new) @@ -235,7 +235,8 @@ struct LfgProposal uint32 encounters; ///< Dungeon Encounters bool isNew; ///< Determines if it's new group or not LfgGuidList queues; ///< Queue Ids to remove/readd - LfgProposalPlayerContainer players; ///< Players data + LfgGuidList showorder; ///< Show order in update window + LfgProposalPlayerContainer players; ///< Players data }; /// Stores all rolecheck info of a group that wants to join @@ -299,7 +300,7 @@ class LFGMgr // Reward void LoadRewards(); - void RewardDungeonDoneFor(uint32 const dungeonId, Player* player); + void FinishDungeon(uint64 gguid, uint32 dungeonId); LfgReward const* GetRandomDungeonReward(uint32 dungeon, uint8 level); // Queue @@ -314,7 +315,7 @@ class LFGMgr void GetCompatibleDungeons(LfgDungeonSet& dungeons, LfgGuidSet const& players, LfgLockPartyMap& lockMap); // Proposals - uint32 AddProposal(LfgProposal const& proposal); + uint32 AddProposal(LfgProposal& proposal); void UpdateProposal(uint32 proposalId, uint64 guid, bool accept); // Teleportation @@ -403,7 +404,7 @@ class LFGMgr void SendLfgRoleCheckUpdate(uint64 guid, LfgRoleCheck const& roleCheck); void SendLfgUpdateParty(uint64 guid, LfgUpdateData const& data); void SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data); - void SendLfgUpdateProposal(uint64 guid, uint32 proposalId, LfgProposal const& proposal); + void SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal); // General variables uint32 m_QueueTimer; ///< used to check interval of update diff --git a/src/server/game/DungeonFinding/LFGPlayerData.cpp b/src/server/game/DungeonFinding/LFGPlayerData.cpp index 0a7f812d03a..410076f7e75 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.cpp +++ b/src/server/game/DungeonFinding/LFGPlayerData.cpp @@ -113,12 +113,12 @@ uint8 LfgPlayerData::GetRoles() const return m_Roles; } -const std::string& LfgPlayerData::GetComment() const +std::string const& LfgPlayerData::GetComment() const { return m_Comment; } -const LfgDungeonSet& LfgPlayerData::GetSelectedDungeons() const +LfgDungeonSet const& LfgPlayerData::GetSelectedDungeons() const { return m_SelectedDungeons; } diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index dae789b2eb4..e75a1bdc4b3 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -139,7 +139,7 @@ void LFGQueue::RemoveFromCurrentQueue(uint64 guid) currentQueueStore.remove(guid); } -void LFGQueue::AddQueueData(uint64 guid, time_t joinTime, const LfgDungeonSet &dungeons, const LfgRolesMap &rolesMap) +void LFGQueue::AddQueueData(uint64 guid, time_t joinTime, LfgDungeonSet const& dungeons, LfgRolesMap const& rolesMap) { QueueDataStore[guid] = LfgQueueData(joinTime, dungeons, rolesMap); AddToQueue(guid); @@ -217,7 +217,6 @@ void LFGQueue::SetCompatibilityData(std::string const& key, LfgCompatibilityData CompatibleMapStore[key] = data; } - /** Get the compatibility of a group of guids @@ -482,8 +481,9 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check) return LFG_COMPATIBLES_WITH_LESS_PLAYERS; } + uint64 gguid = *check.begin(); proposal.queues = check; - proposal.isNew = numLfgGroups != 1; + proposal.isNew = numLfgGroups != 1 || !sLFGMgr->GetDungeon(gguid); if (!sLFGMgr->AllQueued(check)) { diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h index a8b41c39ab0..acb78d2c0f2 100644 --- a/src/server/game/DungeonFinding/LFGQueue.h +++ b/src/server/game/DungeonFinding/LFGQueue.h @@ -52,7 +52,7 @@ struct LfgQueueData healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED) { } - LfgQueueData(time_t _joinTime, const LfgDungeonSet &_dungeons, LfgRolesMap const& _roles): + LfgQueueData(time_t _joinTime, LfgDungeonSet const& _dungeons, LfgRolesMap const& _roles): joinTime(_joinTime), tanks(LFG_TANKS_NEEDED), healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED), dungeons(_dungeons), roles(_roles) { } @@ -87,7 +87,7 @@ class LFGQueue // Add/Remove from queue void AddToQueue(uint64 guid); void RemoveFromQueue(uint64 guid); - void AddQueueData(uint64 guid, time_t joinTime, const LfgDungeonSet &dungeons, const LfgRolesMap &rolesMap); + void AddQueueData(uint64 guid, time_t joinTime, LfgDungeonSet const& dungeons, LfgRolesMap const& rolesMap); void RemoveQueueData(uint64 guid); // Update Timers (when proposal success) diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 39750536863..568b61eef2f 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -107,20 +107,10 @@ void LFGGroupScript::OnAddMember(Group* group, uint64 guid) LfgState gstate = sLFGMgr->GetState(gguid); LfgState state = sLFGMgr->GetState(guid); sLog->outDebug(LOG_FILTER_LFG, "LFGScripts::OnAddMember [" UI64FMTD "]: added [" UI64FMTD "] leader " UI64FMTD "] gstate: %u, state: %u", gguid, guid, leader, gstate, state); - LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_UPDATE_STATUS); - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - if (Player* plrg = itr->getSource()) - { - plrg->GetSession()->SendLfgUpdatePlayer(updateData); - plrg->GetSession()->SendLfgUpdateParty(updateData); - } - } if (state == LFG_STATE_QUEUED) sLFGMgr->LeaveLfg(guid); - // TODO - if group is queued and new player is added convert to rolecheck without notify the current players queued if (gstate == LFG_STATE_QUEUED) sLFGMgr->LeaveLfg(gguid); } diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index aadbf245243..a7df171b1c5 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -499,7 +499,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) } } -void WorldSession::HandleLeaveBattlefieldOpcode(WorldPacket& recvData) +void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message"); diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index a6f89f353a0..0654ae326f9 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -23,7 +23,7 @@ #include "WorldPacket.h" #include "WorldSession.h" -void BuildPlayerLockDungeonBlock(WorldPacket& data, const LfgLockMap& lock) +void BuildPlayerLockDungeonBlock(WorldPacket& data, LfgLockMap const& lock) { data << uint32(lock.size()); // Size of lock dungeons for (LfgLockMap::const_iterator it = lock.begin(); it != lock.end(); ++it) @@ -54,7 +54,6 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) } uint8 numDungeons; - uint32 dungeon; uint32 roles; recvData >> roles; @@ -70,6 +69,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) LfgDungeonSet newDungeons; for (int8 i = 0; i < numDungeons; ++i) { + uint32 dungeon; recvData >> dungeon; newDungeons.insert((dungeon & 0x00FFFFFF)); // remove the type from the dungeon entry } @@ -80,20 +80,21 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) recvData >> comment; sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_JOIN %s roles: %u, Dungeons: %u, Comment: %s", GetPlayerInfo().c_str(), roles, uint8(newDungeons.size()), comment.c_str()); + sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment); } void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recvData*/) { - Group* grp = GetPlayer()->GetGroup(); + Group* group = GetPlayer()->GetGroup(); uint64 guid = GetPlayer()->GetGUID(); - uint64 gguid = grp ? grp->GetGUID() : guid; + uint64 gguid = group ? group->GetGUID() : guid; sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_LEAVE %s in group: %u", - GetPlayerInfo().c_str(), grp ? 1 : 0); + GetPlayerInfo().c_str(), group ? 1 : 0); // Check cheating - only leader can leave the queue - if (!grp || grp->GetLeaderGUID() == GetPlayer()->GetGUID()) + if (!group || group->GetLeaderGUID() == GetPlayer()->GetGUID()) sLFGMgr->LeaveLfg(gguid); } @@ -114,14 +115,14 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recvData) uint8 roles; recvData >> roles; // Player Group Roles uint64 guid = GetPlayer()->GetGUID(); - Group* grp = GetPlayer()->GetGroup(); - if (!grp) + Group* group = GetPlayer()->GetGroup(); + if (!group) { sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_ROLES %s Not in group", GetPlayerInfo().c_str()); return; } - uint64 gguid = grp->GetGUID(); + uint64 gguid = group->GetGUID(); sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_ROLES: Group %u, Player %s, Roles: %u", GUID_LOPART(gguid), GetPlayerInfo().c_str(), roles); sLFGMgr->UpdateRoleCheck(gguid, guid, roles); @@ -131,11 +132,11 @@ void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recvData) { std::string comment; recvData >> comment; - uint64 guid = GetPlayer()->GetGUID(); + sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_SET_COMMENT %s comment: %s", GetPlayerInfo().c_str(), comment.c_str()); - sLFGMgr->SetComment(guid, comment); + sLFGMgr->SetComment(GetPlayer()->GetGUID(), comment); } void WorldSession::HandleLfgSetBootVoteOpcode(WorldPacket& recvData) @@ -193,15 +194,15 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* data << uint32(*it); // Dungeon Entry (id + type) LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); Quest const* quest = NULL; - uint8 done = 0; + bool done = false; if (reward) { - quest = sObjectMgr->GetQuestTemplate(reward->reward[0].questId); + quest = sObjectMgr->GetQuestTemplate(reward->firstQuest); if (quest) { done = !GetPlayer()->CanRewardQuest(quest, false); if (done) - quest = sObjectMgr->GetQuestTemplate(reward->reward[1].questId); + quest = sObjectMgr->GetQuestTemplate(reward->otherQuest); } } @@ -210,8 +211,8 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* data << uint8(done); data << uint32(quest->GetRewOrReqMoney()); data << uint32(quest->XPValue(GetPlayer())); - data << uint32(reward->reward[done].variableMoney); - data << uint32(reward->reward[done].variableXP); + data << uint32(0); + data << uint32(0); data << uint8(quest->GetRewItemsCount()); if (quest->GetRewItemsCount()) { @@ -244,13 +245,13 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_LFG, "CMSG_LFG_PARTY_LOCK_INFO_REQUEST %s", GetPlayerInfo().c_str()); - Group* grp = GetPlayer()->GetGroup(); - if (!grp) + Group* group = GetPlayer()->GetGroup(); + if (!group) return; // Get the locked dungeons of the other party members LfgLockPartyMap lockMap; - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* plrg = itr->getSource(); if (!plrg) @@ -312,7 +313,7 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/) } } -void WorldSession::SendLfgUpdatePlayer(const LfgUpdateData& updateData) +void WorldSession::SendLfgUpdatePlayer(LfgUpdateData const& updateData) { bool queued = false; uint8 size = uint8(updateData.dungeons.size()); @@ -457,7 +458,7 @@ void WorldSession::SendLfgRoleCheckUpdate(const LfgRoleCheck& roleCheck) SendPacket(&data); } -void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) +void WorldSession::SendLfgJoinResult(LfgJoinResultData const& joinData) { uint32 size = 0; for (LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) @@ -465,6 +466,7 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_JOIN_RESULT %s checkResult: %u checkValue: %u", GetPlayerInfo().c_str(), joinData.result, joinData.state); + WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size); data << uint32(joinData.result); // Check Result data << uint32(joinData.state); // Check Value @@ -473,10 +475,14 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) SendPacket(&data); } -void WorldSession::SendLfgQueueStatus(const LfgQueueStatusData& queueData) +void WorldSession::SendLfgQueueStatus(LfgQueueStatusData const& queueData) { - sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_QUEUE_STATUS %s dungeon: %u - waitTime: %d - avgWaitTime: %d - waitTimeTanks: %d - waitTimeHealer: %d - waitTimeDps: %d - queuedTime: %u - tanks: %u - healers: %u - dps: %u", - GetPlayerInfo().c_str(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_QUEUE_STATUS %s dungeon: %u, waitTime: %d, " + "avgWaitTime: %d, waitTimeTanks: %d, waitTimeHealer: %d, waitTimeDps: %d, " + "queuedTime: %u, tanks: %u, healers: %u, dps: %u", + GetPlayerInfo().c_str(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, + queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps, + queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps); WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 +4 + 1 + 1 + 1 + 4); data << uint32(queueData.dungeonId); // Dungeon @@ -492,40 +498,41 @@ void WorldSession::SendLfgQueueStatus(const LfgQueueStatusData& queueData) SendPacket(&data); } -void WorldSession::SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest* quest) +void WorldSession::SendLfgPlayerReward(LfgPlayerRewardData const& rewardData) { - if (!rdungeonEntry || !sdungeonEntry || !quest) + if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest) return; - uint8 itemNum = uint8(quest ? quest->GetRewItemsCount() : 0); + sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PLAYER_REWARD %s rdungeonEntry: %u, sdungeonEntry: %u, done: %u", + GetPlayerInfo().c_str(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done); + + uint8 itemNum = rewardData.quest->GetRewItemsCount(); - sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PLAYER_REWARD %s rdungeonEntry: %u - sdungeonEntry: %u - done: %u", - GetPlayerInfo().c_str(), rdungeonEntry, sdungeonEntry, done); WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4)); - data << uint32(rdungeonEntry); // Random Dungeon Finished - data << uint32(sdungeonEntry); // Dungeon Finished - data << uint8(done); + data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished + data << uint32(rewardData.sdungeonEntry); // Dungeon Finished + data << uint8(rewardData.done); data << uint32(1); - data << uint32(quest->GetRewOrReqMoney()); - data << uint32(quest->XPValue(GetPlayer())); - data << uint32(reward->reward[done].variableMoney); - data << uint32(reward->reward[done].variableXP); + data << uint32(rewardData.quest->GetRewOrReqMoney()); + data << uint32(rewardData.quest->XPValue(GetPlayer())); + data << uint32(0); + data << uint32(0); data << uint8(itemNum); if (itemNum) { for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) - if (uint32 itemId = quest->RewardItemId[i]) + if (uint32 itemId = rewardData.quest->RewardItemId[i]) { ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId); data << uint32(itemId); data << uint32(item ? item->DisplayInfoID : 0); - data << uint32(quest->RewardItemIdCount[i]); + data << uint32(rewardData.quest->RewardItemIdCount[i]); } } SendPacket(&data); } -void WorldSession::SendLfgBootProposalUpdate(const LfgPlayerBoot& boot) +void WorldSession::SendLfgBootProposalUpdate(LfgPlayerBoot const& boot) { uint64 guid = GetPlayer()->GetGUID(); LfgAnswer playerVote = boot.votes.find(guid)->second; @@ -560,7 +567,7 @@ void WorldSession::SendLfgBootProposalUpdate(const LfgPlayerBoot& boot) SendPacket(&data); } -void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& proposal) +void WorldSession::SendLfgUpdateProposal(LfgProposal const& proposal) { uint64 guid = GetPlayer()->GetGUID(); uint64 gguid = proposal.players.find(guid)->second.group; @@ -569,7 +576,6 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& p sLog->outDebug(LOG_FILTER_LFG, "SMSG_LFG_PROPOSAL_UPDATE %s state: %u", GetPlayerInfo().c_str(), proposal.state); - WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); // show random dungeon if player selected random dungeon and it's not lfg group if (!silent) @@ -582,9 +588,10 @@ void WorldSession::SendLfgUpdateProposal(uint32 proposalId, LfgProposal const& p if (LFGDungeonData const* dungeon = sLFGMgr->GetLFGDungeon(dungeonEntry)) dungeonEntry = dungeon->Entry(); + WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1)); data << uint32(dungeonEntry); // Dungeon data << uint8(proposal.state); // Proposal state - data << uint32(proposalId); // Proposal ID + data << uint32(proposal.id); // Proposal ID data << uint32(proposal.encounters); // encounters done data << uint8(silent); // Show proposal window data << uint8(proposal.players.size()); // Group size diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 3deec5a880a..bfd9bd62647 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -20,6 +20,7 @@ #include "CreatureAI.h" #include "DatabaseEnv.h" #include "GameObject.h" +#include "Group.h" #include "InstanceScript.h" #include "LFGMgr.h" #include "Log.h" @@ -422,28 +423,41 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 instance->SendToPlayers(&data); } -void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* source) +void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* /*source*/) { DungeonEncounterList const* encounters = sObjectMgr->GetDungeonEncounterList(instance->GetId(), instance->GetDifficulty()); if (!encounters) return; + uint32 dungeonId = 0; + for (DungeonEncounterList::const_iterator itr = encounters->begin(); itr != encounters->end(); ++itr) { - if ((*itr)->creditType == type && (*itr)->creditEntry == creditEntry) + DungeonEncounter const* encounter = *itr; + if (encounter->creditType == type && encounter->creditEntry == creditEntry) { - completedEncounters |= 1 << (*itr)->dbcEntry->encounterIndex; - sLog->outDebug(LOG_FILTER_TSCR, "Instance %s (instanceId %u) completed encounter %s", instance->GetMapName(), instance->GetInstanceId(), (*itr)->dbcEntry->encounterName[0]); - if (uint32 dungeonId = (*itr)->lastEncounterDungeon) + completedEncounters |= 1 << encounter->dbcEntry->encounterIndex; + if (encounter->lastEncounterDungeon) { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.isEmpty()) - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - if (Player* player = i->getSource()) - if (!source || player->IsAtGroupRewardDistance(source)) - sLFGMgr->RewardDungeonDoneFor(dungeonId, player); + dungeonId = encounter->lastEncounterDungeon; + sLog->outDebug(LOG_FILTER_LFG, "UpdateEncounterState: Instance %s (instanceId %u) completed encounter %s. Credit Dungeon: %u", instance->GetMapName(), instance->GetInstanceId(), encounter->dbcEntry->encounterName[0], dungeonId); + break; } - return; + } + } + + if (dungeonId) + { + Map::PlayerList const& players = instance->GetPlayers(); + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + { + if (Player* player = i->getSource()) + if (Group* grp = player->GetGroup()) + if (grp->isLFGGroup()) + { + sLFGMgr->FinishDungeon(grp->GetGUID(), dungeonId); + return; + } } } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 468fe769857..7237d5f74f7 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -763,7 +763,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePVPLogDataOpcode }, - /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveBattlefieldOpcode }, + /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldLeaveOpcode }, /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueryOpcode}, /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueueOpcode}, /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 5561834303d..39f5425d9df 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -53,7 +53,7 @@ struct LfgLockStatus; struct LfgPlayerBoot; struct LfgProposal; struct LfgQueueStatusData; -struct LfgReward; +struct LfgPlayerRewardData; struct LfgRoleCheck; struct LfgUpdateData; struct MovementInfo; @@ -270,7 +270,7 @@ class WorldSession void SendAttackStop(Unit const* enemy); - void SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId); + void SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId = BATTLEGROUND_RB); void SendTradeStatus(TradeStatus status); void SendUpdateTrade(bool trader_data = true); @@ -327,7 +327,7 @@ class WorldSession void SendDiscoverNewTaxiNode(uint32 nodeid); // Guild/Arena Team - void SendArenaTeamCommandResult(uint32 team_action, std::string const& team, std::string const& player, uint32 error_id); + void SendArenaTeamCommandResult(uint32 team_action, std::string const& team, std::string const& player, uint32 error_id = 0); void SendNotInArenaTeamPacket(uint8 type); void SendPetitionShowList(uint64 guid); @@ -741,7 +741,7 @@ class WorldSession void HandlePVPLogDataOpcode(WorldPacket& recvData); void HandleBattleFieldPortOpcode(WorldPacket& recvData); void HandleBattlefieldListOpcode(WorldPacket& recvData); - void HandleLeaveBattlefieldOpcode(WorldPacket& recvData); + void HandleBattlefieldLeaveOpcode(WorldPacket& recvData); void HandleBattlemasterJoinArena(WorldPacket& recvData); void HandleReportPvPAFK(WorldPacket& recvData); @@ -762,14 +762,14 @@ class WorldSession void HandleInstanceLockResponse(WorldPacket& recvPacket); // Battlefield - void SendBfInvitePlayerToWar(uint32 BattleId,uint32 ZoneId,uint32 time); - void SendBfInvitePlayerToQueue(uint32 BattleId); - void SendBfQueueInviteResponse(uint32 BattleId,uint32 ZoneId, bool CanQueue = true, bool Full = false); - void SendBfEntered(uint32 BattleId); - void SendBfLeaveMessage(uint32 BattleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); - void HandleBfQueueInviteResponse(WorldPacket &recvData); - void HandleBfEntryInviteResponse(WorldPacket &recvData); - void HandleBfExitRequest(WorldPacket &recvData); + void SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 time); + void SendBfInvitePlayerToQueue(uint32 battleId); + void SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue = true, bool full = false); + void SendBfEntered(uint32 battleId); + void SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); + void HandleBfQueueInviteResponse(WorldPacket& recvData); + void HandleBfEntryInviteResponse(WorldPacket& recvData); + void HandleBfExitRequest(WorldPacket& recvData); // Looking for Dungeon/Raid void HandleLfgSetCommentOpcode(WorldPacket& recvData); @@ -785,16 +785,16 @@ class WorldSession void HandleLfrLeaveOpcode(WorldPacket& recvData); void HandleLfgGetStatus(WorldPacket& recvData); - void SendLfgUpdatePlayer(const LfgUpdateData& updateData); - void SendLfgUpdateParty(const LfgUpdateData& updateData); + void SendLfgUpdatePlayer(LfgUpdateData const& updateData); + void SendLfgUpdateParty(LfgUpdateData const& updateData); void SendLfgRoleChosen(uint64 guid, uint8 roles); - void SendLfgRoleCheckUpdate(const LfgRoleCheck& pRoleCheck); + void SendLfgRoleCheckUpdate(LfgRoleCheck const& pRoleCheck); void SendLfgLfrList(bool update); - void SendLfgJoinResult(const LfgJoinResultData& joinData); - void SendLfgQueueStatus(const LfgQueueStatusData& queueData); - void SendLfgPlayerReward(uint32 rdungeonEntry, uint32 sdungeonEntry, uint8 done, const LfgReward* reward, const Quest *qRew); - void SendLfgBootProposalUpdate(const LfgPlayerBoot& boot); - void SendLfgUpdateProposal(uint32 proposalId, const LfgProposal& proposal); + void SendLfgJoinResult(LfgJoinResultData const& joinData); + void SendLfgQueueStatus(LfgQueueStatusData const& queueData); + void SendLfgPlayerReward(LfgPlayerRewardData const& lfgPlayerRewardData); + void SendLfgBootProposalUpdate(LfgPlayerBoot const& boot); + void SendLfgUpdateProposal(LfgProposal const& proposal); void SendLfgDisabled(); void SendLfgOfferContinue(uint32 dungeonEntry); void SendLfgTeleportError(uint8 err); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index 6733200e44d..4927666073b 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -29,6 +29,7 @@ EndScriptData */ #include "scarlet_monastery.h" #include "LFGMgr.h" #include "Player.h" +#include "Group.h" #include "SpellInfo.h" //this texts are already used by 3975 and 3976 @@ -576,10 +577,7 @@ public: Map::PlayerList const& players = me->GetMap()->GetPlayers(); if (!players.isEmpty()) - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - if (Player* player = i->getSource()) - if (player->IsAtGroupRewardDistance(me)) - sLFGMgr->RewardDungeonDoneFor(285, player); + sLFGMgr->FinishDungeon(players.begin()->getSource()->GetGroup()->GetGUID(), 285); } void SpellHit(Unit* caster, const SpellInfo* spell) -- cgit v1.2.3 From c9650de789db26ab954146c9e73093bac6962982 Mon Sep 17 00:00:00 2001 From: Warpten Date: Thu, 10 Jan 2013 10:41:46 +0100 Subject: Scripts/ZulAman: Fixed a crash caused by the grid. Closes #8885. --- .../EasternKingdoms/ZulAman/instance_zulaman.cpp | 52 +++++++++++++--------- 1 file changed, 32 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index abd6b468b07..f61861ebb62 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -73,6 +73,7 @@ class instance_zulaman : public InstanceMapScript uint64 AshlisBagGUID; uint64 KrazsPackageGUID; uint64 StrangeGongGUID; + uint64 HarrisonJonesGUID; uint64 HexLordGateGUID; uint64 ZulJinGateGUID; @@ -105,6 +106,8 @@ class instance_zulaman : public InstanceMapScript HalazziDoorGUID = 0; ZulJinDoorGUID = 0; + HarrisonJonesGUID = 0; + QuestTimer = 0; QuestMinute = 0; BossKilled = 0; @@ -114,7 +117,6 @@ class instance_zulaman : public InstanceMapScript RandVendor[i] = NOT_STARTED; m_auiEncounter[DATA_GONGEVENT] = NOT_STARTED; - instance->SummonCreature(NPC_HARRISON_JONES, HarrisonJonesLoc); } bool IsEncounterInProgress() const @@ -126,16 +128,26 @@ class instance_zulaman : public InstanceMapScript return false; } + void OnPlayerEnter(Player* /*player*/) + { + if (!HarrisonJonesGUID) + instance->SummonCreature(NPC_HARRISON_JONES, HarrisonJonesLoc); + } + void OnCreatureCreate(Creature* creature) { switch (creature->GetEntry()) { - case NPC_JANALAI: - case NPC_ZULJIN: - case NPC_HEXLORD: - case NPC_HALAZZI: - case NPC_NALORAKK: - default: break; + case NPC_HARRISON_JONES: + HarrisonJonesGUID = creature->GetGUID(); + break; + case NPC_JANALAI: + case NPC_ZULJIN: + case NPC_HEXLORD: + case NPC_HALAZZI: + case NPC_NALORAKK: + default: + break; } } @@ -143,19 +155,19 @@ class instance_zulaman : public InstanceMapScript { switch (go->GetEntry()) { - case GO_DOOR_HALAZZI: HalazziDoorGUID = go->GetGUID(); break; - case GO_GATE_ZULJIN: ZulJinGateGUID = go->GetGUID(); break; - case GO_GATE_HEXLORD: HexLordGateGUID = go->GetGUID(); break; - case GO_MASSIVE_GATE: MassiveGateGUID = go->GetGUID(); break; - case GO_DOOR_AKILZON: AkilzonDoorGUID = go->GetGUID(); break; - case GO_DOOR_ZULJIN: ZulJinDoorGUID = go->GetGUID(); break; - - case GO_HARKORS_SATCHEL: HarkorsSatchelGUID = go->GetGUID(); break; - case GO_TANZARS_TRUNK: TanzarsTrunkGUID = go->GetGUID(); break; - case GO_ASHLIS_BAG: AshlisBagGUID = go->GetGUID(); break; - case GO_KRAZS_PACKAGE: KrazsPackageGUID = go->GetGUID(); break; - case GO_STRANGE_GONG: StrangeGongGUID = go->GetGUID(); break; - default: break; + case GO_DOOR_HALAZZI: HalazziDoorGUID = go->GetGUID(); break; + case GO_GATE_ZULJIN: ZulJinGateGUID = go->GetGUID(); break; + case GO_GATE_HEXLORD: HexLordGateGUID = go->GetGUID(); break; + case GO_MASSIVE_GATE: MassiveGateGUID = go->GetGUID(); break; + case GO_DOOR_AKILZON: AkilzonDoorGUID = go->GetGUID(); break; + case GO_DOOR_ZULJIN: ZulJinDoorGUID = go->GetGUID(); break; + + case GO_HARKORS_SATCHEL: HarkorsSatchelGUID = go->GetGUID(); break; + case GO_TANZARS_TRUNK: TanzarsTrunkGUID = go->GetGUID(); break; + case GO_ASHLIS_BAG: AshlisBagGUID = go->GetGUID(); break; + case GO_KRAZS_PACKAGE: KrazsPackageGUID = go->GetGUID(); break; + case GO_STRANGE_GONG: StrangeGongGUID = go->GetGUID(); break; + default: break; } CheckInstanceStatus(); } -- cgit v1.2.3 From 8274e42e3d1d9073c77e7cbb6f573637c1d7ddc9 Mon Sep 17 00:00:00 2001 From: Nay Date: Thu, 10 Jan 2013 15:09:12 +0000 Subject: Core/SAI: Add 2nd parameter to SMART_ACTION_CALL_FOR_HELP to say "%s calls for help!" if enabled Similar to SMART_ACTION_FLEE_FOR_ASSIST "%s attempts to run away in fear!" --- sql/updates/world/2013_01_10_00_world_trinity_string.sql | 3 +++ src/server/game/AI/SmartScripts/SmartScript.cpp | 5 +++++ src/server/game/AI/SmartScripts/SmartScriptMgr.h | 3 ++- src/server/game/Miscellaneous/Language.h | 3 ++- 4 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 sql/updates/world/2013_01_10_00_world_trinity_string.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_10_00_world_trinity_string.sql b/sql/updates/world/2013_01_10_00_world_trinity_string.sql new file mode 100644 index 00000000000..35d0c1eba99 --- /dev/null +++ b/sql/updates/world/2013_01_10_00_world_trinity_string.sql @@ -0,0 +1,3 @@ +DELETE FROM `trinity_string` WHERE `entry`=5035; +INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES +(5035, '%s calls for help!', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index e68c8c27194..c08e085e816 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1000,6 +1000,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (me) { me->CallForHelp((float)e.action.callHelp.range); + if (e.action.callHelp.withEmote) + { + TrinityStringTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, LANG_CALL_FOR_HELP, LANG_UNIVERSAL, 0); + sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE); + } sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: Creature %u", me->GetGUIDLow()); } break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index c70e78d5395..c88ef206b00 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -420,7 +420,7 @@ enum SMART_ACTION SMART_ACTION_UPDATE_TEMPLATE = 36, // Entry, Team SMART_ACTION_DIE = 37, // No Params SMART_ACTION_SET_IN_COMBAT_WITH_ZONE = 38, // No Params - SMART_ACTION_CALL_FOR_HELP = 39, // Radius + SMART_ACTION_CALL_FOR_HELP = 39, // Radius, With Emote SMART_ACTION_SET_SHEATH = 40, // Sheath (0-unarmed, 1-melee, 2-ranged) SMART_ACTION_FORCE_DESPAWN = 41, // timer SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue(+pct, -flat) @@ -677,6 +677,7 @@ struct SmartAction struct { uint32 range; + uint32 withEmote; } callHelp; struct diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index b35fe7237cc..f116d695e17 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -966,7 +966,8 @@ enum TrinityStrings LANG_COMMAND_NO_BATTLEGROUND_FOUND = 5032, LANG_COMMAND_NO_ACHIEVEMENT_CRITERIA_FOUND = 5033, LANG_COMMAND_NO_OUTDOOR_PVP_FORUND = 5034, - // Room for more Trinity strings 5035-9999 + LANG_CALL_FOR_HELP = 5035, + // Room for more Trinity strings 5036-9999 // Level requirement notifications LANG_SAY_REQ = 6604, -- cgit v1.2.3 From 0b50520df785d15b2356b668f8524406110fc803 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Thu, 10 Jan 2013 20:08:30 -0330 Subject: Core/scripting: Updating Scholomance scripts --- sql/updates/world/2013_01_10_05_world_sai.sql | 107 +++++ .../Scholomance/boss_darkmaster_gandling.cpp | 462 +++++++++++++-------- .../Scholomance/boss_doctor_theolen_krastinov.cpp | 9 - .../Scholomance/boss_illucia_barov.cpp | 9 - .../Scholomance/boss_instructor_malicia.cpp | 9 - .../Scholomance/boss_kirtonos_the_herald.cpp | 6 +- .../Scholomance/boss_lord_alexei_barov.cpp | 9 - .../Scholomance/boss_lorekeeper_polkelt.cpp | 9 - .../Scholomance/boss_the_ravenian.cpp | 9 - .../Scholomance/instance_scholomance.cpp | 74 +++- .../EasternKingdoms/Scholomance/scholomance.h | 31 +- 11 files changed, 474 insertions(+), 260 deletions(-) create mode 100644 sql/updates/world/2013_01_10_05_world_sai.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_10_05_world_sai.sql b/sql/updates/world/2013_01_10_05_world_sai.sql new file mode 100644 index 00000000000..82f2a16a113 --- /dev/null +++ b/sql/updates/world/2013_01_10_05_world_sai.sql @@ -0,0 +1,107 @@ +-- Spell Target Positions +DELETE FROM `spell_target_position` WHERE `id` IN (17863,17939,17943,17944,17946,17948); +INSERT INTO `spell_target_position` (`id`,`target_map`,`target_position_x`,`target_position_y`,`target_position_z`,`target_orientation`) VALUES +(17863,289,274.8774,1.333659,85.31167,3.228859), +(17939,289,182.423,-95.8264,85.2284,1.589842), +(17943,289,83.2952,-1.70237,85.2284,0.01745329), +(17944,289,266.774,0.886003,75.2501,3.071779), +(17946,289,179.141,-91.118,71.5433,1.64061), +(17948,289,103.305,-1.677517,75.21828,6.178465); + +-- Spell Script Names +DELETE FROM `spell_script_names` WHERE `spell_id` IN (17950); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(17950, 'spell_shadow_portal'); + +-- Spell Script Names +DELETE FROM `spell_script_names` WHERE `spell_id` IN (17863,17939,17943,17944,17946,17948); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(17863, 'spell_shadow_portal_rooms'), +(17939, 'spell_shadow_portal_rooms'), +(17943, 'spell_shadow_portal_rooms'), +(17944, 'spell_shadow_portal_rooms'), +(17946, 'spell_shadow_portal_rooms'), +(17948, 'spell_shadow_portal_rooms'); + +-- Texts for Darkmaster Gandling +DELETE FROM `creature_text` WHERE `entry`= 1853; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(1853,0,0, 'School is in session!',14,0,100,0,0,0, 'Darkmaster Gandling - Say on summon'); + +-- Risen Guardian SAI +SET @ENTRY := 11598; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=@ENTRY; +DELETE FROM `creature_ai_scripts` WHERE `creature_id`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,0,0,100,2,37600,71200,14300,32700,11,7068,0,0,0,0,0,2,0,0,0,0,0,0,0,"Risen Guardian - Combat - Cast Veil of Shadow"), +(@ENTRY,0,1,0,0,0,100,2,12500,28100,11900,37000,11,16583,0,0,0,0,0,2,0,0,0,0,0,0,0,"Risen Guardian - Combat - Cast Shadow Shock"), +(@ENTRY,0,2,0,0,0,60,2,12300,45800,6000,34100,11,7289,0,0,0,0,0,2,0,0,0,0,0,0,0,"Risen Guardian - Combat - Cast Shrink"), +(@ENTRY,0,3,0,0,0,60,2,24100,41300,20300,38100,11,11443,0,0,0,0,0,2,0,0,0,0,0,0,0,"Risen Guardian - Combat - Cast Cripple"), +(@ENTRY,0,4,0,0,0,100,3,0,40,0,0,11,4974,0,0,0,0,0,2,0,0,0,0,0,0,0,"Risen Guardian - 40% HP - Cast Wither Touch"), +(@ENTRY,0,5,0,38,0,100,2,0,1,0,0,22,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Risen Guardian - On Data Set 0 1 - Set Phase 1"), +(@ENTRY,0,6,0,38,0,100,2,0,2,0,0,22,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Risen Guardian - On Data Set 0 1 - Set Phase 2"), +(@ENTRY,0,7,0,38,0,100,2,0,3,0,0,22,3,0,0,0,0,0,1,0,0,0,0,0,0,0,"Risen Guardian - On Data Set 0 1 - Set Phase 3"), +(@ENTRY,0,8,0,38,0,100,2,0,4,0,0,22,4,0,0,0,0,0,1,0,0,0,0,0,0,0,"Risen Guardian - On Data Set 0 1 - Set Phase 4"), +(@ENTRY,0,9,0,38,0,100,2,0,5,0,0,22,5,0,0,0,0,0,1,0,0,0,0,0,0,0,"Risen Guardian - On Data Set 0 1 - Set Phase 5"), +(@ENTRY,0,10,0,38,0,100,2,0,6,0,0,22,6,0,0,0,0,0,1,0,0,0,0,0,0,0,"Risen Guardian - On Data Set 0 1 - Set Phase 6"), +(@ENTRY,0,11,0,6,1,100,2,0,0,0,0,45,0,1,0,0,0,0,14,177372,100,0,0,0,0,0,"Risen Guardian - On Death - Set Data on go"), +(@ENTRY,0,12,0,6,2,100,2,0,0,0,0,45,0,1,0,0,0,0,14,177377,100,0,0,0,0,0,"Risen Guardian - On Death - Set Data on go"), +(@ENTRY,0,13,0,6,4,100,2,0,0,0,0,45,0,1,0,0,0,0,14,177371,100,0,0,0,0,0,"Risen Guardian - On Death - Set Data on go"), +(@ENTRY,0,14,0,6,8,100,2,0,0,0,0,45,0,1,0,0,0,0,14,177375,100,0,0,0,0,0,"Risen Guardian - On Death - Set Data on go"), +(@ENTRY,0,15,0,6,16,100,2,0,0,0,0,45,0,1,0,0,0,0,14,177373,100,0,0,0,0,0,"Risen Guardian - On Death - Set Data on go"), +(@ENTRY,0,16,0,6,32,100,2,0,0,0,0,45,0,1,0,0,0,0,14,177376,100,0,0,0,0,0,"Risen Guardian - On Death - Set Data on go"); + +-- Gate SAI +SET @ENTRY := 177372; +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,1,0,0,38,0,100,2,0,1,0,0,23,1,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - On Data Set - Increment Phase"), +(@ENTRY,1,1,2,38,2,100,2,0,1,0,0,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Deactivate"), +(@ENTRY,1,2,0,61,0,100,2,0,0,0,0,22,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Set phase 0 (Phase 3)"); + +-- Gate SAI +SET @ENTRY := 177377; +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,1,0,0,38,0,100,2,0,1,0,0,23,1,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - On Data Set - Increment Phase"), +(@ENTRY,1,1,2,38,2,100,2,0,1,0,0,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Deactivate"), +(@ENTRY,1,2,0,61,0,100,2,0,0,0,0,22,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Set phase 0 (Phase 3)"); + +-- Gate SAI +SET @ENTRY := 177371; +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,1,0,0,38,0,100,2,0,1,0,0,23,1,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - On Data Set - Increment Phase"), +(@ENTRY,1,1,2,38,2,100,2,0,1,0,0,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Deactivate"), +(@ENTRY,1,2,0,61,0,100,2,0,0,0,0,22,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Set phase 0 (Phase 3)"); + +-- Gate SAI +SET @ENTRY := 177375; +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,1,0,0,38,0,100,2,0,1,0,0,23,1,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - On Data Set - Increment Phase"), +(@ENTRY,1,1,2,38,2,100,2,0,1,0,0,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Deactivate"), +(@ENTRY,1,2,0,61,0,100,2,0,0,0,0,22,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Set phase 0 (Phase 3)"); + +-- Gate SAI +SET @ENTRY := 177373; +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,1,0,0,38,0,100,2,0,1,0,0,23,1,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - On Data Set - Increment Phase"), +(@ENTRY,1,1,2,38,2,100,2,0,1,0,0,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Deactivate"), +(@ENTRY,1,2,0,61,0,100,2,0,0,0,0,22,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Set phase 0 (Phase 3)"); + +-- Gate SAI +SET @ENTRY := 177376; +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,1,0,0,38,0,100,2,0,1,0,0,23,1,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - On Data Set - Increment Phase"), +(@ENTRY,1,1,2,38,2,100,2,0,1,0,0,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Deactivate"), +(@ENTRY,1,2,0,61,0,100,2,0,0,0,0,22,0,0,0,0,0,0,1,0,0,0,0,0,0,0, "Gate - Ready - Set phase 0 (Phase 3)"); diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp index 471f28835cd..1b5aaf83288 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp @@ -18,214 +18,344 @@ /* ScriptData SDName: Boss_Darkmaster_Gandling -SD%Complete: 75 -SDComment: Doors missing in instance script. +SD%Complete: 90 +SDComment: Doors Not yet reopening. SDCategory: Scholomance EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "scholomance.h" +#include "SpellScript.h" -#define SPELL_ARCANEMISSILES 22272 -#define SPELL_SHADOWSHIELD 22417 //Not right ID. But 12040 is wrong either. -#define SPELL_CURSE 18702 - -#define ADD_1X 170.205f -#define ADD_1Y 99.413f -#define ADD_1Z 104.733f -#define ADD_1O 3.16f - -#define ADD_2X 170.813f -#define ADD_2Y 97.857f -#define ADD_2Z 104.713f -#define ADD_2O 3.16f +enum Says +{ + YELL_SUMMONED = 0 +}; -#define ADD_3X 170.720f -#define ADD_3Y 100.900f -#define ADD_3Z 104.739f -#define ADD_3O 3.16f +enum Spells +{ + SPELL_ARCANEMISSILES = 15790, + SPELL_SHADOWSHIELD = 12040, + SPELL_CURSE = 18702, + SPELL_SHADOW_PORTAL = 17950 +}; -#define ADD_4X 171.866f -#define ADD_4Y 99.373f -#define ADD_4Z 104.732f -#define ADD_4O 3.16f +enum Events +{ + EVENT_ARCANEMISSILES = 1, + EVENT_SHADOWSHIELD = 2, + EVENT_CURSE = 3, + EVENT_SHADOW_PORTAL = 4 +}; class boss_darkmaster_gandling : public CreatureScript { -public: - boss_darkmaster_gandling() : CreatureScript("boss_darkmaster_gandling") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_darkmaster_gandlingAI (creature); - } + public: boss_darkmaster_gandling() : CreatureScript("boss_darkmaster_gandling") { } - struct boss_darkmaster_gandlingAI : public ScriptedAI - { - boss_darkmaster_gandlingAI(Creature* creature) : ScriptedAI(creature) + struct boss_darkmaster_gandlingAI : public BossAI { - instance = me->GetInstanceScript(); - } + boss_darkmaster_gandlingAI(Creature* creature) : BossAI(creature, DATA_DARKMASTERGANDLING) {} - InstanceScript* instance; + void Reset() + { + if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_GATE_GANDLING))) + gate->SetGoState(GO_STATE_ACTIVE); + } + + void JustDied(Unit* /*killer*/) + { + if (instance) + instance->SetData(DATA_DARKMASTERGANDLING, DONE); + if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_GATE_GANDLING))) + gate->SetGoState(GO_STATE_ACTIVE); + } + + void EnterCombat(Unit* /*who*/) + { + events.ScheduleEvent(EVENT_ARCANEMISSILES, 4500); + events.ScheduleEvent(EVENT_SHADOWSHIELD, 12000); + events.ScheduleEvent(EVENT_CURSE, 2000); + events.ScheduleEvent(EVENT_SHADOW_PORTAL, 16000); + + if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_GATE_GANDLING))) + gate->SetGoState(GO_STATE_READY); + } - uint32 ArcaneMissiles_Timer; - uint32 ShadowShield_Timer; - uint32 Curse_Timer; - uint32 Teleport_Timer; + void IsSummonedBy(Unit* /*summoner*/) + { + Talk(YELL_SUMMONED); + me->GetMotionMaster()->MoveRandom(5); + } - void Reset() + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ARCANEMISSILES: + DoCastVictim(SPELL_ARCANEMISSILES, true); + events.ScheduleEvent(EVENT_ARCANEMISSILES, 8000); + break; + case EVENT_SHADOWSHIELD: + DoCast(me, SPELL_SHADOWSHIELD); + events.ScheduleEvent(EVENT_SHADOWSHIELD, urand(14000, 28000)); + break; + case EVENT_CURSE: + DoCastVictim(SPELL_CURSE, true); + events.ScheduleEvent(EVENT_CURSE, urand(15000, 27000)); + break; + case EVENT_SHADOW_PORTAL: + if (HealthAbovePct(3)) + { + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0, 100, true),SPELL_SHADOW_PORTAL,true); + events.ScheduleEvent(EVENT_SHADOW_PORTAL, urand(17000, 27000)); + } + } + } + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const { - ArcaneMissiles_Timer = 4500; - ShadowShield_Timer = 12000; - Curse_Timer = 2000; - Teleport_Timer = 16000; + return new boss_darkmaster_gandlingAI (creature); } +}; - void EnterCombat(Unit* /*who*/) +// Script for Shadow Portal spell 17950 +enum Rooms +{ + ROOM_HALL_OF_SECRETS = 0, + ROOM_HALL_OF_THE_DAMNED = 1, + ROOM_THE_COVEN = 2, + ROOM_THE_SHADOW_VAULT = 3, + ROOM_BAROV_FAMILY_VAULT = 4, + ROOM_VAULT_OF_THE_RAVENIAN = 5 +}; + +enum SPSpells +{ + SPELL_SHADOW_PORTAL_HALLOFSECRETS = 17863, + SPELL_SHADOW_PORTAL_HALLOFTHEDAMNED = 17939, + SPELL_SHADOW_PORTAL_THECOVEN = 17943, + SPELL_SHADOW_PORTAL_THESHADOWVAULT = 17944, + SPELL_SHADOW_PORTAL_BAROVFAMILYVAULT = 17946, + SPELL_SHADOW_PORTAL_VAULTOFTHERAVENIAN = 17948 +}; + +class spell_shadow_portal : public SpellScriptLoader +{ + public: + spell_shadow_portal() : SpellScriptLoader("spell_shadow_portal") { } + + class spell_shadow_portal_SpellScript : public SpellScript { - } + PrepareSpellScript(spell_shadow_portal_SpellScript); + + void HandleCast(SpellEffIndex /*effIndex*/) + { + Creature* caster = GetCaster()->ToCreature(); + int8 attempts = 0; + int32 spell_to_cast =0; + + while (!spell_to_cast) + { + if (attempts++ >= 6) break; + + switch (urand(0,5)) + { + case ROOM_HALL_OF_SECRETS: + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (GameObject::GetGameObject(*caster, instance->GetData64(GO_GATE_RAVENIAN))->GetGoState() == GO_STATE_ACTIVE) + spell_to_cast = SPELL_SHADOW_PORTAL_HALLOFSECRETS; + break; + case ROOM_HALL_OF_THE_DAMNED: + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (GameObject::GetGameObject(*caster, instance->GetData64(GO_GATE_THEOLEN))->GetGoState() == GO_STATE_ACTIVE) + spell_to_cast = SPELL_SHADOW_PORTAL_HALLOFTHEDAMNED; + break; + case ROOM_THE_COVEN: + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (GameObject::GetGameObject(*caster, instance->GetData64(GO_GATE_MALICIA))->GetGoState() == GO_STATE_ACTIVE) + spell_to_cast = SPELL_SHADOW_PORTAL_THECOVEN; + break; + case ROOM_THE_SHADOW_VAULT: + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (GameObject::GetGameObject(*caster, instance->GetData64(GO_GATE_ILLUCIA))->GetGoState() == GO_STATE_ACTIVE) + spell_to_cast = SPELL_SHADOW_PORTAL_THESHADOWVAULT; + break; + case ROOM_BAROV_FAMILY_VAULT: + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (GameObject::GetGameObject(*caster, instance->GetData64(GO_GATE_BAROV))->GetGoState() == GO_STATE_ACTIVE) + spell_to_cast = SPELL_SHADOW_PORTAL_BAROVFAMILYVAULT; + break; + case ROOM_VAULT_OF_THE_RAVENIAN: + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (GameObject::GetGameObject(*caster, instance->GetData64(GO_GATE_POLKELT))->GetGoState() == GO_STATE_ACTIVE) + spell_to_cast = SPELL_SHADOW_PORTAL_VAULTOFTHERAVENIAN; + break; + } + + if (spell_to_cast) + GetHitUnit()->CastSpell(GetHitUnit(), spell_to_cast); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_shadow_portal_SpellScript::HandleCast, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; - void JustDied(Unit* /*killer*/) + SpellScript* GetSpellScript() const { - if (instance) - instance->SetData(TYPE_GANDLING, DONE); + return new spell_shadow_portal_SpellScript(); } +}; + +// Script for Shadow Portal spells 17863,17939,17943,17944,17946,17948 +Position const SummonPos[18] = +{ + // Hall of Secrects + + + + // The Hall of the damned + { 177.9624f, -68.23893f, 84.95197f, 3.228859f }, + { 183.7705f, -61.43489f, 84.92424f, 5.148721f }, + { 184.7035f, -77.74805f, 84.92424f, 4.660029f }, + // The Coven + { 111.7203f, -1.105035f, 85.45985f, 3.961897f }, + { 118.0079f, 6.430664f, 85.31169f, 2.408554f }, + { 120.0276f, -7.496636f, 85.31169f, 2.984513f }, + // The Shadow Vault + { 245.3716f, 0.628038f, 72.73877f, 0.01745329f }, + { 240.9920f, 3.405653f, 72.73877f, 6.143559f }, + { 240.9543f, -3.182943f, 72.73877f, 0.2268928f }, + // Barov Family Vault + { 181.8245f, -42.58117f, 75.4812f, 4.660029f }, + { 177.7456f, -42.74745f, 75.4812f, 4.886922f }, + { 185.6157f, -42.91200f, 75.4812f, 4.45059f }, + // Vault of the Ravenian + + + +}; - void UpdateAI(const uint32 diff) +enum Creatures +{ + NPC_RISEN_GUARDIAN = 11598 +}; + +enum ScriptEventId +{ + SPELL_EVENT_HALLOFSECRETS = 5618, + SPELL_EVENT_HALLOFTHEDAMNED = 5619, + SPELL_EVENT_THECOVEN = 5620, + SPELL_EVENT_THESHADOWVAULT = 5621, + SPELL_EVENT_BAROVFAMILYVAULT = 5622, + SPELL_EVENT_VAULTOFTHERAVENIAN = 5623 +}; + +class spell_shadow_portal_rooms : public SpellScriptLoader +{ + public: + spell_shadow_portal_rooms() : SpellScriptLoader("spell_shadow_portal_rooms") { } + + class spell_shadow_portal_rooms_SpellScript : public SpellScript { - if (!UpdateVictim()) - return; + PrepareSpellScript(spell_shadow_portal_rooms_SpellScript); - //ArcaneMissiles_Timer - if (ArcaneMissiles_Timer <= diff) + void HandleSendEvent(SpellEffIndex effIndex) { - DoCast(me->getVictim(), SPELL_ARCANEMISSILES); - ArcaneMissiles_Timer = 8000; - } else ArcaneMissiles_Timer -= diff; + // If only one player in threat list fail spell - //ShadowShield_Timer - if (ShadowShield_Timer <= diff) - { - DoCast(me, SPELL_SHADOWSHIELD); - ShadowShield_Timer = urand(14000, 28000); - } else ShadowShield_Timer -= diff; + Creature* Summoned = NULL; + Creature* caster = GetCaster()->ToCreature(); - //Curse_Timer - if (Curse_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_CURSE); - Curse_Timer = urand(15000, 27000); - } else Curse_Timer -= diff; + int8 pos_to_summon = 0; + int8 phase_to_set = 0; + int32 gate_to_close = 0; - //Teleporting Random Target to one of the six pre boss rooms and spawn 3-4 skeletons near the gamer. - //We will only telport if gandling has more than 3% of hp so teleported gamers can always loot. - if (HealthAbovePct(3)) - { - if (Teleport_Timer <= diff) + switch (GetSpellInfo()->Effects[effIndex].MiscValue) { - Unit* target = NULL; - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target && target->GetTypeId() == TYPEID_PLAYER) - { - if (DoGetThreat(target)) - DoModifyThreatPercent(target, -100); + case SPELL_EVENT_HALLOFSECRETS: + pos_to_summon = 0; // Not yet spawned + phase_to_set = 1; + gate_to_close = GO_GATE_RAVENIAN; + break; + case SPELL_EVENT_HALLOFTHEDAMNED: + pos_to_summon = 0; + phase_to_set = 2; + gate_to_close = GO_GATE_THEOLEN; + break; + case SPELL_EVENT_THECOVEN: + pos_to_summon = 3; + phase_to_set = 3; + gate_to_close = GO_GATE_MALICIA; + break; + case SPELL_EVENT_THESHADOWVAULT: + pos_to_summon = 6; + phase_to_set = 4; + gate_to_close = GO_GATE_ILLUCIA; + break; + case SPELL_EVENT_BAROVFAMILYVAULT: + pos_to_summon = 9; + phase_to_set = 5; + gate_to_close = GO_GATE_BAROV; + break; + case SPELL_EVENT_VAULTOFTHERAVENIAN: + pos_to_summon = 0; // Not yet spawned + phase_to_set = 6; + gate_to_close = GO_GATE_POLKELT; + break; + default: + break; + } - Creature* Summoned = NULL; - switch (rand()%6) + if (gate_to_close && (GetCaster()->GetMap()->GetId() == 289)) + { + for (uint8 i = 0; i < 3; ++i) + { + Summoned = GetCaster()->SummonCreature(NPC_RISEN_GUARDIAN, SummonPos[pos_to_summon++], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (Summoned) { - case 0: - DoTeleportPlayer(target, 250.0696f, 0.3921f, 84.8408f, 3.149f); - Summoned = me->SummonCreature(16119, 254.2325f, 0.3417f, 84.8407f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 257.7133f, 4.0226f, 84.8407f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 258.6702f, -2.60656f, 84.8407f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - break; - case 1: - DoTeleportPlayer(target, 181.4220f, -91.9481f, 84.8410f, 1.608f); - Summoned = me->SummonCreature(16119, 184.0519f, -73.5649f, 84.8407f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 179.5951f, -73.7045f, 84.8407f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 180.6452f, -78.2143f, 84.8407f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 283.2274f, -78.1518f, 84.8407f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - break; - case 2: - DoTeleportPlayer(target, 95.1547f, -1.8173f, 85.2289f, 0.043f); - Summoned = me->SummonCreature(16119, 100.9404f, -1.8016f, 85.2289f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 101.3729f, 0.4882f, 85.2289f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 101.4596f, -4.4740f, 85.2289f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - break; - case 3: - DoTeleportPlayer(target, 250.0696f, 0.3921f, 72.6722f, 3.149f); - Summoned = me->SummonCreature(16119, 240.34481f, 0.7368f, 72.6722f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 240.3633f, -2.9520f, 72.6722f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 240.6702f, 3.34949f, 72.6722f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - break; - case 4: - DoTeleportPlayer(target, 181.4220f, -91.9481f, 70.7734f, 1.608f); - Summoned = me->SummonCreature(16119, 184.0519f, -73.5649f, 70.7734f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 179.5951f, -73.7045f, 70.7734f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 180.6452f, -78.2143f, 70.7734f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 283.2274f, -78.1518f, 70.7734f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - break; - case 5: - DoTeleportPlayer(target, 106.1541f, -1.8994f, 75.3663f, 0.043f); - Summoned = me->SummonCreature(16119, 115.3945f, -1.5555f, 75.3663f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 257.7133f, 1.8066f, 75.3663f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - Summoned = me->SummonCreature(16119, 258.6702f, -5.1001f, 75.3663f, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Summoned) - Summoned->AI()->AttackStart(target); - break; + Summoned->GetMotionMaster()->MoveRandom(5); + Summoned->AI()->SetData(0,phase_to_set); } } - Teleport_Timer = urand(20000, 35000); - } else Teleport_Timer -= diff; + + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (GameObject* gate = GameObject::GetGameObject(*caster, instance->GetData64(gate_to_close))) + gate->SetGoState(GO_STATE_READY); + } } - DoMeleeAttackIfReady(); - } - }; + void Register() + { + OnEffectHit += SpellEffectFn(spell_shadow_portal_rooms_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT); + } + }; + SpellScript* GetSpellScript() const + { + return new spell_shadow_portal_rooms_SpellScript(); + } }; void AddSC_boss_darkmaster_gandling() { new boss_darkmaster_gandling(); + new spell_shadow_portal(); + new spell_shadow_portal_rooms(); } diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp index ea60b0ce333..fbc0ec4fd3e 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp @@ -58,17 +58,8 @@ class boss_doctor_theolen_krastinov : public CreatureScript void JustDied(Unit* /*killer*/) { - InstanceScript* instance = me->GetInstanceScript(); if (instance) - { instance->SetData(DATA_DOCTORTHEOLENKRASTINOV, DONE); - - if (instance->GetData(TYPE_GANDLING) == IN_PROGRESS) - { - instance->SetData(TYPE_GANDLING, IN_PROGRESS); - me->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } } void EnterCombat(Unit* /*who*/) diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp index 54fc9e4a17e..59a1eaf87a4 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp @@ -55,17 +55,8 @@ class boss_illucia_barov : public CreatureScript void JustDied(Unit* /*killer*/) { - InstanceScript* instance = me->GetInstanceScript(); if (instance) - { instance->SetData(DATA_LADYILLUCIABAROV, DONE); - - if (instance->GetData(TYPE_GANDLING) == IN_PROGRESS) - { - instance->SetData(TYPE_GANDLING, IN_PROGRESS); - me->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } } void EnterCombat(Unit* /*who*/) diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_instructor_malicia.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_instructor_malicia.cpp index daf03f41db5..d7234da00ce 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_instructor_malicia.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_instructor_malicia.cpp @@ -64,17 +64,8 @@ class boss_instructor_malicia : public CreatureScript void JustDied(Unit* /*killer*/) { - InstanceScript* instance = me->GetInstanceScript(); if (instance) - { instance->SetData(DATA_INSTRUCTORMALICIA, DONE); - - if (instance->GetData(TYPE_GANDLING) == IN_PROGRESS) - { - instance->SetData(TYPE_GANDLING, IN_PROGRESS); - me->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } } void EnterCombat(Unit* /*who*/) diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp index 68d7dcdebe8..9d8f448964c 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp @@ -57,7 +57,7 @@ enum Events EVENT_KIRTONOS_TRANSFORM = 14 }; -enum Misc +enum eMisc { WEAPON_KIRTONOS_STAFF = 11365, POINT_KIRTONOS_LAND = 13, @@ -70,7 +70,7 @@ class boss_kirtonos_the_herald : public CreatureScript struct boss_kirtonos_the_heraldAI : public BossAI { - boss_kirtonos_the_heraldAI(Creature* creature) : BossAI(creature, TYPE_KIRTONOS) { } + boss_kirtonos_the_heraldAI(Creature* creature) : BossAI(creature, DATA_KIRTONOS) { } void Reset() { @@ -104,7 +104,7 @@ class boss_kirtonos_the_herald : public CreatureScript brazier->SetGoState(GO_STATE_READY); } if (instance) - instance->SetData(TYPE_KIRTONOS, DONE); + instance->SetData(DATA_KIRTONOS, DONE); } void EnterEvadeMode() diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp index 55ef0605c31..01a36cc678a 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp @@ -54,17 +54,8 @@ class boss_lord_alexei_barov : public CreatureScript void JustDied(Unit* /*killer*/) { - InstanceScript* instance = me->GetInstanceScript(); if (instance) - { instance->SetData(DATA_LORDALEXEIBAROV, DONE); - - if (instance->GetData(TYPE_GANDLING) == IN_PROGRESS) - { - instance->SetData(TYPE_GANDLING, IN_PROGRESS); - me->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } } void EnterCombat(Unit* /*who*/) diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp index cc9180ded76..effd321dfe9 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp @@ -55,17 +55,8 @@ class boss_lorekeeper_polkelt : public CreatureScript void JustDied(Unit* /*killer*/) { - InstanceScript* instance = me->GetInstanceScript(); if (instance) - { instance->SetData(DATA_LOREKEEPERPOLKELT, DONE); - - if (instance->GetData(TYPE_GANDLING) == IN_PROGRESS) - { - instance->SetData(TYPE_GANDLING, IN_PROGRESS); - me->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } } void EnterCombat(Unit* /*who*/) diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_the_ravenian.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_the_ravenian.cpp index 5a6f5d436c4..9ebee93a6bc 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_the_ravenian.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_the_ravenian.cpp @@ -56,17 +56,8 @@ class boss_the_ravenian : public CreatureScript void JustDied(Unit* /*killer*/) { - InstanceScript* instance = me->GetInstanceScript(); if (instance) - { instance->SetData(DATA_THERAVENIAN, DONE); - - if (instance->GetData(TYPE_GANDLING) == IN_PROGRESS) - { - instance->SetData(TYPE_GANDLING, IN_PROGRESS); - me->SummonCreature(1853, 180.73f, -9.43856f, 75.507f, 1.61399f, TEMPSUMMON_DEAD_DESPAWN, 0); - } - } } void EnterCombat(Unit* /*who*/) diff --git a/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp b/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp index 04a12ae2bd2..b91b7ee605d 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp @@ -27,6 +27,13 @@ EndScriptData */ #include "InstanceScript.h" #include "scholomance.h" +enum CreatureId +{ + NPC_DARKMASTER_GANDLING = 1853 +}; + +Position const GandlingLoc = {180.7712f, -5.428603f, 75.57024f, 1.291544f}; + class instance_scholomance : public InstanceMapScript { public: @@ -42,9 +49,7 @@ public: instance_scholomance_InstanceMapScript(Map* map) : InstanceScript(map) {} //Lord Alexei Barov, Doctor Theolen Krastinov, The Ravenian, Lorekeeper Polkelt, Instructor Malicia and the Lady Illucia Barov. - bool IsBossDied[6]; uint32 m_auiEncounter[MAX_ENCOUNTER]; - uint64 GateKirtonosGUID; uint64 GateGandlingGUID; uint64 GateMiliciaGUID; @@ -57,8 +62,6 @@ public: void Initialize() { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - GateKirtonosGUID = 0; GateGandlingGUID = 0; GateMiliciaGUID = 0; @@ -69,8 +72,8 @@ public: GateIlluciaGUID = 0; BrazierOfTheHeraldGUID = 0; - for (uint8 i = 0; i < 6; ++i) - IsBossDied[i] = false; + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + m_auiEncounter[i] = NOT_STARTED; } void OnGameObjectCreate(GameObject* go) @@ -94,37 +97,43 @@ public: switch (type) { case DATA_LORDALEXEIBAROV: - IsBossDied[0] = true; + m_auiEncounter[DATA_LORDALEXEIBAROV] = data; + CheckToSpawnGandling(); break; case DATA_DOCTORTHEOLENKRASTINOV: - IsBossDied[1] = true; + m_auiEncounter[DATA_DOCTORTHEOLENKRASTINOV] = data; + CheckToSpawnGandling(); break; case DATA_THERAVENIAN: - IsBossDied[2] = true; + m_auiEncounter[DATA_THERAVENIAN] = data; + CheckToSpawnGandling(); break; case DATA_LOREKEEPERPOLKELT: - IsBossDied[3] = true; + m_auiEncounter[DATA_LOREKEEPERPOLKELT] = data; + CheckToSpawnGandling(); break; case DATA_INSTRUCTORMALICIA: - IsBossDied[4] = true; + m_auiEncounter[DATA_INSTRUCTORMALICIA] = data; + CheckToSpawnGandling(); break; case DATA_LADYILLUCIABAROV: - IsBossDied[5] = true; + m_auiEncounter[DATA_LADYILLUCIABAROV] = data; + CheckToSpawnGandling(); break; - case TYPE_GANDLING: - m_auiEncounter[0] = data; + case DATA_DARKMASTERGANDLING: + m_auiEncounter[DATA_DARKMASTERGANDLING] = data; break; - case TYPE_KIRTONOS: - m_auiEncounter[1] = data; + case DATA_KIRTONOS: + m_auiEncounter[DATA_KIRTONOS] = data; break; } } uint32 GetData(uint32 type) const { - return (type == TYPE_GANDLING && - IsBossDied[0] && IsBossDied[1] && IsBossDied[2] && - IsBossDied[3] && IsBossDied[4] && IsBossDied[5]) + return type == (m_auiEncounter[DATA_LORDALEXEIBAROV] == DONE) && (m_auiEncounter[DATA_DOCTORTHEOLENKRASTINOV] == DONE) && + (m_auiEncounter[DATA_THERAVENIAN] == DONE) && (m_auiEncounter[DATA_LOREKEEPERPOLKELT] == DONE) && + (m_auiEncounter[DATA_INSTRUCTORMALICIA] == DONE) && (m_auiEncounter[DATA_LADYILLUCIABAROV] == DONE) ? IN_PROGRESS : 0; } @@ -132,14 +141,33 @@ public: { switch (type) { - case GO_GATE_KIRTONOS: - return GateKirtonosGUID; - case GO_BRAZIER_OF_THE_HERALD: - return BrazierOfTheHeraldGUID; + case GO_GATE_KIRTONOS: return GateKirtonosGUID; break; + case GO_GATE_GANDLING: return GateGandlingGUID; break; + case GO_GATE_MALICIA: return GateMiliciaGUID; break; + case GO_GATE_THEOLEN: return GateTheolenGUID; break; + case GO_GATE_POLKELT: return GatePolkeltGUID; break; + case GO_GATE_RAVENIAN: return GateRavenianGUID; break; + case GO_GATE_BAROV: return GateBarovGUID; break; + case GO_GATE_ILLUCIA: return GateIlluciaGUID; break; + case GO_BRAZIER_OF_THE_HERALD: return BrazierOfTheHeraldGUID; break; } return 0; } + + void CheckToSpawnGandling() + { + if (GetData(DATA_DARKMASTERGANDLING) == IN_PROGRESS) + { + Map::PlayerList const &PlayerList = instance->GetPlayers(); + if (PlayerList.isEmpty()) + return; + + Map::PlayerList::const_iterator i = PlayerList.begin(); + if (Player* i_pl = i->getSource()) + i_pl->SummonCreature(NPC_DARKMASTER_GANDLING, GandlingLoc); + } + } }; }; diff --git a/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h b/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h index f89f36d91e5..53916b2e37c 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h +++ b/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h @@ -19,31 +19,34 @@ #ifndef DEF_SCHOLOMANCE_H #define DEF_SCHOLOMANCE_H -uint32 const MAX_ENCOUNTER = 2; - enum DataTypes { - TYPE_GANDLING = 1, - DATA_DOCTORTHEOLENKRASTINOV = 2, - DATA_INSTRUCTORMALICIA = 3, - DATA_LADYILLUCIABAROV = 4, - DATA_LORDALEXEIBAROV = 5, - DATA_LOREKEEPERPOLKELT = 6, - DATA_THERAVENIAN = 7, - TYPE_KIRTONOS = 8 + DATA_DOCTORTHEOLENKRASTINOV = 0, + DATA_INSTRUCTORMALICIA = 1, + DATA_LADYILLUCIABAROV = 2, + DATA_LORDALEXEIBAROV = 3, + DATA_LOREKEEPERPOLKELT = 4, + DATA_THERAVENIAN = 5, + DATA_DARKMASTERGANDLING = 6, + DATA_KIRTONOS = 7 }; enum GameobjectIds { GO_GATE_KIRTONOS = 175570, GO_GATE_GANDLING = 177374, - GO_GATE_MALICIA = 177375, - GO_GATE_THEOLEN = 177377, - GO_GATE_POLKELT = 177376, GO_GATE_RAVENIAN = 177372, - GO_GATE_BAROV = 177373, + GO_GATE_THEOLEN = 177377, GO_GATE_ILLUCIA = 177371, + GO_GATE_MALICIA = 177375, + GO_GATE_BAROV = 177373, + GO_GATE_POLKELT = 177376, GO_BRAZIER_OF_THE_HERALD = 175564 }; +enum Misc +{ + MAX_ENCOUNTER = 8 +}; + #endif -- cgit v1.2.3 From ddea01290c91d0a2b1c89463fc89f2c139f882bc Mon Sep 17 00:00:00 2001 From: Malcrom Date: Thu, 10 Jan 2013 20:50:32 -0330 Subject: Core/Scriptd: Rewrite :) --- .../Scholomance/boss_darkmaster_gandling.cpp | 13 ++++++------- .../Scholomance/boss_doctor_theolen_krastinov.cpp | 13 ++++++------- .../EasternKingdoms/Scholomance/boss_illucia_barov.cpp | 13 ++++++------- .../EasternKingdoms/Scholomance/boss_instructor_malicia.cpp | 1 - .../EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp | 1 - .../EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp | 13 ++++++------- .../EasternKingdoms/Scholomance/boss_the_ravenian.cpp | 13 ++++++------- .../EasternKingdoms/Scholomance/instance_scholomance.cpp | 10 +++++----- .../scripts/EasternKingdoms/Scholomance/scholomance.h | 1 - 9 files changed, 35 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp index 1b5aaf83288..4e2a1b6fa19 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,12 +15,12 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Darkmaster_Gandling -SD%Complete: 90 -SDComment: Doors Not yet reopening. -SDCategory: Scholomance -EndScriptData */ +/* +Name: Boss_Darkmaster_Gandling +%Complete: 90 +Comment: Doors Not yet reopening. +Category: Scholomance +*/ #include "ScriptMgr.h" #include "ScriptedCreature.h" diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp index fbc0ec4fd3e..fc54b90ab45 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_doctor_theolen_krastinov.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,12 +15,12 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Doctor_Theolen_Krastinov -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ +/* +Name: Boss_Doctor_Theolen_Krastinov +%Complete: 100 +Comment: +Category: Scholomance +*/ #include "ScriptMgr.h" #include "ScriptedCreature.h" diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp index 59a1eaf87a4..64d827e41f1 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_illucia_barov.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,12 +15,12 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Illucia_Barov -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ +/* +Name: Boss_Illucia_Barov +%Complete: 100 +Comment: +Category: Scholomance +*/ #include "ScriptMgr.h" #include "ScriptedCreature.h" diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_instructor_malicia.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_instructor_malicia.cpp index d7234da00ce..1f55666acc3 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_instructor_malicia.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_instructor_malicia.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp index 01a36cc678a..c246e781bd8 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_lord_alexei_barov.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp index effd321dfe9..2239194a5e3 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,12 +15,12 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Lorekeeper_Polkelt -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ +/* +Name: Boss_Lorekeeper_Polkelt +%Complete: 100 +Comment: +Category: Scholomance +*/ #include "ScriptMgr.h" #include "ScriptedCreature.h" diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_the_ravenian.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_the_ravenian.cpp index 9ebee93a6bc..e2e04ae7b81 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_the_ravenian.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_the_ravenian.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,12 +15,12 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_the_ravenian -SD%Complete: 100 -SDComment: -SDCategory: Scholomance -EndScriptData */ +/* +Name: Boss_the_ravenian +%Complete: 100 +Comment: +Category: Scholomance +*/ #include "ScriptMgr.h" #include "ScriptedCreature.h" diff --git a/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp b/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp index b91b7ee605d..d97372d4379 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/instance_scholomance.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -17,15 +16,16 @@ */ /* ScriptData -SDName: Instance_Scholomance -SD%Complete: 100 -SDComment: -SDCategory: Scholomance +Name: Instance_Scholomance +%Complete: 100 +Comment: +Category: Scholomance EndScriptData */ #include "ScriptMgr.h" #include "InstanceScript.h" #include "scholomance.h" +#include "Player.h" enum CreatureId { diff --git a/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h b/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h index 53916b2e37c..2d9c8c7bbe7 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h +++ b/src/server/scripts/EasternKingdoms/Scholomance/scholomance.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the -- cgit v1.2.3 From 0c16b959057fae07f506fcd75572840dd95cdb86 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Fri, 11 Jan 2013 04:18:02 +0100 Subject: Misc: Reorder scripts in some script files and some cosmetic stuff --- src/server/scripts/Spells/spell_dk.cpp | 720 ++++++++++++++--------------- src/server/scripts/Spells/spell_hunter.cpp | 441 +++++++++--------- src/server/scripts/Spells/spell_priest.cpp | 223 ++++----- src/server/scripts/Spells/spell_rogue.cpp | 329 ++++++------- 4 files changed, 864 insertions(+), 849 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 4bd619155ac..afb9a625761 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -28,21 +28,30 @@ enum DeathKnightSpells { - DK_SPELL_RUNIC_POWER_ENERGIZE = 49088, - DK_SPELL_ANTI_MAGIC_SHELL_TALENT = 51052, - DK_SPELL_CORPSE_EXPLOSION_TRIGGERED = 43999, - DK_SPELL_CORPSE_EXPLOSION_VISUAL = 51270, - DK_SPELL_GHOUL_EXPLODE = 47496, - DK_SPELL_SCOURGE_STRIKE_TRIGGERED = 70890, - DK_SPELL_BLOOD_BOIL_TRIGGERED = 65658, - DK_SPELL_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189, - DK_SPELL_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284, - DK_SPELL_BLOOD_PRESENCE = 48266, - DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611, - DK_SPELL_UNHOLY_PRESENCE = 48265, - DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622, + SPELL_DK_ANTI_MAGIC_SHELL_TALENT = 51052, + SPELL_DK_BLACK_ICE_R1 = 49140, + SPELL_DK_BLOOD_BOIL_TRIGGERED = 65658, + SPELL_DK_CORPSE_EXPLOSION_TRIGGERED = 43999, + SPELL_DK_CORPSE_EXPLOSION_VISUAL = 51270, + SPELL_DK_DEATH_COIL_DAMAGE = 47632, + SPELL_DK_DEATH_COIL_HEAL = 47633, + SPELL_DK_DEATH_STRIKE_HEAL = 45470, + SPELL_DK_GHOUL_EXPLODE = 47496, + SPELL_DK_RUNIC_POWER_ENERGIZE = 49088, + SPELL_DK_SCOURGE_STRIKE_TRIGGERED = 70890, + SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189, + SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284, + SPELL_DK_BLOOD_PRESENCE = 48266, + SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611, + SPELL_DK_UNHOLY_PRESENCE = 48265, + SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622, + SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART = 64962, SPELL_DK_ITEM_T8_MELEE_4P_BONUS = 64736, - DK_SPELL_BLACK_ICE_R1 = 49140, +}; + +enum DeathKnightSpellIcons +{ + DK_ICON_ID_IMPROVED_DEATH_STRIKE = 2751, }; // 50462 - Anti-Magic Shell (on raid member) @@ -71,13 +80,13 @@ class spell_dk_anti_magic_shell_raid : public SpellScriptLoader void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) { - absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); + absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); } void Register() { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_anti_magic_shell_raid_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_raid_AuraScript::Absorb, EFFECT_0); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_anti_magic_shell_raid_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_raid_AuraScript::Absorb, EFFECT_0); } }; @@ -105,9 +114,9 @@ class spell_dk_anti_magic_shell_self : public SpellScriptLoader return true; } - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(DK_SPELL_RUNIC_POWER_ENERGIZE)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_RUNIC_POWER_ENERGIZE)) return false; return true; } @@ -128,14 +137,14 @@ class spell_dk_anti_magic_shell_self : public SpellScriptLoader // damage absorbed by Anti-Magic Shell energizes the DK with additional runic power. // This, if I'm not mistaken, shows that we get back ~20% of the absorbed damage as runic power. int32 bp = absorbAmount * 2 / 10; - target->CastCustomSpell(target, DK_SPELL_RUNIC_POWER_ENERGIZE, &bp, NULL, NULL, true, NULL, aurEff); + target->CastCustomSpell(target, SPELL_DK_RUNIC_POWER_ENERGIZE, &bp, NULL, NULL, true, NULL, aurEff); } void Register() { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_anti_magic_shell_self_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_self_AuraScript::Absorb, EFFECT_0); - AfterEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_self_AuraScript::Trigger, EFFECT_0); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_anti_magic_shell_self_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_self_AuraScript::Absorb, EFFECT_0); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_self_AuraScript::Trigger, EFFECT_0); } }; @@ -165,14 +174,14 @@ class spell_dk_anti_magic_zone : public SpellScriptLoader bool Validate(SpellInfo const* /*spellEntry*/) { - if (!sSpellMgr->GetSpellInfo(DK_SPELL_ANTI_MAGIC_SHELL_TALENT)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT)) return false; return true; } void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) { - SpellInfo const* talentSpell = sSpellMgr->GetSpellInfo(DK_SPELL_ANTI_MAGIC_SHELL_TALENT); + SpellInfo const* talentSpell = sSpellMgr->GetSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT); amount = talentSpell->Effects[EFFECT_0].CalcValue(GetCaster()); if (Player* player = GetCaster()->ToPlayer()) amount += int32(2 * player->GetTotalAttackPowerValue(BASE_ATTACK)); @@ -196,7 +205,53 @@ class spell_dk_anti_magic_zone : public SpellScriptLoader } }; -// 49158 Corpse Explosion (51325, 51326, 51327, 51328) +// 48721 - Blood Boil +class spell_dk_blood_boil : public SpellScriptLoader +{ + public: + spell_dk_blood_boil() : SpellScriptLoader("spell_dk_blood_boil") { } + + class spell_dk_blood_boil_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dk_blood_boil_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_BOIL_TRIGGERED)) + return false; + return true; + } + + bool Load() + { + _executed = false; + return GetCaster()->GetTypeId() == TYPEID_PLAYER && GetCaster()->getClass() == CLASS_DEATH_KNIGHT; + } + + void HandleAfterHit() + { + if (_executed || !GetHitUnit()) + return; + + _executed = true; + GetCaster()->CastSpell(GetCaster(), SPELL_DK_BLOOD_BOIL_TRIGGERED, true); + } + + void Register() + { + AfterHit += SpellHitFn(spell_dk_blood_boil_SpellScript::HandleAfterHit); + } + + bool _executed; + }; + + SpellScript* GetSpellScript() const + { + return new spell_dk_blood_boil_SpellScript(); + } +}; + +// 49158 - Corpse Explosion (51325, 51326, 51327, 51328) class spell_dk_corpse_explosion : public SpellScriptLoader { public: @@ -206,11 +261,11 @@ class spell_dk_corpse_explosion : public SpellScriptLoader { PrepareSpellScript(spell_dk_corpse_explosion_SpellScript); - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(DK_SPELL_CORPSE_EXPLOSION_TRIGGERED) || !sSpellMgr->GetSpellInfo(DK_SPELL_GHOUL_EXPLODE)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_EXPLODE)) return false; - if (!sSpellMgr->GetSpellInfo(DK_SPELL_CORPSE_EXPLOSION_VISUAL)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_VISUAL)) return false; return true; } @@ -223,17 +278,17 @@ class spell_dk_corpse_explosion : public SpellScriptLoader if (unitTarget->isAlive()) // Living ghoul as a target { bp = int32(unitTarget->CountPctFromMaxHealth(25)); - unitTarget->CastCustomSpell(unitTarget, DK_SPELL_GHOUL_EXPLODE, &bp, NULL, NULL, false); + unitTarget->CastCustomSpell(unitTarget, SPELL_DK_GHOUL_EXPLODE, &bp, NULL, NULL, false); } else // Some corpse { bp = GetEffectValue(); GetCaster()->CastCustomSpell(unitTarget, GetSpellInfo()->Effects[EFFECT_1].CalcValue(), &bp, NULL, NULL, true); // Corpse Explosion (Suicide) - unitTarget->CastSpell(unitTarget, DK_SPELL_CORPSE_EXPLOSION_TRIGGERED, true); + unitTarget->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED, true); } // Set corpse look - GetCaster()->CastSpell(unitTarget, DK_SPELL_CORPSE_EXPLOSION_VISUAL, true); + GetCaster()->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_VISUAL, true); } } @@ -249,44 +304,74 @@ class spell_dk_corpse_explosion : public SpellScriptLoader } }; -// 47496 - Explode, Ghoul spell for Corpse Explosion -class spell_dk_ghoul_explode : public SpellScriptLoader +// -47541, 52375, 59134, -62900 - Death Coil +class spell_dk_death_coil : public SpellScriptLoader { public: - spell_dk_ghoul_explode() : SpellScriptLoader("spell_dk_ghoul_explode") { } + spell_dk_death_coil() : SpellScriptLoader("spell_dk_death_coil") { } - class spell_dk_ghoul_explode_SpellScript : public SpellScript + class spell_dk_death_coil_SpellScript : public SpellScript { - PrepareSpellScript(spell_dk_ghoul_explode_SpellScript); + PrepareSpellScript(spell_dk_death_coil_SpellScript); - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spell*/) { - if (!sSpellMgr->GetSpellInfo(DK_SPELL_CORPSE_EXPLOSION_TRIGGERED)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_COIL_DAMAGE) || !sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_COIL_HEAL)) return false; return true; } - void Suicide(SpellEffIndex /*effIndex*/) + void HandleDummy(SpellEffIndex /*effIndex*/) { - if (Unit* unitTarget = GetHitUnit()) + int32 damage = GetEffectValue(); + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) { - // Corpse Explosion (Suicide) - unitTarget->CastSpell(unitTarget, DK_SPELL_CORPSE_EXPLOSION_TRIGGERED, true); + if (caster->IsFriendlyTo(target)) + { + int32 bp = int32(damage * 1.5f); + caster->CastCustomSpell(target, SPELL_DK_DEATH_COIL_HEAL, &bp, NULL, NULL, true); + } + else + { + if (AuraEffect const* auraEffect = caster->GetAuraEffect(SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART, EFFECT_1)) + damage += auraEffect->GetBaseAmount(); + caster->CastCustomSpell(target, SPELL_DK_DEATH_COIL_DAMAGE, &damage, NULL, NULL, true); + } + } + } + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (Unit* target = GetExplTargetUnit()) + { + if (!caster->IsFriendlyTo(target) && !caster->isInFront(target)) + return SPELL_FAILED_UNIT_NOT_INFRONT; + + if (target->IsFriendlyTo(caster) && target->GetCreatureType() != CREATURE_TYPE_UNDEAD) + return SPELL_FAILED_BAD_TARGETS; } + else + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_dk_ghoul_explode_SpellScript::Suicide, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + OnCheckCast += SpellCheckCastFn(spell_dk_death_coil_SpellScript::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_dk_death_coil_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; SpellScript* GetSpellScript() const { - return new spell_dk_ghoul_explode_SpellScript(); + return new spell_dk_death_coil_SpellScript(); } }; +// 52751 - Death Gate class spell_dk_death_gate : public SpellScriptLoader { public: @@ -327,6 +412,41 @@ class spell_dk_death_gate : public SpellScriptLoader } }; +// 49560 - Death Grip +class spell_dk_death_grip : public SpellScriptLoader +{ + public: + spell_dk_death_grip() : SpellScriptLoader("spell_dk_death_grip") { } + + class spell_dk_death_grip_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dk_death_grip_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + int32 damage = GetEffectValue(); + Position const* pos = GetExplTargetDest(); + if (Unit* target = GetHitUnit()) + { + if (!target->HasAuraType(SPELL_AURA_DEFLECT_SPELLS)) // Deterrence + target->CastSpell(pos->GetPositionX(), pos->GetPositionY(), pos->GetPositionZ(), damage, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_dk_death_grip_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + + }; + + SpellScript* GetSpellScript() const + { + return new spell_dk_death_grip_SpellScript(); + } +}; + +// 48743 - Death Pact class spell_dk_death_pact : public SpellScriptLoader { public: @@ -351,22 +471,22 @@ class spell_dk_death_pact : public SpellScriptLoader return SPELL_FAILED_NO_PET; } - void FilterTargets(std::list& unitList) + void FilterTargets(std::list& targetList) { - Unit* unit_to_add = NULL; - for (std::list::iterator itr = unitList.begin(); itr != unitList.end(); ++itr) + Unit* target = NULL; + for (std::list::iterator itr = targetList.begin(); itr != targetList.end(); ++itr) { if (Unit* unit = (*itr)->ToUnit()) - if (unit->GetOwnerGUID() == GetCaster()->GetGUID() && unit->GetCreatureType() == CREATURE_TYPE_UNDEAD) - { - unit_to_add = unit; - break; - } + if (unit->GetOwnerGUID() == GetCaster()->GetGUID() && unit->GetCreatureType() == CREATURE_TYPE_UNDEAD) + { + target = unit; + break; + } } - unitList.clear(); - if (unit_to_add) - unitList.push_back(unit_to_add); + targetList.clear(); + if (target) + targetList.push_back(target); } void Register() @@ -382,26 +502,19 @@ class spell_dk_death_pact : public SpellScriptLoader } }; -// 55090 Scourge Strike (55265, 55270, 55271) -class spell_dk_scourge_strike : public SpellScriptLoader +// -49998 - Death Strike +class spell_dk_death_strike : public SpellScriptLoader { public: - spell_dk_scourge_strike() : SpellScriptLoader("spell_dk_scourge_strike") { } + spell_dk_death_strike() : SpellScriptLoader("spell_dk_death_strike") { } - class spell_dk_scourge_strike_SpellScript : public SpellScript + class spell_dk_death_strike_SpellScript : public SpellScript { - PrepareSpellScript(spell_dk_scourge_strike_SpellScript); - float multiplier; - - bool Load() - { - multiplier = 1.0f; - return true; - } + PrepareSpellScript(spell_dk_death_strike_SpellScript); - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(DK_SPELL_SCOURGE_STRIKE_TRIGGERED)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_STRIKE_HEAL)) return false; return true; } @@ -409,442 +522,329 @@ class spell_dk_scourge_strike : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); - if (Unit* unitTarget = GetHitUnit()) - { - multiplier = (GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()) / 100.f); - // Death Knight T8 Melee 4P Bonus - if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DK_ITEM_T8_MELEE_4P_BONUS, EFFECT_0)) - AddPct(multiplier, aurEff->GetAmount()); - } - } - - void HandleAfterHit() - { - Unit* caster = GetCaster(); - if (Unit* unitTarget = GetHitUnit()) + if (Unit* target = GetHitUnit()) { - int32 bp = GetHitDamage() * multiplier; - - if (AuraEffect* aurEff = caster->GetAuraEffectOfRankedSpell(DK_SPELL_BLACK_ICE_R1, EFFECT_0)) - AddPct(bp, aurEff->GetAmount()); - - caster->CastCustomSpell(unitTarget, DK_SPELL_SCOURGE_STRIKE_TRIGGERED, &bp, NULL, NULL, true); + uint32 count = target->GetDiseasesByCaster(caster->GetGUID()); + int32 bp = int32(count * caster->CountPctFromMaxHealth(int32(GetSpellInfo()->Effects[EFFECT_0].DamageMultiplier))); + // Improved Death Strike + if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_DEATHKNIGHT, DK_ICON_ID_IMPROVED_DEATH_STRIKE, 0)) + AddPct(bp, caster->CalculateSpellDamage(caster, aurEff->GetSpellInfo(), 2)); + caster->CastCustomSpell(caster, SPELL_DK_DEATH_STRIKE_HEAL, &bp, NULL, NULL, false); } } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); - AfterHit += SpellHitFn(spell_dk_scourge_strike_SpellScript::HandleAfterHit); + OnEffectHitTarget += SpellEffectFn(spell_dk_death_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); } + }; SpellScript* GetSpellScript() const { - return new spell_dk_scourge_strike_SpellScript(); + return new spell_dk_death_strike_SpellScript(); } }; -// 49145 - Spell Deflection -class spell_dk_spell_deflection : public SpellScriptLoader +// 47496 - Explode, Ghoul spell for Corpse Explosion +class spell_dk_ghoul_explode : public SpellScriptLoader { public: - spell_dk_spell_deflection() : SpellScriptLoader("spell_dk_spell_deflection") { } + spell_dk_ghoul_explode() : SpellScriptLoader("spell_dk_ghoul_explode") { } - class spell_dk_spell_deflection_AuraScript : public AuraScript + class spell_dk_ghoul_explode_SpellScript : public SpellScript { - PrepareAuraScript(spell_dk_spell_deflection_AuraScript); - - uint32 absorbPct; + PrepareSpellScript(spell_dk_ghoul_explode_SpellScript); - bool Load() + bool Validate(SpellInfo const* /*spellInfo*/) { - absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); + if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED)) + return false; return true; } - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) - { - // Set absorbtion amount to unlimited - amount = -1; - } - - void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + void Suicide(SpellEffIndex /*effIndex*/) { - // You have a chance equal to your Parry chance - if ((dmgInfo.GetDamageType() == SPELL_DIRECT_DAMAGE) && roll_chance_f(GetTarget()->GetUnitParryChance())) - absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); + if (Unit* unitTarget = GetHitUnit()) + { + // Corpse Explosion (Suicide) + unitTarget->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED, true); + } } void Register() { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_spell_deflection_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_spell_deflection_AuraScript::Absorb, EFFECT_0); + OnEffectHitTarget += SpellEffectFn(spell_dk_ghoul_explode_SpellScript::Suicide, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); } }; - AuraScript* GetAuraScript() const + SpellScript* GetSpellScript() const { - return new spell_dk_spell_deflection_AuraScript(); + return new spell_dk_ghoul_explode_SpellScript(); } }; -// 48721 Blood Boil -class spell_dk_blood_boil : public SpellScriptLoader +// 50365, 50371 - Improved Blood Presence +class spell_dk_improved_blood_presence : public SpellScriptLoader { public: - spell_dk_blood_boil() : SpellScriptLoader("spell_dk_blood_boil") { } + spell_dk_improved_blood_presence() : SpellScriptLoader("spell_dk_improved_blood_presence") { } - class spell_dk_blood_boil_SpellScript : public SpellScript + class spell_dk_improved_blood_presence_AuraScript : public AuraScript { - PrepareSpellScript(spell_dk_blood_boil_SpellScript); + PrepareAuraScript(spell_dk_improved_blood_presence_AuraScript); - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(DK_SPELL_BLOOD_BOIL_TRIGGERED)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE) || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) return false; return true; } - bool Load() + void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { - _executed = false; - return GetCaster()->GetTypeId() == TYPEID_PLAYER && GetCaster()->getClass() == CLASS_DEATH_KNIGHT; + Unit* target = GetTarget(); + if (!target->HasAura(SPELL_DK_BLOOD_PRESENCE) && !target->HasAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) + { + int32 basePoints1 = aurEff->GetAmount(); + target->CastCustomSpell(target, SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED, NULL, &basePoints1, NULL, true, 0, aurEff); + } } - void HandleAfterHit() + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (_executed || !GetHitUnit()) - return; - - _executed = true; - GetCaster()->CastSpell(GetCaster(), DK_SPELL_BLOOD_BOIL_TRIGGERED, true); + Unit* target = GetTarget(); + if (!target->HasAura(SPELL_DK_BLOOD_PRESENCE)) + target->RemoveAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED); } void Register() { - AfterHit += SpellHitFn(spell_dk_blood_boil_SpellScript::HandleAfterHit); + AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } - - bool _executed; }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_dk_blood_boil_SpellScript(); + return new spell_dk_improved_blood_presence_AuraScript(); } }; -// 52284 - Will of the Necropolis -class spell_dk_will_of_the_necropolis : public SpellScriptLoader +// 50391, 50392 - Improved Unholy Presence +class spell_dk_improved_unholy_presence : public SpellScriptLoader { public: - spell_dk_will_of_the_necropolis() : SpellScriptLoader("spell_dk_will_of_the_necropolis") { } + spell_dk_improved_unholy_presence() : SpellScriptLoader("spell_dk_improved_unholy_presence") { } - class spell_dk_will_of_the_necropolis_AuraScript : public AuraScript + class spell_dk_improved_unholy_presence_AuraScript : public AuraScript { - PrepareAuraScript(spell_dk_will_of_the_necropolis_AuraScript); + PrepareAuraScript(spell_dk_improved_unholy_presence_AuraScript); - bool Validate(SpellInfo const* spellEntry) + bool Validate(SpellInfo const* /*spellInfo*/) { - // can't use other spell than will of the necropolis due to spell_ranks dependency - if (sSpellMgr->GetFirstSpellInChain(DK_SPELL_WILL_OF_THE_NECROPOLIS_AURA_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id)) - return false; - - uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id); - if (!sSpellMgr->GetSpellWithRank(DK_SPELL_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank, true)) + if (!sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE) || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)) return false; - return true; } - uint32 absorbPct; - - bool Load() + void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) { - absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); - return true; + Unit* target = GetTarget(); + if (target->HasAura(SPELL_DK_UNHOLY_PRESENCE) && !target->HasAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)) + { + // Not listed as any effect, only base points set in dbc + int32 basePoints0 = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + target->CastCustomSpell(target, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, &basePoints0, &basePoints0, &basePoints0, true, 0, aurEff); + } } - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - // Set absorbtion amount to unlimited - amount = -1; - } - - void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) - { - // min pct of hp is stored in effect 0 of talent spell - uint32 rank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id); - SpellInfo const* talentProto = sSpellMgr->GetSpellInfo(sSpellMgr->GetSpellWithRank(DK_SPELL_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank)); - - int32 remainingHp = int32(GetTarget()->GetHealth() - dmgInfo.GetDamage()); - int32 minHp = int32(GetTarget()->CountPctFromMaxHealth(talentProto->Effects[EFFECT_0].CalcValue(GetCaster()))); - - // Damage that would take you below [effect0] health or taken while you are at [effect0] - if (remainingHp < minHp) - absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); + GetTarget()->RemoveAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED); } void Register() { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_will_of_the_necropolis_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_will_of_the_necropolis_AuraScript::Absorb, EFFECT_0); + AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_unholy_presence_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_dk_improved_unholy_presence_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; AuraScript* GetAuraScript() const { - return new spell_dk_will_of_the_necropolis_AuraScript(); + return new spell_dk_improved_unholy_presence_AuraScript(); } }; -// 50365, 50371 Improved Blood Presence -class spell_dk_improved_blood_presence : public SpellScriptLoader +// 55090 - Scourge Strike (55265, 55270, 55271) +class spell_dk_scourge_strike : public SpellScriptLoader { -public: - spell_dk_improved_blood_presence() : SpellScriptLoader("spell_dk_improved_blood_presence") { } - - class spell_dk_improved_blood_presence_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dk_improved_blood_presence_AuraScript); + public: + spell_dk_scourge_strike() : SpellScriptLoader("spell_dk_scourge_strike") { } - bool Validate(SpellInfo const* /*entry*/) + class spell_dk_scourge_strike_SpellScript : public SpellScript { - if (!sSpellMgr->GetSpellInfo(DK_SPELL_BLOOD_PRESENCE) || !sSpellMgr->GetSpellInfo(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) - return false; - return true; - } + PrepareSpellScript(spell_dk_scourge_strike_SpellScript); + float multiplier; - void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE) && !target->HasAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) + bool Load() { - int32 basePoints1 = aurEff->GetAmount(); - target->CastCustomSpell(target, DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED, NULL, &basePoints1, NULL, true, 0, aurEff); + multiplier = 1.0f; + return true; } - } - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE)) - target->RemoveAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED); - } - void Register() - { - AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_dk_improved_blood_presence_AuraScript(); - } -}; - -// 50391, 50392 Improved Unholy Presence -class spell_dk_improved_unholy_presence : public SpellScriptLoader -{ -public: - spell_dk_improved_unholy_presence() : SpellScriptLoader("spell_dk_improved_unholy_presence") { } - - class spell_dk_improved_unholy_presence_AuraScript : public AuraScript - { - PrepareAuraScript(spell_dk_improved_unholy_presence_AuraScript); - - bool Validate(SpellInfo const* /*entry*/) - { - if (!sSpellMgr->GetSpellInfo(DK_SPELL_UNHOLY_PRESENCE) || !sSpellMgr->GetSpellInfo(DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)) - return false; - return true; - } - - void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - if (target->HasAura(DK_SPELL_UNHOLY_PRESENCE) && !target->HasAura(DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)) + bool Validate(SpellInfo const* /*spellInfo*/) { - // Not listed as any effect, only base points set in dbc - int32 basePoints0 = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); - target->CastCustomSpell(target, DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, &basePoints0, &basePoints0, &basePoints0, true, 0, aurEff); + if (!sSpellMgr->GetSpellInfo(SPELL_DK_SCOURGE_STRIKE_TRIGGERED)) + return false; + return true; } - } - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveAura(DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED); - } - - void Register() - { - AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_unholy_presence_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_dk_improved_unholy_presence_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_dk_improved_unholy_presence_AuraScript(); - } -}; - -enum DeathStrike -{ - ICON_ID_IMPROVED_DEATH_STRIKE = 2751, - SPELL_DEATH_STRIKE_HEAL = 45470, -}; - -class spell_dk_death_strike : public SpellScriptLoader -{ - public: - spell_dk_death_strike() : SpellScriptLoader("spell_dk_death_strike") { } - - class spell_dk_death_strike_SpellScript : public SpellScript - { - PrepareSpellScript(spell_dk_death_strike_SpellScript); - bool Validate(SpellInfo const* /*SpellEntry*/) + void HandleDummy(SpellEffIndex /*effIndex*/) { - if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_STRIKE_HEAL)) - return false; - return true; + Unit* caster = GetCaster(); + if (Unit* unitTarget = GetHitUnit()) + { + multiplier = (GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()) / 100.f); + // Death Knight T8 Melee 4P Bonus + if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DK_ITEM_T8_MELEE_4P_BONUS, EFFECT_0)) + AddPct(multiplier, aurEff->GetAmount()); + } } - void HandleDummy(SpellEffIndex /* effIndex */) + void HandleAfterHit() { Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) + if (Unit* unitTarget = GetHitUnit()) { - uint32 count = target->GetDiseasesByCaster(caster->GetGUID()); - int32 bp = int32(count * caster->CountPctFromMaxHealth(int32(GetSpellInfo()->Effects[EFFECT_0].DamageMultiplier))); - // Improved Death Strike - if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_DEATHKNIGHT, ICON_ID_IMPROVED_DEATH_STRIKE, 0)) - AddPct(bp, caster->CalculateSpellDamage(caster, aurEff->GetSpellInfo(), 2)); - caster->CastCustomSpell(caster, SPELL_DEATH_STRIKE_HEAL, &bp, NULL, NULL, false); + int32 bp = GetHitDamage() * multiplier; + + if (AuraEffect* aurEff = caster->GetAuraEffectOfRankedSpell(SPELL_DK_BLACK_ICE_R1, EFFECT_0)) + AddPct(bp, aurEff->GetAmount()); + + caster->CastCustomSpell(unitTarget, SPELL_DK_SCOURGE_STRIKE_TRIGGERED, &bp, NULL, NULL, true); } } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_dk_death_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); + AfterHit += SpellHitFn(spell_dk_scourge_strike_SpellScript::HandleAfterHit); } - }; SpellScript* GetSpellScript() const { - return new spell_dk_death_strike_SpellScript(); + return new spell_dk_scourge_strike_SpellScript(); } }; -enum DeathCoil -{ - SPELL_DEATH_COIL_DAMAGE = 47632, - SPELL_DEATH_COIL_HEAL = 47633, - SPELL_SIGIL_VENGEFUL_HEART = 64962, -}; - -class spell_dk_death_coil : public SpellScriptLoader +// 49145 - Spell Deflection +class spell_dk_spell_deflection : public SpellScriptLoader { public: - spell_dk_death_coil() : SpellScriptLoader("spell_dk_death_coil") { } + spell_dk_spell_deflection() : SpellScriptLoader("spell_dk_spell_deflection") { } - class spell_dk_death_coil_SpellScript : public SpellScript + class spell_dk_spell_deflection_AuraScript : public AuraScript { - PrepareSpellScript(spell_dk_death_coil_SpellScript); + PrepareAuraScript(spell_dk_spell_deflection_AuraScript); - bool Validate(SpellInfo const* /*spell*/) + uint32 absorbPct; + + bool Load() { - if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_DAMAGE) || !sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_HEAL)) - return false; + absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); return true; } - void HandleDummy(SpellEffIndex /*effIndex*/) + void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) { - int32 damage = GetEffectValue(); - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - { - if (caster->IsFriendlyTo(target)) - { - int32 bp = int32(damage * 1.5f); - caster->CastCustomSpell(target, SPELL_DEATH_COIL_HEAL, &bp, NULL, NULL, true); - } - else - { - if (AuraEffect const* auraEffect = caster->GetAuraEffect(SPELL_SIGIL_VENGEFUL_HEART, EFFECT_1)) - damage += auraEffect->GetBaseAmount(); - caster->CastCustomSpell(target, SPELL_DEATH_COIL_DAMAGE, &damage, NULL, NULL, true); - } - } + // Set absorbtion amount to unlimited + amount = -1; } - SpellCastResult CheckCast() + void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) { - Unit* caster = GetCaster(); - if (Unit* target = GetExplTargetUnit()) - { - if (!caster->IsFriendlyTo(target) && !caster->isInFront(target)) - return SPELL_FAILED_UNIT_NOT_INFRONT; - - if (target->IsFriendlyTo(caster) && target->GetCreatureType() != CREATURE_TYPE_UNDEAD) - return SPELL_FAILED_BAD_TARGETS; - } - else - return SPELL_FAILED_BAD_TARGETS; - - return SPELL_CAST_OK; + // You have a chance equal to your Parry chance + if ((dmgInfo.GetDamageType() == SPELL_DIRECT_DAMAGE) && roll_chance_f(GetTarget()->GetUnitParryChance())) + absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); } void Register() { - OnCheckCast += SpellCheckCastFn(spell_dk_death_coil_SpellScript::CheckCast); - OnEffectHitTarget += SpellEffectFn(spell_dk_death_coil_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_spell_deflection_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_spell_deflection_AuraScript::Absorb, EFFECT_0); } - }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_dk_death_coil_SpellScript(); + return new spell_dk_spell_deflection_AuraScript(); } }; -class spell_dk_death_grip : public SpellScriptLoader +// 52284 - Will of the Necropolis +class spell_dk_will_of_the_necropolis : public SpellScriptLoader { public: - spell_dk_death_grip() : SpellScriptLoader("spell_dk_death_grip") { } + spell_dk_will_of_the_necropolis() : SpellScriptLoader("spell_dk_will_of_the_necropolis") { } - class spell_dk_death_grip_SpellScript : public SpellScript + class spell_dk_will_of_the_necropolis_AuraScript : public AuraScript { - PrepareSpellScript(spell_dk_death_grip_SpellScript); + PrepareAuraScript(spell_dk_will_of_the_necropolis_AuraScript); - void HandleDummy(SpellEffIndex /*effIndex*/) + bool Validate(SpellInfo const* spellInfo) { - int32 damage = GetEffectValue(); - Position const* pos = GetExplTargetDest(); - if (Unit* target = GetHitUnit()) - { - if (!target->HasAuraType(SPELL_AURA_DEFLECT_SPELLS)) // Deterrence - target->CastSpell(pos->GetPositionX(), pos->GetPositionY(), pos->GetPositionZ(), damage, true); - } + // can't use other spell than will of the necropolis due to spell_ranks dependency + if (sSpellMgr->GetFirstSpellInChain(SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1) != sSpellMgr->GetFirstSpellInChain(spellInfo->Id)) + return false; + + uint8 rank = sSpellMgr->GetSpellRank(spellInfo->Id); + if (!sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank, true)) + return false; + + return true; } - void Register() + uint32 absorbPct; + + bool Load() { - OnEffectHitTarget += SpellEffectFn(spell_dk_death_grip_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); + return true; + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) + { + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // min pct of hp is stored in effect 0 of talent spell + uint32 rank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id); + SpellInfo const* talentProto = sSpellMgr->GetSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank)); + + int32 remainingHp = int32(GetTarget()->GetHealth() - dmgInfo.GetDamage()); + int32 minHp = int32(GetTarget()->CountPctFromMaxHealth(talentProto->Effects[EFFECT_0].CalcValue(GetCaster()))); + + // Damage that would take you below [effect0] health or taken while you are at [effect0] + if (remainingHp < minHp) + absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct); } + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_will_of_the_necropolis_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_will_of_the_necropolis_AuraScript::Absorb, EFFECT_0); + } }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_dk_death_grip_SpellScript(); + return new spell_dk_will_of_the_necropolis_AuraScript(); } }; @@ -853,17 +853,17 @@ void AddSC_deathknight_spell_scripts() new spell_dk_anti_magic_shell_raid(); new spell_dk_anti_magic_shell_self(); new spell_dk_anti_magic_zone(); + new spell_dk_blood_boil(); new spell_dk_corpse_explosion(); - new spell_dk_ghoul_explode(); + new spell_dk_death_coil(); new spell_dk_death_gate(); + new spell_dk_death_grip(); new spell_dk_death_pact(); + new spell_dk_death_strike(); + new spell_dk_ghoul_explode(); + new spell_dk_improved_blood_presence(); + new spell_dk_improved_unholy_presence(); new spell_dk_scourge_strike(); new spell_dk_spell_deflection(); - new spell_dk_blood_boil(); new spell_dk_will_of_the_necropolis(); - new spell_dk_improved_blood_presence(); - new spell_dk_improved_unholy_presence(); - new spell_dk_death_strike(); - new spell_dk_death_coil(); - new spell_dk_death_grip(); } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 18326a8f059..36194a596ce 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -32,23 +32,25 @@ enum HunterSpells { - HUNTER_SPELL_READINESS = 23989, - DRAENEI_SPELL_GIFT_OF_THE_NAARU = 59543, - HUNTER_SPELL_BESTIAL_WRATH = 19574, - HUNTER_PET_SPELL_LAST_STAND_TRIGGERED = 53479, - HUNTER_PET_HEART_OF_THE_PHOENIX = 55709, - HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114, - HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF = 55711, - HUNTER_PET_SPELL_CARRION_FEEDER_TRIGGERED = 54045, - HUNTER_SPELL_INVIGORATION_TRIGGERED = 53398, - HUNTER_SPELL_MASTERS_CALL_TRIGGERED = 62305, - HUNTER_SPELL_CHIMERA_SHOT_SERPENT = 53353, - HUNTER_SPELL_CHIMERA_SHOT_VIPER = 53358, - HUNTER_SPELL_CHIMERA_SHOT_SCORPID = 53359, - HUNTER_SPELL_ASPECT_OF_THE_BEAST_PET = 61669, + SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET = 61669, + SPELL_HUNTER_BESTIAL_WRATH = 19574, + SPELL_HUNTER_CHIMERA_SHOT_SERPENT = 53353, + SPELL_HUNTER_CHIMERA_SHOT_VIPER = 53358, + SPELL_HUNTER_CHIMERA_SHOT_SCORPID = 53359, + SPELL_HUNTER_INVIGORATION_TRIGGERED = 53398, + SPELL_HUNTER_MASTERS_CALL_TRIGGERED = 62305, + SPELL_HUNTER_PET_LAST_STAND_TRIGGERED = 53479, + SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX = 55709, + SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114, + SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF = 55711, + SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED = 54045, + SPELL_HUNTER_READINESS = 23989, + SPELL_HUNTER_SNIPER_TRAINING_R1 = 53302, + SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 = 64418, + SPELL_DRAENEI_GIFT_OF_THE_NAARU = 59543, }; -// 13161 Aspect of the Beast +// 13161 - Aspect of the Beast class spell_hun_aspect_of_the_beast : public SpellScriptLoader { public: @@ -63,9 +65,9 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader return GetCaster()->GetTypeId() == TYPEID_PLAYER; } - bool Validate(SpellInfo const* /*entry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(HUNTER_SPELL_ASPECT_OF_THE_BEAST_PET)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET)) return false; return true; } @@ -74,14 +76,14 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader { if (Player* caster = GetCaster()->ToPlayer()) if (Pet* pet = caster->GetPet()) - pet->RemoveAurasDueToSpell(HUNTER_SPELL_ASPECT_OF_THE_BEAST_PET); + pet->RemoveAurasDueToSpell(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET); } void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (Player* caster = GetCaster()->ToPlayer()) if (caster->GetPet()) - caster->CastSpell(caster, HUNTER_SPELL_ASPECT_OF_THE_BEAST_PET, true); + caster->CastSpell(caster, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true); } void Register() @@ -97,7 +99,7 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader } }; -// 53209 Chimera Shot +// 53209 - Chimera Shot class spell_hun_chimera_shot : public SpellScriptLoader { public: @@ -107,9 +109,9 @@ class spell_hun_chimera_shot : public SpellScriptLoader { PrepareSpellScript(spell_hun_chimera_shot_SpellScript); - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(HUNTER_SPELL_CHIMERA_SHOT_SERPENT) || !sSpellMgr->GetSpellInfo(HUNTER_SPELL_CHIMERA_SHOT_VIPER) || !sSpellMgr->GetSpellInfo(HUNTER_SPELL_CHIMERA_SHOT_SCORPID)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_SERPENT) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_VIPER) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_SCORPID)) return false; return true; } @@ -138,7 +140,7 @@ class spell_hun_chimera_shot : public SpellScriptLoader if (familyFlag[0] & 0x4000) { int32 TickCount = aurEff->GetTotalTicks(); - spellId = HUNTER_SPELL_CHIMERA_SHOT_SERPENT; + spellId = SPELL_HUNTER_CHIMERA_SHOT_SERPENT; basePoint = caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount()); ApplyPct(basePoint, TickCount * 40); basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount()); @@ -147,7 +149,7 @@ class spell_hun_chimera_shot : public SpellScriptLoader else if (familyFlag[1] & 0x00000080) { int32 TickCount = aura->GetEffect(0)->GetTotalTicks(); - spellId = HUNTER_SPELL_CHIMERA_SHOT_VIPER; + spellId = SPELL_HUNTER_CHIMERA_SHOT_VIPER; // Amount of one aura tick basePoint = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), aurEff->GetAmount())); @@ -158,7 +160,7 @@ class spell_hun_chimera_shot : public SpellScriptLoader } // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. else if (familyFlag[0] & 0x00008000) - spellId = HUNTER_SPELL_CHIMERA_SHOT_SCORPID; + spellId = SPELL_HUNTER_CHIMERA_SHOT_SCORPID; // ?? nothing say in spell desc (possibly need addition check) //if (familyFlag & 0x0000010000000000LL || // dot // familyFlag & 0x0000100000000000LL) // stun @@ -173,7 +175,7 @@ class spell_hun_chimera_shot : public SpellScriptLoader } if (spellId) caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true); - if (spellId == HUNTER_SPELL_CHIMERA_SHOT_SCORPID && caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown + if (spellId == SPELL_HUNTER_CHIMERA_SHOT_SCORPID && caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown caster->ToPlayer()->AddSpellCooldown(spellId, 0, uint32(time(NULL) + 60)); } } @@ -190,7 +192,38 @@ class spell_hun_chimera_shot : public SpellScriptLoader } }; -// 53412 Invigoration +// 781 - Disengage +class spell_hun_disengage : public SpellScriptLoader +{ + public: + spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { } + + class spell_hun_disengage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_hun_disengage_SpellScript); + + SpellCastResult CheckCast() + { + Unit* caster = GetCaster(); + if (caster->GetTypeId() == TYPEID_PLAYER && !caster->isInCombat()) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; + + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_hun_disengage_SpellScript(); + } +}; + +// 53412 - Invigoration class spell_hun_invigoration : public SpellScriptLoader { public: @@ -200,9 +233,9 @@ class spell_hun_invigoration : public SpellScriptLoader { PrepareSpellScript(spell_hun_invigoration_SpellScript); - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(HUNTER_SPELL_INVIGORATION_TRIGGERED)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_INVIGORATION_TRIGGERED)) return false; return true; } @@ -212,7 +245,7 @@ class spell_hun_invigoration : public SpellScriptLoader if (Unit* unitTarget = GetHitUnit()) if (AuraEffect* aurEff = unitTarget->GetDummyAuraEffect(SPELLFAMILY_HUNTER, 3487, 0)) if (roll_chance_i(aurEff->GetAmount())) - unitTarget->CastSpell(unitTarget, HUNTER_SPELL_INVIGORATION_TRIGGERED, true); + unitTarget->CastSpell(unitTarget, SPELL_HUNTER_INVIGORATION_TRIGGERED, true); } void Register() @@ -227,6 +260,7 @@ class spell_hun_invigoration : public SpellScriptLoader } }; +// 53478 - Last Stand Pet class spell_hun_last_stand_pet : public SpellScriptLoader { public: @@ -236,9 +270,9 @@ class spell_hun_last_stand_pet : public SpellScriptLoader { PrepareSpellScript(spell_hun_last_stand_pet_SpellScript); - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(HUNTER_PET_SPELL_LAST_STAND_TRIGGERED)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_PET_LAST_STAND_TRIGGERED)) return false; return true; } @@ -247,7 +281,7 @@ class spell_hun_last_stand_pet : public SpellScriptLoader { Unit* caster = GetCaster(); int32 healthModSpellBasePoints0 = int32(caster->CountPctFromMaxHealth(30)); - caster->CastCustomSpell(caster, HUNTER_PET_SPELL_LAST_STAND_TRIGGERED, &healthModSpellBasePoints0, NULL, NULL, true, NULL); + caster->CastCustomSpell(caster, SPELL_HUNTER_PET_LAST_STAND_TRIGGERED, &healthModSpellBasePoints0, NULL, NULL, true, NULL); } void Register() @@ -263,6 +297,7 @@ class spell_hun_last_stand_pet : public SpellScriptLoader } }; +// 53271 - Masters Call class spell_hun_masters_call : public SpellScriptLoader { public: @@ -272,9 +307,9 @@ class spell_hun_masters_call : public SpellScriptLoader { PrepareSpellScript(spell_hun_masters_call_SpellScript); - bool Validate(SpellInfo const* spellEntry) + bool Validate(SpellInfo const* spellInfo) { - if (!sSpellMgr->GetSpellInfo(HUNTER_SPELL_MASTERS_CALL_TRIGGERED) || !sSpellMgr->GetSpellInfo(spellEntry->Effects[EFFECT_0].CalcValue()) || !sSpellMgr->GetSpellInfo(spellEntry->Effects[EFFECT_1].CalcValue())) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MASTERS_CALL_TRIGGERED) || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()) || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].CalcValue())) return false; return true; } @@ -297,7 +332,7 @@ class spell_hun_masters_call : public SpellScriptLoader { // Cannot be processed while pet is dead TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE); - target->CastSpell(target, HUNTER_SPELL_MASTERS_CALL_TRIGGERED, castMask); + target->CastSpell(target, SPELL_HUNTER_MASTERS_CALL_TRIGGERED, castMask); } } @@ -314,156 +349,122 @@ class spell_hun_masters_call : public SpellScriptLoader } }; -class spell_hun_readiness : public SpellScriptLoader +// 34477 - Misdirection +class spell_hun_misdirection : public SpellScriptLoader { public: - spell_hun_readiness() : SpellScriptLoader("spell_hun_readiness") { } + spell_hun_misdirection() : SpellScriptLoader("spell_hun_misdirection") { } - class spell_hun_readiness_SpellScript : public SpellScript + class spell_hun_misdirection_AuraScript : public AuraScript { - PrepareSpellScript(spell_hun_readiness_SpellScript); - - bool Load() - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareAuraScript(spell_hun_misdirection_AuraScript); - void HandleDummy(SpellEffIndex /*effIndex*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Player* caster = GetCaster()->ToPlayer(); - // immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath - const SpellCooldowns& cm = caster->ToPlayer()->GetSpellCooldownMap(); - for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); - - ///! If spellId in cooldown map isn't valid, the above will return a null pointer. - if (spellInfo && - spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && - spellInfo->Id != HUNTER_SPELL_READINESS && - spellInfo->Id != HUNTER_SPELL_BESTIAL_WRATH && - spellInfo->Id != DRAENEI_SPELL_GIFT_OF_THE_NAARU && - spellInfo->GetRecoveryTime() > 0) - caster->RemoveSpellCooldown((itr++)->first, true); - else - ++itr; - } + if (Unit* caster = GetCaster()) + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) + caster->SetReducedThreatPercent(0, 0); } void Register() { - // add dummy effect spell handler to Readiness - OnEffectHitTarget += SpellEffectFn(spell_hun_readiness_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_hun_readiness_SpellScript(); + return new spell_hun_misdirection_AuraScript(); } }; -// 37506 Scatter Shot -class spell_hun_scatter_shot : public SpellScriptLoader +// 35079 - Misdirection proc +class spell_hun_misdirection_proc : public SpellScriptLoader { public: - spell_hun_scatter_shot() : SpellScriptLoader("spell_hun_scatter_shot") { } + spell_hun_misdirection_proc() : SpellScriptLoader("spell_hun_misdirection_proc") { } - class spell_hun_scatter_shot_SpellScript : public SpellScript + class spell_hun_misdirection_proc_AuraScript : public AuraScript { - PrepareSpellScript(spell_hun_scatter_shot_SpellScript); - - bool Load() - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } + PrepareAuraScript(spell_hun_misdirection_proc_AuraScript); - void HandleDummy(SpellEffIndex /*effIndex*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - Player* caster = GetCaster()->ToPlayer(); - // break Auto Shot and autohit - caster->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); - caster->AttackStop(); - caster->SendAttackSwingCancelAttack(); + if (GetCaster()) + GetCaster()->SetReducedThreatPercent(0, 0); } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_hun_scatter_shot_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_proc_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_hun_scatter_shot_SpellScript(); + return new spell_hun_misdirection_proc_AuraScript(); } }; -// 53302, 53303, 53304 Sniper Training -enum eSniperTrainingSpells -{ - SPELL_SNIPER_TRAINING_R1 = 53302, - SPELL_SNIPER_TRAINING_BUFF_R1 = 64418, -}; - -class spell_hun_sniper_training : public SpellScriptLoader +// 54044 - Pet Carrion Feeder +class spell_hun_pet_carrion_feeder : public SpellScriptLoader { public: - spell_hun_sniper_training() : SpellScriptLoader("spell_hun_sniper_training") { } + spell_hun_pet_carrion_feeder() : SpellScriptLoader("spell_hun_pet_carrion_feeder") { } - class spell_hun_sniper_training_AuraScript : public AuraScript + class spell_hun_pet_carrion_feeder_SpellScript : public SpellScript { - PrepareAuraScript(spell_hun_sniper_training_AuraScript); + PrepareSpellScript(spell_hun_pet_carrion_feeder_SpellScript); - bool Validate(SpellInfo const* /*entry*/) + bool Load() { - if (!sSpellMgr->GetSpellInfo(SPELL_SNIPER_TRAINING_R1) || !sSpellMgr->GetSpellInfo(SPELL_SNIPER_TRAINING_BUFF_R1)) + if (!GetCaster()->isPet()) return false; return true; } - void HandlePeriodic(AuraEffect const* aurEff) + bool Validate(SpellInfo const* /*spellInfo*/) { - PreventDefaultAction(); - if (aurEff->GetAmount() <= 0) - { - Unit* caster = GetCaster(); - uint32 spellId = SPELL_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_SNIPER_TRAINING_R1; - if (Unit* target = GetTarget()) - if (!target->HasAura(spellId)) - { - SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(spellId); - Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster() ? caster : target; - triggerCaster->CastSpell(target, triggeredSpellInfo, true, 0, aurEff); - } - } + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED)) + return false; + return true; } - void HandleUpdatePeriodic(AuraEffect* aurEff) + SpellCastResult CheckIfCorpseNear() { - if (Player* playerTarget = GetUnitOwner()->ToPlayer()) - { - int32 baseAmount = aurEff->GetBaseAmount(); - int32 amount = playerTarget->isMoving() ? - playerTarget->CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff->GetEffIndex(), &baseAmount) : - aurEff->GetAmount() - 1; - aurEff->SetAmount(amount); - } + Unit* caster = GetCaster(); + float max_range = GetSpellInfo()->GetMaxRange(false); + WorldObject* result = NULL; + // search for nearby enemy corpse in range + Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY); + Trinity::WorldObjectSearcher searcher(caster, result, check); + caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher); + if (!result) + return SPELL_FAILED_NO_EDIBLE_CORPSES; + return SPELL_CAST_OK; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED, false); } void Register() { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_hun_sniper_training_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_hun_sniper_training_AuraScript::HandleUpdatePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + // add dummy effect spell handler to pet's Last Stand + OnEffectHit += SpellEffectFn(spell_hun_pet_carrion_feeder_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnCheckCast += SpellCheckCastFn(spell_hun_pet_carrion_feeder_SpellScript::CheckIfCorpseNear); } }; - AuraScript* GetAuraScript() const + SpellScript* GetSpellScript() const { - return new spell_hun_sniper_training_AuraScript(); + return new spell_hun_pet_carrion_feeder_SpellScript(); } }; +// 55709 - Pet Heart of the Phoenix class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader { public: @@ -480,9 +481,9 @@ class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader return true; } - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED) || !sSpellMgr->GetSpellInfo(HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF)) + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF)) return false; return true; } @@ -491,10 +492,10 @@ class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader { Unit* caster = GetCaster(); if (Unit* owner = caster->GetOwner()) - if (!caster->HasAura(HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF)) + if (!caster->HasAura(SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF)) { - owner->CastCustomSpell(HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED, SPELLVALUE_BASE_POINT0, 100, caster, true); - caster->CastSpell(caster, HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF, true); + owner->CastCustomSpell(SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED, SPELLVALUE_BASE_POINT0, 100, caster, true); + caster->CastSpell(caster, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF, true); } } @@ -511,150 +512,152 @@ class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader } }; -class spell_hun_pet_carrion_feeder : public SpellScriptLoader +// 23989 - Readiness +class spell_hun_readiness : public SpellScriptLoader { public: - spell_hun_pet_carrion_feeder() : SpellScriptLoader("spell_hun_pet_carrion_feeder") { } + spell_hun_readiness() : SpellScriptLoader("spell_hun_readiness") { } - class spell_hun_pet_carrion_feeder_SpellScript : public SpellScript + class spell_hun_readiness_SpellScript : public SpellScript { - PrepareSpellScript(spell_hun_pet_carrion_feeder_SpellScript); + PrepareSpellScript(spell_hun_readiness_SpellScript); bool Load() { - if (!GetCaster()->isPet()) - return false; - return true; - } - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(HUNTER_PET_SPELL_CARRION_FEEDER_TRIGGERED)) - return false; - return true; - } - - SpellCastResult CheckIfCorpseNear() - { - Unit* caster = GetCaster(); - float max_range = GetSpellInfo()->GetMaxRange(false); - WorldObject* result = NULL; - // search for nearby enemy corpse in range - Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY); - Trinity::WorldObjectSearcher searcher(caster, result, check); - caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher); - if (!result) - return SPELL_FAILED_NO_EDIBLE_CORPSES; - return SPELL_CAST_OK; + return GetCaster()->GetTypeId() == TYPEID_PLAYER; } void HandleDummy(SpellEffIndex /*effIndex*/) { - Unit* caster = GetCaster(); - caster->CastSpell(caster, HUNTER_PET_SPELL_CARRION_FEEDER_TRIGGERED, false); + Player* caster = GetCaster()->ToPlayer(); + // immediately finishes the cooldown on your other Hunter abilities except Bestial Wrath + const SpellCooldowns& cm = caster->ToPlayer()->GetSpellCooldownMap(); + for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); + + ///! If spellId in cooldown map isn't valid, the above will return a null pointer. + if (spellInfo && + spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && + spellInfo->Id != SPELL_HUNTER_READINESS && + spellInfo->Id != SPELL_HUNTER_BESTIAL_WRATH && + spellInfo->Id != SPELL_DRAENEI_GIFT_OF_THE_NAARU && + spellInfo->GetRecoveryTime() > 0) + caster->RemoveSpellCooldown((itr++)->first, true); + else + ++itr; + } } void Register() { - // add dummy effect spell handler to pet's Last Stand - OnEffectHit += SpellEffectFn(spell_hun_pet_carrion_feeder_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - OnCheckCast += SpellCheckCastFn(spell_hun_pet_carrion_feeder_SpellScript::CheckIfCorpseNear); + // add dummy effect spell handler to Readiness + OnEffectHitTarget += SpellEffectFn(spell_hun_readiness_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; SpellScript* GetSpellScript() const { - return new spell_hun_pet_carrion_feeder_SpellScript(); + return new spell_hun_readiness_SpellScript(); } }; -// 34477 Misdirection -class spell_hun_misdirection : public SpellScriptLoader +// 37506 - Scatter Shot +class spell_hun_scatter_shot : public SpellScriptLoader { public: - spell_hun_misdirection() : SpellScriptLoader("spell_hun_misdirection") { } + spell_hun_scatter_shot() : SpellScriptLoader("spell_hun_scatter_shot") { } - class spell_hun_misdirection_AuraScript : public AuraScript + class spell_hun_scatter_shot_SpellScript : public SpellScript { - PrepareAuraScript(spell_hun_misdirection_AuraScript); + PrepareSpellScript(spell_hun_scatter_shot_SpellScript); - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + bool Load() { - if (Unit* caster = GetCaster()) - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) - caster->SetReducedThreatPercent(0, 0); + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); + // break Auto Shot and autohit + caster->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); + caster->AttackStop(); + caster->SendAttackSwingCancelAttack(); } void Register() { - AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectHitTarget += SpellEffectFn(spell_hun_scatter_shot_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; - AuraScript* GetAuraScript() const + SpellScript* GetSpellScript() const { - return new spell_hun_misdirection_AuraScript(); + return new spell_hun_scatter_shot_SpellScript(); } }; -// 35079 Misdirection proc -class spell_hun_misdirection_proc : public SpellScriptLoader +// -53302 - Sniper Training +class spell_hun_sniper_training : public SpellScriptLoader { public: - spell_hun_misdirection_proc() : SpellScriptLoader("spell_hun_misdirection_proc") { } + spell_hun_sniper_training() : SpellScriptLoader("spell_hun_sniper_training") { } - class spell_hun_misdirection_proc_AuraScript : public AuraScript + class spell_hun_sniper_training_AuraScript : public AuraScript { - PrepareAuraScript(spell_hun_misdirection_proc_AuraScript); + PrepareAuraScript(spell_hun_sniper_training_AuraScript); - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (GetCaster()) - GetCaster()->SetReducedThreatPercent(0, 0); + if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_R1) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1)) + return false; + return true; } - void Register() + void HandlePeriodic(AuraEffect const* aurEff) { - AfterEffectRemove += AuraEffectRemoveFn(spell_hun_misdirection_proc_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + PreventDefaultAction(); + if (aurEff->GetAmount() <= 0) + { + Unit* caster = GetCaster(); + uint32 spellId = SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_HUNTER_SNIPER_TRAINING_R1; + if (Unit* target = GetTarget()) + if (!target->HasAura(spellId)) + { + SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(spellId); + Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster() ? caster : target; + triggerCaster->CastSpell(target, triggeredSpellInfo, true, 0, aurEff); + } + } } - }; - - AuraScript* GetAuraScript() const - { - return new spell_hun_misdirection_proc_AuraScript(); - } -}; -class spell_hun_disengage : public SpellScriptLoader -{ - public: - spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { } - - class spell_hun_disengage_SpellScript : public SpellScript - { - PrepareSpellScript(spell_hun_disengage_SpellScript); - - SpellCastResult CheckCast() + void HandleUpdatePeriodic(AuraEffect* aurEff) { - Unit* caster = GetCaster(); - if (caster->GetTypeId() == TYPEID_PLAYER && !caster->isInCombat()) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - - return SPELL_CAST_OK; + if (Player* playerTarget = GetUnitOwner()->ToPlayer()) + { + int32 baseAmount = aurEff->GetBaseAmount(); + int32 amount = playerTarget->isMoving() ? + playerTarget->CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff->GetEffIndex(), &baseAmount) : + aurEff->GetAmount() - 1; + aurEff->SetAmount(amount); + } } void Register() { - OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_hun_sniper_training_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_hun_sniper_training_AuraScript::HandleUpdatePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); } }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_hun_disengage_SpellScript(); + return new spell_hun_sniper_training_AuraScript(); } }; +// 1515 - Tame Beast class spell_hun_tame_beast : public SpellScriptLoader { public: @@ -706,6 +709,8 @@ class spell_hun_tame_beast : public SpellScriptLoader } }; +// -24604 - Furious Howl +// 53434 - Call of the Wild class spell_hun_target_only_pet_and_owner : public SpellScriptLoader { public: @@ -740,17 +745,17 @@ void AddSC_hunter_spell_scripts() { new spell_hun_aspect_of_the_beast(); new spell_hun_chimera_shot(); + new spell_hun_disengage(); new spell_hun_invigoration(); new spell_hun_last_stand_pet(); new spell_hun_masters_call(); + new spell_hun_misdirection(); + new spell_hun_misdirection_proc(); + new spell_hun_pet_carrion_feeder(); + new spell_hun_pet_heart_of_the_phoenix(); new spell_hun_readiness(); new spell_hun_scatter_shot(); new spell_hun_sniper_training(); - new spell_hun_pet_heart_of_the_phoenix(); - new spell_hun_pet_carrion_feeder(); - new spell_hun_misdirection(); - new spell_hun_misdirection_proc(); - new spell_hun_disengage(); new spell_hun_tame_beast(); new spell_hun_target_only_pet_and_owner(); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 045df640090..68a9337f8ea 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -29,20 +29,25 @@ enum PriestSpells { - PRIEST_SPELL_GUARDIAN_SPIRIT_HEAL = 48153, - PRIEST_SPELL_PENANCE_R1 = 47540, - PRIEST_SPELL_PENANCE_R1_DAMAGE = 47758, - PRIEST_SPELL_PENANCE_R1_HEAL = 47757, - PRIEST_SPELL_REFLECTIVE_SHIELD_TRIGGERED = 33619, - PRIEST_SPELL_REFLECTIVE_SHIELD_R1 = 33201, - PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL = 64085, - PRIEST_SPELL_EMPOWERED_RENEW = 63544, + SPELL_PRIEST_EMPOWERED_RENEW = 63544, + SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153, + SPELL_PRIEST_PENANCE_R1 = 47540, + SPELL_PRIEST_PENANCE_R1_DAMAGE = 47758, + SPELL_PRIEST_PENANCE_R1_HEAL = 47757, + SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED = 33619, + SPELL_PRIEST_REFLECTIVE_SHIELD_R1 = 33201, + SPELL_PRIEST_SHADOW_WORD_DEATH = 32409, + SPELL_PRIEST_T9_HEALING_2P = 67201, + SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085, +}; + +enum PriestSpellIcons +{ PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, - PRIEST_SHADOW_WORD_DEATH = 32409, }; -// Guardian Spirit +// -47788 - Guardian Spirit class spell_pri_guardian_spirit : public SpellScriptLoader { public: @@ -54,9 +59,9 @@ class spell_pri_guardian_spirit : public SpellScriptLoader uint32 healPct; - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(PRIEST_SPELL_GUARDIAN_SPIRIT_HEAL)) + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL)) return false; return true; } @@ -82,7 +87,7 @@ class spell_pri_guardian_spirit : public SpellScriptLoader int32 healAmount = int32(target->CountPctFromMaxHealth(healPct)); // remove the aura now, we don't want 40% healing bonus Remove(AURA_REMOVE_BY_ENEMY_SPELL); - target->CastCustomSpell(target, PRIEST_SPELL_GUARDIAN_SPIRIT_HEAL, &healAmount, NULL, NULL, true); + target->CastCustomSpell(target, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL, &healAmount, NULL, NULL, true); absorbAmount = dmgInfo.GetDamage(); } @@ -99,6 +104,7 @@ class spell_pri_guardian_spirit : public SpellScriptLoader } }; +// -8129 - Mana Burn class spell_pri_mana_burn : public SpellScriptLoader { public: @@ -126,6 +132,7 @@ class spell_pri_mana_burn : public SpellScriptLoader } }; +// -49821 - Mind Sear class spell_pri_mind_sear : public SpellScriptLoader { public: @@ -152,12 +159,12 @@ class spell_pri_mind_sear : public SpellScriptLoader } }; +// 47948 - Pain and Suffering (Proc) class spell_pri_pain_and_suffering_proc : public SpellScriptLoader { public: spell_pri_pain_and_suffering_proc() : SpellScriptLoader("spell_pri_pain_and_suffering_proc") { } - // 47948 Pain and Suffering (proc) class spell_pri_pain_and_suffering_proc_SpellScript : public SpellScript { PrepareSpellScript(spell_pri_pain_and_suffering_proc_SpellScript); @@ -182,6 +189,7 @@ class spell_pri_pain_and_suffering_proc : public SpellScriptLoader } }; +// -47540 - Penance class spell_pri_penance : public SpellScriptLoader { public: @@ -196,18 +204,18 @@ class spell_pri_penance : public SpellScriptLoader return GetCaster()->GetTypeId() == TYPEID_PLAYER; } - bool Validate(SpellInfo const* spellEntry) + bool Validate(SpellInfo const* spellInfo) { - if (!sSpellMgr->GetSpellInfo(PRIEST_SPELL_PENANCE_R1)) + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_PENANCE_R1)) return false; // can't use other spell than this penance due to spell_ranks dependency - if (sSpellMgr->GetFirstSpellInChain(PRIEST_SPELL_PENANCE_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id)) + if (sSpellMgr->GetFirstSpellInChain(SPELL_PRIEST_PENANCE_R1) != sSpellMgr->GetFirstSpellInChain(spellInfo->Id)) return false; - uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id); - if (!sSpellMgr->GetSpellWithRank(PRIEST_SPELL_PENANCE_R1_DAMAGE, rank, true)) + uint8 rank = sSpellMgr->GetSpellRank(spellInfo->Id); + if (!sSpellMgr->GetSpellWithRank(SPELL_PRIEST_PENANCE_R1_DAMAGE, rank, true)) return false; - if (!sSpellMgr->GetSpellWithRank(PRIEST_SPELL_PENANCE_R1_HEAL, rank, true)) + if (!sSpellMgr->GetSpellWithRank(SPELL_PRIEST_PENANCE_R1_HEAL, rank, true)) return false; return true; @@ -224,9 +232,9 @@ class spell_pri_penance : public SpellScriptLoader uint8 rank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id); if (caster->IsFriendlyTo(unitTarget)) - caster->CastSpell(unitTarget, sSpellMgr->GetSpellWithRank(PRIEST_SPELL_PENANCE_R1_HEAL, rank), false, 0); + caster->CastSpell(unitTarget, sSpellMgr->GetSpellWithRank(SPELL_PRIEST_PENANCE_R1_HEAL, rank), false, 0); else - caster->CastSpell(unitTarget, sSpellMgr->GetSpellWithRank(PRIEST_SPELL_PENANCE_R1_DAMAGE, rank), false, 0); + caster->CastSpell(unitTarget, sSpellMgr->GetSpellWithRank(SPELL_PRIEST_PENANCE_R1_DAMAGE, rank), false, 0); } } @@ -253,129 +261,86 @@ class spell_pri_penance : public SpellScriptLoader } }; -// Reflective Shield -class spell_pri_reflective_shield_trigger : public SpellScriptLoader +// 33110 - Prayer of Mending Heal +class spell_pri_prayer_of_mending_heal : public SpellScriptLoader { public: - spell_pri_reflective_shield_trigger() : SpellScriptLoader("spell_pri_reflective_shield_trigger") { } + spell_pri_prayer_of_mending_heal() : SpellScriptLoader("spell_pri_prayer_of_mending_heal") { } - class spell_pri_reflective_shield_trigger_AuraScript : public AuraScript + class spell_pri_prayer_of_mending_heal_SpellScript : public SpellScript { - PrepareAuraScript(spell_pri_reflective_shield_trigger_AuraScript); + PrepareSpellScript(spell_pri_prayer_of_mending_heal_SpellScript); - bool Validate(SpellInfo const* /*spellEntry*/) + void HandleHeal(SpellEffIndex /*effIndex*/) { - if (!sSpellMgr->GetSpellInfo(PRIEST_SPELL_REFLECTIVE_SHIELD_TRIGGERED) || !sSpellMgr->GetSpellInfo(PRIEST_SPELL_REFLECTIVE_SHIELD_R1)) - return false; - return true; - } - - void Trigger(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) - { - Unit* target = GetTarget(); - if (dmgInfo.GetAttacker() == target) - return; - - if (GetCaster()) - if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(PRIEST_SPELL_REFLECTIVE_SHIELD_R1, EFFECT_0)) + if (Unit* caster = GetOriginalCaster()) + { + if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_PRIEST_T9_HEALING_2P, EFFECT_0)) { - int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount()); - target->CastCustomSpell(dmgInfo.GetAttacker(), PRIEST_SPELL_REFLECTIVE_SHIELD_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); + int32 heal = GetHitHeal(); + AddPct(heal, aurEff->GetAmount()); + SetHitHeal(heal); } + } + } void Register() { - AfterEffectAbsorb += AuraEffectAbsorbFn(spell_pri_reflective_shield_trigger_AuraScript::Trigger, EFFECT_0); + OnEffectHitTarget += SpellEffectFn(spell_pri_prayer_of_mending_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); } }; - AuraScript* GetAuraScript() const - { - return new spell_pri_reflective_shield_trigger_AuraScript(); - } -}; - -enum PrayerOfMending -{ - SPELL_T9_HEALING_2_PIECE = 67201, -}; -// Prayer of Mending Heal -class spell_pri_prayer_of_mending_heal : public SpellScriptLoader -{ -public: - spell_pri_prayer_of_mending_heal() : SpellScriptLoader("spell_pri_prayer_of_mending_heal") { } - - class spell_pri_prayer_of_mending_heal_SpellScript : public SpellScript - { - PrepareSpellScript(spell_pri_prayer_of_mending_heal_SpellScript); - - void HandleHeal(SpellEffIndex /*effIndex*/) - { - if (Unit* caster = GetOriginalCaster()) - { - if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_T9_HEALING_2_PIECE, EFFECT_0)) - { - int32 heal = GetHitHeal(); - AddPct(heal, aurEff->GetAmount()); - SetHitHeal(heal); - } - } - - } - - void Register() + SpellScript* GetSpellScript() const { - OnEffectHitTarget += SpellEffectFn(spell_pri_prayer_of_mending_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL); + return new spell_pri_prayer_of_mending_heal_SpellScript(); } - }; - - SpellScript* GetSpellScript() const - { - return new spell_pri_prayer_of_mending_heal_SpellScript(); - } }; -class spell_pri_vampiric_touch : public SpellScriptLoader +// -17 - Reflective Shield +class spell_pri_reflective_shield_trigger : public SpellScriptLoader { public: - spell_pri_vampiric_touch() : SpellScriptLoader("spell_pri_vampiric_touch") { } + spell_pri_reflective_shield_trigger() : SpellScriptLoader("spell_pri_reflective_shield_trigger") { } - class spell_pri_vampiric_touch_AuraScript : public AuraScript + class spell_pri_reflective_shield_trigger_AuraScript : public AuraScript { - PrepareAuraScript(spell_pri_vampiric_touch_AuraScript); + PrepareAuraScript(spell_pri_reflective_shield_trigger_AuraScript); - bool Validate(SpellInfo const* /*spell*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL)) + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_R1)) return false; return true; } - void HandleDispel(DispelInfo* /*dispelInfo*/) + void Trigger(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) { - if (Unit* caster = GetCaster()) - if (Unit* target = GetUnitOwner()) - if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) - { - int32 damage = aurEff->GetAmount() * 8; - // backfire damage - caster->CastCustomSpell(target, PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL, &damage, NULL, NULL, true, NULL, aurEff); - } + Unit* target = GetTarget(); + if (dmgInfo.GetAttacker() == target) + return; + + if (GetCaster()) + if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PRIEST_REFLECTIVE_SHIELD_R1, EFFECT_0)) + { + int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount()); + target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); + } } void Register() { - AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_pri_reflective_shield_trigger_AuraScript::Trigger, EFFECT_0); } }; AuraScript* GetAuraScript() const { - return new spell_pri_vampiric_touch_AuraScript(); + return new spell_pri_reflective_shield_trigger_AuraScript(); } }; +// -139 - Renew class spell_pri_renew : public SpellScriptLoader { public: @@ -401,7 +366,7 @@ class spell_pri_renew : public SpellScriptLoader heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT); int32 basepoints0 = empoweredRenewAurEff->GetAmount() * GetEffect(EFFECT_0)->GetTotalTicks() * int32(heal) / 100; - caster->CastCustomSpell(GetTarget(), PRIEST_SPELL_EMPOWERED_RENEW, &basepoints0, NULL, NULL, true, NULL, aurEff); + caster->CastCustomSpell(GetTarget(), SPELL_PRIEST_EMPOWERED_RENEW, &basepoints0, NULL, NULL, true, NULL, aurEff); } } } @@ -418,6 +383,7 @@ class spell_pri_renew : public SpellScriptLoader } }; +// -32379 - Shadow Word Death class spell_pri_shadow_word_death : public SpellScriptLoader { public: @@ -435,7 +401,7 @@ class spell_pri_shadow_word_death : public SpellScriptLoader if (AuraEffect* aurEff = GetCaster()->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_PAIN_AND_SUFFERING, EFFECT_1)) AddPct(damage, aurEff->GetAmount()); - GetCaster()->CastCustomSpell(GetCaster(), PRIEST_SHADOW_WORD_DEATH, &damage, 0, 0, true); + GetCaster()->CastCustomSpell(GetCaster(), SPELL_PRIEST_SHADOW_WORD_DEATH, &damage, 0, 0, true); } void Register() @@ -450,16 +416,57 @@ class spell_pri_shadow_word_death : public SpellScriptLoader } }; +// -34914 - Vampiric Touch +class spell_pri_vampiric_touch : public SpellScriptLoader +{ + public: + spell_pri_vampiric_touch() : SpellScriptLoader("spell_pri_vampiric_touch") { } + + class spell_pri_vampiric_touch_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_vampiric_touch_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL)) + return false; + return true; + } + + void HandleDispel(DispelInfo* /*dispelInfo*/) + { + if (Unit* caster = GetCaster()) + if (Unit* target = GetUnitOwner()) + if (AuraEffect const* aurEff = GetEffect(EFFECT_1)) + { + int32 damage = aurEff->GetAmount() * 8; + // backfire damage + caster->CastCustomSpell(target, SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL, &damage, NULL, NULL, true, NULL, aurEff); + } + } + + void Register() + { + AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_vampiric_touch_AuraScript(); + } +}; + void AddSC_priest_spell_scripts() { new spell_pri_guardian_spirit(); new spell_pri_mana_burn(); + new spell_pri_mind_sear(); new spell_pri_pain_and_suffering_proc(); new spell_pri_penance(); - new spell_pri_reflective_shield_trigger(); - new spell_pri_mind_sear(); new spell_pri_prayer_of_mending_heal(); - new spell_pri_vampiric_touch(); + new spell_pri_reflective_shield_trigger(); new spell_pri_renew(); new spell_pri_shadow_word_death(); + new spell_pri_vampiric_touch(); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index ad69b4b1026..01a4225cc00 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -28,13 +28,13 @@ enum RogueSpells { - ROGUE_SPELL_SHIV_TRIGGERED = 5940, - ROGUE_SPELL_GLYPH_OF_PREPARATION = 56819, - ROGUE_SPELL_PREY_ON_THE_WEAK = 58670, - ROGUE_SPELL_CHEAT_DEATH_COOLDOWN = 31231, + SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231, + SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819, + SPELL_ROGUE_PREY_ON_THE_WEAK = 58670, + SPELL_ROGUE_SHIV_TRIGGERED = 5940, }; -// Cheat Death +// -31228 - Cheat Death class spell_rog_cheat_death : public SpellScriptLoader { public: @@ -46,9 +46,9 @@ class spell_rog_cheat_death : public SpellScriptLoader uint32 absorbChance; - bool Validate(SpellInfo const* /*spellEntry*/) + bool Validate(SpellInfo const* /*spellInfo*/) { - if (!sSpellMgr->GetSpellInfo(ROGUE_SPELL_CHEAT_DEATH_COOLDOWN)) + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN)) return false; return true; } @@ -68,11 +68,11 @@ class spell_rog_cheat_death : public SpellScriptLoader void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) { Player* target = GetTarget()->ToPlayer(); - if (dmgInfo.GetDamage() < target->GetHealth() || target->HasSpellCooldown(ROGUE_SPELL_CHEAT_DEATH_COOLDOWN) || !roll_chance_i(absorbChance)) + if (dmgInfo.GetDamage() < target->GetHealth() || target->HasSpellCooldown(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN) || !roll_chance_i(absorbChance)) return; - target->CastSpell(target, ROGUE_SPELL_CHEAT_DEATH_COOLDOWN, true); - target->AddSpellCooldown(ROGUE_SPELL_CHEAT_DEATH_COOLDOWN, 0, time(NULL) + 60); + target->CastSpell(target, SPELL_ROGUE_CHEAT_DEATH_COOLDOWN, true); + target->AddSpellCooldown(SPELL_ROGUE_CHEAT_DEATH_COOLDOWN, 0, time(NULL) + 60); uint32 health10 = target->CountPctFromMaxHealth(10); @@ -97,7 +97,101 @@ class spell_rog_cheat_death : public SpellScriptLoader } }; -// 31130 - Nerves of Steel +// -2818 - Deadly Poison +class spell_rog_deadly_poison : public SpellScriptLoader +{ + public: + spell_rog_deadly_poison() : SpellScriptLoader("spell_rog_deadly_poison") { } + + class spell_rog_deadly_poison_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rog_deadly_poison_SpellScript); + + bool Load() + { + _stackAmount = 0; + // at this point CastItem must already be initialized + return GetCaster()->GetTypeId() == TYPEID_PLAYER && GetCastItem(); + } + + void HandleBeforeHit() + { + if (Unit* target = GetHitUnit()) + // Deadly Poison + if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x10000, 0x80000, 0, GetCaster()->GetGUID())) + _stackAmount = aurEff->GetBase()->GetStackAmount(); + } + + void HandleAfterHit() + { + if (_stackAmount < 5) + return; + + Player* player = GetCaster()->ToPlayer(); + + if (Unit* target = GetHitUnit()) + { + + Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); + + if (item == GetCastItem()) + item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + + if (!item) + return; + + // item combat enchantments + for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot) + { + SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot))); + if (!enchant) + continue; + + for (uint8 s = 0; s < 3; ++s) + { + if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL) + continue; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(enchant->spellid[s]); + if (!spellInfo) + { + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::CastItemCombatSpell Enchant %i, player (Name: %s, GUID: %u) cast unknown spell %i", enchant->ID, player->GetName().c_str(), player->GetGUIDLow(), enchant->spellid[s]); + continue; + } + + // Proc only rogue poisons + if (spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE || spellInfo->Dispel != DISPEL_POISON) + continue; + + // Do not reproc deadly + if (spellInfo->SpellFamilyFlags.IsEqual(0x10000, 0x80000, 0)) + continue; + + if (spellInfo->IsPositive()) + player->CastSpell(player, enchant->spellid[s], true, item); + else + player->CastSpell(target, enchant->spellid[s], true, item); + } + } + } + } + + void Register() + { + BeforeHit += SpellHitFn(spell_rog_deadly_poison_SpellScript::HandleBeforeHit); + AfterHit += SpellHitFn(spell_rog_deadly_poison_SpellScript::HandleAfterHit); + } + + uint8 _stackAmount; + }; + + SpellScript* GetSpellScript() const + { + return new spell_rog_deadly_poison_SpellScript(); + } +}; + +// -31130 - Nerves of Steel class spell_rog_nerves_of_steel : public SpellScriptLoader { public: @@ -141,6 +235,7 @@ class spell_rog_nerves_of_steel : public SpellScriptLoader } }; +// 14185 - Preparation class spell_rog_preparation : public SpellScriptLoader { public: @@ -157,7 +252,7 @@ class spell_rog_preparation : public SpellScriptLoader bool Validate(SpellInfo const* /*spellEntry*/) { - if (!sSpellMgr->GetSpellInfo(ROGUE_SPELL_GLYPH_OF_PREPARATION)) + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_GLYPH_OF_PREPARATION)) return false; return true; } @@ -177,7 +272,7 @@ class spell_rog_preparation : public SpellScriptLoader if (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_COLDB_SHADOWSTEP || // Cold Blood, Shadowstep spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_VAN_EVAS_SPRINT) // Vanish, Evasion, Sprint caster->RemoveSpellCooldown((itr++)->first, true); - else if (caster->HasAura(ROGUE_SPELL_GLYPH_OF_PREPARATION)) + else if (caster->HasAura(SPELL_ROGUE_GLYPH_OF_PREPARATION)) { if (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_DISMANTLE || // Dismantle spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_KICK || // Kick @@ -208,220 +303,128 @@ class spell_rog_preparation : public SpellScriptLoader } }; -// 51685-51689 Prey on the Weak +// -51685 - Prey on the Weak class spell_rog_prey_on_the_weak : public SpellScriptLoader -{ -public: - spell_rog_prey_on_the_weak() : SpellScriptLoader("spell_rog_prey_on_the_weak") { } - - class spell_rog_prey_on_the_weak_AuraScript : public AuraScript - { - PrepareAuraScript(spell_rog_prey_on_the_weak_AuraScript); - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(ROGUE_SPELL_PREY_ON_THE_WEAK)) - return false; - return true; - } - - void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - Unit* victim = target->getVictim(); - if (victim && (target->GetHealthPct() > victim->GetHealthPct())) - { - if (!target->HasAura(ROGUE_SPELL_PREY_ON_THE_WEAK)) - { - int32 bp = GetSpellInfo()->Effects[EFFECT_0].CalcValue(); - target->CastCustomSpell(target, ROGUE_SPELL_PREY_ON_THE_WEAK, &bp, 0, 0, true); - } - } - else - target->RemoveAurasDueToSpell(ROGUE_SPELL_PREY_ON_THE_WEAK); - } - - void Register() - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_prey_on_the_weak_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_rog_prey_on_the_weak_AuraScript(); - } -}; - -class spell_rog_shiv : public SpellScriptLoader { public: - spell_rog_shiv() : SpellScriptLoader("spell_rog_shiv") { } + spell_rog_prey_on_the_weak() : SpellScriptLoader("spell_rog_prey_on_the_weak") { } - class spell_rog_shiv_SpellScript : public SpellScript + class spell_rog_prey_on_the_weak_AuraScript : public AuraScript { - PrepareSpellScript(spell_rog_shiv_SpellScript); + PrepareAuraScript(spell_rog_prey_on_the_weak_AuraScript); - bool Load() + bool Validate(SpellInfo const* /*spellInfo*/) { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(ROGUE_SPELL_SHIV_TRIGGERED)) + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_PREY_ON_THE_WEAK)) return false; return true; } - void HandleDummy(SpellEffIndex /*effIndex*/) + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) { - Unit* caster = GetCaster(); - if (Unit* unitTarget = GetHitUnit()) - caster->CastSpell(unitTarget, ROGUE_SPELL_SHIV_TRIGGERED, true); + Unit* target = GetTarget(); + Unit* victim = target->getVictim(); + if (victim && (target->GetHealthPct() > victim->GetHealthPct())) + { + if (!target->HasAura(SPELL_ROGUE_PREY_ON_THE_WEAK)) + { + int32 bp = GetSpellInfo()->Effects[EFFECT_0].CalcValue(); + target->CastCustomSpell(target, SPELL_ROGUE_PREY_ON_THE_WEAK, &bp, 0, 0, true); + } + } + else + target->RemoveAurasDueToSpell(SPELL_ROGUE_PREY_ON_THE_WEAK); } void Register() { - // add dummy effect spell handler to Shiv - OnEffectHitTarget += SpellEffectFn(spell_rog_shiv_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_prey_on_the_weak_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); } }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_rog_shiv_SpellScript(); + return new spell_rog_prey_on_the_weak_AuraScript(); } }; -class spell_rog_deadly_poison : public SpellScriptLoader +// 36554 - Shadowstep +class spell_rog_shadowstep : public SpellScriptLoader { public: - spell_rog_deadly_poison() : SpellScriptLoader("spell_rog_deadly_poison") { } + spell_rog_shadowstep() : SpellScriptLoader("spell_rog_shadowstep") { } - class spell_rog_deadly_poison_SpellScript : public SpellScript + class spell_rog_shadowstep_SpellScript : public SpellScript { - PrepareSpellScript(spell_rog_deadly_poison_SpellScript); - - bool Load() - { - _stackAmount = 0; - // at this point CastItem must already be initialized - return GetCaster()->GetTypeId() == TYPEID_PLAYER && GetCastItem(); - } - - void HandleBeforeHit() - { - if (Unit* target = GetHitUnit()) - // Deadly Poison - if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x10000, 0x80000, 0, GetCaster()->GetGUID())) - _stackAmount = aurEff->GetBase()->GetStackAmount(); - } + PrepareSpellScript(spell_rog_shadowstep_SpellScript); - void HandleAfterHit() + SpellCastResult CheckCast() { - if (_stackAmount < 5) - return; - - Player* player = GetCaster()->ToPlayer(); - - if (Unit* target = GetHitUnit()) - { - - Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); - - if (item == GetCastItem()) - item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - - if (!item) - return; - - // item combat enchantments - for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot) - { - SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot))); - if (!enchant) - continue; - - for (uint8 s = 0; s < 3; ++s) - { - if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL) - continue; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(enchant->spellid[s]); - if (!spellInfo) - { - sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::CastItemCombatSpell Enchant %i, player (Name: %s, GUID: %u) cast unknown spell %i", enchant->ID, player->GetName().c_str(), player->GetGUIDLow(), enchant->spellid[s]); - continue; - } - - // Proc only rogue poisons - if (spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE || spellInfo->Dispel != DISPEL_POISON) - continue; - - // Do not reproc deadly - if (spellInfo->SpellFamilyFlags.IsEqual(0x10000, 0x80000, 0)) - continue; - - if (spellInfo->IsPositive()) - player->CastSpell(player, enchant->spellid[s], true, item); - else - player->CastSpell(target, enchant->spellid[s], true, item); - } - } - } + if (GetCaster()->HasUnitState(UNIT_STATE_ROOT)) + return SPELL_FAILED_ROOTED; + return SPELL_CAST_OK; } void Register() { - BeforeHit += SpellHitFn(spell_rog_deadly_poison_SpellScript::HandleBeforeHit); - AfterHit += SpellHitFn(spell_rog_deadly_poison_SpellScript::HandleAfterHit); + OnCheckCast += SpellCheckCastFn(spell_rog_shadowstep_SpellScript::CheckCast); } - - uint8 _stackAmount; }; SpellScript* GetSpellScript() const { - return new spell_rog_deadly_poison_SpellScript(); + return new spell_rog_shadowstep_SpellScript(); } }; -class spell_rog_shadowstep : public SpellScriptLoader +// 5938 - Shiv +class spell_rog_shiv : public SpellScriptLoader { public: - spell_rog_shadowstep() : SpellScriptLoader("spell_rog_shadowstep") { } + spell_rog_shiv() : SpellScriptLoader("spell_rog_shiv") { } - class spell_rog_shadowstep_SpellScript : public SpellScript + class spell_rog_shiv_SpellScript : public SpellScript { - PrepareSpellScript(spell_rog_shadowstep_SpellScript); + PrepareSpellScript(spell_rog_shiv_SpellScript); - SpellCastResult CheckCast() + bool Load() { - if (GetCaster()->HasUnitState(UNIT_STATE_ROOT)) - return SPELL_FAILED_ROOTED; - return SPELL_CAST_OK; + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_SHIV_TRIGGERED)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* unitTarget = GetHitUnit()) + caster->CastSpell(unitTarget, SPELL_ROGUE_SHIV_TRIGGERED, true); } void Register() { - OnCheckCast += SpellCheckCastFn(spell_rog_shadowstep_SpellScript::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_rog_shiv_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; SpellScript* GetSpellScript() const { - return new spell_rog_shadowstep_SpellScript(); + return new spell_rog_shiv_SpellScript(); } }; void AddSC_rogue_spell_scripts() { new spell_rog_cheat_death(); + new spell_rog_deadly_poison(); new spell_rog_nerves_of_steel(); new spell_rog_preparation(); new spell_rog_prey_on_the_weak(); - new spell_rog_shiv(); - new spell_rog_deadly_poison(); new spell_rog_shadowstep(); + new spell_rog_shiv(); } -- cgit v1.2.3 From dc30c6353375a6fbc03b32cc20d569b807fcffe9 Mon Sep 17 00:00:00 2001 From: krofna Date: Fri, 11 Jan 2013 12:52:19 +0000 Subject: Script/AQ Implement Ayamiss the Hunter and fix screwup in my Ossirian Closes #8862 Signed-off-by: Nay --- sql/updates/world/2013_01_11_00_world_ayamiss.sql | 4 + .../Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp | 263 ++++++++++++++++++--- .../Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp | 10 +- .../RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp | 10 + .../Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h | 11 +- 5 files changed, 251 insertions(+), 47 deletions(-) create mode 100644 sql/updates/world/2013_01_11_00_world_ayamiss.sql (limited to 'src') diff --git a/sql/updates/world/2013_01_11_00_world_ayamiss.sql b/sql/updates/world/2013_01_11_00_world_ayamiss.sql new file mode 100644 index 00000000000..cbdb7a2ed16 --- /dev/null +++ b/sql/updates/world/2013_01_11_00_world_ayamiss.sql @@ -0,0 +1,4 @@ +DELETE FROM `creature_text` WHERE `entry`=15369; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(15369,0,0,'%s goes into a frenzy!',16,0,100,0,0,0,'Ayamiss frenzy'); +UPDATE `creature_template` SET ScriptName='npc_hive_zara_larva' WHERE entry=15555; diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp index e72e6dff9cf..3db03b5b312 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp @@ -16,25 +16,58 @@ * with this program. If not, see . */ -#include "ObjectMgr.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ruins_of_ahnqiraj.h" enum Spells { - SPELL_STINGERSPRAY = 25749, - SPELL_POISONSTINGER = 25748, // Only used in phase 1 + SPELL_STINGER_SPRAY = 25749, + SPELL_POISON_STINGER = 25748, SPELL_PARALYZE = 25725, SPELL_TRASH = 3391, - SPELL_FRENZY = 8269, // Not used + SPELL_FRENZY = 8269, SPELL_LASH = 25852, - SPELL_FEED = 25721, + SPELL_FEED = 25721 }; -enum Says +enum Events { - EMOTE_FRENZY = 0 // Not used + EVENT_STINGER_SPRAY = 0, + EVENT_POISON_STINGER = 1, + EVENT_SUMMON_SWARMER = 2, + EVENT_SWARMER_ATTACK = 3, + EVENT_PARALYZE = 4, + EVENT_LASH = 5, + EVENT_TRASH = 6 +}; + +enum Emotes +{ + EMOTE_FRENZY = 0 +}; + +enum Phases +{ + PHASE_AIR = 0, + PHASE_GROUND = 1 +}; + +enum Points +{ + POINT_AIR = 0, + POINT_GROUND = 1, + POINT_PARALYZE = 2 +}; + +const Position AyamissAirPos = { -9689.292f, 1547.912f, 48.02729f, 0.0f }; +const Position AltarPos = { -9717.18f, 1517.72f, 27.4677f, 0.0f }; +// TODO: These below are probably incorrect, taken from SD2 +const Position SwarmerPos = { -9647.352f, 1578.062f, 55.32f, 0.0f }; +const Position LarvaPos[2] = +{ + { -9674.4707f, 1528.4133f, 22.457f, 0.0f }, + { -9701.6005f, 1566.9993f, 24.118f, 0.0f } }; class boss_ayamiss : public CreatureScript @@ -42,65 +75,221 @@ class boss_ayamiss : public CreatureScript public: boss_ayamiss() : CreatureScript("boss_ayamiss") { } - struct boss_ayamissAI : public ScriptedAI + struct boss_ayamissAI : public BossAI { - boss_ayamissAI(Creature* creature) : ScriptedAI(creature) + boss_ayamissAI(Creature* creature) : BossAI(creature, DATA_AYAMISS) { - instance = creature->GetInstanceScript(); } - uint32 STINGERSPRAY_Timer; - uint32 POISONSTINGER_Timer; - uint32 SUMMONSWARMER_Timer; - uint32 phase; - - InstanceScript* instance; - void Reset() { - STINGERSPRAY_Timer = 30000; - POISONSTINGER_Timer = 30000; - SUMMONSWARMER_Timer = 60000; - phase = 1; + _Reset(); + _phase = PHASE_AIR; + _enraged = false; + SetCombatMovement(false); + } + + void JustSummoned(Creature* who) + { + switch (who->GetEntry()) + { + case NPC_SWARMER: + _swarmers.push_back(who->GetGUID()); + break; + case NPC_LARVA: + who->GetMotionMaster()->MovePoint(POINT_PARALYZE, AltarPos); + break; + case NPC_HORNET: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + who->AI()->AttackStart(target); + break; + } + } + + void MovementInform(uint32 type, uint32 id) + { + if (type == POINT_MOTION_TYPE) + { + switch (id) + { + case POINT_AIR: + me->AddUnitState(UNIT_STATE_ROOT); + break; + case POINT_GROUND: + me->ClearUnitState(UNIT_STATE_ROOT); + break; + } + } + } + + void EnterEvadeMode() + { + me->ClearUnitState(UNIT_STATE_ROOT); + BossAI::EnterEvadeMode(); + } + + void EnterCombat(Unit* attacker) + { + BossAI::EnterCombat(attacker); + + events.ScheduleEvent(EVENT_STINGER_SPRAY, urand(20000, 30000)); + events.ScheduleEvent(EVENT_POISON_STINGER, 5000); + events.ScheduleEvent(EVENT_SUMMON_SWARMER, 5000); + events.ScheduleEvent(EVENT_SWARMER_ATTACK, 60000); + events.ScheduleEvent(EVENT_PARALYZE, 15000); + me->SetCanFly(true); + me->SetDisableGravity(true); + me->GetMotionMaster()->MovePoint(POINT_AIR, AyamissAirPos); } void UpdateAI(uint32 const diff) { if (!UpdateVictim()) return; + + events.Update(diff); - //If he is 70% start phase 2 - if (phase == 1 && !HealthAbovePct(70) && !me->IsNonMeleeSpellCasted(false)) + if (_phase == PHASE_AIR && me->GetHealthPct() < 70.0f) { - phase=2; + _phase = PHASE_GROUND; + SetCombatMovement(true); + me->SetCanFly(false); + Position VictimPos; + me->getVictim()->GetPosition(&VictimPos); + me->GetMotionMaster()->MovePoint(POINT_GROUND, VictimPos); + DoResetThreat(); + events.ScheduleEvent(EVENT_LASH, urand(5000, 8000)); + events.ScheduleEvent(EVENT_TRASH, urand(3000, 6000)); + events.CancelEvent(EVENT_POISON_STINGER); } - - //STINGERSPRAY_Timer (only in phase2) - if (phase == 2 && STINGERSPRAY_Timer <= diff) + else + { + DoMeleeAttackIfReady(); + } + + if (!_enraged && me->GetHealthPct() < 20.0f) { - DoCast(me->getVictim(), SPELL_STINGERSPRAY); - STINGERSPRAY_Timer = 30000; - } else STINGERSPRAY_Timer -= diff; + DoCast(me, SPELL_FRENZY); + Talk(EMOTE_FRENZY); + _enraged = true; + } - //POISONSTINGER_Timer (only in phase1) - if (phase == 1 && POISONSTINGER_Timer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - DoCast(me->getVictim(), SPELL_POISONSTINGER); - POISONSTINGER_Timer = 30000; - } else POISONSTINGER_Timer -= diff; + switch (eventId) + { + case EVENT_STINGER_SPRAY: + DoCast(me, SPELL_STINGER_SPRAY); + events.ScheduleEvent(EVENT_STINGER_SPRAY, urand(15000, 20000)); + break; + case EVENT_POISON_STINGER: + DoCastVictim(SPELL_POISON_STINGER); + events.ScheduleEvent(EVENT_POISON_STINGER, urand(2000, 3000)); + break; + case EVENT_PARALYZE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true)) + { + DoCast(target, SPELL_PARALYZE); + instance->SetData64(DATA_PARALYZED, target->GetGUID()); + uint8 Index = urand(0, 1); + me->SummonCreature(NPC_LARVA, LarvaPos[Index], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); + } + events.ScheduleEvent(EVENT_PARALYZE, 15000); + break; + case EVENT_SWARMER_ATTACK: + for (std::list::iterator i = _swarmers.begin(); i != _swarmers.end(); ++i) + if (Creature* swarmer = me->GetMap()->GetCreature(*i)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + swarmer->AI()->AttackStart(target); + + _swarmers.clear(); + events.ScheduleEvent(EVENT_SWARMER_ATTACK, 60000); + break; + case EVENT_SUMMON_SWARMER: + Position Pos; + me->GetRandomPoint(SwarmerPos, 80.0f, Pos); + me->SummonCreature(NPC_SWARMER, Pos); + events.ScheduleEvent(EVENT_SUMMON_SWARMER, 5000); + break; + case EVENT_TRASH: + DoCastVictim(SPELL_TRASH); + events.ScheduleEvent(EVENT_TRASH, urand(5000, 7000)); + break; + case EVENT_LASH: + DoCastVictim(SPELL_LASH); + events.ScheduleEvent(EVENT_LASH, urand(8000, 15000)); + break; + } + } + } + private: + std::list _swarmers; + uint8 _phase; + bool _enraged; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_ayamissAI(creature); + } +}; + +class npc_hive_zara_larva : public CreatureScript +{ + public: + npc_hive_zara_larva() : CreatureScript("npc_hive_zara_larva") { } + + struct npc_hive_zara_larvaAI : public ScriptedAI + { + npc_hive_zara_larvaAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type == POINT_MOTION_TYPE) + if (id == POINT_PARALYZE) + if (Player* target = Unit::GetPlayer(*me, _instance->GetData64(DATA_PARALYZED))) + DoCast(target, SPELL_FEED); // Omnomnom + } + + void MoveInLineOfSight(Unit* who) + { + if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS) + return; + + ScriptedAI::MoveInLineOfSight(who); + } - DoMeleeAttackIfReady(); + void AttackStart(Unit* victim) + { + if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS) + return; + + ScriptedAI::AttackStart(victim); + } + + void UpdateAI(uint32 const diff) + { + if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS) + return; + + ScriptedAI::UpdateAI(diff); } + private: + InstanceScript* _instance; }; CreatureAI* GetAI(Creature* creature) const { - return new boss_ayamissAI (creature); + return new npc_hive_zara_larvaAI(creature); } }; void AddSC_boss_ayamiss() { new boss_ayamiss(); + new npc_hive_zara_larva(); } diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp index fcb6364244e..20c0dd035a4 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp @@ -89,7 +89,6 @@ class boss_ossirian : public CreatureScript boss_ossirianAI(Creature* creature) : BossAI(creature, DATA_OSSIRIAN) { SaidIntro = false; - Reset(); } uint64 TriggerGUID; @@ -121,13 +120,9 @@ class boss_ossirian : public CreatureScript void DoAction(const int32 action) { if (action == ACTION_TRIGGER_WEAKNESS) - { if (Creature* Trigger = me->GetMap()->GetCreature(TriggerGUID)) - { if (!Trigger->HasUnitState(UNIT_STATE_CASTING)) Trigger->CastSpell(Trigger, SpellWeakness[urand(0, 4)], false); - } - } } void EnterCombat(Unit* /*who*/) @@ -172,7 +167,7 @@ class boss_ossirian : public CreatureScript { Cleanup(); summons.DespawnAll(); - ScriptedAI::EnterEvadeMode(); + BossAI::EnterEvadeMode(); } void JustDied(Unit* /*killer*/) @@ -207,13 +202,14 @@ class boss_ossirian : public CreatureScript } } - void MoveInLineOfSight(Unit* /*who*/) + void MoveInLineOfSight(Unit* who) { if (!SaidIntro) { Talk(SAY_INTRO); SaidIntro = true; } + BossAI::MoveInLineOfSight(who); } void UpdateAI(uint32 const diff) diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp index 6dbeaed9e5d..7fd6efcebd6 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp @@ -36,6 +36,7 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript _buruGUID = 0; _ayamissGUID = 0; _ossirianGUID = 0; + _paralyzedGUID = 0; } void OnCreatureCreate(Creature* creature) @@ -70,6 +71,12 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript return true; } + + void SetData64(uint32 type, uint64 data) + { + if (type == DATA_PARALYZED) + _paralyzedGUID = data; + } uint64 GetData64(uint32 type) const { @@ -87,6 +94,8 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript return _ayamissGUID; case DATA_OSSIRIAN: return _ossirianGUID; + case DATA_PARALYZED: + return _paralyzedGUID; } return 0; @@ -142,6 +151,7 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript uint64 _buruGUID; uint64 _ayamissGUID; uint64 _ossirianGUID; + uint64 _paralyzedGUID; }; InstanceScript* GetInstanceScript(InstanceMap* map) const diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h index 6ece21f627b..419aaf1c303 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h @@ -26,7 +26,9 @@ enum DataTypes DATA_BURU = 3, DATA_AYAMISS = 4, DATA_OSSIRIAN = 5, - NUM_ENCOUNTER = 6 + NUM_ENCOUNTER = 6, + + DATA_PARALYZED = 7 }; enum Creatures @@ -42,12 +44,15 @@ enum Creatures NPC_HIVEZARA_LARVA = 15555, NPC_SAND_VORTEX = 15428, NPC_OSSIRIAN_TRIGGER = 15590, - NPC_HATCHLING = 15521 + NPC_HATCHLING = 15521, + NPC_LARVA = 15555, + NPC_SWARMER = 15546, + NPC_HORNET = 15934 }; enum GameObjects { - GO_OSSIRIAN_CRYSTAL = 180619, + GO_OSSIRIAN_CRYSTAL = 180619 }; #endif -- cgit v1.2.3 From 6cd962ee71c7ddc1d25270b37222730bf76ed540 Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Fri, 11 Jan 2013 14:21:39 +0100 Subject: Core: Fix non pch build --- src/server/game/Handlers/ReferAFriendHandler.cpp | 2 +- src/server/game/Spells/SpellEffects.cpp | 2 +- src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/game/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp index a40e763b030..8a1793af557 100644 --- a/src/server/game/Handlers/ReferAFriendHandler.cpp +++ b/src/server/game/Handlers/ReferAFriendHandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 TrinityCore + * Copyright (C) 2008-2013 TrinityCore * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 8913cf2ac20..4e4698eb01b 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -6162,7 +6162,7 @@ void Spell::EffectPlaySound(SpellEffIndex effIndex) if (!sSoundEntriesStore.LookupEntry(soundId)) { - sLog->outError(LOG_FILTER_SPELLS_AURAS, "EffectPlayerSound: Sound (Id: %u) not exist in spell %u.", soundId, m_spellInfo->Id); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "EffectPlaySound: Sound (Id: %u) not exist in spell %u.", soundId, m_spellInfo->Id); return; } diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp index 3db03b5b312..49fd8b038a4 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp @@ -18,6 +18,7 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "Player.h" #include "ruins_of_ahnqiraj.h" enum Spells @@ -251,7 +252,7 @@ class npc_hive_zara_larva : public CreatureScript { if (type == POINT_MOTION_TYPE) if (id == POINT_PARALYZE) - if (Player* target = Unit::GetPlayer(*me, _instance->GetData64(DATA_PARALYZED))) + if (Player* target = ObjectAccessor::GetPlayer(*me, _instance->GetData64(DATA_PARALYZED))) DoCast(target, SPELL_FEED); // Omnomnom } -- cgit v1.2.3 From ecbcca87943660ca732a5bbf0d9c71da1fc55bee Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Fri, 11 Jan 2013 14:49:38 +0100 Subject: Core: Whitespace cleanup --- .../Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp | 26 +++++++++---------- .../scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp | 30 +++++++++++----------- .../RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp | 2 +- .../Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp | 10 ++++---- src/server/scripts/Spells/spell_hunter.cpp | 2 +- 5 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp index 49fd8b038a4..cfc35b676ea 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp @@ -89,7 +89,7 @@ class boss_ayamiss : public CreatureScript _enraged = false; SetCombatMovement(false); } - + void JustSummoned(Creature* who) { switch (who->GetEntry()) @@ -106,7 +106,7 @@ class boss_ayamiss : public CreatureScript break; } } - + void MovementInform(uint32 type, uint32 id) { if (type == POINT_MOTION_TYPE) @@ -122,17 +122,17 @@ class boss_ayamiss : public CreatureScript } } } - + void EnterEvadeMode() { me->ClearUnitState(UNIT_STATE_ROOT); BossAI::EnterEvadeMode(); } - + void EnterCombat(Unit* attacker) { BossAI::EnterCombat(attacker); - + events.ScheduleEvent(EVENT_STINGER_SPRAY, urand(20000, 30000)); events.ScheduleEvent(EVENT_POISON_STINGER, 5000); events.ScheduleEvent(EVENT_SUMMON_SWARMER, 5000); @@ -148,7 +148,7 @@ class boss_ayamiss : public CreatureScript { if (!UpdateVictim()) return; - + events.Update(diff); if (_phase == PHASE_AIR && me->GetHealthPct() < 70.0f) @@ -168,7 +168,7 @@ class boss_ayamiss : public CreatureScript { DoMeleeAttackIfReady(); } - + if (!_enraged && me->GetHealthPct() < 20.0f) { DoCast(me, SPELL_FRENZY); @@ -247,7 +247,7 @@ class npc_hive_zara_larva : public CreatureScript { _instance = me->GetInstanceScript(); } - + void MovementInform(uint32 type, uint32 id) { if (type == POINT_MOTION_TYPE) @@ -255,12 +255,12 @@ class npc_hive_zara_larva : public CreatureScript if (Player* target = ObjectAccessor::GetPlayer(*me, _instance->GetData64(DATA_PARALYZED))) DoCast(target, SPELL_FEED); // Omnomnom } - + void MoveInLineOfSight(Unit* who) { if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS) return; - + ScriptedAI::MoveInLineOfSight(who); } @@ -268,15 +268,15 @@ class npc_hive_zara_larva : public CreatureScript { if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS) return; - + ScriptedAI::AttackStart(victim); } - + void UpdateAI(uint32 const diff) { if (_instance->GetBossState(DATA_AYAMISS) == IN_PROGRESS) return; - + ScriptedAI::UpdateAI(diff); } private: diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp index e26cba9cb6e..285d893fe41 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp @@ -70,11 +70,11 @@ class boss_buru : public CreatureScript boss_buruAI(Creature* creature) : BossAI(creature, DATA_BURU) { } - + void EnterEvadeMode() { BossAI::EnterEvadeMode(); - + for (std::list::iterator i = Eggs.begin(); i != Eggs.end(); ++i) if (Creature* egg = me->GetMap()->GetCreature(*Eggs.begin())) egg->Respawn(); @@ -101,7 +101,7 @@ class boss_buru : public CreatureScript if (_phase == PHASE_EGG) me->DealDamage(me, 45000); } - + void KilledUnit(Unit* victim) { if (victim->GetTypeId() == TYPEID_PLAYER) @@ -112,12 +112,12 @@ class boss_buru : public CreatureScript { if (_phase != PHASE_EGG) return; - + me->RemoveAurasDueToSpell(SPELL_FULL_SPEED); me->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED); events.ScheduleEvent(EVENT_GATHERING_SPEED, 9000); events.ScheduleEvent(EVENT_FULL_SPEED, 60000); - + if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { DoResetThreat(); @@ -125,21 +125,21 @@ class boss_buru : public CreatureScript Talk(EMOTE_TARGET, victim->GetGUID()); } } - + void ManageRespawn(uint64 EggGUID) { ChaseNewVictim(); Eggs.push_back(EggGUID); events.ScheduleEvent(EVENT_RESPAWN_EGG, 100000); } - + void UpdateAI(uint32 const diff) { if (!UpdateVictim()) return; events.Update(diff); - + while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) @@ -170,7 +170,7 @@ class boss_buru : public CreatureScript break; } } - + if (me->GetHealthPct() < 20.0f && _phase == PHASE_EGG) { DoCast(me, SPELL_BURU_TRANSFORM); // Enrage @@ -178,7 +178,7 @@ class boss_buru : public CreatureScript me->RemoveAurasDueToSpell(SPELL_THORNS); _phase = PHASE_TRANSFORM; } - + DoMeleeAttackIfReady(); } private: @@ -203,14 +203,14 @@ class npc_buru_egg : public CreatureScript { _instance = me->GetInstanceScript(); } - + void EnterCombat(Unit* attacker) { if (Creature* buru = me->GetMap()->GetCreature(_instance->GetData64(DATA_BURU))) if (!buru->isInCombat()) buru->AI()->AttackStart(attacker); } - + void JustSummoned(Creature* who) { if (who->GetEntry() == NPC_HATCHLING) @@ -218,7 +218,7 @@ class npc_buru_egg : public CreatureScript if (Unit* target = buru->AI()->SelectTarget(SELECT_TARGET_RANDOM)) who->AI()->AttackStart(target); } - + void JustDied(Unit* /*killer*/) { DoCastAOE(SPELL_EXPLODE, true); @@ -247,13 +247,13 @@ class spell_egg_explosion : public SpellScriptLoader class spell_egg_explosion_SpellScript : public SpellScript { PrepareSpellScript(spell_egg_explosion_SpellScript); - + void HandleAfterCast() { if (Creature* buru = GetCaster()->FindNearestCreature(NPC_BURU, 5.f)) buru->AI()->DoAction(ACTION_EXPLODE); } - + void HandleDummyHitTarget(SpellEffIndex /*effIndex*/) { if (Unit* target = GetHitUnit()) diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp index 7fd6efcebd6..658528f1fb4 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp @@ -71,7 +71,7 @@ class instance_ruins_of_ahnqiraj : public InstanceMapScript return true; } - + void SetData64(uint32 type, uint64 data) { if (type == DATA_PARALYZED) diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp index 1186459218c..8030358a068 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp @@ -68,7 +68,7 @@ class boss_skeram : public CreatureScript { Talk(SAY_SLAY); } - + void EnterEvadeMode() { ScriptedAI::EnterEvadeMode(); @@ -93,10 +93,10 @@ class boss_skeram : public CreatureScript rand = urand(0, 2); creature->CastSpell(creature, BlinkSpells[rand]); _flag |= (1 << rand); - + if (_flag & (1 << 7)) _flag = 0; - + if (Unit* Target = SelectTarget(SELECT_TARGET_RANDOM)) creature->AI()->AttackStart(Target); @@ -183,12 +183,12 @@ class boss_skeram : public CreatureScript DoMeleeAttackIfReady(); } } - + private: float _hpct; uint8 _flag; }; - + CreatureAI* GetAI(Creature* creature) const { return new boss_skeramAI(creature); diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 36194a596ce..b3c429d27aa 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -32,7 +32,7 @@ enum HunterSpells { - SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET = 61669, + SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET = 61669, SPELL_HUNTER_BESTIAL_WRATH = 19574, SPELL_HUNTER_CHIMERA_SHOT_SERPENT = 53353, SPELL_HUNTER_CHIMERA_SHOT_VIPER = 53358, -- cgit v1.2.3