From dfdc19f3bc57757965d1d3b760a27622e411eb05 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 13 Jul 2014 16:52:38 -0500 Subject: Merge branch `master` into `boost` Conflicts: BattlegroundMgr.h --- src/server/game/Accounts/RBAC.h | 2 +- .../game/Battlefield/Zones/BattlefieldWG.cpp | 8 +- src/server/game/Battlefield/Zones/BattlefieldWG.h | 8 +- src/server/game/Battlegrounds/Battleground.cpp | 36 +-- src/server/game/Battlegrounds/Battleground.h | 24 +- src/server/game/Battlegrounds/BattlegroundMgr.cpp | 299 +++++++++------------ src/server/game/Battlegrounds/BattlegroundMgr.h | 82 +++--- .../game/Battlegrounds/BattlegroundQueue.cpp | 5 +- .../game/Battlegrounds/Zones/BattlegroundIC.cpp | 12 +- src/server/game/DungeonFinding/LFGMgr.cpp | 10 +- src/server/game/Entities/Creature/Creature.cpp | 3 +- src/server/game/Entities/GameObject/GameObject.cpp | 11 + src/server/game/Entities/GameObject/GameObject.h | 2 + src/server/game/Entities/Player/Player.cpp | 262 ++++++++++-------- src/server/game/Entities/Player/Player.h | 21 +- src/server/game/Entities/Unit/Unit.cpp | 28 +- src/server/game/Groups/Group.cpp | 1 - src/server/game/Handlers/CharacterHandler.cpp | 4 +- src/server/game/Handlers/NPCHandler.cpp | 2 +- src/server/game/Handlers/SkillHandler.cpp | 2 +- src/server/game/Instances/InstanceScript.cpp | 19 +- src/server/game/Instances/InstanceScript.h | 4 +- src/server/game/Maps/MapManager.cpp | 18 +- src/server/game/Movement/PathGenerator.cpp | 26 +- src/server/game/Scripting/ScriptLoader.cpp | 2 - src/server/game/Spells/Spell.cpp | 1 + src/server/game/Spells/SpellEffects.cpp | 9 +- src/server/game/World/World.cpp | 2 +- src/server/scripts/Commands/cs_account.cpp | 4 +- src/server/scripts/Commands/cs_learn.cpp | 18 +- src/server/scripts/Commands/cs_reload.cpp | 11 + src/server/scripts/Commands/cs_reset.cpp | 4 +- .../BlackrockSpire/boss_pyroguard_emberseer.cpp | 21 +- .../BlackrockSpire/instance_blackrock_spire.cpp | 14 +- src/server/scripts/EasternKingdoms/CMakeLists.txt | 1 - .../Karazhan/boss_terestian_illhoof.cpp | 17 +- .../ScarletMonastery/boss_arcanist_doan.cpp | 158 +++++------ .../ScarletMonastery/scarlet_monastery.h | 3 +- src/server/scripts/EasternKingdoms/boss_kruul.cpp | 163 ----------- .../EscapeFromDurnholdeKeep/old_hillsbrad.cpp | 9 +- .../scripts/Kalimdor/ZulFarrak/zulfarrak.cpp | 10 +- .../scripts/Outland/BlackTemple/black_temple.cpp | 56 ++-- src/server/scripts/Spells/spell_druid.cpp | 8 +- src/server/scripts/Spells/spell_generic.cpp | 6 +- src/server/scripts/Spells/spell_item.cpp | 42 ++- src/server/scripts/Spells/spell_paladin.cpp | 8 +- src/server/scripts/Spells/spell_shaman.cpp | 38 +++ src/server/scripts/World/npc_professions.cpp | 128 ++++----- 48 files changed, 754 insertions(+), 868 deletions(-) delete mode 100644 src/server/scripts/EasternKingdoms/boss_kruul.cpp (limited to 'src') diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 9ce1f9bb67a..f2637a5febc 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -534,7 +534,7 @@ enum RBACPermissions RBAC_PERM_COMMAND_RELOAD_COMMAND = 628, RBAC_PERM_COMMAND_RELOAD_CONDITIONS = 629, RBAC_PERM_COMMAND_RELOAD_CONFIG = 630, - RBAC_PERM_UNUSED_631 = 631, // unused + RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE = 631, RBAC_PERM_UNUSED_632 = 632, // unused RBAC_PERM_COMMAND_RELOAD_CREATURE_LINKED_RESPAWN = 633, RBAC_PERM_COMMAND_RELOAD_CREATURE_LOOT_TEMPLATE = 634, diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 41539b9cda6..b16ac1e84de 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -683,9 +683,9 @@ void BattlefieldWG::PromotePlayer(Player* killer) if (!m_isActive) return; // Updating rank of player - if (Aura* aur = killer->GetAura(SPELL_RECRUIT)) + if (Aura* auraRecruit = killer->GetAura(SPELL_RECRUIT)) { - if (aur->GetStackAmount() >= 5) + if (auraRecruit->GetStackAmount() >= 5) { killer->RemoveAura(SPELL_RECRUIT); killer->CastSpell(killer, SPELL_CORPORAL, true); @@ -694,9 +694,9 @@ void BattlefieldWG::PromotePlayer(Player* killer) else killer->CastSpell(killer, SPELL_RECRUIT, true); } - else if (Aura* aur = killer->GetAura(SPELL_CORPORAL)) + else if (Aura* auraCorporal = killer->GetAura(SPELL_CORPORAL)) { - if (aur->GetStackAmount() >= 5) + if (auraCorporal->GetStackAmount() >= 5) { killer->RemoveAura(SPELL_CORPORAL); killer->CastSpell(killer, SPELL_LIEUTENANT, true); diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 3a64458c48b..c01e6eb22ee 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -1277,10 +1277,10 @@ struct BfWGGameObjectBuilding for (uint8 i = 0; i < AttackTowers[towerid - 4].nbObject; i++) { WintergraspObjectPositionData gobData = AttackTowers[towerid - 4].GameObject[i]; - if (GameObject* go = m_WG->SpawnGameObject(gobData.entryHorde, gobData.x, gobData.y, gobData.z, gobData.o)) - m_GameObjectList[TEAM_HORDE].insert(go->GetGUID()); - if (GameObject* go = m_WG->SpawnGameObject(gobData.entryAlliance, gobData.x, gobData.y, gobData.z, gobData.o)) - m_GameObjectList[TEAM_ALLIANCE].insert(go->GetGUID()); + if (GameObject* goHorde = m_WG->SpawnGameObject(gobData.entryHorde, gobData.x, gobData.y, gobData.z, gobData.o)) + m_GameObjectList[TEAM_HORDE].insert(goHorde->GetGUID()); + if (GameObject* goAlliance = m_WG->SpawnGameObject(gobData.entryAlliance, gobData.x, gobData.y, gobData.z, gobData.o)) + m_GameObjectList[TEAM_ALLIANCE].insert(goAlliance->GetGUID()); } // Spawn associate npc bottom diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 4e077979b3e..a0d35d4c742 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -152,18 +152,6 @@ Battleground::Battleground() m_StartMaxDist = 0.0f; ScriptId = 0; - m_TeamStartLocX[TEAM_ALLIANCE] = 0; - m_TeamStartLocX[TEAM_HORDE] = 0; - - m_TeamStartLocY[TEAM_ALLIANCE] = 0; - m_TeamStartLocY[TEAM_HORDE] = 0; - - m_TeamStartLocZ[TEAM_ALLIANCE] = 0; - m_TeamStartLocZ[TEAM_HORDE] = 0; - - m_TeamStartLocO[TEAM_ALLIANCE] = 0; - m_TeamStartLocO[TEAM_HORDE] = 0; - m_ArenaTeamIds[TEAM_ALLIANCE] = 0; m_ArenaTeamIds[TEAM_HORDE] = 0; @@ -300,16 +288,15 @@ inline void Battleground::_CheckSafePositions(uint32 diff) { m_ValidStartPositionTimer = 0; - float x, y, z, o; for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) if (Player* player = ObjectAccessor::FindPlayer(itr->first)) { Position pos = player->GetPosition(); - GetTeamStartLoc(player->GetBGTeam(), x, y, z, o); - if (pos.GetExactDistSq(x, y, z) > maxDist) + Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetBGTeam())); + if (pos.GetExactDistSq(startPos) > maxDist) { TC_LOG_DEBUG("bg.battleground", "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName().c_str(), GetMapId()); - player->TeleportTo(GetMapId(), x, y, z, o); + player->TeleportTo(GetMapId(), startPos->GetPositionX(), startPos->GetPositionY(), startPos->GetPositionZ(), startPos->GetOrientation()); } } } @@ -550,7 +537,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) } // Announce BG starting if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE)) - sWorld->SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel()); + sWorld->SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName().c_str(), GetMinLevel(), GetMaxLevel()); } } } @@ -614,13 +601,16 @@ inline Player* Battleground::_GetPlayerForTeam(uint32 teamId, BattlegroundPlayer return player; } -void Battleground::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O) +void Battleground::SetTeamStartPosition(TeamId teamId, Position const& pos) +{ + ASSERT(teamId < TEAM_NEUTRAL); + StartPosition[teamId] = pos; +} + +Position const* Battleground::GetTeamStartPosition(TeamId teamId) const { - TeamId idx = GetTeamIndexByTeamId(TeamID); - m_TeamStartLocX[idx] = X; - m_TeamStartLocY[idx] = Y; - m_TeamStartLocZ[idx] = Z; - m_TeamStartLocO[idx] = O; + ASSERT(teamId < TEAM_NEUTRAL); + return &StartPosition[teamId]; } void Battleground::SendPacketToAll(WorldPacket* packet) diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 2904ec1dc7e..468b73c51ab 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -23,6 +23,7 @@ #include "SharedDefines.h" #include "DBCEnums.h" #include "WorldPacket.h" +#include "Object.h" class Creature; class GameObject; @@ -34,7 +35,6 @@ class WorldPacket; class BattlegroundMap; struct BattlegroundScore; -struct Position; struct PvPDifficultyEntry; struct WorldSafeLocsEntry; @@ -256,7 +256,7 @@ class Battleground /* Battleground */ // Get methods: - char const* GetName() const { return m_Name; } + std::string const& GetName() const { return m_Name; } BattlegroundTypeId GetTypeID(bool GetRandom = false) const { return GetRandom ? m_RandomTypeID : m_TypeID; } BattlegroundBracketId GetBracketId() const { return m_BracketId; } uint32 GetInstanceID() const { return m_InstanceID; } @@ -282,7 +282,7 @@ class Battleground bool IsRandom() const { return m_IsRandom; } // Set methods: - void SetName(char const* Name) { m_Name = Name; } + void SetName(std::string const& name) { m_Name = name; } void SetTypeID(BattlegroundTypeId TypeID) { m_TypeID = TypeID; } void SetRandomTypeID(BattlegroundTypeId TypeID) { m_RandomTypeID = TypeID; } //here we can count minlevel and maxlevel for players @@ -352,15 +352,8 @@ class Battleground BattlegroundMap* GetBgMap() const { ASSERT(m_Map); return m_Map; } BattlegroundMap* FindBgMap() const { return m_Map; } - void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O); - void GetTeamStartLoc(uint32 TeamID, float &X, float &Y, float &Z, float &O) const - { - TeamId idx = GetTeamIndexByTeamId(TeamID); - X = m_TeamStartLocX[idx]; - Y = m_TeamStartLocY[idx]; - Z = m_TeamStartLocZ[idx]; - O = m_TeamStartLocO[idx]; - } + void SetTeamStartPosition(TeamId teamId, Position const& pos); + Position const* GetTeamStartPosition(TeamId teamId) const; void SetStartMaxDist(float startMaxDist) { m_StartMaxDist = startMaxDist; } float GetStartMaxDist() const { return m_StartMaxDist; } @@ -559,7 +552,7 @@ class Battleground bool m_IsRated; // is this battle rated? bool m_PrematureCountDown; uint32 m_PrematureCountDownTimer; - char const* m_Name; + std::string m_Name; /* Pre- and post-update hooks */ @@ -669,10 +662,7 @@ class Battleground // Start location uint32 m_MapId; BattlegroundMap* m_Map; - float m_TeamStartLocX[BG_TEAMS_COUNT]; - float m_TeamStartLocY[BG_TEAMS_COUNT]; - float m_TeamStartLocZ[BG_TEAMS_COUNT]; - float m_TeamStartLocO[BG_TEAMS_COUNT]; + Position StartPosition[BG_TEAMS_COUNT]; float m_StartMaxDist; uint32 ScriptId; }; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index ef78594626a..615bbc12199 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -343,20 +343,7 @@ uint32 BattlegroundMgr::CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeI // create a new battleground that will really be used to play Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId originalBgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated) { - BattlegroundTypeId bgTypeId = originalBgTypeId; - bool isRandom = false; - - switch (originalBgTypeId) - { - case BATTLEGROUND_RB: - isRandom = true; - /// Intentional fallback, "All Arenas" is random too - case BATTLEGROUND_AA: - bgTypeId = GetRandomBG(originalBgTypeId); - break; - default: - break; - } + BattlegroundTypeId bgTypeId = GetRandomBG(originalBgTypeId); // get the template BG Battleground* bg_template = GetBattlegroundTemplate(bgTypeId); @@ -406,15 +393,15 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original break; case BATTLEGROUND_RB: case BATTLEGROUND_AA: - bg = new Battleground(*bg_template); - break; default: return NULL; } + bool isRandom = bgTypeId != originalBgTypeId && !bg->isArena(); + bg->SetBracket(bracketEntry); bg->SetInstanceID(sMapMgr->GenerateInstanceId()); - bg->SetClientInstanceID(CreateClientVisibleInstanceId(isRandom ? BATTLEGROUND_RB : bgTypeId, bracketEntry->GetBracketId())); + bg->SetClientInstanceID(CreateClientVisibleInstanceId(originalBgTypeId, bracketEntry->GetBracketId())); bg->Reset(); // reset the new bg (set status to status_wait_queue from status_none) bg->SetStatus(STATUS_WAIT_JOIN); // start the joining of the bg bg->SetArenaType(arenaType); @@ -448,82 +435,88 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original } // used to create the BG templates -bool BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data) +bool BattlegroundMgr::CreateBattleground(BattlegroundTemplate const* bgTemplate) { - // Create the BG - Battleground* bg = NULL; - switch (data.bgTypeId) + Battleground* bg = GetBattlegroundTemplate(bgTemplate->Id); + if (!bg) { - case BATTLEGROUND_AV: - bg = new BattlegroundAV; - break; - case BATTLEGROUND_WS: - bg = new BattlegroundWS; - break; - case BATTLEGROUND_AB: - bg = new BattlegroundAB; - break; - case BATTLEGROUND_NA: - bg = new BattlegroundNA; - break; - case BATTLEGROUND_BE: - bg = new BattlegroundBE; - break; - case BATTLEGROUND_EY: - bg = new BattlegroundEY; - break; - case BATTLEGROUND_RL: - bg = new BattlegroundRL; - break; - case BATTLEGROUND_SA: - bg = new BattlegroundSA; - break; - case BATTLEGROUND_DS: - bg = new BattlegroundDS; - break; - case BATTLEGROUND_RV: - bg = new BattlegroundRV; - break; - case BATTLEGROUND_IC: - bg = new BattlegroundIC; - break; - case BATTLEGROUND_AA: - bg = new Battleground; - break; - case BATTLEGROUND_RB: - bg = new Battleground; - bg->SetRandom(true); - break; - default: - return false; + // Create the BG + switch (bgTemplate->Id) + { + case BATTLEGROUND_AV: + bg = new BattlegroundAV(); + break; + case BATTLEGROUND_WS: + bg = new BattlegroundWS(); + break; + case BATTLEGROUND_AB: + bg = new BattlegroundAB(); + break; + case BATTLEGROUND_NA: + bg = new BattlegroundNA(); + break; + case BATTLEGROUND_BE: + bg = new BattlegroundBE(); + break; + case BATTLEGROUND_EY: + bg = new BattlegroundEY(); + break; + case BATTLEGROUND_RL: + bg = new BattlegroundRL(); + break; + case BATTLEGROUND_SA: + bg = new BattlegroundSA(); + break; + case BATTLEGROUND_DS: + bg = new BattlegroundDS(); + break; + case BATTLEGROUND_RV: + bg = new BattlegroundRV(); + break; + case BATTLEGROUND_IC: + bg = new BattlegroundIC(); + break; + case BATTLEGROUND_AA: + bg = new Battleground(); + break; + case BATTLEGROUND_RB: + bg = new Battleground(); + bg->SetRandom(true); + break; + default: + return false; + } + + bg->SetTypeID(bgTemplate->Id); + bg->SetInstanceID(0); + AddBattleground(bg); } - bg->SetMapId(data.MapID); - bg->SetTypeID(data.bgTypeId); - bg->SetInstanceID(0); - bg->SetArenaorBGType(data.IsArena); - bg->SetMinPlayersPerTeam(data.MinPlayersPerTeam); - bg->SetMaxPlayersPerTeam(data.MaxPlayersPerTeam); - bg->SetMinPlayers(data.MinPlayersPerTeam * 2); - bg->SetMaxPlayers(data.MaxPlayersPerTeam * 2); - bg->SetName(data.BattlegroundName); - bg->SetTeamStartLoc(ALLIANCE, data.Team1StartLocX, data.Team1StartLocY, data.Team1StartLocZ, data.Team1StartLocO); - bg->SetTeamStartLoc(HORDE, data.Team2StartLocX, data.Team2StartLocY, data.Team2StartLocZ, data.Team2StartLocO); - bg->SetStartMaxDist(data.StartMaxDist); - bg->SetLevelRange(data.LevelMin, data.LevelMax); - bg->SetScriptId(data.scriptId); - - AddBattleground(bg); + bg->SetMapId(bgTemplate->BattlemasterEntry->mapid[0]); + bg->SetName(bgTemplate->BattlemasterEntry->name[sWorld->GetDefaultDbcLocale()]); + bg->SetArenaorBGType(bgTemplate->IsArena()); + bg->SetMinPlayersPerTeam(bgTemplate->MinPlayersPerTeam); + bg->SetMaxPlayersPerTeam(bgTemplate->MaxPlayersPerTeam); + bg->SetMinPlayers(bgTemplate->MinPlayersPerTeam * 2); + bg->SetMaxPlayers(bgTemplate->MaxPlayersPerTeam * 2); + bg->SetTeamStartPosition(TEAM_ALLIANCE, bgTemplate->StartLocation[TEAM_ALLIANCE]); + bg->SetTeamStartPosition(TEAM_HORDE, bgTemplate->StartLocation[TEAM_HORDE]); + bg->SetStartMaxDist(bgTemplate->MaxStartDistSq); + bg->SetLevelRange(bgTemplate->MinLevel, bgTemplate->MaxLevel); + bg->SetScriptId(bgTemplate->ScriptId); return true; } -void BattlegroundMgr::CreateInitialBattlegrounds() +void BattlegroundMgr::LoadBattlegroundTemplates() { uint32 oldMSTime = getMSTime(); + + _battlegroundMapTemplates.clear(); + _battlegroundTemplates.clear(); + // 0 1 2 3 4 5 6 7 8 9 10 11 QueryResult result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, AllianceStartLoc, AllianceStartO, HordeStartLoc, HordeStartO, StartMaxDist, Weight, ScriptName FROM battleground_template"); - if (!result) { TC_LOG_ERROR("server.loading", ">> Loaded 0 battlegrounds. DB table `battleground_template` is empty."); @@ -536,7 +529,8 @@ void BattlegroundMgr::CreateInitialBattlegrounds() { Field* fields = result->Fetch(); - uint32 bgTypeId = fields[0].GetUInt32(); + BattlegroundTypeId bgTypeId = BattlegroundTypeId(fields[0].GetUInt32()); + if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId, NULL)) continue; @@ -548,86 +542,64 @@ void BattlegroundMgr::CreateInitialBattlegrounds() continue; } - CreateBattlegroundData data; - data.bgTypeId = BattlegroundTypeId(bgTypeId); - data.IsArena = (bl->type == TYPE_ARENA); - data.MinPlayersPerTeam = fields[1].GetUInt16(); - data.MaxPlayersPerTeam = fields[2].GetUInt16(); - data.LevelMin = fields[3].GetUInt8(); - data.LevelMax = fields[4].GetUInt8(); - float dist = fields[9].GetFloat(); - data.StartMaxDist = dist * dist; - - data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString()); - data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()]; - data.MapID = bl->mapid[0]; - - if (data.MaxPlayersPerTeam == 0 || data.MinPlayersPerTeam > data.MaxPlayersPerTeam) + BattlegroundTemplate bgTemplate; + bgTemplate.Id = bgTypeId; + bgTemplate.MinPlayersPerTeam = fields[1].GetUInt16(); + bgTemplate.MaxPlayersPerTeam = fields[2].GetUInt16(); + bgTemplate.MinLevel = fields[3].GetUInt8(); + bgTemplate.MaxLevel = fields[4].GetUInt8(); + float dist = fields[9].GetFloat(); + bgTemplate.MaxStartDistSq = dist * dist; + bgTemplate.Weight = fields[10].GetUInt8(); + bgTemplate.ScriptId = sObjectMgr->GetScriptId(fields[11].GetCString()); + bgTemplate.BattlemasterEntry = bl; + + if (bgTemplate.MaxPlayersPerTeam == 0 || bgTemplate.MinPlayersPerTeam > bgTemplate.MaxPlayersPerTeam) { TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has bad values for MinPlayersPerTeam (%u) and MaxPlayersPerTeam(%u)", - data.bgTypeId, data.MinPlayersPerTeam, data.MaxPlayersPerTeam); + bgTemplate.Id, bgTemplate.MinPlayersPerTeam, bgTemplate.MaxPlayersPerTeam); continue; } - if (data.LevelMin == 0 || data.LevelMax == 0 || data.LevelMin > data.LevelMax) + if (bgTemplate.MinLevel == 0 || bgTemplate.MaxLevel == 0 || bgTemplate.MinLevel > bgTemplate.MaxLevel) { - TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has bad values for LevelMin (%u) and LevelMax(%u)", - data.bgTypeId, data.LevelMin, data.LevelMax); + TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has bad values for MinLevel (%u) and MaxLevel (%u)", + bgTemplate.Id, bgTemplate.MinLevel, bgTemplate.MaxLevel); continue; } - if (data.bgTypeId == BATTLEGROUND_AA || data.bgTypeId == BATTLEGROUND_RB) - { - data.Team1StartLocX = 0; - data.Team1StartLocY = 0; - data.Team1StartLocZ = 0; - data.Team1StartLocO = fields[6].GetFloat(); - data.Team2StartLocX = 0; - data.Team2StartLocY = 0; - data.Team2StartLocZ = 0; - data.Team2StartLocO = fields[8].GetFloat(); - } - else + if (bgTemplate.Id != BATTLEGROUND_AA && bgTemplate.Id != BATTLEGROUND_RB) { uint32 startId = fields[5].GetUInt32(); if (WorldSafeLocsEntry const* start = sWorldSafeLocsStore.LookupEntry(startId)) { - data.Team1StartLocX = start->x; - data.Team1StartLocY = start->y; - data.Team1StartLocZ = start->z; - data.Team1StartLocO = fields[6].GetFloat(); + bgTemplate.StartLocation[TEAM_ALLIANCE].Relocate(start->x, start->y, start->z, fields[6].GetFloat()); } else { - TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", data.bgTypeId, startId); + TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", bgTemplate.Id, startId); continue; } startId = fields[7].GetUInt32(); if (WorldSafeLocsEntry const* start = sWorldSafeLocsStore.LookupEntry(startId)) { - data.Team2StartLocX = start->x; - data.Team2StartLocY = start->y; - data.Team2StartLocZ = start->z; - data.Team2StartLocO = fields[8].GetFloat(); + bgTemplate.StartLocation[TEAM_HORDE].Relocate(start->x, start->y, start->z, fields[8].GetFloat()); } else { - TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", data.bgTypeId, startId); + TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", bgTemplate.Id, startId); continue; } } - if (!CreateBattleground(data)) + if (!CreateBattleground(&bgTemplate)) continue; - if (data.IsArena) - { - if (data.bgTypeId != BATTLEGROUND_AA) - m_ArenaSelectionWeights[data.bgTypeId] = fields[10].GetUInt8(); - } - else if (data.bgTypeId != BATTLEGROUND_RB) - m_BGSelectionWeights[data.bgTypeId] = fields[10].GetUInt8(); + _battlegroundTemplates[bgTypeId] = bgTemplate; + + if (bgTemplate.BattlemasterEntry->mapid[1] == -1) // in this case we have only one mapId + _battlegroundMapTemplates[bgTemplate.BattlemasterEntry->mapid[0]] = &_battlegroundTemplates[bgTypeId]; ++count; } @@ -722,15 +694,14 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt { if (Battleground* bg = GetBattleground(instanceId, bgTypeId)) { - float x, y, z, O; uint32 mapid = bg->GetMapId(); uint32 team = player->GetBGTeam(); if (team == 0) team = player->GetTeam(); - bg->GetTeamStartLoc(team, x, y, z, O); - TC_LOG_DEBUG("bg.battleground", "BattlegroundMgr::SendToBattleground: Sending %s to map %u, X %f, Y %f, Z %f, O %f (bgType %u)", player->GetName().c_str(), mapid, x, y, z, O, bgTypeId); - player->TeleportTo(mapid, x, y, z, O); + Position const* pos = bg->GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(team)); + TC_LOG_DEBUG("bg.battleground", "BattlegroundMgr::SendToBattleground: Sending %s to map %u, %s (bgType %u)", player->GetName().c_str(), mapid, pos->ToString().c_str(), bgTypeId); + player->TeleportTo(mapid, pos->GetPositionX(), pos->GetPositionY(), pos->GetPositionZ(), pos->GetOrientation()); } else TC_LOG_ERROR("bg.battleground", "BattlegroundMgr::SendToBattleground: Instance %u (bgType %u) not found while trying to teleport player %s", instanceId, bgTypeId, player->GetName().c_str()); @@ -987,51 +958,43 @@ bool BattlegroundMgr::IsBGWeekend(BattlegroundTypeId bgTypeId) BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId) { - uint32 weight = 0; - BattlegroundTypeId returnBgTypeId = BATTLEGROUND_TYPE_NONE; - BattlegroundSelectionWeightMap selectionWeights; - - if (bgTypeId == BATTLEGROUND_AA) + if (BattlegroundTemplate const* bgTemplate = GetBattlegroundTemplateByTypeId(bgTypeId)) { - for (BattlegroundSelectionWeightMap::const_iterator it = m_ArenaSelectionWeights.begin(); it != m_ArenaSelectionWeights.end(); ++it) - { - if (it->second) - { - weight += it->second; - selectionWeights[it->first] = it->second; - } - } - } - else if (bgTypeId == BATTLEGROUND_RB) - { - for (BattlegroundSelectionWeightMap::const_iterator it = m_BGSelectionWeights.begin(); it != m_BGSelectionWeights.end(); ++it) + uint32 weight = 0; + BattlegroundSelectionWeightMap selectionWeights; + + for (int32 mapId : bgTemplate->BattlemasterEntry->mapid) { - if (it->second) + if (mapId == -1) + break; + + if (BattlegroundTemplate const* bg = GetBattlegroundTemplateByMapId(mapId)) { - weight += it->second; - selectionWeights[it->first] = it->second; + weight += bg->Weight; + selectionWeights[bg->Id] = bg->Weight; } } - } - if (weight) - { - // Select a random value - uint32 selectedWeight = urand(0, weight - 1); - // Select the correct bg (if we have in DB A(10), B(20), C(10), D(15) --> [0---A---9|10---B---29|30---C---39|40---D---54]) - weight = 0; - for (BattlegroundSelectionWeightMap::const_iterator it = selectionWeights.begin(); it != selectionWeights.end(); ++it) + // there is only one bg to select + if (selectionWeights.size() == 1) + return bgTypeId; + + if (weight) { - weight += it->second; - if (selectedWeight < weight) + // Select a random value + uint32 selectedWeight = urand(0, weight - 1); + // Select the correct bg (if we have in DB A(10), B(20), C(10), D(15) --> [0---A---9|10---B---29|30---C---39|40---D---54]) + weight = 0; + for (auto it : selectionWeights) { - returnBgTypeId = it->first; - break; + weight += it.second; + if (selectedWeight < weight) + return it.first; } } } - return returnBgTypeId; + return BATTLEGROUND_TYPE_NONE; } BGFreeSlotQueueContainer& BattlegroundMgr::GetBGFreeSlotQueueStore(BattlegroundTypeId bgTypeId) diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index d9cedbc4546..20cd8e4f7be 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -23,6 +23,7 @@ #include "DBCEnums.h" #include "Battleground.h" #include "BattlegroundQueue.h" +#include typedef std::map BattlegroundContainer; typedef std::set BattlegroundClientIdsContainer; @@ -32,28 +33,6 @@ typedef std::unordered_map BattleMastersMap; #define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day #define WS_ARENA_DISTRIBUTION_TIME 20001 // Custom worldstate -struct CreateBattlegroundData -{ - BattlegroundTypeId bgTypeId; - bool IsArena; - uint32 MinPlayersPerTeam; - uint32 MaxPlayersPerTeam; - uint32 LevelMin; - uint32 LevelMax; - char* BattlegroundName; - uint32 MapID; - float Team1StartLocX; - float Team1StartLocY; - float Team1StartLocZ; - float Team1StartLocO; - float Team2StartLocX; - float Team2StartLocY; - float Team2StartLocZ; - float Team2StartLocO; - float StartMaxDist; - uint32 scriptId; -}; - struct BattlegroundData { BattlegroundContainer m_Battlegrounds; @@ -61,19 +40,31 @@ struct BattlegroundData BGFreeSlotQueueContainer BGFreeSlotQueue; }; +struct BattlegroundTemplate +{ + BattlegroundTypeId Id; + uint16 MinPlayersPerTeam; + uint16 MaxPlayersPerTeam; + uint8 MinLevel; + uint8 MaxLevel; + Position StartLocation[BG_TEAMS_COUNT]; + float MaxStartDistSq; + uint8 Weight; + uint32 ScriptId; + BattlemasterListEntry const* BattlemasterEntry; + + bool IsArena() const { return BattlemasterEntry->type == MAP_ARENA; } +}; + class BattlegroundMgr { + friend class ACE_Singleton; + private: BattlegroundMgr(); ~BattlegroundMgr(); public: - static BattlegroundMgr* instance() - { - static BattlegroundMgr* instance = new BattlegroundMgr(); - return instance; - } - void Update(uint32 diff); /* Packet Building */ @@ -98,7 +89,7 @@ class BattlegroundMgr void RemoveFromBGFreeSlotQueue(BattlegroundTypeId bgTypeId, uint32 instanceId); BGFreeSlotQueueContainer& GetBGFreeSlotQueueStore(BattlegroundTypeId bgTypeId); - void CreateInitialBattlegrounds(); + void LoadBattlegroundTemplates(); void DeleteAllBattlegrounds(); void SendToBattleground(Player* player, uint32 InstanceID, BattlegroundTypeId bgTypeId); @@ -138,7 +129,7 @@ class BattlegroundMgr } private: - bool CreateBattleground(CreateBattlegroundData& data); + bool CreateBattleground(BattlegroundTemplate const* bgTemplate); uint32 CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id); static bool IsArenaType(BattlegroundTypeId bgTypeId); BattlegroundTypeId GetRandomBG(BattlegroundTypeId id); @@ -148,9 +139,6 @@ class BattlegroundMgr BattlegroundQueue m_BattlegroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; - typedef std::map BattlegroundSelectionWeightMap; // TypeId and its selectionWeight - BattlegroundSelectionWeightMap m_ArenaSelectionWeights; - BattlegroundSelectionWeightMap m_BGSelectionWeights; std::vector m_QueueUpdateScheduler; uint32 m_NextRatedArenaUpdate; time_t m_NextAutoDistributionTime; @@ -158,7 +146,31 @@ class BattlegroundMgr bool m_ArenaTesting; bool m_Testing; BattleMastersMap mBattleMastersMap; + + BattlegroundTemplate const* GetBattlegroundTemplateByTypeId(BattlegroundTypeId id) + { + BattlegroundTemplateMap::const_iterator itr = _battlegroundTemplates.find(id); + if (itr != _battlegroundTemplates.end()) + return &itr->second; + return nullptr; + } + + BattlegroundTemplate const* GetBattlegroundTemplateByMapId(uint32 mapId) + { + BattlegroundMapTemplateContainer::const_iterator itr = _battlegroundMapTemplates.find(mapId); + if (itr != _battlegroundMapTemplates.end()) + return itr->second; + return nullptr; + } + + typedef std::map BattlegroundSelectionWeightMap; + + typedef std::map BattlegroundTemplateMap; + typedef std::map BattlegroundMapTemplateContainer; + BattlegroundTemplateMap _battlegroundTemplates; + BattlegroundMapTemplateContainer _battlegroundMapTemplates; }; -#define sBattlegroundMgr BattlegroundMgr::instance() -#endif +#define sBattlegroundMgr ACE_Singleton::instance() + +#endif // __BATTLEGROUNDMGR_H diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 2f632377756..e52f75a1c41 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -198,7 +198,6 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr { if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId)) { - char const* bgName = bg->GetName(); uint32 MinPlayers = bg->GetMinPlayersPerTeam(); uint32 qHorde = 0; uint32 qAlliance = 0; @@ -215,13 +214,13 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr // Show queue status to player only (when joining queue) if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) { - ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level, + ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bg->GetName().c_str(), q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); } // System message else { - sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level, + sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bg->GetName().c_str(), q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0); } } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index da0b00af40f..1685f06f92d 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -110,8 +110,8 @@ void BattlegroundIC::PostUpdateImpl(uint32 diff) GetBGObject(BG_IC_GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01)->RemoveFromWorld(); GetBGObject(BG_IC_GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01)->RemoveFromWorld(); - GetBGObject(BG_IC_GO_ALLIANCE_GATE_3)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Alliance door - GetBGObject(BG_IC_GO_HORDE_GATE_1)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Horde door + GetBGObject(BG_IC_GO_ALLIANCE_GATE_3)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); // Alliance door + GetBGObject(BG_IC_GO_HORDE_GATE_1)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); // Horde door doorsClosed = true; } else closeFortressDoorsTimer -= diff; @@ -241,10 +241,10 @@ void BattlegroundIC::PostUpdateImpl(uint32 diff) void BattlegroundIC::StartingEventCloseDoors() { // Show Full Gate Displays - GetBGObject(BG_IC_GO_ALLIANCE_GATE_1)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Alliance door - GetBGObject(BG_IC_GO_ALLIANCE_GATE_2)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Alliance door - GetBGObject(BG_IC_GO_HORDE_GATE_2)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Horde door - GetBGObject(BG_IC_GO_HORDE_GATE_3)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); // Horde door + GetBGObject(BG_IC_GO_ALLIANCE_GATE_1)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); + GetBGObject(BG_IC_GO_ALLIANCE_GATE_2)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); + GetBGObject(BG_IC_GO_HORDE_GATE_2)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); + GetBGObject(BG_IC_GO_HORDE_GATE_3)->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); } void BattlegroundIC::StartingEventOpenDoors() diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index d353efb58c7..a24b3e3878a 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -355,7 +355,6 @@ void LFGMgr::Update(uint32 diff) if (m_QueueTimer > LFG_QUEUEUPDATE_INTERVAL) { m_QueueTimer = 0; - time_t currTime = time(NULL); for (LfgQueueContainer::iterator it = QueuesStore.begin(); it != QueuesStore.end(); ++it) it->second.UpdateQueueTimers(currTime); } @@ -1707,14 +1706,13 @@ void LFGMgr::RemoveGroupData(uint64 guid) LfgState state = GetState(guid); // If group is being formed after proposal success do nothing more LfgGuidSet const& players = it->second.GetPlayers(); - for (LfgGuidSet::const_iterator it = players.begin(); it != players.end(); ++it) + for (uint64 playerGUID : players) { - uint64 guid = (*it); - SetGroup(*it, 0); + SetGroup(playerGUID, 0); if (state != LFG_STATE_PROPOSAL) { - SetState(*it, LFG_STATE_NONE); - SendLfgUpdateParty(guid, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE)); + SetState(playerGUID, LFG_STATE_NONE); + SendLfgUpdateParty(playerGUID, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE)); } } GroupsStore.erase(it); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index fd8aaff8159..341225741ea 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2276,6 +2276,7 @@ void Creature::AllLootRemovedFromCorpse() SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); time_t now = time(NULL); + // Do not reset corpse remove time if corpse is already removed if (m_corpseRemoveTime <= now) return; @@ -2283,7 +2284,7 @@ void Creature::AllLootRemovedFromCorpse() // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update if (loot.loot_type == LOOT_SKINNING) - m_corpseRemoveTime = time(NULL); + m_corpseRemoveTime = now; else m_corpseRemoveTime = now + m_corpseDelay * decayRate; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index ae08a4251a5..23e40382fa2 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -958,6 +958,17 @@ void GameObject::SaveRespawnTime() GetMap()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime); } +bool GameObject::IsNeverVisible() const +{ + if (WorldObject::IsNeverVisible()) + return true; + + if (GetGoType() == GAMEOBJECT_TYPE_SPELL_FOCUS && GetGOInfo()->spellFocus.serverOnly == 1) + return true; + + return false; +} + bool GameObject::IsAlwaysVisibleFor(WorldObject const* seer) const { if (WorldObject::IsAlwaysVisibleFor(seer)) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 8f70fc0e907..549de28bb12 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -778,6 +778,8 @@ class GameObject : public WorldObject, public GridObject, public Map void TriggeringLinkedGameObject(uint32 trapEntry, Unit* target); + bool IsNeverVisible() const override; + bool IsAlwaysVisibleFor(WorldObject const* seer) const; bool IsInvisibleDueToDespawn() const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e00728d25c6..6eda51667e1 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3116,7 +3116,7 @@ void Player::InitTalentForLevel() // Remove all talent points if (m_usedTalentCount > 0) // Free any used talents { - resetTalents(true); /// @todo: Has to (collectively) be renamed to ResetTalents + ResetTalents(true); /// @todo: Has to (collectively) be renamed to ResetTalents SetFreeTalentPoints(0); } } @@ -3134,7 +3134,7 @@ void Player::InitTalentForLevel() if (m_usedTalentCount > talentPointsForLevel) { if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED)) - resetTalents(true); + ResetTalents(true); else SetFreeTalentPoints(0); } @@ -3525,7 +3525,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) return false; } -bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/) +bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/, bool fromSkill /*= false*/) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) @@ -3688,7 +3688,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent if (!rankSpellId || rankSpellId == spellId) continue; - removeSpell(rankSpellId, false, false); + RemoveSpell(rankSpellId, false, false); } } } @@ -3696,9 +3696,9 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent else if (uint32 prev_spell = sSpellMgr->GetPrevSpellInChain(spellId)) { if (!IsInWorld() || disabled) // at spells loading, no output, but allow save - addSpell(prev_spell, active, true, true, disabled); + AddSpell(prev_spell, active, true, true, disabled, false, fromSkill); else // at normal learning - learnSpell(prev_spell, true); + LearnSpell(prev_spell, true, fromSkill); } PlayerSpell* newspell = new PlayerSpell; @@ -3797,45 +3797,44 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent SetFreePrimaryProfessions(freeProfs-1); } - // add dependent skills - uint16 maxskill = GetMaxSkillValueForLevel(); - - SpellLearnSkillNode const* spellLearnSkill = sSpellMgr->GetSpellLearnSkill(spellId); - SkillLineAbilityMapBounds skill_bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellId); - if (spellLearnSkill) + // add dependent skills if this spell is not learned from adding skill already + if (!fromSkill) { - uint32 skill_value = GetPureSkillValue(spellLearnSkill->skill); - uint32 skill_max_value = GetPureMaxSkillValue(spellLearnSkill->skill); + if (SpellLearnSkillNode const* spellLearnSkill = sSpellMgr->GetSpellLearnSkill(spellId)) + { + uint32 skill_value = GetPureSkillValue(spellLearnSkill->skill); + uint32 skill_max_value = GetPureMaxSkillValue(spellLearnSkill->skill); - if (skill_value < spellLearnSkill->value) - skill_value = spellLearnSkill->value; + if (skill_value < spellLearnSkill->value) + skill_value = spellLearnSkill->value; - uint32 new_skill_max_value = spellLearnSkill->maxvalue == 0 ? maxskill : spellLearnSkill->maxvalue; + uint32 new_skill_max_value = spellLearnSkill->maxvalue == 0 ? GetMaxSkillValueForLevel() : spellLearnSkill->maxvalue; - if (skill_max_value < new_skill_max_value) - skill_max_value = new_skill_max_value; + if (skill_max_value < new_skill_max_value) + skill_max_value = new_skill_max_value; - SetSkill(spellLearnSkill->skill, spellLearnSkill->step, skill_value, skill_max_value); - } - else - { - // not ranked skills - for (SkillLineAbilityMap::const_iterator _spell_idx = skill_bounds.first; _spell_idx != skill_bounds.second; ++_spell_idx) + SetSkill(spellLearnSkill->skill, spellLearnSkill->step, skill_value, skill_max_value); + } + else { - SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(_spell_idx->second->skillId); - if (!pSkill) - continue; + // not ranked skills + for (SkillLineAbilityMap::const_iterator _spell_idx = skill_bounds.first; _spell_idx != skill_bounds.second; ++_spell_idx) + { + SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(_spell_idx->second->skillId); + if (!pSkill) + continue; - if (_spell_idx->second->AutolearnType == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(pSkill->id)) - LearnDefaultSkill(pSkill->id, 0); + if (_spell_idx->second->AutolearnType == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(pSkill->id)) + LearnDefaultSkill(pSkill->id, 0); - if (pSkill->id == SKILL_MOUNTS && !Has310Flyer(false)) - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && - spellInfo->Effects[i].CalcValue() == 310) - SetHas310Flyer(true); + if (pSkill->id == SKILL_MOUNTS && !Has310Flyer(false)) + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && + spellInfo->Effects[i].CalcValue() == 310) + SetHas310Flyer(true); + } } } @@ -3847,9 +3846,9 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent if (!itr2->second.autoLearned) { if (!IsInWorld() || !itr2->second.active) // at spells loading, no output, but allow save - addSpell(itr2->second.spell, itr2->second.active, true, true, false); + AddSpell(itr2->second.spell, itr2->second.active, true, true, false); else // at normal learning - learnSpell(itr2->second.spell, true); + LearnSpell(itr2->second.spell, true); } } @@ -3908,14 +3907,14 @@ bool Player::IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraStateType(spellInfo->CasterAuraState))); } -void Player::learnSpell(uint32 spell_id, bool dependent) +void Player::LearnSpell(uint32 spell_id, bool dependent, bool fromSkill /*= false*/) { PlayerSpellMap::iterator itr = m_spells.find(spell_id); bool disabled = (itr != m_spells.end()) ? itr->second->disabled : false; bool active = disabled ? itr->second->active : true; - bool learning = addSpell(spell_id, active, true, dependent, false); + bool learning = AddSpell(spell_id, active, true, dependent, false, false, fromSkill); // prevent duplicated entires in spell book, also not send if not in world (loading) if (learning && IsInWorld()) @@ -3933,7 +3932,7 @@ void Player::learnSpell(uint32 spell_id, bool dependent) { PlayerSpellMap::iterator iter = m_spells.find(nextSpell); if (iter != m_spells.end() && iter->second->disabled) - learnSpell(nextSpell, false); + LearnSpell(nextSpell, false, fromSkill); } SpellsRequiringSpellMapBounds spellsRequiringSpell = sSpellMgr->GetSpellsRequiringSpellBounds(spell_id); @@ -3941,12 +3940,12 @@ void Player::learnSpell(uint32 spell_id, bool dependent) { PlayerSpellMap::iterator iter2 = m_spells.find(itr2->second); if (iter2 != m_spells.end() && iter2->second->disabled) - learnSpell(itr2->second, false); + LearnSpell(itr2->second, false, fromSkill); } } } -void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) +void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank) { PlayerSpellMap::iterator itr = m_spells.find(spell_id); if (itr == m_spells.end()) @@ -3959,12 +3958,12 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) if (uint32 nextSpell = sSpellMgr->GetNextSpellInChain(spell_id)) { if (HasSpell(nextSpell) && !GetTalentSpellPos(nextSpell)) - removeSpell(nextSpell, disabled, false); + RemoveSpell(nextSpell, disabled, false); } //unlearn spells dependent from recently removed spells SpellsRequiringSpellMapBounds spellsRequiringSpell = sSpellMgr->GetSpellsRequiringSpellBounds(spell_id); for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequiringSpell.first; itr2 != spellsRequiringSpell.second; ++itr2) - removeSpell(itr2->second, disabled); + RemoveSpell(itr2->second, disabled); // re-search, it can be corrupted in prev loop itr = m_spells.find(spell_id); @@ -4089,7 +4088,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) SpellLearnSpellMapBounds spell_bounds = sSpellMgr->GetSpellLearnSpellMapBounds(spell_id); for (SpellLearnSpellMap::const_iterator itr2 = spell_bounds.first; itr2 != spell_bounds.second; ++itr2) - removeSpell(itr2->second.spell, disabled); + RemoveSpell(itr2->second.spell, disabled); // activate lesser rank in spellbook/action bar, and cast it if need bool prev_activate = false; @@ -4121,7 +4120,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) // now re-learn if need re-activate if (cur_active && !prev_itr->second->active && learn_low_rank) { - if (addSpell(prev_id, true, false, prev_itr->second->dependent, prev_itr->second->disabled)) + if (AddSpell(prev_id, true, false, prev_itr->second->dependent, prev_itr->second->disabled)) { // downgrade spell ranks in spellbook and action bar WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4); @@ -4336,7 +4335,7 @@ void Player::_SaveSpellCooldowns(SQLTransaction& trans) trans->Append(ss.str().c_str()); } -uint32 Player::resetTalentsCost() const +uint32 Player::ResetTalentsCost() const { // The first time reset costs 1 gold if (m_resetTalentsCost < 1*GOLD) @@ -4369,7 +4368,7 @@ uint32 Player::resetTalentsCost() const } } -bool Player::resetTalents(bool no_cost) +bool Player::ResetTalents(bool no_cost) { sScriptMgr->OnPlayerTalentsReset(this, no_cost); @@ -4389,7 +4388,7 @@ bool Player::resetTalents(bool no_cost) if (!no_cost && !sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST)) { - cost = resetTalentsCost(); + cost = ResetTalentsCost(); if (!HasEnoughMoney(cost)) { @@ -4426,11 +4425,11 @@ bool Player::resetTalents(bool no_cost) const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank]); if (!_spellEntry) continue; - removeSpell(talentInfo->RankID[rank], true); + RemoveSpell(talentInfo->RankID[rank], true); // search for spells that the talent teaches and unlearn them for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL) - removeSpell(_spellEntry->Effects[i].TriggerSpell, true); + RemoveSpell(_spellEntry->Effects[i].TriggerSpell, true); // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]); if (plrTalent != m_talents[m_activeSpec]->end()) @@ -6113,7 +6112,7 @@ bool Player::UpdateCraftSkill(uint32 spellid) if (spellEntry && spellEntry->Mechanic == MECHANIC_DISCOVERY) { if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this)) - learnSpell(discoveredSpell, false); + LearnSpell(discoveredSpell, false); } uint32 craft_skill_gain = sWorld->getIntConfig(CONFIG_SKILL_GAIN_CRAFTING); @@ -6216,7 +6215,7 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) uint32 bsl = bonusSkillLevels[i]; if (SkillValue < bsl && new_value >= bsl) { - learnSkillRewardedSpells(SkillId, new_value); + LearnSkillRewardedSpells(SkillId, new_value); break; } } @@ -6423,7 +6422,7 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), MAKE_SKILL_VALUE(newVal, maxVal)); if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; - learnSkillRewardedSpells(id, newVal); + LearnSkillRewardedSpells(id, newVal); // if skill value is going up, update enchantments after setting the new value if (newVal > currVal) UpdateSkillEnchantments(id, currVal, newVal); @@ -6449,55 +6448,57 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) if (SkillLineAbilityEntry const* pAbility = sSkillLineAbilityStore.LookupEntry(j)) if (pAbility->skillId == id) - removeSpell(sSpellMgr->GetFirstSpellInChain(pAbility->spellId)); + RemoveSpell(sSpellMgr->GetFirstSpellInChain(pAbility->spellId)); } } else if (newVal) //add { currVal = 0; for (int i=0; i < PLAYER_MAX_SKILLS; ++i) - if (!GetUInt32Value(PLAYER_SKILL_INDEX(i))) { - SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(id); - if (!pSkill) + if (!GetUInt32Value(PLAYER_SKILL_INDEX(i))) { - TC_LOG_ERROR("entities.player.skills", "Skill not found in SkillLineStore: skill #%u", id); - return; - } + SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(id); + if (!pSkill) + { + TC_LOG_ERROR("entities.player.skills", "Skill not found in SkillLineStore: skill #%u", id); + return; + } - SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id, step)); - SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i), MAKE_SKILL_VALUE(newVal, maxVal)); - UpdateSkillEnchantments(id, currVal, newVal); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); + SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id, step)); + SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i), MAKE_SKILL_VALUE(newVal, maxVal)); + UpdateSkillEnchantments(id, currVal, newVal); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); - // insert new entry or update if not deleted old entry yet - if (itr != mSkillStatus.end()) - { - itr->second.pos = i; - itr->second.uState = SKILL_CHANGED; - } - else - mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(i, SKILL_NEW))); + // insert new entry or update if not deleted old entry yet + if (itr != mSkillStatus.end()) + { + itr->second.pos = i; + itr->second.uState = SKILL_CHANGED; + } + else + mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(i, SKILL_NEW))); - // apply skill bonuses - SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i), 0); + // apply skill bonuses + SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i), 0); - // temporary bonuses - AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL); - for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j) - if ((*j)->GetMiscValue() == int32(id)) + // temporary bonuses + AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL); + for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j) + if ((*j)->GetMiscValue() == int32(id)) (*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true); - // permanent bonuses - AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT); - for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j) - if ((*j)->GetMiscValue() == int32(id)) + // permanent bonuses + AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT); + for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j) + if ((*j)->GetMiscValue() == int32(id)) (*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true); - // Learn all spells for skill - learnSkillRewardedSpells(id, newVal); - return; + // Learn all spells for skill + LearnSkillRewardedSpells(id, newVal); + return; + } } } } @@ -9774,7 +9775,7 @@ void Player::SendTalentWipeConfirm(uint64 guid) { WorldPacket data(MSG_TALENT_WIPE_CONFIRM, (8+4)); data << uint64(guid); - uint32 cost = sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : resetTalentsCost(); + uint32 cost = sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : ResetTalentsCost(); data << cost; GetSession()->SendPacket(&data); } @@ -18502,7 +18503,7 @@ void Player::_LoadQuestStatusRewarded(PreparedQueryResult result) if (quest) { // learn rewarded spell if unknown - learnQuestRewardedSpells(quest); + LearnQuestRewardedSpells(quest); // set rewarded title if any if (quest->GetCharTitleId()) @@ -18650,7 +18651,7 @@ void Player::_LoadSpells(PreparedQueryResult result) if (result) { do - addSpell((*result)[0].GetUInt32(), (*result)[1].GetBool(), false, false, (*result)[2].GetBool(), true); + AddSpell((*result)[0].GetUInt32(), (*result)[1].GetBool(), false, false, (*result)[2].GetBool(), true); while (result->NextRow()); } } @@ -22061,6 +22062,27 @@ void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time) m_spellCooldowns[spellid] = sc; } +void Player::ModifySpellCooldown(uint32 spellId, int32 cooldown) +{ + SpellCooldowns::iterator itr = m_spellCooldowns.find(spellId); + if (itr == m_spellCooldowns.end()) + return; + + time_t now = time(NULL); + if (itr->second.end + (cooldown / IN_MILLISECONDS) > now) + itr->second.end += (cooldown / IN_MILLISECONDS); + else + m_spellCooldowns.erase(itr); + + WorldPacket data(SMSG_MODIFY_COOLDOWN, 4 + 8 + 4); + data << uint32(spellId); // Spell ID + data << uint64(GetGUID()); // Player GUID + data << int32(cooldown); // Cooldown mod in milliseconds + GetSession()->SendPacket(&data); + + TC_LOG_DEBUG("misc", "ModifySpellCooldown:: Player: %s (GUID: %u) Spell: %u cooldown: %u", GetName().c_str(), GetGUIDLow(), spellId, GetSpellCooldownDelay(spellId)); +} + void Player::SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId /*= 0*/, Spell* spell /*= NULL*/, bool setCooldown /*= true*/) { // start cooldowns at server side, if any @@ -23017,7 +23039,7 @@ void Player::ApplyEquipCooldown(Item* pItem) } } -void Player::resetSpells(bool myClassOnly) +void Player::ResetSpells(bool myClassOnly) { // not need after this call if (HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) @@ -23066,11 +23088,11 @@ void Player::resetSpells(bool myClassOnly) } else for (PlayerSpellMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter) - removeSpell(iter->first, false, false); // only iter->first can be accessed, object by iter->second can be deleted already + RemoveSpell(iter->first, false, false); // only iter->first can be accessed, object by iter->second can be deleted already LearnDefaultSkills(); LearnCustomSpells(); - learnQuestRewardedSpells(); + LearnQuestRewardedSpells(); } void Player::LearnCustomSpells() @@ -23085,9 +23107,9 @@ void Player::LearnCustomSpells() uint32 tspell = *itr; TC_LOG_DEBUG("entities.player.loading", "PLAYER (Class: %u Race: %u): Adding initial spell, id = %u", uint32(getClass()), uint32(getRace()), tspell); if (!IsInWorld()) // will send in INITIAL_SPELLS in list anyway at map add - addSpell(tspell, true, true, true, false); + AddSpell(tspell, true, true, true, false); else // but send in normal spell in game learn case - learnSpell(tspell, true); + LearnSpell(tspell, true); } } @@ -23153,7 +23175,7 @@ void Player::LearnDefaultSkill(uint32 skillId, uint16 rank) } } -void Player::learnQuestRewardedSpells(Quest const* quest) +void Player::LearnQuestRewardedSpells(Quest const* quest) { int32 spell_id = quest->GetRewSpellCast(); uint32 src_spell_id = quest->GetSrcSpell(); @@ -23233,7 +23255,7 @@ void Player::learnQuestRewardedSpells(Quest const* quest) CastSpell(this, spell_id, true); } -void Player::learnQuestRewardedSpells() +void Player::LearnQuestRewardedSpells() { // learn spells received from quest completing for (RewardedQuestSet::const_iterator itr = m_RewardedQuests.begin(); itr != m_RewardedQuests.end(); ++itr) @@ -23242,43 +23264,42 @@ void Player::learnQuestRewardedSpells() if (!quest) continue; - learnQuestRewardedSpells(quest); + LearnQuestRewardedSpells(quest); } } -void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value) +void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue) { uint32 raceMask = getRaceMask(); uint32 classMask = getClassMask(); for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { - SkillLineAbilityEntry const* pAbility = sSkillLineAbilityStore.LookupEntry(j); - if (!pAbility || pAbility->skillId != skill_id) + SkillLineAbilityEntry const* ability = sSkillLineAbilityStore.LookupEntry(j); + if (!ability || ability->skillId != skillId) continue; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pAbility->spellId); - if (!spellInfo) + if (!sSpellMgr->GetSpellInfo(ability->spellId)) continue; - if (pAbility->AutolearnType != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE && pAbility->AutolearnType != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN) + if (ability->AutolearnType != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE && ability->AutolearnType != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN) continue; // Check race if set - if (pAbility->racemask && !(pAbility->racemask & raceMask)) + if (ability->racemask && !(ability->racemask & raceMask)) continue; // Check class if set - if (pAbility->classmask && !(pAbility->classmask & classMask)) + if (ability->classmask && !(ability->classmask & classMask)) continue; // need unlearn spell - if (skill_value < pAbility->req_skill_value && pAbility->AutolearnType == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE) - removeSpell(pAbility->spellId); + if (skillValue < ability->req_skill_value && ability->AutolearnType == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE) + RemoveSpell(ability->spellId); // need learn else if (!IsInWorld()) - addSpell(pAbility->spellId, true, true, true, false); + AddSpell(ability->spellId, true, true, true, false, false, true); else - learnSpell(pAbility->spellId, true); + LearnSpell(ability->spellId, true, true); } } @@ -24946,12 +24967,12 @@ bool Player::IsKnowHowFlyIn(uint32 mapid, uint32 zone) const return v_map != 571 || HasSpell(54197); // Cold Weather Flying } -void Player::learnSpellHighRank(uint32 spellid) +void Player::LearnSpellHighestRank(uint32 spellid) { - learnSpell(spellid, false); + LearnSpell(spellid, false); if (uint32 next = sSpellMgr->GetNextSpellInChain(spellid)) - learnSpellHighRank(next); + LearnSpellHighestRank(next); } void Player::_LoadSkills(PreparedQueryResult result) @@ -24972,7 +24993,10 @@ void Player::_LoadSkills(PreparedQueryResult result) SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skill, getRace(), getClass()); if (!rcEntry) { - TC_LOG_ERROR("entities.player", "Character %u has skill %u that does not exist.", GetGUIDLow(), skill); + TC_LOG_ERROR("entities.player", "Character: %s (GUID: %u Race: %u Class: %u) has skill %u not allowed for his race/class combination", + GetName().c_str(), GetGUIDLow(), uint32(getRace()), uint32(getClass()), skill); + + mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(0, SKILL_DELETED))); continue; } @@ -25025,7 +25049,7 @@ void Player::_LoadSkills(PreparedQueryResult result) mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(count, SKILL_UNCHANGED))); - learnSkillRewardedSpells(skill, value); + LearnSkillRewardedSpells(skill, value); ++count; @@ -25333,7 +25357,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) return; // learn! (other talent ranks will unlearned at learning) - learnSpell(spellid, false); + LearnSpell(spellid, false); AddTalent(spellid, m_activeSpec, true); TC_LOG_INFO("entities.player", "TalentID: %u Rank: %u Spell: %u Spec: %u\n", talentId, talentRank, spellid, m_activeSpec); @@ -26144,11 +26168,11 @@ void Player::ActivateSpec(uint8 spec) // skip non-existant talent ranks if (talentInfo->RankID[rank] == 0) continue; - removeSpell(talentInfo->RankID[rank], true); // removes the talent, and all dependant, learned, and chained spells.. + RemoveSpell(talentInfo->RankID[rank], true); // removes the talent, and all dependant, learned, and chained spells.. if (const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank])) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) // search through the SpellInfo for valid trigger spells if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL) - removeSpell(_spellEntry->Effects[i].TriggerSpell, true); // and remove any spells that the talent teaches + RemoveSpell(_spellEntry->Effects[i].TriggerSpell, true); // and remove any spells that the talent teaches // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted //PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]); //if (plrTalent != m_talents[m_activeSpec]->end()) @@ -26191,7 +26215,7 @@ void Player::ActivateSpec(uint8 spec) // if the talent can be found in the newly activated PlayerTalentMap if (HasTalent(talentInfo->RankID[rank], m_activeSpec)) { - learnSpell(talentInfo->RankID[rank], false); // add the talent to the PlayerSpellMap + LearnSpell(talentInfo->RankID[rank], false); // add the talent to the PlayerSpellMap spentTalents += (rank + 1); // increment the spentTalents count } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 5f500b7f1d8..d815b37f98f 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1578,16 +1578,16 @@ class Player : public Unit, public GridObject void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask); void SendInitialSpells(); - bool addSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false); - void learnSpell(uint32 spell_id, bool dependent); - void removeSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true); - void resetSpells(bool myClassOnly = false); + bool AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, bool fromSkill = false); + void LearnSpell(uint32 spell_id, bool dependent, bool fromSkill = false); + void RemoveSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true); + void ResetSpells(bool myClassOnly = false); void LearnCustomSpells(); void LearnDefaultSkills(); void LearnDefaultSkill(uint32 skillId, uint16 rank); - void learnQuestRewardedSpells(); - void learnQuestRewardedSpells(Quest const* quest); - void learnSpellHighRank(uint32 spellid); + void LearnQuestRewardedSpells(); + void LearnQuestRewardedSpells(Quest const* quest); + void LearnSpellHighestRank(uint32 spellid); void AddTemporarySpell(uint32 spellId); void RemoveTemporarySpell(uint32 spellId); void SetReputation(uint32 factionentry, uint32 value); @@ -1595,8 +1595,8 @@ class Player : public Unit, public GridObject std::string const& GetGuildName(); uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); } void SetFreeTalentPoints(uint32 points); - bool resetTalents(bool no_cost = false); - uint32 resetTalentsCost() const; + bool ResetTalents(bool no_cost = false); + uint32 ResetTalentsCost() const; void InitTalentForLevel(); void BuildPlayerTalentsInfoData(WorldPacket* data); void BuildPetTalentsInfoData(WorldPacket* data); @@ -1647,6 +1647,7 @@ class Player : public Unit, public GridObject uint32 GetSpellCooldownDelay(uint32 spell_id) const; void AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = NULL, bool infinityCooldown = false); void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time); + void ModifySpellCooldown(uint32 spellId, int32 cooldown); void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = NULL, bool setCooldown = true); void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs); void RemoveSpellCooldown(uint32 spell_id, bool update = false); @@ -1889,7 +1890,7 @@ class Player : public Unit, public GridObject int16 GetSkillTempBonusValue(uint32 skill) const; uint16 GetSkillStep(uint16 skill) const; // 0...6 bool HasSkill(uint32 skill) const; - void learnSkillRewardedSpells(uint32 id, uint32 value); + void LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue); WorldLocation& GetTeleportDest() { return m_teleport_dest; } bool IsBeingTeleported() const { return mSemaphoreTeleport_Near || mSemaphoreTeleport_Far; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 72c1a071487..730bafa4c06 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6889,31 +6889,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } break; } - // Item - Shaman T10 Elemental 2P Bonus - case 70811: - { - // Lightning Bolt & Chain Lightning - if (procSpell->SpellFamilyFlags[0] & 0x3) - { - if (ToPlayer()->HasSpellCooldown(16166)) - { - uint32 newCooldownDelay = ToPlayer()->GetSpellCooldownDelay(16166); - if (newCooldownDelay < 3) - newCooldownDelay = 0; - else - newCooldownDelay -= 2; - ToPlayer()->AddSpellCooldown(16166, 0, uint32(time(NULL) + newCooldownDelay)); - - WorldPacket data(SMSG_MODIFY_COOLDOWN, 4+8+4); - data << uint32(16166); // Spell ID - data << uint64(GetGUID()); // Player GUID - data << int32(-2000); // Cooldown mod in milliseconds - ToPlayer()->GetSession()->SendPacket(&data); - return true; - } - } - return false; - } // Item - Shaman T10 Elemental 4P Bonus case 70817: { @@ -11156,6 +11131,9 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons if (!spellInfo || !spellInfo->Effects[index].IsEffect()) return false; + if (spellInfo->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) + return false; + // If m_immuneToEffect type contain this effect type, IMMUNE effect. uint32 effect = spellInfo->Effects[index].Effect; SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 45ecbf0c3df..00106d971ec 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -400,7 +400,6 @@ bool Group::AddMember(Player* player) stmt->setUInt8(4, member.roles); CharacterDatabase.Execute(stmt); - } SendUpdate(); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 9ad382b4686..6c4c657ba2c 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1003,13 +1003,13 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) // Apply at_login requests if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { - pCurrChar->resetSpells(); + pCurrChar->ResetSpells(); SendNotification(LANG_RESET_SPELLS); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { - pCurrChar->resetTalents(true); + pCurrChar->ResetTalents(true); pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state SendNotification(LANG_RESET_TALENTS); } diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index d8a518a24db..4f65bcee4e5 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -288,7 +288,7 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) if (trainer_spell->IsCastable()) _player->CastSpell(_player, trainer_spell->spell, true); else - _player->learnSpell(spellId, false); + _player->LearnSpell(spellId, false); WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12); data << uint64(guid); diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index 8a94753b692..92c7c60bca0 100644 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -80,7 +80,7 @@ void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recvData) if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - if (!(_player->resetTalents())) + if (!(_player->ResetTalents())) { WorldPacket data(MSG_TALENT_WIPE_CONFIRM, 8+4); //you have not any talent data << uint64(0); diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index d21ebca9a91..adef21fe7a2 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -148,7 +148,7 @@ void InstanceScript::AddDoor(GameObject* door, bool add) if (add) { - data.bossInfo->door[data.type].insert(door); + data.bossInfo->door[data.type].insert(door->GetGUID()); switch (data.boundary) { default: @@ -173,7 +173,7 @@ void InstanceScript::AddDoor(GameObject* door, bool add) } } else - data.bossInfo->door[data.type].erase(door); + data.bossInfo->door[data.type].erase(door->GetGUID()); } if (add) @@ -187,9 +187,9 @@ void InstanceScript::AddMinion(Creature* minion, bool add) return; if (add) - itr->second.bossInfo->minion.insert(minion); + itr->second.bossInfo->minion.insert(minion->GetGUID()); else - itr->second.bossInfo->minion.erase(minion); + itr->second.bossInfo->minion.erase(minion->GetGUID()); } bool InstanceScript::SetBossState(uint32 id, EncounterState state) @@ -210,8 +210,9 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state) if (state == DONE) for (MinionSet::iterator i = bossInfo->minion.begin(); i != bossInfo->minion.end(); ++i) - if ((*i)->isWorldBoss() && (*i)->IsAlive()) - return false; + if (Creature* minion = instance->GetCreature(*i)) + if (minion->isWorldBoss() && minion->IsAlive()) + return false; bossInfo->state = state; SaveToDB(); @@ -219,10 +220,12 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state) for (uint32 type = 0; type < MAX_DOOR_TYPES; ++type) for (DoorSet::iterator i = bossInfo->door[type].begin(); i != bossInfo->door[type].end(); ++i) - UpdateDoorState(*i); + if (GameObject* door = instance->GetGameObject(*i)) + UpdateDoorState(door); for (MinionSet::iterator i = bossInfo->minion.begin(); i != bossInfo->minion.end(); ++i) - UpdateMinionState(*i, state); + if (Creature* minion = instance->GetCreature(*i)) + UpdateMinionState(minion, state); return true; } diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 9e11c566c22..f379572961c 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -35,8 +35,8 @@ class Player; class GameObject; class Creature; -typedef std::set DoorSet; -typedef std::set MinionSet; +typedef std::set DoorSet; +typedef std::set MinionSet; enum EncounterFrameType { diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 1de13d137c4..9c023b86bc9 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -131,21 +131,15 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) if (!instance) return false; - Difficulty targetDifficulty = player->GetDifficulty(entry->IsRaid()); - //The player has a heroic mode and tries to enter into instance which has no a heroic mode - MapDifficulty const* mapDiff = GetMapDifficultyData(entry->MapID, targetDifficulty); + Difficulty targetDifficulty, requestedDifficulty; + targetDifficulty = requestedDifficulty = player->GetDifficulty(entry->IsRaid()); + // Get the highest available difficulty if current setting is higher than the instance allows + MapDifficulty const* mapDiff = GetDownscaledMapDifficultyData(entry->MapID, targetDifficulty); if (!mapDiff) { - // Send aborted message for dungeons - if (entry->IsNonRaidDungeon()) - { - player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, player->GetDungeonDifficulty()); - return false; - } - else // attempt to downscale - mapDiff = GetDownscaledMapDifficultyData(entry->MapID, targetDifficulty); + player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, requestedDifficulty); + return false; } - // FIXME: mapDiff is never used //Bypass checks for GMs if (player->IsGameMaster()) diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 3140fc23296..f2e1bb518d4 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -477,11 +477,29 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin dtStatus dtResult = DT_FAILURE; if (_straightLine) { - // if the path is a straight line then start and end position are enough dtResult = DT_SUCCESS; - pointCount = 2; - memcpy(&pathPoints[0], startPoint, sizeof(float)* 3); - memcpy(&pathPoints[3], endPoint, sizeof(float)* 3); + pointCount = 1; + memcpy(&pathPoints[VERTEX_SIZE * 0], startPoint, sizeof(float)* 3); // first point + + // path has to be split into polygons with dist SMOOTH_PATH_STEP_SIZE between them + G3D::Vector3 startVec = G3D::Vector3(startPoint[0], startPoint[1], startPoint[2]); + G3D::Vector3 endVec = G3D::Vector3(endPoint[0], endPoint[1], endPoint[2]); + G3D::Vector3 diffVec = (endVec - startVec); + G3D::Vector3 prevVec = startVec; + float len = diffVec.length(); + diffVec *= SMOOTH_PATH_STEP_SIZE / len; + while (len > SMOOTH_PATH_STEP_SIZE) + { + len -= SMOOTH_PATH_STEP_SIZE; + prevVec += diffVec; + pathPoints[VERTEX_SIZE * pointCount + 0] = prevVec.x; + pathPoints[VERTEX_SIZE * pointCount + 1] = prevVec.y; + pathPoints[VERTEX_SIZE * pointCount + 2] = prevVec.z; + ++pointCount; + } + + memcpy(&pathPoints[VERTEX_SIZE * pointCount], endPoint, sizeof(float)* 3); // last point + ++pointCount; } else if (_useStraightPath) { diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index f1359b70aa6..ce01273ab3b 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -263,7 +263,6 @@ void AddSC_instance_zulgurub(); //void AddSC_alterac_mountains(); void AddSC_arathi_highlands(); void AddSC_blasted_lands(); -void AddSC_boss_kruul(); void AddSC_burning_steppes(); void AddSC_duskwood(); void AddSC_eastern_plaguelands(); @@ -978,7 +977,6 @@ void AddEasternKingdomsScripts() //AddSC_alterac_mountains(); AddSC_arathi_highlands(); AddSC_blasted_lands(); - AddSC_boss_kruul(); AddSC_burning_steppes(); AddSC_duskwood(); AddSC_eastern_plaguelands(); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 0d7dd8819af..d223425a027 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1305,6 +1305,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { + ASSERT(m_targets.GetObjectTarget() && "Spell::SelectImplicitTargetDestTargets - no explicit object target available!"); WorldObject* target = m_targets.GetObjectTarget(); SpellDestination dest(*target); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index abeeb394218..4c0d5770cea 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -866,7 +866,10 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex) if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION) targets.SetDst(m_targets); - targets.SetUnitTarget(m_caster); + if (Unit* target = m_targets.GetUnitTarget()) + targets.SetUnitTarget(target); + else + targets.SetUnitTarget(m_caster); } CustomSpellValues values; @@ -1227,7 +1230,7 @@ void Spell::EffectUnlearnSpecialization(SpellEffIndex effIndex) Player* player = unitTarget->ToPlayer(); uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell; - player->removeSpell(spellToUnlearn); + player->RemoveSpell(spellToUnlearn); TC_LOG_DEBUG("spells", "Spell: Player %u has unlearned spell %u from NpcGUID: %u", player->GetGUIDLow(), spellToUnlearn, m_caster->GetGUIDLow()); } @@ -2370,7 +2373,7 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex) Player* player = unitTarget->ToPlayer(); uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell; - player->learnSpell(spellToLearn, false); + player->LearnSpell(spellToLearn, false); TC_LOG_DEBUG("spells", "Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow()); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 08bccd75f0c..631c4e61d5f 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1781,7 +1781,7 @@ void World::SetInitialWorldSettings() ///- Initialize Battlegrounds TC_LOG_INFO("server.loading", "Starting Battleground System"); - sBattlegroundMgr->CreateInitialBattlegrounds(); + sBattlegroundMgr->LoadBattlegroundTemplates(); sBattlegroundMgr->InitAutomaticArenaPointDistribution(); ///- Initialize outdoor pvp diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index 1121e4d0a2f..4b7aa8ecad3 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -51,8 +51,8 @@ public: }; static ChatCommand accountLockCommandTable[] = { - { "country", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK_COUNTRY, true, &HandleAccountLockCountryCommand, "", NULL }, - { "ip", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK_IP, true, &HandleAccountLockIpCommand, "", NULL }, + { "country", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK_COUNTRY, false, &HandleAccountLockCountryCommand, "", NULL }, + { "ip", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK_IP, false, &HandleAccountLockIpCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand accountCommandTable[] = diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp index 03d10149ae5..88acd491427 100644 --- a/src/server/scripts/Commands/cs_learn.cpp +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -112,9 +112,9 @@ public: } if (allRanks) - targetPlayer->learnSpellHighRank(spell); + targetPlayer->LearnSpellHighestRank(spell); else - targetPlayer->learnSpell(spell, false); + targetPlayer->LearnSpell(spell, false); if (GetTalentSpellCost(spellInfo->GetFirstRankSpell()->Id)) targetPlayer->SendTalentsInfoData(false); @@ -133,7 +133,7 @@ public: if (!spellInfo->IsAbilityOfSkillType(SKILL_INTERNAL)) continue; - handler->GetSession()->GetPlayer()->learnSpell(i, false); + handler->GetSession()->GetPlayer()->LearnSpell(i, false); } handler->SendSysMessage(LANG_LEARNING_GM_SKILLS); @@ -184,7 +184,7 @@ public: if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false)) continue; - handler->GetSession()->GetPlayer()->learnSpell(spellInfo->Id, false); + handler->GetSession()->GetPlayer()->LearnSpell(spellInfo->Id, false); } handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS); @@ -228,7 +228,7 @@ public: continue; // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) - player->learnSpellHighRank(spellId); + player->LearnSpellHighestRank(spellId); player->AddTalent(spellId, player->GetActiveSpec(), true); } @@ -320,7 +320,7 @@ public: { // skipping UNIVERSAL language (0) for (uint8 i = 1; i < LANGUAGES_COUNT; ++i) - handler->GetSession()->GetPlayer()->learnSpell(lang_description[i].spell_id, false); + handler->GetSession()->GetPlayer()->LearnSpell(lang_description[i].spell_id, false); handler->SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG); return true; @@ -334,7 +334,7 @@ public: target->LearnDefaultSkills(); target->LearnCustomSpells(); - target->learnQuestRewardedSpells(); + target->LearnQuestRewardedSpells(); handler->PSendSysMessage(LANG_COMMAND_LEARN_ALL_DEFAULT_AND_QUEST, handler->GetNameLink(target).c_str()); return true; @@ -470,7 +470,7 @@ public: if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, player, false)) continue; - player->learnSpell(skillLine->spellId, false); + player->LearnSpell(skillLine->spellId, false); } } @@ -499,7 +499,7 @@ public: spellId = sSpellMgr->GetFirstSpellInChain(spellId); if (target->HasSpell(spellId)) - target->removeSpell(spellId, false, !allRanks); + target->RemoveSpell(spellId, false, !allRanks); else handler->SendSysMessage(LANG_FORGET_SPELL); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 89dc08d5737..f39dd0f0616 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -25,6 +25,7 @@ EndScriptData */ #include "AccountMgr.h" #include "AchievementMgr.h" #include "AuctionHouseMgr.h" +#include "BattlegroundMgr.h" #include "Chat.h" #include "CreatureTextMgr.h" #include "DisableMgr.h" @@ -74,6 +75,7 @@ public: { "areatrigger_tavern", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TAVERN, true, &HandleReloadAreaTriggerTavernCommand, "", NULL }, { "areatrigger_teleport", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TELEPORT, true, &HandleReloadAreaTriggerTeleportCommand, "", NULL }, { "autobroadcast", rbac::RBAC_PERM_COMMAND_RELOAD_AUTOBROADCAST, true, &HandleReloadAutobroadcastCommand, "", NULL }, + { "battleground_template", rbac::RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE, true, &HandleReloadBattlegroundTemplate, "", NULL }, { "broadcast_text", rbac::RBAC_PERM_COMMAND_RELOAD_BROADCAST_TEXT, true, &HandleReloadBroadcastTextCommand, "", NULL }, { "command", rbac::RBAC_PERM_COMMAND_RELOAD_COMMAND, true, &HandleReloadCommandCommand, "", NULL }, { "conditions", rbac::RBAC_PERM_COMMAND_RELOAD_CONDITIONS, true, &HandleReloadConditions, "", NULL }, @@ -200,6 +202,7 @@ public: HandleReloadVehicleTemplateAccessoryCommand(handler, ""); HandleReloadAutobroadcastCommand(handler, ""); + HandleReloadBattlegroundTemplate(handler, ""); return true; } @@ -376,6 +379,14 @@ public: return true; } + static bool HandleReloadBattlegroundTemplate(ChatHandler* handler, char const* /*args*/) + { + TC_LOG_INFO("misc", "Re-Loading Battleground Templates..."); + sBattlegroundMgr->LoadBattlegroundTemplates(); + handler->SendGlobalGMSysMessage("DB table `battleground_template` reloaded."); + return true; + } + static bool HandleReloadBroadcastTextCommand(ChatHandler* handler, const char* /*args*/) { TC_LOG_INFO("misc", "Re-Loading Broadcast texts..."); diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp index 279f9c2ef4c..00a669609f9 100644 --- a/src/server/scripts/Commands/cs_reset.cpp +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -165,7 +165,7 @@ public: if (target) { - target->resetSpells(/* bool myClassOnly */); + target->ResetSpells(/* bool myClassOnly */); ChatHandler(target->GetSession()).SendSysMessage(LANG_RESET_SPELLS); if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) @@ -233,7 +233,7 @@ public: if (target) { - target->resetTalents(true); + target->ResetTalents(true); target->SendTalentsInfoData(false); ChatHandler(target->GetSession()).SendSysMessage(LANG_RESET_TALENTS); if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_pyroguard_emberseer.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_pyroguard_emberseer.cpp index 4be139c2ee9..2bd43e7283c 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_pyroguard_emberseer.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_pyroguard_emberseer.cpp @@ -212,13 +212,12 @@ public: std::list creatureList; GetCreatureListWithEntryInGrid(creatureList, me, NPC_BLACKHAND_INCARCERATOR, 35.0f); for (std::list::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) - if (Creature* creatureList = *itr) + if (Creature* creature = *itr) { - if (!creatureList->IsAlive()) - { - creatureList->Respawn(); - } - creatureList->AI()->SetData(1, 1); + if (!creature->IsAlive()) + creature->Respawn(); + + creature->AI()->SetData(1, 1); } me->AddAura(SPELL_ENCAGED_EMBERSEER, me); instance->SetBossState(DATA_PYROGAURD_EMBERSEER, NOT_STARTED); @@ -231,8 +230,8 @@ public: GetCreatureListWithEntryInGrid(creatureList, me, NPC_BLACKHAND_INCARCERATOR, 35.0f); for (std::list::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) { - if (Creature* creatureList = *itr) - creatureList->AI()->SetData(1, 1); + if (Creature* creature = *itr) + creature->AI()->SetData(1, 1); } events.ScheduleEvent(EVENT_PRE_FIGHT_2, 32000); break; @@ -355,9 +354,7 @@ public: } if (data == 1 && value == 2) - { _events.ScheduleEvent(EVENT_ENCAGED_EMBERSEER, 1000); - } } void EnterCombat(Unit* /*who*/) override @@ -371,8 +368,8 @@ public: GetCreatureListWithEntryInGrid(creatureList, me, NPC_BLACKHAND_INCARCERATOR, 60.0f); for (std::list::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) { - if (Creature* creatureList = *itr) - creatureList->SetInCombatWithZone(); // AI()->AttackStart(me->GetVictim()); + if (Creature* creature = *itr) + creature->SetInCombatWithZone(); // AI()->AttackStart(me->GetVictim()); } _events.ScheduleEvent(EVENT_STRIKE, urand(8000, 16000)); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp index b3a55e1fe4a..555eac21c43 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp @@ -410,24 +410,24 @@ public: void Dragonspireroomstore() { - uint8 creaturecount; + uint8 creatureCount; for (uint8 i = 0; i < 7; ++i) { - creaturecount = 0; + creatureCount = 0; if (GameObject* rune = instance->GetGameObject(go_roomrunes[i])) { - for (uint8 ii = 0; ii < 3; ++ii) + for (uint8 j = 0; j < 3; ++j) { std::list creatureList; - GetCreatureListWithEntryInGrid(creatureList, rune, DragonspireMobs[ii], 15.0f); + GetCreatureListWithEntryInGrid(creatureList, rune, DragonspireMobs[j], 15.0f); for (std::list::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) { - if (Creature* creatureList = *itr) + if (Creature* creature = *itr) { - runecreaturelist[i] [creaturecount] = creatureList->GetGUID(); - ++creaturecount; + runecreaturelist[i][creatureCount] = creature->GetGUID(); + ++creatureCount; } } } diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt index 4adb087921b..ef2e9fceb21 100644 --- a/src/server/scripts/EasternKingdoms/CMakeLists.txt +++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt @@ -85,7 +85,6 @@ set(scripts_STAT_SRCS EasternKingdoms/Scholomance/boss_ras_frostwhisper.cpp EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp EasternKingdoms/zone_isle_of_queldanas.cpp - EasternKingdoms/boss_kruul.cpp EasternKingdoms/ZulGurub/boss_hakkar.cpp EasternKingdoms/ZulGurub/boss_mandokir.cpp EasternKingdoms/ZulGurub/boss_marli.cpp diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp index 3b499b649cf..256ab06a7b7 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp @@ -84,29 +84,20 @@ public: InstanceScript* instance; - uint64 TerestianGUID; - uint32 AmplifyTimer; void Reset() override { - TerestianGUID = 0; AmplifyTimer = 2000; } - void EnterCombat(Unit* /*who*/) override - { - } + void EnterCombat(Unit* /*who*/) override { } void JustDied(Unit* /*killer*/) override { - uint64 TerestianGUID = instance->GetData64(DATA_TERESTIAN); - if (TerestianGUID) - { - Unit* Terestian = ObjectAccessor::GetUnit(*me, TerestianGUID); - if (Terestian && Terestian->IsAlive()) - DoCast(Terestian, SPELL_BROKEN_PACT, true); - } + Creature* Terestian = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TERESTIAN)); + if (Terestian && Terestian->IsAlive()) + DoCast(Terestian, SPELL_BROKEN_PACT, true); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp index 787bf7584e5..f18c0aac8bb 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 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,15 +15,9 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Arcanist_Doan -SD%Complete: 100 -SDComment: -SDCategory: Scarlet Monastery -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "scarlet_monastery.h" enum Yells { @@ -34,103 +27,100 @@ enum Yells enum Spells { - SPELL_POLYMORPH = 13323, - SPELL_AOESILENCE = 8988, - SPELL_ARCANEEXPLOSION = 9433, - SPELL_FIREAOE = 9435, - SPELL_ARCANEBUBBLE = 9438 + SPELL_SILENCE = 8988, + SPELL_ARCANE_EXPLOSION = 9433, + SPELL_DETONATION = 9435, + SPELL_ARCANE_BUBBLE = 9438, + SPELL_POLYMORPH = 13323 }; -class boss_arcanist_doan : public CreatureScript +enum Events { -public: - boss_arcanist_doan() : CreatureScript("boss_arcanist_doan") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_arcanist_doanAI(creature); - } - - struct boss_arcanist_doanAI : public ScriptedAI - { - boss_arcanist_doanAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 Polymorph_Timer; - uint32 AoESilence_Timer; - uint32 ArcaneExplosion_Timer; - bool bCanDetonate; - bool bShielded; - - void Reset() override - { - Polymorph_Timer = 20000; - AoESilence_Timer = 15000; - ArcaneExplosion_Timer = 3000; - bCanDetonate = false; - bShielded = false; - } + EVENT_SILENCE = 1, + EVENT_ARCANE_EXPLOSION = 2, + EVENT_ARCANE_BUBBLE = 3, + EVENT_POLYMORPH = 4 +}; - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); - } +class boss_arcanist_doan : public CreatureScript +{ + public: + boss_arcanist_doan() : CreatureScript("boss_arcanist_doan") { } - void UpdateAI(uint32 diff) override + struct boss_arcanist_doanAI : public BossAI { - if (!UpdateVictim()) - return; - - if (bShielded && bCanDetonate) + boss_arcanist_doanAI(Creature* creature) : BossAI(creature, DATA_ARCANIST_DOAN) { - DoCast(me, SPELL_FIREAOE); - bCanDetonate = false; + _healthAbove50Pct = true; } - if (me->HasAura(SPELL_ARCANEBUBBLE)) - return; - - //If we are <50% hp cast Arcane Bubble - if (!bShielded && !HealthAbovePct(50)) + void Reset() override { - //wait if we already casting - if (me->IsNonMeleeSpellCast(false)) - return; - - Talk(SAY_SPECIALAE); - DoCast(me, SPELL_ARCANEBUBBLE); - - bCanDetonate = true; - bShielded = true; + _Reset(); + _healthAbove50Pct = true; } - if (Polymorph_Timer <= diff) + void EnterCombat(Unit* /*who*/) override { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) - DoCast(target, SPELL_POLYMORPH); + _EnterCombat(); + Talk(SAY_AGGRO); - Polymorph_Timer = 20000; + events.ScheduleEvent(EVENT_SILENCE, 15 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, 3 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_POLYMORPH, 30 * IN_MILLISECONDS); } - else Polymorph_Timer -= diff; - //AoESilence_Timer - if (AoESilence_Timer <= diff) + void UpdateAI(uint32 diff) override { - DoCastVictim(SPELL_AOESILENCE); - AoESilence_Timer = urand(15000, 20000); - } - else AoESilence_Timer -= diff; + if (!UpdateVictim()) + return; - //ArcaneExplosion_Timer - if (ArcaneExplosion_Timer <= diff) - { - DoCastVictim(SPELL_ARCANEEXPLOSION); - ArcaneExplosion_Timer = 8000; + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SILENCE: + DoCastVictim(SPELL_SILENCE); + events.ScheduleEvent(EVENT_SILENCE, urand(15, 20) * IN_MILLISECONDS); + break; + case EVENT_ARCANE_EXPLOSION: + DoCastVictim(SPELL_ARCANE_EXPLOSION); + events.ScheduleEvent(EVENT_SILENCE, 8 * IN_MILLISECONDS); + break; + case EVENT_POLYMORPH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 30.0f, true)) + DoCast(target, SPELL_POLYMORPH); + events.ScheduleEvent(EVENT_POLYMORPH, 20 * IN_MILLISECONDS); + break; + default: + break; + } + } + + if (_healthAbove50Pct && HealthBelowPct(50)) + { + _healthAbove50Pct = false; + Talk(SAY_SPECIALAE); + DoCast(me, SPELL_ARCANE_BUBBLE); + DoCastAOE(SPELL_DETONATION); + } + + DoMeleeAttackIfReady(); } - else ArcaneExplosion_Timer -= diff; - DoMeleeAttackIfReady(); + private: + bool _healthAbove50Pct; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new boss_arcanist_doanAI(creature); } - }; }; void AddSC_boss_arcanist_doan() diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h b/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h index cd5a74ee478..bdac6b089fd 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h @@ -30,7 +30,8 @@ enum DataTypes DATA_HORSEMAN_EVENT = 5, GAMEOBJECT_PUMPKIN_SHRINE = 6, - DATA_VORREL = 7 + DATA_VORREL = 7, + DATA_ARCANIST_DOAN = 8 }; #endif // SCARLET_M_ diff --git a/src/server/scripts/EasternKingdoms/boss_kruul.cpp b/src/server/scripts/EasternKingdoms/boss_kruul.cpp deleted file mode 100644 index 13f9f76532e..00000000000 --- a/src/server/scripts/EasternKingdoms/boss_kruul.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2008-2014 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 - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/* ScriptData -SDName: Boss_Kruul -SD%Complete: 100 -SDComment: Highlord Kruul are presumably no longer in-game on regular bases, however future events could bring him back. -SDCategory: Bosses -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" - -enum Spells -{ - SPELL_SHADOWVOLLEY = 21341, - SPELL_CLEAVE = 20677, - SPELL_THUNDERCLAP = 23931, - SPELL_TWISTEDREFLECTION = 21063, - SPELL_VOIDBOLT = 21066, - SPELL_RAGE = 21340, - SPELL_CAPTURESOUL = 21054 -}; - -class boss_kruul : public CreatureScript -{ -public: - boss_kruul() : CreatureScript("boss_kruul") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_kruulAI(creature); - } - - struct boss_kruulAI : public ScriptedAI - { - boss_kruulAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 ShadowVolley_Timer; - uint32 Cleave_Timer; - uint32 ThunderClap_Timer; - uint32 TwistedReflection_Timer; - uint32 VoidBolt_Timer; - uint32 Rage_Timer; - uint32 Hound_Timer; - - void Reset() override - { - ShadowVolley_Timer = 10000; - Cleave_Timer = 14000; - ThunderClap_Timer = 20000; - TwistedReflection_Timer = 25000; - VoidBolt_Timer = 30000; - Rage_Timer = 60000; //Cast rage after 1 minute - Hound_Timer = 8000; - } - - void EnterCombat(Unit* /*who*/) override - { - } - - void KilledUnit(Unit* /*victim*/) override - { - // When a player, pet or totem gets killed, Lord Kazzak casts this spell to instantly regenerate 70, 000 health. - DoCast(me, SPELL_CAPTURESOUL); - } - - void SummonHounds(Unit* victim) - { - if (Creature* Hound = DoSpawnCreature(19207, float(irand(-9, 9)), float(irand(-9, 9)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000)) - Hound->AI()->AttackStart(victim); - } - - void UpdateAI(uint32 diff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //ShadowVolley_Timer - if (ShadowVolley_Timer <= diff) - { - if (urand(0, 99) < 45) - DoCastVictim(SPELL_SHADOWVOLLEY); - - ShadowVolley_Timer = 5000; - } else ShadowVolley_Timer -= diff; - - //Cleave_Timer - if (Cleave_Timer <= diff) - { - if (urand(0, 1)) - DoCastVictim(SPELL_CLEAVE); - - Cleave_Timer = 10000; - } else Cleave_Timer -= diff; - - //ThunderClap_Timer - if (ThunderClap_Timer <= diff) - { - if (urand(0, 9) < 2) - DoCastVictim(SPELL_THUNDERCLAP); - - ThunderClap_Timer = 12000; - } else ThunderClap_Timer -= diff; - - //TwistedReflection_Timer - if (TwistedReflection_Timer <= diff) - { - DoCastVictim(SPELL_TWISTEDREFLECTION); - TwistedReflection_Timer = 30000; - } else TwistedReflection_Timer -= diff; - - //VoidBolt_Timer - if (VoidBolt_Timer <= diff) - { - if (urand(0, 9) < 4) - DoCastVictim(SPELL_VOIDBOLT); - - VoidBolt_Timer = 18000; - } else VoidBolt_Timer -= diff; - - //Rage_Timer - if (Rage_Timer <= diff) - { - DoCast(me, SPELL_RAGE); - Rage_Timer = 70000; - } else Rage_Timer -= diff; - - //Hound_Timer - if (Hound_Timer <= diff) - { - SummonHounds(me->GetVictim()); - SummonHounds(me->GetVictim()); - SummonHounds(me->GetVictim()); - - Hound_Timer = 45000; - } else Hound_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_boss_kruul() -{ - new boss_kruul(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index 14f9bfb2e2f..da40ec333a6 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -283,8 +283,6 @@ public: InstanceScript* instance; - uint64 TarethaGUID; - bool LowHp; bool HadMount; @@ -400,11 +398,8 @@ public: me->SummonCreature(NPC_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); break; case 94: - if (uint64 TarethaGUID = instance->GetData64(DATA_TARETHA)) - { - if (Creature* Taretha = ObjectAccessor::GetCreature(*me, TarethaGUID)) - Taretha->AI()->Talk(SAY_TA_ESCAPED, me); - } + if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA))) + Taretha->AI()->Talk(SAY_TA_ESCAPED, me); break; case 95: Talk(SAY_TH_MEET_TARETHA); diff --git a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp index ecb28a5b0cb..04be688d8aa 100644 --- a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp +++ b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp @@ -148,9 +148,9 @@ public: if (Player* target = ObjectAccessor::GetPlayer(*me, PlayerGUID)) AttackStart(target); - switchFactionIfAlive(instance, ENTRY_RAVEN); - switchFactionIfAlive(instance, ENTRY_ORO); - switchFactionIfAlive(instance, ENTRY_MURTA); + switchFactionIfAlive(ENTRY_RAVEN); + switchFactionIfAlive(ENTRY_ORO); + switchFactionIfAlive(ENTRY_MURTA); } postGossipStep++; } @@ -185,9 +185,9 @@ public: Text_Timer = 0; } - void switchFactionIfAlive(InstanceScript* instance, uint32 entry) + void switchFactionIfAlive(uint32 entry) { - if (Creature* crew = instance->instance->GetCreature(instance->GetData64(entry))) + if (Creature* crew = ObjectAccessor::GetCreature(*me, instance->GetData64(entry))) if (crew->IsAlive()) crew->setFaction(FACTION_HOSTILE); } diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.cpp b/src/server/scripts/Outland/BlackTemple/black_temple.cpp index 5edae14d47a..3a33561e998 100644 --- a/src/server/scripts/Outland/BlackTemple/black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/black_temple.cpp @@ -95,32 +95,34 @@ public: { npc_wrathbone_flayerAI(Creature* creature) : ScriptedAI(creature) { - instance = creature->GetInstanceScript(); + _instance = creature->GetInstanceScript(); } void Reset() override { - events.ScheduleEvent(EVENT_GET_CHANNELERS, 3000); - enteredCombat = false; + _events.ScheduleEvent(EVENT_GET_CHANNELERS, 3000); + _enteredCombat = false; + _bloodmageList.clear(); + _deathshaperList.clear(); } void JustDied(Unit* /*killer*/) override { } void EnterCombat(Unit* /*who*/) override { - events.ScheduleEvent(EVENT_CLEAVE, 5000); - events.ScheduleEvent(EVENT_IGNORED, 7000); - enteredCombat = true; + _events.ScheduleEvent(EVENT_CLEAVE, 5000); + _events.ScheduleEvent(EVENT_IGNORED, 7000); + _enteredCombat = true; } void UpdateAI(uint32 diff) override { - if (!enteredCombat) + if (!_enteredCombat) { - events.Update(diff); + _events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { @@ -132,7 +134,7 @@ public: if (!BloodMageList.empty()) for (std::list::const_iterator itr = BloodMageList.begin(); itr != BloodMageList.end(); ++itr) { - bloodmage.push_back((*itr)->GetGUID()); + _bloodmageList.push_back((*itr)->GetGUID()); if ((*itr)->isDead()) (*itr)->Respawn(); } @@ -143,26 +145,26 @@ public: if (!DeathShaperList.empty()) for (std::list::const_iterator itr = DeathShaperList.begin(); itr != DeathShaperList.end(); ++itr) { - deathshaper.push_back((*itr)->GetGUID()); + _deathshaperList.push_back((*itr)->GetGUID()); if ((*itr)->isDead()) (*itr)->Respawn(); } - events.ScheduleEvent(EVENT_SET_CHANNELERS, 3000); + _events.ScheduleEvent(EVENT_SET_CHANNELERS, 3000); break; } case EVENT_SET_CHANNELERS: { - for (std::list::const_iterator itr = bloodmage.begin(); itr != bloodmage.end(); ++itr) - if (Creature* bloodmage = (ObjectAccessor::GetCreature(*me, *itr))) + for (uint64 guid : _bloodmageList) + if (Creature* bloodmage = ObjectAccessor::GetCreature(*me, guid)) bloodmage->CastSpell((Unit*)NULL, SPELL_SUMMON_CHANNEL); - for (std::list::const_iterator itr = deathshaper.begin(); itr != deathshaper.end(); ++itr) - if (Creature* deathshaper = (ObjectAccessor::GetCreature(*me, *itr))) + for (uint64 guid : _deathshaperList) + if (Creature* deathshaper = ObjectAccessor::GetCreature(*me, guid)) deathshaper->CastSpell((Unit*)NULL, SPELL_SUMMON_CHANNEL); - events.ScheduleEvent(EVENT_SET_CHANNELERS, 12000); + _events.ScheduleEvent(EVENT_SET_CHANNELERS, 12000); break; } @@ -175,20 +177,20 @@ public: if (!UpdateVictim()) return; - events.Update(diff); + _events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_CLEAVE: DoCastVictim(SPELL_CLEAVE); - events.ScheduleEvent(EVENT_CLEAVE, urand (1000, 2000)); + _events.ScheduleEvent(EVENT_CLEAVE, urand (1000, 2000)); break; case EVENT_IGNORED: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, SPELL_IGNORED); - events.ScheduleEvent(EVENT_IGNORED, 10000); + _events.ScheduleEvent(EVENT_IGNORED, 10000); break; default: break; @@ -198,12 +200,12 @@ public: } private: - InstanceScript* instance; - EventMap events; - std::list bloodmage; - std::list deathshaper; - bool enteredCombat; - }; + InstanceScript* _instance; + EventMap _events; + std::list _bloodmageList; + std::list _deathshaperList; + bool _enteredCombat; + }; CreatureAI* GetAI(Creature* creature) const override { diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index e466c15d417..5f432bb8b61 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -578,11 +578,11 @@ class spell_dru_rip : public SpellScriptLoader uint8 cp = caster->ToPlayer()->GetComboPoints(); // Idol of Feral Shadows. Can't be handled as SpellMod due its dependency from CPs - if (AuraEffect const* idol = caster->GetAuraEffect(SPELL_DRUID_IDOL_OF_FERAL_SHADOWS, EFFECT_0)) - amount += cp * idol->GetAmount(); + if (AuraEffect const* auraEffIdolOfFeralShadows = caster->GetAuraEffect(SPELL_DRUID_IDOL_OF_FERAL_SHADOWS, EFFECT_0)) + amount += cp * auraEffIdolOfFeralShadows->GetAmount(); // Idol of Worship. Can't be handled as SpellMod due its dependency from CPs - else if (AuraEffect const* idol = caster->GetAuraEffect(SPELL_DRUID_IDOL_OF_WORSHIP, EFFECT_0)) - amount += cp * idol->GetAmount(); + else if (AuraEffect const* auraEffIdolOfWorship = caster->GetAuraEffect(SPELL_DRUID_IDOL_OF_WORSHIP, EFFECT_0)) + amount += cp * auraEffIdolOfWorship->GetAmount(); amount += int32(CalculatePct(caster->GetTotalAttackPowerValue(BASE_ATTACK), cp)); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 4c72d790059..a8a73310592 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -449,9 +449,9 @@ class spell_gen_bonked : public SpellScriptLoader target->CastSpell(target, SPELL_FOAM_SWORD_DEFEAT, true); target->RemoveAurasDueToSpell(SPELL_BONKED); - if (Aura const* aura = target->GetAura(SPELL_ON_GUARD)) + if (Aura const* auraOnGuard = target->GetAura(SPELL_ON_GUARD)) { - if (Item* item = target->GetItemByGuid(aura->GetCastItemGUID())) + if (Item* item = target->GetItemByGuid(auraOnGuard->GetCastItemGUID())) target->DestroyItemCount(item->GetEntry(), 1, true); } } @@ -2912,7 +2912,7 @@ class spell_gen_profession_research : public SpellScriptLoader // learn random explicit discovery recipe (if any) if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster)) - caster->learnSpell(discoveredSpellId, false); + caster->LearnSpell(discoveredSpellId, false); caster->UpdateCraftSkill(spellId); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index a17d7dce2ea..7139c9ecfba 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -383,6 +383,45 @@ class spell_item_echoes_of_light : public SpellScriptLoader } }; +// 7434 - Fate Rune of Unsurpassed Vigor +enum FateRuneOfUnsurpassedVigor +{ + SPELL_UNSURPASSED_VIGOR = 25733 +}; + +class spell_item_fate_rune_of_unsurpassed_vigor : public SpellScriptLoader +{ + public: + spell_item_fate_rune_of_unsurpassed_vigor() : SpellScriptLoader("spell_item_fate_rune_of_unsurpassed_vigor") { } + + class spell_item_fate_rune_of_unsurpassed_vigor_AuraScript : public AuraScript + { + PrepareAuraScript(spell_item_fate_rune_of_unsurpassed_vigor_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_UNSURPASSED_VIGOR)) + return false; + return true; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_UNSURPASSED_VIGOR, true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_fate_rune_of_unsurpassed_vigor_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_item_fate_rune_of_unsurpassed_vigor_AuraScript(); + } +}; + // http://www.wowhead.com/item=47499 Flask of the North // 67019 Flask of the North enum FlaskOfTheNorthSpells @@ -1413,7 +1452,7 @@ class spell_item_book_of_glyph_mastery : public SpellScriptLoader // learn random explicit discovery recipe (if any) if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster)) - caster->learnSpell(discoveredSpellId, false); + caster->LearnSpell(discoveredSpellId, false); } void Register() override @@ -2607,6 +2646,7 @@ void AddSC_item_spell_scripts() new spell_item_desperate_defense(); new spell_item_deviate_fish(); new spell_item_echoes_of_light(); + new spell_item_fate_rune_of_unsurpassed_vigor(); new spell_item_flask_of_the_north(); new spell_item_gnomish_death_ray(); new spell_item_make_a_wish(); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 447cb645e76..53af04c2e98 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -1211,11 +1211,11 @@ class spell_pal_sacred_shield : public SpellScriptLoader amount += int32(bonus); // Arena - Dampening - if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_ARENA_DAMPENING, EFFECT_0)) - AddPct(amount, dampening->GetAmount()); + if (AuraEffect const* auraEffArenaDampening = caster->GetAuraEffect(SPELL_GENERIC_ARENA_DAMPENING, EFFECT_0)) + AddPct(amount, auraEffArenaDampening->GetAmount()); // Battleground - Dampening - else if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_BATTLEGROUND_DAMPENING, EFFECT_0)) - AddPct(amount, dampening->GetAmount()); + else if (AuraEffect const* auraEffBattlegroudDampening = caster->GetAuraEffect(SPELL_GENERIC_BATTLEGROUND_DAMPENING, EFFECT_0)) + AddPct(amount, auraEffBattlegroudDampening->GetAmount()); } } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 61ff79c505e..a1c2d0e1d1c 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -34,6 +34,7 @@ enum ShamanSpells SPELL_SHAMAN_BIND_SIGHT = 6277, SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT = 52025, SPELL_SHAMAN_EARTH_SHIELD_HEAL = 379, + SPELL_SHAMAN_ELEMENTAL_MASTERY = 16166, SPELL_SHAMAN_EXHAUSTION = 57723, SPELL_SHAMAN_FIRE_NOVA_R1 = 1535, SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1 = 8349, @@ -767,6 +768,42 @@ class spell_sha_item_mana_surge : public SpellScriptLoader } }; +// 70811 - Item - Shaman T10 Elemental 2P Bonus +class spell_sha_item_t10_elemental_2p_bonus : public SpellScriptLoader +{ + public: + spell_sha_item_t10_elemental_2p_bonus() : SpellScriptLoader("spell_sha_item_t10_elemental_2p_bonus") { } + + class spell_sha_item_t10_elemental_2p_bonus_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_item_t10_elemental_2p_bonus_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ELEMENTAL_MASTERY)) + return false; + return true; + } + + void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + { + PreventDefaultAction(); + if (Player* target = GetTarget()->ToPlayer()) + target->ModifySpellCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, -aurEff->GetAmount()); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_sha_item_t10_elemental_2p_bonus_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_sha_item_t10_elemental_2p_bonus_AuraScript(); + } +}; + // 60103 - Lava Lash class spell_sha_lava_lash : public SpellScriptLoader { @@ -989,6 +1026,7 @@ void AddSC_shaman_spell_scripts() new spell_sha_item_lightning_shield(); new spell_sha_item_lightning_shield_trigger(); new spell_sha_item_mana_surge(); + new spell_sha_item_t10_elemental_2p_bonus(); new spell_sha_lava_lash(); new spell_sha_mana_spring_totem(); new spell_sha_mana_tide_totem(); diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp index 21489c714e2..083105b6aa4 100644 --- a/src/server/scripts/World/npc_professions.cpp +++ b/src/server/scripts/World/npc_professions.cpp @@ -260,90 +260,90 @@ void ProfessionUnlearnSpells(Player* player, uint32 type) switch (type) { case S_UNLEARN_WEAPON: // S_UNLEARN_WEAPON - player->removeSpell(36125); // Light Earthforged Blade - player->removeSpell(36128); // Light Emberforged Hammer - player->removeSpell(36126); // Light Skyforged Axe + player->RemoveSpell(36125); // Light Earthforged Blade + player->RemoveSpell(36128); // Light Emberforged Hammer + player->RemoveSpell(36126); // Light Skyforged Axe break; case S_UNLEARN_ARMOR: // S_UNLEARN_ARMOR - player->removeSpell(36122); // Earthforged Leggings - player->removeSpell(36129); // Heavy Earthforged Breastplate - player->removeSpell(36130); // Stormforged Hauberk - player->removeSpell(34533); // Breastplate of Kings - player->removeSpell(34529); // Nether Chain Shirt - player->removeSpell(34534); // Bulwark of Kings - player->removeSpell(36257); // Bulwark of the Ancient Kings - player->removeSpell(36256); // Embrace of the Twisting Nether - player->removeSpell(34530); // Twisting Nether Chain Shirt - player->removeSpell(36124); // Windforged Leggings + player->RemoveSpell(36122); // Earthforged Leggings + player->RemoveSpell(36129); // Heavy Earthforged Breastplate + player->RemoveSpell(36130); // Stormforged Hauberk + player->RemoveSpell(34533); // Breastplate of Kings + player->RemoveSpell(34529); // Nether Chain Shirt + player->RemoveSpell(34534); // Bulwark of Kings + player->RemoveSpell(36257); // Bulwark of the Ancient Kings + player->RemoveSpell(36256); // Embrace of the Twisting Nether + player->RemoveSpell(34530); // Twisting Nether Chain Shirt + player->RemoveSpell(36124); // Windforged Leggings break; case S_UNLEARN_HAMMER: // S_UNLEARN_HAMMER - player->removeSpell(36262); // Dragonstrike - player->removeSpell(34546); // Dragonmaw - player->removeSpell(34545); // Drakefist Hammer - player->removeSpell(36136); // Lavaforged Warhammer - player->removeSpell(34547); // Thunder - player->removeSpell(34567); // Deep Thunder - player->removeSpell(36263); // Stormherald - player->removeSpell(36137); // Great Earthforged Hammer + player->RemoveSpell(36262); // Dragonstrike + player->RemoveSpell(34546); // Dragonmaw + player->RemoveSpell(34545); // Drakefist Hammer + player->RemoveSpell(36136); // Lavaforged Warhammer + player->RemoveSpell(34547); // Thunder + player->RemoveSpell(34567); // Deep Thunder + player->RemoveSpell(36263); // Stormherald + player->RemoveSpell(36137); // Great Earthforged Hammer break; case S_UNLEARN_AXE: // S_UNLEARN_AXE - player->removeSpell(36260); // Wicked Edge of the Planes - player->removeSpell(34562); // Black Planar Edge - player->removeSpell(34541); // The Planar Edge - player->removeSpell(36134); // Stormforged Axe - player->removeSpell(36135); // Skyforged Great Axe - player->removeSpell(36261); // Bloodmoon - player->removeSpell(34543); // Lunar Crescent - player->removeSpell(34544); // Mooncleaver + player->RemoveSpell(36260); // Wicked Edge of the Planes + player->RemoveSpell(34562); // Black Planar Edge + player->RemoveSpell(34541); // The Planar Edge + player->RemoveSpell(36134); // Stormforged Axe + player->RemoveSpell(36135); // Skyforged Great Axe + player->RemoveSpell(36261); // Bloodmoon + player->RemoveSpell(34543); // Lunar Crescent + player->RemoveSpell(34544); // Mooncleaver break; case S_UNLEARN_SWORD: // S_UNLEARN_SWORD - player->removeSpell(36258); // Blazefury - player->removeSpell(34537); // Blazeguard - player->removeSpell(34535); // Fireguard - player->removeSpell(36131); // Windforged Rapier - player->removeSpell(36133); // Stoneforged Claymore - player->removeSpell(34538); // Lionheart Blade - player->removeSpell(34540); // Lionheart Champion - player->removeSpell(36259); // Lionheart Executioner + player->RemoveSpell(36258); // Blazefury + player->RemoveSpell(34537); // Blazeguard + player->RemoveSpell(34535); // Fireguard + player->RemoveSpell(36131); // Windforged Rapier + player->RemoveSpell(36133); // Stoneforged Claymore + player->RemoveSpell(34538); // Lionheart Blade + player->RemoveSpell(34540); // Lionheart Champion + player->RemoveSpell(36259); // Lionheart Executioner break; case S_UNLEARN_DRAGON: // S_UNLEARN_DRAGON - player->removeSpell(36076); // Dragonstrike Leggings - player->removeSpell(36079); // Golden Dragonstrike Breastplate - player->removeSpell(35576); // Ebon Netherscale Belt - player->removeSpell(35577); // Ebon Netherscale Bracers - player->removeSpell(35575); // Ebon Netherscale Breastplate - player->removeSpell(35582); // Netherstrike Belt - player->removeSpell(35584); // Netherstrike Bracers - player->removeSpell(35580); // Netherstrike Breastplate + player->RemoveSpell(36076); // Dragonstrike Leggings + player->RemoveSpell(36079); // Golden Dragonstrike Breastplate + player->RemoveSpell(35576); // Ebon Netherscale Belt + player->RemoveSpell(35577); // Ebon Netherscale Bracers + player->RemoveSpell(35575); // Ebon Netherscale Breastplate + player->RemoveSpell(35582); // Netherstrike Belt + player->RemoveSpell(35584); // Netherstrike Bracers + player->RemoveSpell(35580); // Netherstrike Breastplate break; case S_UNLEARN_ELEMENTAL: // S_UNLEARN_ELEMENTAL - player->removeSpell(36074); // Blackstorm Leggings - player->removeSpell(36077); // Primalstorm Breastplate - player->removeSpell(35590); // Primalstrike Belt - player->removeSpell(35591); // Primalstrike Bracers - player->removeSpell(35589); // Primalstrike Vest + player->RemoveSpell(36074); // Blackstorm Leggings + player->RemoveSpell(36077); // Primalstorm Breastplate + player->RemoveSpell(35590); // Primalstrike Belt + player->RemoveSpell(35591); // Primalstrike Bracers + player->RemoveSpell(35589); // Primalstrike Vest break; case S_UNLEARN_TRIBAL: // S_UNLEARN_TRIBAL - player->removeSpell(35585); // Windhawk Hauberk - player->removeSpell(35587); // Windhawk Belt - player->removeSpell(35588); // Windhawk Bracers - player->removeSpell(36075); // Wildfeather Leggings - player->removeSpell(36078); // Living Crystal Breastplate + player->RemoveSpell(35585); // Windhawk Hauberk + player->RemoveSpell(35587); // Windhawk Belt + player->RemoveSpell(35588); // Windhawk Bracers + player->RemoveSpell(36075); // Wildfeather Leggings + player->RemoveSpell(36078); // Living Crystal Breastplate break; case S_UNLEARN_SPELLFIRE: // S_UNLEARN_SPELLFIRE - player->removeSpell(26752); // Spellfire Belt - player->removeSpell(26753); // Spellfire Gloves - player->removeSpell(26754); // Spellfire Robe + player->RemoveSpell(26752); // Spellfire Belt + player->RemoveSpell(26753); // Spellfire Gloves + player->RemoveSpell(26754); // Spellfire Robe break; case S_UNLEARN_MOONCLOTH: // S_UNLEARN_MOONCLOTH - player->removeSpell(26760); // Primal Mooncloth Belt - player->removeSpell(26761); // Primal Mooncloth Shoulders - player->removeSpell(26762); // Primal Mooncloth Robe + player->RemoveSpell(26760); // Primal Mooncloth Belt + player->RemoveSpell(26761); // Primal Mooncloth Shoulders + player->RemoveSpell(26762); // Primal Mooncloth Robe break; case S_UNLEARN_SHADOWEAVE: // S_UNLEARN_SHADOWEAVE - player->removeSpell(26756); // Frozen Shadoweave Shoulders - player->removeSpell(26757); // Frozen Shadoweave Boots - player->removeSpell(26758); // Frozen Shadoweave Robe + player->RemoveSpell(26756); // Frozen Shadoweave Shoulders + player->RemoveSpell(26757); // Frozen Shadoweave Boots + player->RemoveSpell(26758); // Frozen Shadoweave Robe break; } } -- cgit v1.2.3