diff options
Diffstat (limited to 'src')
38 files changed, 1320 insertions, 1541 deletions
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 046af770aff..5ef3426d602 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -17,19 +17,18 @@ #include "Battlefield.h" #include "BattlefieldMgr.h" -#include "ObjectAccessor.h" -#include "ObjectMgr.h" -#include "Map.h" -#include "MapManager.h" -#include "Group.h" -#include "WorldPacket.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" +#include "Battleground.h" #include "CellImpl.h" #include "CreatureTextMgr.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "Group.h" #include "GroupMgr.h" +#include "Map.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "WorldPacket.h" Battlefield::Battlefield() { @@ -202,7 +201,7 @@ void Battlefield::InvitePlayersInZoneToQueue() { for (uint8 team = 0; team < 2; ++team) for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) InvitePlayerToQueue(player); } @@ -221,7 +220,7 @@ void Battlefield::InvitePlayersInQueueToWar() { for (GuidSet::const_iterator itr = m_PlayersInQueue[team].begin(); itr != m_PlayersInQueue[team].end(); ++itr) { - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) { if (m_PlayersInWar[player->GetTeamId()].size() + m_InvitedPlayers[player->GetTeamId()].size() < m_MaxPlayer) InvitePlayerToWar(player); @@ -240,7 +239,7 @@ void Battlefield::InvitePlayersInZoneToWar() for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) { - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) { if (m_PlayersInWar[player->GetTeamId()].count(player->GetGUID()) || m_InvitedPlayers[player->GetTeamId()].count(player->GetGUID())) continue; @@ -284,9 +283,9 @@ void Battlefield::InvitePlayerToWar(Player* player) player->GetSession()->SendBfInvitePlayerToWar(m_Guid, m_ZoneId, m_TimeForAcceptInvite); } -void Battlefield::InitStalker(uint32 entry, float x, float y, float z, float o) +void Battlefield::InitStalker(uint32 entry, Position const& pos) { - if (Creature* creature = SpawnCreature(entry, x, y, z, o, TEAM_NEUTRAL)) + if (Creature* creature = SpawnCreature(entry, pos, TEAM_NEUTRAL)) StalkerGuid = creature->GetGUID(); else TC_LOG_ERROR("bg.battlefield", "Battlefield::InitStalker: could not spawn Stalker (Creature entry %u), zone messeges will be un-available", entry); @@ -296,14 +295,14 @@ void Battlefield::KickAfkPlayers() { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) if (player->isAFK()) KickPlayerFromBattlefield(*itr); } void Battlefield::KickPlayerFromBattlefield(uint64 guid) { - if (Player* player = sObjectAccessor->FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindPlayer(guid)) if (player->GetZoneId() == GetZoneId()) player->TeleportTo(KickPosition); } @@ -363,8 +362,8 @@ void Battlefield::DoPlaySoundToAll(uint32 SoundID) for (int team = 0; team < BG_TEAMS_COUNT; team++) for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) - player->GetSession()->SendPacket(&data); + if (Player* player = ObjectAccessor::FindPlayer(*itr)) + player->SendDirectMessage(&data); } bool Battlefield::HasPlayer(Player* player) const @@ -412,13 +411,13 @@ void Battlefield::TeamCastSpell(TeamId team, int32 spellId) if (spellId > 0) { for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->CastSpell(player, uint32(spellId), true); } else { for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->RemoveAuraFromStack(uint32(-spellId)); } } @@ -427,24 +426,24 @@ void Battlefield::BroadcastPacketToZone(WorldPacket& data) const { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) - player->GetSession()->SendPacket(&data); + if (Player* player = ObjectAccessor::FindPlayer(*itr)) + player->SendDirectMessage(&data); } void Battlefield::BroadcastPacketToQueue(WorldPacket& data) const { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_PlayersInQueue[team].begin(); itr != m_PlayersInQueue[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) - player->GetSession()->SendPacket(&data); + if (Player* player = ObjectAccessor::FindPlayer(*itr)) + player->SendDirectMessage(&data); } void Battlefield::BroadcastPacketToWar(WorldPacket& data) const { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) - player->GetSession()->SendPacket(&data); + if (Player* player = ObjectAccessor::FindPlayer(*itr)) + player->SendDirectMessage(&data); } void Battlefield::SendWarningToAllInZone(uint32 entry) @@ -465,7 +464,7 @@ void Battlefield::SendUpdateWorldState(uint32 field, uint32 value) { for (uint8 i = 0; i < BG_TEAMS_COUNT; ++i) for (GuidSet::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->SendUpdateWorldState(field, value); } @@ -635,8 +634,7 @@ void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, uint64 guid) uint32 time = m_LastResurrectTimer; // resurrect every 30 seconds data << guid << time; - ASSERT(player && player->GetSession()); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } // ---------------------- @@ -681,7 +679,7 @@ void BfGraveyard::AddPlayer(uint64 playerGuid) { m_ResurrectQueue.insert(playerGuid); - if (Player* player = sObjectAccessor->FindPlayer(playerGuid)) + if (Player* player = ObjectAccessor::FindPlayer(playerGuid)) player->CastSpell(player, SPELL_WAITING_FOR_RESURRECT, true); } } @@ -690,7 +688,7 @@ void BfGraveyard::RemovePlayer(uint64 playerGuid) { m_ResurrectQueue.erase(m_ResurrectQueue.find(playerGuid)); - if (Player* player = sObjectAccessor->FindPlayer(playerGuid)) + if (Player* player = ObjectAccessor::FindPlayer(playerGuid)) player->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT); } @@ -702,7 +700,7 @@ void BfGraveyard::Resurrect() for (GuidSet::const_iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr) { // Get player object from his guid - Player* player = sObjectAccessor->FindPlayer(*itr); + Player* player = ObjectAccessor::FindPlayer(*itr); if (!player) continue; @@ -743,7 +741,7 @@ void BfGraveyard::RelocateDeadPlayers() WorldSafeLocsEntry const* closestGrave = NULL; for (GuidSet::const_iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr) { - Player* player = sObjectAccessor->FindPlayer(*itr); + Player* player = ObjectAccessor::FindPlayer(*itr); if (!player) continue; @@ -776,19 +774,19 @@ bool BfGraveyard::HasNpc(uint64 guid) // ********************** Misc *************************** // ******************************************************* -Creature* Battlefield::SpawnCreature(uint32 entry, const Position& pos, TeamId team) +Creature* Battlefield::SpawnCreature(uint32 entry, Position const& pos, TeamId teamId) { - return SpawnCreature(entry, pos.m_positionX, pos.m_positionY, pos.m_positionZ, pos.m_orientation, team); + return SpawnCreature(entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teamId); } -Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId /*team*/) +Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId /*teamId*/) { //Get map object Map* map = sMapMgr->CreateBaseMap(m_MapId); if (!map) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Can't create creature entry: %u map not found", entry); - return 0; + return nullptr; } Creature* creature = new Creature(); @@ -796,7 +794,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Can't create creature entry: %u", entry); delete creature; - return NULL; + return nullptr; } creature->SetHomePosition(x, y, z, o); @@ -804,7 +802,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl if (!cinfo) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: entry %u does not exist.", entry); - return NULL; + return nullptr; } // Set creature in world @@ -986,7 +984,7 @@ bool BfCapturePoint::Update(uint32 diff) { for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end();) { - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) { if (!capturePoint->IsWithinDistInMap(player, radius) || !player->IsOutdoorPvPActive()) itr = HandlePlayerLeave(player); @@ -1099,7 +1097,7 @@ void BfCapturePoint::SendUpdateWorldState(uint32 field, uint32 value) { for (uint8 team = 0; team < 2; ++team) for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr) // send to all players present in the area - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->SendUpdateWorldState(field, value); } @@ -1120,7 +1118,7 @@ void BfCapturePoint::SendObjectiveComplete(uint32 id, uint64 guid) // send to all players present in the area for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->KilledMonsterCredit(id, guid); } diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 1b142d1c89f..0aa6a51d6bf 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -18,13 +18,8 @@ #ifndef BATTLEFIELD_H_ #define BATTLEFIELD_H_ -#include "Utilities/Util.h" #include "SharedDefines.h" #include "ZoneScript.h" -#include "WorldPacket.h" -#include "GameObject.h" -#include "Battleground.h" -#include "ObjectAccessor.h" enum BattlefieldTypes { @@ -111,7 +106,7 @@ class BfCapturePoint bool DelCapturePoint(); // active Players in the area of the objective, 0 - alliance, 1 - horde - GuidSet m_activePlayers[2]; + GuidSet m_activePlayers[BG_TEAMS_COUNT]; // Total shift needed to capture the objective float m_maxValue; @@ -183,7 +178,7 @@ class BfGraveyard protected: TeamId m_ControlTeam; uint32 m_GraveyardId; - uint64 m_SpiritGuide[2]; + uint64 m_SpiritGuide[BG_TEAMS_COUNT]; GuidSet m_ResurrectQueue; Battlefield* m_Bf; }; @@ -287,8 +282,8 @@ class Battlefield : public ZoneScript BfGraveyard* GetGraveyardById(uint32 id) const; // Misc methods - virtual Creature* SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId team); - Creature* SpawnCreature(uint32 entry, const Position& pos, TeamId team); + virtual Creature* SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId /*teamId*/); + Creature* SpawnCreature(uint32 entry, Position const& pos, TeamId /*teamId*/); GameObject* SpawnGameObject(uint32 entry, float x, float y, float z, float o); Creature* GetCreature(uint64 GUID); @@ -346,7 +341,7 @@ class Battlefield : public ZoneScript void InvitePlayerToQueue(Player* player); void InvitePlayerToWar(Player* player); - void InitStalker(uint32 entry, float x, float y, float z, float o); + void InitStalker(uint32 entry, Position const& pos); protected: uint64 m_Guid; diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index b16ac1e84de..3e603f4bb28 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -21,13 +21,13 @@ #include "BattlefieldWG.h" #include "AchievementMgr.h" +#include "Battleground.h" #include "MapManager.h" #include "ObjectMgr.h" #include "Opcodes.h" #include "Player.h" #include "SpellAuras.h" #include "TemporarySummon.h" -#include "Vehicle.h" #include "WorldSession.h" BattlefieldWG::~BattlefieldWG() @@ -47,7 +47,7 @@ bool BattlefieldWG::SetupBattlefield() m_MapId = BATTLEFIELD_WG_MAPID; m_Map = sMapMgr->FindMap(m_MapId, 0); - InitStalker(BATTLEFIELD_WG_NPC_STALKER, WintergraspStalkerPos[0], WintergraspStalkerPos[1], WintergraspStalkerPos[2], WintergraspStalkerPos[3]); + InitStalker(BATTLEFIELD_WG_NPC_STALKER, WintergraspStalkerPos); m_MaxPlayer = sWorld->getIntConfig(CONFIG_WINTERGRASP_PLR_MAX); m_IsEnabled = sWorld->getBoolConfig(CONFIG_WINTERGRASP_ENABLE); @@ -847,7 +847,7 @@ void BattlefieldWG::SendInitWorldStatesTo(Player* player) FillInitialWorldStates(data); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } void BattlefieldWG::SendInitWorldStatesToAll() @@ -1060,3 +1060,572 @@ BfGraveyardWG::BfGraveyardWG(BattlefieldWG* battlefield) : BfGraveyard(battlefie m_Bf = battlefield; m_GossipTextId = 0; } + +BfWGGameObjectBuilding::BfWGGameObjectBuilding(BattlefieldWG* wg) +{ + m_WG = wg; + m_Team = 0; + m_BuildGUID = 0; + m_Type = 0; + m_WorldState = 0; + m_State = 0; + m_NameId = 0; +} + +void BfWGGameObjectBuilding::Rebuild() +{ + switch (m_Type) + { + case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER: + case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST: + case BATTLEFIELD_WG_OBJECTTYPE_DOOR: + case BATTLEFIELD_WG_OBJECTTYPE_WALL: + m_Team = m_WG->GetDefenderTeam(); // Objects that are part of the keep should be the defender's + break; + case BATTLEFIELD_WG_OBJECTTYPE_TOWER: + m_Team = m_WG->GetAttackerTeam(); // The towers in the south should be the attacker's + break; + default: + m_Team = TEAM_NEUTRAL; + break; + } + + if (GameObject* build = m_WG->GetGameObject(m_BuildGUID)) + { + // Rebuild gameobject + if (build->IsDestructibleBuilding()) + { + build->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, NULL, true); + if (build->GetEntry() == GO_WINTERGRASP_VAULT_GATE) + if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f)) + go->SetGoState(GO_STATE_READY); + + // Update worldstate + m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT - (m_Team * 3); + m_WG->SendUpdateWorldState(m_WorldState, m_State); + } + UpdateCreatureAndGo(); + build->SetFaction(WintergraspFaction[m_Team]); + } +} + +void BfWGGameObjectBuilding::Damaged() +{ + // Update worldstate + m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE - (m_Team * 3); + m_WG->SendUpdateWorldState(m_WorldState, m_State); + + // Send warning message + if (m_NameId) // tower damage + name + m_WG->SendWarningToAllInZone(m_NameId); + + for (uint64 guid : m_CreatureTopList[m_WG->GetAttackerTeam()]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->HideNpc(creature); + + for (uint64 guid : m_TurretTopList) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->HideNpc(creature); + + if (m_Type == BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER) + m_WG->UpdateDamagedTowerCount(m_WG->GetDefenderTeam()); + else if (m_Type == BATTLEFIELD_WG_OBJECTTYPE_TOWER) + m_WG->UpdateDamagedTowerCount(m_WG->GetAttackerTeam()); +} + +void BfWGGameObjectBuilding::Destroyed() +{ + // Update worldstate + m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY - (m_Team * 3); + m_WG->SendUpdateWorldState(m_WorldState, m_State); + + // Warn players + if (m_NameId) + m_WG->SendWarningToAllInZone(m_NameId); + + switch (m_Type) + { + // Inform the global wintergrasp script of the destruction of this object + case BATTLEFIELD_WG_OBJECTTYPE_TOWER: + case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER: + m_WG->UpdatedDestroyedTowerCount(TeamId(m_Team)); + break; + case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST: + if (GameObject* build = m_WG->GetGameObject(m_BuildGUID)) + if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f)) + go->SetGoState(GO_STATE_ACTIVE); + m_WG->SetRelicInteractible(true); + if (m_WG->GetRelic()) + m_WG->GetRelic()->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + else + TC_LOG_ERROR("misc", "BattlefieldWG: Relic not found."); + break; + } + + m_WG->BrokenWallOrTower(TeamId(m_Team)); +} + +void BfWGGameObjectBuilding::Init(GameObject* go, uint32 type, uint32 worldstate, uint32 nameId) +{ + if (!go) + return; + + // GameObject associated to object + m_BuildGUID = go->GetGUID(); + + // Type of building (WALL/TOWER/DOOR) + m_Type = type; + + // WorldState for client (icon on map) + m_WorldState = worldstate; + + // NameId for Warning text + m_NameId = nameId; + + switch (m_Type) + { + case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER: + case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST: + case BATTLEFIELD_WG_OBJECTTYPE_DOOR: + case BATTLEFIELD_WG_OBJECTTYPE_WALL: + m_Team = m_WG->GetDefenderTeam(); // Objects that are part of the keep should be the defender's + break; + case BATTLEFIELD_WG_OBJECTTYPE_TOWER: + m_Team = m_WG->GetAttackerTeam(); // The towers in the south should be the attacker's + break; + default: + m_Team = TEAM_NEUTRAL; + break; + } + + m_State = sWorld->getWorldState(m_WorldState); + switch (m_State) + { + case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT: + case BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT: + go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, NULL, true); + break; + case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY: + case BATTLEFIELD_WG_OBJECTSTATE_HORDE_DESTROY: + go->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED); + break; + case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE: + case BATTLEFIELD_WG_OBJECTSTATE_HORDE_DAMAGE: + go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); + break; + } + + int32 towerId = -1; + switch (go->GetEntry()) + { + case GO_WINTERGRASP_FORTRESS_TOWER_1: + towerId = 0; + break; + case GO_WINTERGRASP_FORTRESS_TOWER_2: + towerId = 1; + break; + case GO_WINTERGRASP_FORTRESS_TOWER_3: + towerId = 2; + break; + case GO_WINTERGRASP_FORTRESS_TOWER_4: + towerId = 3; + break; + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + towerId = 4; + break; + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + towerId = 5; + break; + case GO_WINTERGRASP_FLAMEWATCH_TOWER: + towerId = 6; + break; + } + + if (towerId > 3) // Attacker towers + { + // Spawn associate gameobjects + for (uint8 i = 0; i < AttackTowers[towerId - 4].nbObject; i++) + { + WintergraspObjectPositionData const& gobData = AttackTowers[towerId - 4].GameObject[i]; + 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 + for (uint8 i = 0; i < AttackTowers[towerId - 4].nbCreatureBottom; i++) + { + WintergraspObjectPositionData const& creatureData = AttackTowers[towerId - 4].CreatureBottom[i]; + if (Creature* creature = m_WG->SpawnCreature(creatureData.entryHorde, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_HORDE)) + m_CreatureBottomList[TEAM_HORDE].insert(creature->GetGUID()); + if (Creature* creature = m_WG->SpawnCreature(creatureData.entryAlliance, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_ALLIANCE)) + m_CreatureBottomList[TEAM_ALLIANCE].insert(creature->GetGUID()); + } + + // Spawn associate npc top + for (uint8 i = 0; i < AttackTowers[towerId - 4].nbCreatureTop; i++) + { + WintergraspObjectPositionData const& creatureData = AttackTowers[towerId - 4].CreatureTop[i]; + if (Creature* creature = m_WG->SpawnCreature(creatureData.entryHorde, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_HORDE)) + m_CreatureTopList[TEAM_HORDE].insert(creature->GetGUID()); + if (Creature* creature = m_WG->SpawnCreature(creatureData.entryAlliance, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_ALLIANCE)) + m_CreatureTopList[TEAM_ALLIANCE].insert(creature->GetGUID()); + } + } + + if (towerId >= 0) + { + // Spawn Turret bottom + for (uint8 i = 0; i < TowerCannon[towerId].nbTowerCannonBottom; i++) + { + Position const& turretPos = TowerCannon[towerId].TowerCannonBottom[i]; + if (Creature* turret = m_WG->SpawnCreature(NPC_WINTERGRASP_TOWER_CANNON, turretPos, TEAM_ALLIANCE)) + { + m_TowerCannonBottomList.insert(turret->GetGUID()); + switch (go->GetEntry()) + { + case GO_WINTERGRASP_FORTRESS_TOWER_1: + case GO_WINTERGRASP_FORTRESS_TOWER_2: + case GO_WINTERGRASP_FORTRESS_TOWER_3: + case GO_WINTERGRASP_FORTRESS_TOWER_4: + turret->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); + break; + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: + turret->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); + break; + } + m_WG->HideNpc(turret); + } + } + + // Spawn Turret top + for (uint8 i = 0; i < TowerCannon[towerId].nbTurretTop; i++) + { + Position const& towerCannonPos = TowerCannon[towerId].TurretTop[i]; + if (Creature* turret = m_WG->SpawnCreature(NPC_WINTERGRASP_TOWER_CANNON, towerCannonPos, TeamId(0))) + { + m_TurretTopList.insert(turret->GetGUID()); + switch (go->GetEntry()) + { + case GO_WINTERGRASP_FORTRESS_TOWER_1: + case GO_WINTERGRASP_FORTRESS_TOWER_2: + case GO_WINTERGRASP_FORTRESS_TOWER_3: + case GO_WINTERGRASP_FORTRESS_TOWER_4: + turret->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); + break; + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: + turret->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); + break; + } + m_WG->HideNpc(turret); + } + } + UpdateCreatureAndGo(); + } +} + +void BfWGGameObjectBuilding::UpdateCreatureAndGo() +{ + for (uint64 guid : m_CreatureTopList[m_WG->GetDefenderTeam()]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->HideNpc(creature); + + for (uint64 guid : m_CreatureTopList[m_WG->GetAttackerTeam()]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->ShowNpc(creature, true); + + for (uint64 guid : m_CreatureBottomList[m_WG->GetDefenderTeam()]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->HideNpc(creature); + + for (uint64 guid : m_CreatureBottomList[m_WG->GetAttackerTeam()]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->ShowNpc(creature, true); + + for (uint64 guid : m_GameObjectList[m_WG->GetDefenderTeam()]) + if (GameObject* object = m_WG->GetGameObject(guid)) + object->SetRespawnTime(RESPAWN_ONE_DAY); + + for (uint64 guid : m_GameObjectList[m_WG->GetAttackerTeam()]) + if (GameObject* object = m_WG->GetGameObject(guid)) + object->SetRespawnTime(RESPAWN_IMMEDIATELY); +} + +void BfWGGameObjectBuilding::UpdateTurretAttack(bool disable) +{ + for (uint64 guid : m_TowerCannonBottomList) + { + if (Creature* creature = m_WG->GetCreature(guid)) + { + if (GameObject* build = m_WG->GetGameObject(m_BuildGUID)) + { + if (disable) + m_WG->HideNpc(creature); + else + m_WG->ShowNpc(creature, true); + + switch (build->GetEntry()) + { + case GO_WINTERGRASP_FORTRESS_TOWER_1: + case GO_WINTERGRASP_FORTRESS_TOWER_2: + case GO_WINTERGRASP_FORTRESS_TOWER_3: + case GO_WINTERGRASP_FORTRESS_TOWER_4: + { + creature->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); + break; + } + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: + { + creature->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); + break; + } + } + } + } + } + + for (uint64 guid : m_TurretTopList) + { + if (Creature* creature = m_WG->GetCreature(guid)) + { + if (GameObject* build = m_WG->GetGameObject(m_BuildGUID)) + { + if (disable) + m_WG->HideNpc(creature); + else + m_WG->ShowNpc(creature, true); + + switch (build->GetEntry()) + { + case GO_WINTERGRASP_FORTRESS_TOWER_1: + case GO_WINTERGRASP_FORTRESS_TOWER_2: + case GO_WINTERGRASP_FORTRESS_TOWER_3: + case GO_WINTERGRASP_FORTRESS_TOWER_4: + { + creature->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); + break; + } + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: + { + creature->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); + break; + } + } + } + } + } +} + +void BfWGGameObjectBuilding::Save() +{ + sWorld->setWorldState(m_WorldState, m_State); +} + +WGWorkshop::WGWorkshop(BattlefieldWG* _bf, uint8 _workshopId) +{ + ASSERT(_bf || _workshopId < WG_MAX_WORKSHOP); + + bf = _bf; + workshopId = _workshopId; + teamControl = BATTLEFIELD_WG_TEAM_NEUTRAL; + state = BATTLEFIELD_WG_OBJECTSTATE_NONE; +} + +void WGWorkshop::GiveControlTo(uint8 team, bool init) +{ + switch (team) + { + case BATTLEFIELD_WG_TEAM_NEUTRAL: + { + // Send warning message to all player to inform a faction attack to a workshop + // alliance / horde attacking a workshop + bf->SendWarningToAllInZone(teamControl ? WorkshopsData[workshopId].text : WorkshopsData[workshopId].text + 1); + break; + } + case BATTLEFIELD_WG_TEAM_ALLIANCE: + case BATTLEFIELD_WG_TEAM_HORDE: + { + // Updating worldstate + state = team == BATTLEFIELD_WG_TEAM_ALLIANCE ? BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT : BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT; + bf->SendUpdateWorldState(WorkshopsData[workshopId].worldstate, state); + + // Warning message + if (!init) // workshop taken - alliance + bf->SendWarningToAllInZone(team == BATTLEFIELD_WG_TEAM_ALLIANCE ? WorkshopsData[workshopId].text : WorkshopsData[workshopId].text + 1); + + // Found associate graveyard and update it + if (workshopId < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) + if (bf->GetGraveyardById(workshopId)) + bf->GetGraveyardById(workshopId)->GiveControlTo(team == BATTLEFIELD_WG_TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE); + + teamControl = team; + break; + } + } + + if (!init) + bf->UpdateCounterVehicle(false); +} + +void WGWorkshop::UpdateGraveyardAndWorkshop() +{ + if (workshopId < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) + bf->GetGraveyardById(workshopId)->GiveControlTo(TeamId(teamControl)); + else + GiveControlTo(bf->GetDefenderTeam(), true); +} + +void WGWorkshop::Save() +{ + sWorld->setWorldState(WorkshopsData[workshopId].worldstate, state); +} + +WintergraspWorkshopData::WintergraspWorkshopData(BattlefieldWG* wg) +{ + m_WG = wg; + m_BuildGUID = 0; + m_Type = 0; + m_State = 0; + m_WorldState = 0; + m_TeamControl = 0; + m_NameId = 0; +} + +void WintergraspWorkshopData::AddCreature(WintergraspObjectPositionData const& obj) +{ + if (Creature* creature = m_WG->SpawnCreature(obj.entryHorde, obj.x, obj.y, obj.z, obj.o, TEAM_HORDE)) + m_CreatureOnPoint[TEAM_HORDE].insert(creature->GetGUID()); + + if (Creature* creature = m_WG->SpawnCreature(obj.entryAlliance, obj.x, obj.y, obj.z, obj.o, TEAM_ALLIANCE)) + m_CreatureOnPoint[TEAM_ALLIANCE].insert(creature->GetGUID()); +} + +void WintergraspWorkshopData::AddGameObject(WintergraspObjectPositionData const& obj) +{ + if (GameObject* gameobject = m_WG->SpawnGameObject(obj.entryHorde, obj.x, obj.y, obj.z, obj.o)) + m_GameObjectOnPoint[TEAM_HORDE].insert(gameobject->GetGUID()); + if (GameObject* gameobject = m_WG->SpawnGameObject(obj.entryAlliance, obj.x, obj.y, obj.z, obj.o)) + m_GameObjectOnPoint[TEAM_ALLIANCE].insert(gameobject->GetGUID()); +} + +void WintergraspWorkshopData::Init(uint32 worldstate, uint32 type, uint32 nameId) +{ + m_WorldState = worldstate; + m_Type = type; + m_NameId = nameId; +} + +void WintergraspWorkshopData::GiveControlTo(uint8 team, bool init) +{ + switch (team) + { + case BATTLEFIELD_WG_TEAM_NEUTRAL: + { + // Send warning message to all player for inform a faction attack a workshop + // alliance / horde attacking workshop + m_WG->SendWarningToAllInZone(m_TeamControl ? m_NameId : m_NameId + 1); + break; + } + case BATTLEFIELD_WG_TEAM_ALLIANCE: + { + // Show Alliance creature + for (uint64 guid : m_CreatureOnPoint[TEAM_ALLIANCE]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->ShowNpc(creature, creature->GetEntry() != 30499); + + // Hide Horde creature + for (uint64 guid : m_CreatureOnPoint[TEAM_HORDE]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->HideNpc(creature); + + // Show Alliance gameobject + for (uint64 guid : m_GameObjectOnPoint[TEAM_ALLIANCE]) + if (GameObject* object = m_WG->GetGameObject(guid)) + object->SetRespawnTime(RESPAWN_IMMEDIATELY); + + // Hide Horde gameobject + for (uint64 guid : m_GameObjectOnPoint[TEAM_HORDE]) + if (GameObject* object = m_WG->GetGameObject(guid)) + object->SetRespawnTime(RESPAWN_ONE_DAY); + + + // Updating worldstate + m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT; + m_WG->SendUpdateWorldState(m_WorldState, m_State); + + // Warning message + if (!init) // workshop taken - alliance + m_WG->SendWarningToAllInZone(m_NameId); + + // Found associate graveyard and update it + if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) + if (m_WG->GetGraveyardById(m_Type)) + m_WG->GetGraveyardById(m_Type)->GiveControlTo(TEAM_ALLIANCE); + + m_TeamControl = team; + break; + } + case BATTLEFIELD_WG_TEAM_HORDE: + { + // Show Horde creature + for (uint64 guid : m_CreatureOnPoint[TEAM_HORDE]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->ShowNpc(creature, creature->GetEntry() != 30400); + + // Hide Alliance creature + for (uint64 guid : m_CreatureOnPoint[TEAM_ALLIANCE]) + if (Creature* creature = m_WG->GetCreature(guid)) + m_WG->HideNpc(creature); + + // Hide Alliance gameobject + for (uint64 guid : m_GameObjectOnPoint[TEAM_ALLIANCE]) + if (GameObject* object = m_WG->GetGameObject(guid)) + object->SetRespawnTime(RESPAWN_ONE_DAY); + + // Show Horde gameobject + for (uint64 guid : m_GameObjectOnPoint[TEAM_HORDE]) + if (GameObject* object = m_WG->GetGameObject(guid)) + object->SetRespawnTime(RESPAWN_IMMEDIATELY); + + // Update worldstate + m_State = BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT; + m_WG->SendUpdateWorldState(m_WorldState, m_State); + + // Warning message + if (!init) // workshop taken - horde + m_WG->SendWarningToAllInZone(m_NameId + 1); + + // Update graveyard control + if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) + if (m_WG->GetGraveyardById(m_Type)) + m_WG->GetGraveyardById(m_Type)->GiveControlTo(TEAM_HORDE); + + m_TeamControl = team; + break; + } + } + if (!init) + m_WG->UpdateCounterVehicle(false); +} + +void WintergraspWorkshopData::UpdateGraveyardAndWorkshop() +{ + if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) + m_WG->GetGraveyardById(m_Type)->GiveControlTo(TeamId(m_TeamControl)); + else + GiveControlTo(m_WG->GetDefenderTeam(), true); +} + +void WintergraspWorkshopData::Save() +{ + sWorld->setWorldState(m_WorldState, m_State); +} diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index fa28ce17e4a..03c2992e812 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -18,10 +18,7 @@ #ifndef BATTLEFIELD_WG_ #define BATTLEFIELD_WG_ -#include "ObjectAccessor.h" -#include "WorldPacket.h" #include "Battlefield.h" -#include "World.h" class Group; class BattlefieldWG; @@ -151,10 +148,11 @@ class BfGraveyardWG : public BfGraveyard public: BfGraveyardWG(BattlefieldWG* Bf); - void SetTextId(int32 textid) { m_GossipTextId = textid; } - int32 GetTextId() { return m_GossipTextId; } + void SetTextId(uint32 textId) { m_GossipTextId = textId; } + uint32 GetTextId() { return m_GossipTextId; } + protected: - int32 m_GossipTextId; + uint32 m_GossipTextId; }; enum WGGraveyardId @@ -233,6 +231,7 @@ uint32 const WGQuest[2][6] = { 13186, 13181, 13222, 13538, 13177, 13179 }, { 13185, 13183, 13223, 13539, 13178, 13180 }, }; + // 7 in sql, 7 in header BfWGCoordGY const WGGraveYard[BATTLEFIELD_WG_GRAVEYARD_MAX] = { @@ -419,13 +418,13 @@ class BattlefieldWG : public Battlefield Workshop WorkshopsList; GuidSet DefenderPortalList; - GuidSet m_KeepGameObject[2]; + GuidSet m_KeepGameObject[BG_TEAMS_COUNT]; GameObjectBuilding BuildingsInZone; - GuidSet m_vehicles[2]; + GuidSet m_vehicles[BG_TEAMS_COUNT]; GuidSet CanonList; - GuidSet KeepCreature[2]; - GuidSet OutsideCreature[2]; + GuidSet KeepCreature[BG_TEAMS_COUNT]; + GuidSet OutsideCreature[BG_TEAMS_COUNT]; uint32 m_tenacityStack; uint32 m_saveTimer; @@ -437,7 +436,8 @@ uint32 const VehNumWorldState[] = { 3680, 3490 }; uint32 const MaxVehNumWorldState[] = { 3681, 3491 }; uint32 const ClockWorldState[] = { 3781, 4354 }; uint32 const WintergraspFaction[] = { 1732, 1735, 35 }; -float const WintergraspStalkerPos[] = { 4948.985f, 2937.789f, 550.5172f, 1.815142f }; + +Position const WintergraspStalkerPos = { 4948.985f, 2937.789f, 550.5172f, 1.815142f }; uint8 const WG_MAX_OBJ = 32; uint8 const WG_MAX_TURRET = 15; @@ -445,7 +445,7 @@ uint8 const WG_MAX_KEEP_NPC = 39; uint8 const WG_MAX_OUTSIDE_NPC = 14; uint8 const WG_OUTSIDE_ALLIANCE_NPC = 7; uint8 const WG_MAX_TELEPORTER = 12; -uint8 const WG_MAX_WORKSHOP = 6; +uint8 const WG_MAX_WORKSHOP = 6; enum WintergraspGameObjectBuildingType { @@ -1059,16 +1059,7 @@ const WGWorkshopData WorkshopsData[WG_MAX_WORKSHOP] = // Structure for different buildings that can be destroyed during battle struct BfWGGameObjectBuilding { - BfWGGameObjectBuilding(BattlefieldWG* WG) - { - m_WG = WG; - m_Team = 0; - m_BuildGUID = 0; - m_Type = 0; - m_WorldState = 0; - m_State = 0; - m_NameId = 0; - } + BfWGGameObjectBuilding(BattlefieldWG* wg); // the team that controls this point uint8 m_Team; @@ -1100,365 +1091,21 @@ struct BfWGGameObjectBuilding GuidSet m_TowerCannonBottomList; GuidSet m_TurretTopList; - void Rebuild() - { - switch (m_Type) - { - case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER: - case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST: - case BATTLEFIELD_WG_OBJECTTYPE_DOOR: - case BATTLEFIELD_WG_OBJECTTYPE_WALL: - m_Team = m_WG->GetDefenderTeam(); // Objects that are part of the keep should be the defender's - break; - case BATTLEFIELD_WG_OBJECTTYPE_TOWER: - m_Team = m_WG->GetAttackerTeam(); // The towers in the south should be the attacker's - break; - default: - m_Team = TEAM_NEUTRAL; - break; - } - - if (GameObject* build = m_WG->GetGameObject(m_BuildGUID)) - { - // Rebuild gameobject - if (build->IsDestructibleBuilding()) - { - build->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, NULL, true); - if (build->GetEntry() == GO_WINTERGRASP_VAULT_GATE) - if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f)) - go->SetGoState(GO_STATE_READY); - - // Update worldstate - m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT - (m_Team * 3); - m_WG->SendUpdateWorldState(m_WorldState, m_State); - } - UpdateCreatureAndGo(); - build->SetFaction(WintergraspFaction[m_Team]); - } - } + void Rebuild(); // Called when associated gameobject is damaged - void Damaged() - { - // Update worldstate - m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE - (m_Team * 3); - m_WG->SendUpdateWorldState(m_WorldState, m_State); - - // Send warning message - if (m_NameId) // tower damage + name - m_WG->SendWarningToAllInZone(m_NameId); - - for (GuidSet::const_iterator itr = m_CreatureTopList[m_WG->GetAttackerTeam()].begin(); itr != m_CreatureTopList[m_WG->GetAttackerTeam()].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->HideNpc(creature); - - for (GuidSet::const_iterator itr = m_TurretTopList.begin(); itr != m_TurretTopList.end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->HideNpc(creature); - - if (m_Type == BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER) - m_WG->UpdateDamagedTowerCount(m_WG->GetDefenderTeam()); - else if (m_Type == BATTLEFIELD_WG_OBJECTTYPE_TOWER) - m_WG->UpdateDamagedTowerCount(m_WG->GetAttackerTeam()); - } + void Damaged(); // Called when associated gameobject is destroyed - void Destroyed() - { - // Update worldstate - m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY - (m_Team * 3); - m_WG->SendUpdateWorldState(m_WorldState, m_State); - - // Warn players - if (m_NameId) - m_WG->SendWarningToAllInZone(m_NameId); - - switch (m_Type) - { - // Inform the global wintergrasp script of the destruction of this object - case BATTLEFIELD_WG_OBJECTTYPE_TOWER: - case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER: - m_WG->UpdatedDestroyedTowerCount(TeamId(m_Team)); - break; - case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST: - if (GameObject* build = m_WG->GetGameObject(m_BuildGUID)) - if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f)) - go->SetGoState(GO_STATE_ACTIVE); - m_WG->SetRelicInteractible(true); - if (m_WG->GetRelic()) - m_WG->GetRelic()->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - else - TC_LOG_ERROR("misc", "BattlefieldWG: Relic not found."); - break; - } - - m_WG->BrokenWallOrTower(TeamId(m_Team)); - } - - void Init(GameObject* go, uint32 type, uint32 worldstate, uint32 nameid) - { - if (!go) - return; - - // GameObject associated to object - m_BuildGUID = go->GetGUID(); - - // Type of building (WALL/TOWER/DOOR) - m_Type = type; - - // WorldState for client (icon on map) - m_WorldState = worldstate; - - // NameId for Warning text - m_NameId = nameid; - - switch (m_Type) - { - case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER: - case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST: - case BATTLEFIELD_WG_OBJECTTYPE_DOOR: - case BATTLEFIELD_WG_OBJECTTYPE_WALL: - m_Team = m_WG->GetDefenderTeam(); // Objects that are part of the keep should be the defender's - break; - case BATTLEFIELD_WG_OBJECTTYPE_TOWER: - m_Team = m_WG->GetAttackerTeam(); // The towers in the south should be the attacker's - break; - default: - m_Team = TEAM_NEUTRAL; - break; - } - - m_State = sWorld->getWorldState(m_WorldState); - switch (m_State) - { - case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT: - case BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT: - go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, NULL, true); - break; - case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY: - case BATTLEFIELD_WG_OBJECTSTATE_HORDE_DESTROY: - go->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED); - break; - case BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE: - case BATTLEFIELD_WG_OBJECTSTATE_HORDE_DAMAGE: - go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); - break; - } - - int32 towerid = -1; - switch (go->GetEntry()) - { - case GO_WINTERGRASP_FORTRESS_TOWER_1: - towerid = 0; - break; - case GO_WINTERGRASP_FORTRESS_TOWER_2: - towerid = 1; - break; - case GO_WINTERGRASP_FORTRESS_TOWER_3: - towerid = 2; - break; - case GO_WINTERGRASP_FORTRESS_TOWER_4: - towerid = 3; - break; - case GO_WINTERGRASP_SHADOWSIGHT_TOWER: - towerid = 4; - break; - case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: - towerid = 5; - break; - case GO_WINTERGRASP_FLAMEWATCH_TOWER: - towerid = 6; - break; - } + void Destroyed(); - if (towerid > 3) // Attacker towers - { - // Spawn associate gameobjects - for (uint8 i = 0; i < AttackTowers[towerid - 4].nbObject; i++) - { - WintergraspObjectPositionData gobData = AttackTowers[towerid - 4].GameObject[i]; - 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 - for (uint8 i = 0; i < AttackTowers[towerid - 4].nbCreatureBottom; i++) - { - WintergraspObjectPositionData creatureData = AttackTowers[towerid - 4].CreatureBottom[i]; - if (Creature* creature = m_WG->SpawnCreature(creatureData.entryHorde, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_HORDE)) - m_CreatureBottomList[TEAM_HORDE].insert(creature->GetGUID()); - if (Creature* creature = m_WG->SpawnCreature(creatureData.entryAlliance, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_ALLIANCE)) - m_CreatureBottomList[TEAM_ALLIANCE].insert(creature->GetGUID()); - } - - // Spawn associate npc top - for (uint8 i = 0; i < AttackTowers[towerid - 4].nbCreatureTop; i++) - { - WintergraspObjectPositionData creatureData = AttackTowers[towerid - 4].CreatureTop[i]; - if (Creature* creature = m_WG->SpawnCreature(creatureData.entryHorde, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_HORDE)) - m_CreatureTopList[TEAM_HORDE].insert(creature->GetGUID()); - if (Creature* creature = m_WG->SpawnCreature(creatureData.entryAlliance, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_ALLIANCE)) - m_CreatureTopList[TEAM_ALLIANCE].insert(creature->GetGUID()); - } - } - - if (towerid >= 0) - { - // Spawn Turret bottom - for (uint8 i = 0; i < TowerCannon[towerid].nbTowerCannonBottom; i++) - { - Position turretPos = TowerCannon[towerid].TowerCannonBottom[i].GetPosition(); - if (Creature* turret = m_WG->SpawnCreature(NPC_WINTERGRASP_TOWER_CANNON, turretPos, TEAM_ALLIANCE)) - { - m_TowerCannonBottomList.insert(turret->GetGUID()); - switch (go->GetEntry()) - { - case GO_WINTERGRASP_FORTRESS_TOWER_1: - case GO_WINTERGRASP_FORTRESS_TOWER_2: - case GO_WINTERGRASP_FORTRESS_TOWER_3: - case GO_WINTERGRASP_FORTRESS_TOWER_4: - turret->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); - break; - case GO_WINTERGRASP_SHADOWSIGHT_TOWER: - case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: - case GO_WINTERGRASP_FLAMEWATCH_TOWER: - turret->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); - break; - } - m_WG->HideNpc(turret); - } - } - - // Spawn Turret top - for (uint8 i = 0; i < TowerCannon[towerid].nbTurretTop; i++) - { - Position towerCannonPos = TowerCannon[towerid].TurretTop[i].GetPosition(); - if (Creature* turret = m_WG->SpawnCreature(NPC_WINTERGRASP_TOWER_CANNON, towerCannonPos, TeamId(0))) - { - m_TurretTopList.insert(turret->GetGUID()); - switch (go->GetEntry()) - { - case GO_WINTERGRASP_FORTRESS_TOWER_1: - case GO_WINTERGRASP_FORTRESS_TOWER_2: - case GO_WINTERGRASP_FORTRESS_TOWER_3: - case GO_WINTERGRASP_FORTRESS_TOWER_4: - turret->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); - break; - case GO_WINTERGRASP_SHADOWSIGHT_TOWER: - case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: - case GO_WINTERGRASP_FLAMEWATCH_TOWER: - turret->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); - break; - } - m_WG->HideNpc(turret); - } - } - UpdateCreatureAndGo(); - } - } - - void UpdateCreatureAndGo() - { - for (GuidSet::const_iterator itr = m_CreatureTopList[m_WG->GetDefenderTeam()].begin(); itr != m_CreatureTopList[m_WG->GetDefenderTeam()].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->HideNpc(creature); - - for (GuidSet::const_iterator itr = m_CreatureTopList[m_WG->GetAttackerTeam()].begin(); itr != m_CreatureTopList[m_WG->GetAttackerTeam()].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->ShowNpc(creature, true); - - for (GuidSet::const_iterator itr = m_CreatureBottomList[m_WG->GetDefenderTeam()].begin(); itr != m_CreatureBottomList[m_WG->GetDefenderTeam()].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->HideNpc(creature); + void Init(GameObject* go, uint32 type, uint32 worldstate, uint32 nameId); - for (GuidSet::const_iterator itr = m_CreatureBottomList[m_WG->GetAttackerTeam()].begin(); itr != m_CreatureBottomList[m_WG->GetAttackerTeam()].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->ShowNpc(creature, true); + void UpdateCreatureAndGo(); - for (GuidSet::const_iterator itr = m_GameObjectList[m_WG->GetDefenderTeam()].begin(); itr != m_GameObjectList[m_WG->GetDefenderTeam()].end(); ++itr) - if (GameObject* object = m_WG->GetGameObject(*itr)) - object->SetRespawnTime(RESPAWN_ONE_DAY); + void UpdateTurretAttack(bool disable); - for (GuidSet::const_iterator itr = m_GameObjectList[m_WG->GetAttackerTeam()].begin(); itr != m_GameObjectList[m_WG->GetAttackerTeam()].end(); ++itr) - if (GameObject* object = m_WG->GetGameObject(*itr)) - object->SetRespawnTime(RESPAWN_IMMEDIATELY); - } - - void UpdateTurretAttack(bool disable) - { - for (GuidSet::const_iterator itr = m_TowerCannonBottomList.begin(); itr != m_TowerCannonBottomList.end(); ++itr) - { - if (Creature* creature = m_WG->GetCreature(*itr)) - { - if (GameObject* build = m_WG->GetGameObject(m_BuildGUID)) - { - if (disable) - m_WG->HideNpc(creature); - else - m_WG->ShowNpc(creature, true); - - switch (build->GetEntry()) - { - case GO_WINTERGRASP_FORTRESS_TOWER_1: - case GO_WINTERGRASP_FORTRESS_TOWER_2: - case GO_WINTERGRASP_FORTRESS_TOWER_3: - case GO_WINTERGRASP_FORTRESS_TOWER_4: - { - creature->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); - break; - } - case GO_WINTERGRASP_SHADOWSIGHT_TOWER: - case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: - case GO_WINTERGRASP_FLAMEWATCH_TOWER: - { - creature->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); - break; - } - } - } - } - } - - for (GuidSet::const_iterator itr = m_TurretTopList.begin(); itr != m_TurretTopList.end(); ++itr) - { - if (Creature* creature = m_WG->GetCreature(*itr)) - { - if (GameObject* build = m_WG->GetGameObject(m_BuildGUID)) - { - if (disable) - m_WG->HideNpc(creature); - else - m_WG->ShowNpc(creature, true); - - switch (build->GetEntry()) - { - case GO_WINTERGRASP_FORTRESS_TOWER_1: - case GO_WINTERGRASP_FORTRESS_TOWER_2: - case GO_WINTERGRASP_FORTRESS_TOWER_3: - case GO_WINTERGRASP_FORTRESS_TOWER_4: - { - creature->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); - break; - } - case GO_WINTERGRASP_SHADOWSIGHT_TOWER: - case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: - case GO_WINTERGRASP_FLAMEWATCH_TOWER: - { - creature->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); - break; - } - } - } - } - } - } - - void Save() - { - sWorld->setWorldState(m_WorldState, m_State); - } + void Save(); }; struct WGWorkshop @@ -1472,64 +1119,13 @@ struct WGWorkshop // for worldstate uint32 state; - WGWorkshop(BattlefieldWG* _bf, uint8 _workshopId) - { - ASSERT(_bf || _workshopId < WG_MAX_WORKSHOP); - - bf = _bf; - workshopId = _workshopId; - teamControl = BATTLEFIELD_WG_TEAM_NEUTRAL; - state = BATTLEFIELD_WG_OBJECTSTATE_NONE; - } + WGWorkshop(BattlefieldWG* _bf, uint8 _workshopId); - void GiveControlTo(uint8 team, bool init /* for first call in setup*/) - { - switch (team) - { - case BATTLEFIELD_WG_TEAM_NEUTRAL: - { - // Send warning message to all player to inform a faction attack to a workshop - // alliance / horde attacking a workshop - bf->SendWarningToAllInZone(teamControl ? WorkshopsData[workshopId].text : WorkshopsData[workshopId].text + 1); - break; - } - case BATTLEFIELD_WG_TEAM_ALLIANCE: - case BATTLEFIELD_WG_TEAM_HORDE: - { - // Updating worldstate - state = team == BATTLEFIELD_WG_TEAM_ALLIANCE ? BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT : BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT; - bf->SendUpdateWorldState(WorkshopsData[workshopId].worldstate, state); - - // Warning message - if (!init) // workshop taken - alliance - bf->SendWarningToAllInZone(team == BATTLEFIELD_WG_TEAM_ALLIANCE ? WorkshopsData[workshopId].text : WorkshopsData[workshopId].text+1); - - // Found associate graveyard and update it - if (workshopId < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - if (bf->GetGraveyardById(workshopId)) - bf->GetGraveyardById(workshopId)->GiveControlTo(team == BATTLEFIELD_WG_TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE); - - teamControl = team; - break; - } - } + void GiveControlTo(uint8 team, bool init /*for first call in setup*/); - if (!init) - bf->UpdateCounterVehicle(false); - } + void UpdateGraveyardAndWorkshop(); - void UpdateGraveyardAndWorkshop() - { - if (workshopId < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - bf->GetGraveyardById(workshopId)->GiveControlTo(TeamId(teamControl)); - else - GiveControlTo(bf->GetDefenderTeam(), true); - } - - void Save() - { - sWorld->setWorldState(WorkshopsData[workshopId].worldstate, state); - } + void Save(); }; // Structure for the 6 workshop @@ -1542,153 +1138,26 @@ struct WintergraspWorkshopData uint32 m_WorldState; uint32 m_TeamControl; // Team witch control the workshop GuidSet m_CreatureOnPoint[2]; // Contain all Creature associate to this point - GuidSet m_GameObjectOnPoint[2]; // Contain all Gameobject associate to this point + GuidSet m_GameObjectOnPoint[2]; // Contain all Gameobject associate to this point uint32 m_NameId; // Id of trinity_string witch contain name of this node, using for alert message - WintergraspWorkshopData(BattlefieldWG* WG) - { - m_WG = WG; - m_BuildGUID = 0; - m_Type = 0; - m_State = 0; - m_WorldState = 0; - m_TeamControl = 0; - m_NameId = 0; - } + WintergraspWorkshopData(BattlefieldWG* wg); // Spawning associate creature and store them - void AddCreature(const WintergraspObjectPositionData& obj) - { - if (Creature* creature = m_WG->SpawnCreature(obj.entryHorde, obj.x, obj.y, obj.z, obj.o, TEAM_HORDE)) - m_CreatureOnPoint[TEAM_HORDE].insert(creature->GetGUID()); - - if (Creature* creature = m_WG->SpawnCreature(obj.entryAlliance, obj.x, obj.y, obj.z, obj.o, TEAM_ALLIANCE)) - m_CreatureOnPoint[TEAM_ALLIANCE].insert(creature->GetGUID()); - } + void AddCreature(WintergraspObjectPositionData const& obj); // Spawning Associate gameobject and store them - void AddGameObject(const WintergraspObjectPositionData& obj) - { - if (GameObject* gameobject = m_WG->SpawnGameObject(obj.entryHorde, obj.x, obj.y, obj.z, obj.o)) - m_GameObjectOnPoint[TEAM_HORDE].insert(gameobject->GetGUID()); - if (GameObject* gameobject = m_WG->SpawnGameObject(obj.entryAlliance, obj.x, obj.y, obj.z, obj.o)) - m_GameObjectOnPoint[TEAM_ALLIANCE].insert(gameobject->GetGUID()); - } + void AddGameObject(WintergraspObjectPositionData const& obj); // Init method, setup variable - void Init(uint32 worldstate, uint32 type, uint32 nameid) - { - m_WorldState = worldstate; - m_Type = type; - m_NameId = nameid; - } + void Init(uint32 worldstate, uint32 type, uint32 nameId); // Called on change faction in CapturePoint class - void GiveControlTo(uint8 team, bool init /* for first call in setup*/) - { - switch (team) - { - case BATTLEFIELD_WG_TEAM_NEUTRAL: - { - // Send warning message to all player for inform a faction attack a workshop - // alliance / horde attacking workshop - m_WG->SendWarningToAllInZone(m_TeamControl ? m_NameId : m_NameId + 1); - break; - } - case BATTLEFIELD_WG_TEAM_ALLIANCE: - { - // Show Alliance creature - for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_ALLIANCE].begin(); itr != m_CreatureOnPoint[TEAM_ALLIANCE].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->ShowNpc(creature, creature->GetEntry() != 30499); - - // Hide Horde creature - for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_HORDE].begin(); itr != m_CreatureOnPoint[TEAM_HORDE].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->HideNpc(creature); - - // Show Alliance gameobject - for (GuidSet::const_iterator itr = m_GameObjectOnPoint[TEAM_ALLIANCE].begin(); itr != m_GameObjectOnPoint[TEAM_ALLIANCE].end(); ++itr) - if (GameObject* object = m_WG->GetGameObject(*itr)) - object->SetRespawnTime(RESPAWN_IMMEDIATELY); - - // Hide Horde gameobject - for (GuidSet::const_iterator itr = m_GameObjectOnPoint[TEAM_HORDE].begin(); itr != m_GameObjectOnPoint[TEAM_HORDE].end(); ++itr) - if (GameObject* object = m_WG->GetGameObject(*itr)) - object->SetRespawnTime(RESPAWN_ONE_DAY); - - - // Updating worldstate - m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT; - m_WG->SendUpdateWorldState(m_WorldState, m_State); - - // Warning message - if (!init) // workshop taken - alliance - m_WG->SendWarningToAllInZone(m_NameId); - - // Found associate graveyard and update it - if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - if (m_WG->GetGraveyardById(m_Type)) - m_WG->GetGraveyardById(m_Type)->GiveControlTo(TEAM_ALLIANCE); - - m_TeamControl = team; - break; - } - case BATTLEFIELD_WG_TEAM_HORDE: - { - // Show Horde creature - for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_HORDE].begin(); itr != m_CreatureOnPoint[TEAM_HORDE].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->ShowNpc(creature, creature->GetEntry() != 30400); - - // Hide Alliance creature - for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_ALLIANCE].begin(); itr != m_CreatureOnPoint[TEAM_ALLIANCE].end(); ++itr) - if (Creature* creature = m_WG->GetCreature(*itr)) - m_WG->HideNpc(creature); - - // Hide Alliance gameobject - for (GuidSet::const_iterator itr = m_GameObjectOnPoint[TEAM_ALLIANCE].begin(); itr != m_GameObjectOnPoint[TEAM_ALLIANCE].end(); ++itr) - if (GameObject* object = m_WG->GetGameObject(*itr)) - object->SetRespawnTime(RESPAWN_ONE_DAY); - - // Show Horde gameobject - for (GuidSet::const_iterator itr = m_GameObjectOnPoint[TEAM_HORDE].begin(); itr != m_GameObjectOnPoint[TEAM_HORDE].end(); ++itr) - if (GameObject* object = m_WG->GetGameObject(*itr)) - object->SetRespawnTime(RESPAWN_IMMEDIATELY); - - // Update worlstate - m_State = BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT; - m_WG->SendUpdateWorldState(m_WorldState, m_State); - - // Warning message - if (!init) // workshop taken - horde - m_WG->SendWarningToAllInZone(m_NameId + 1); - - // Update graveyard control - if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - if (m_WG->GetGraveyardById(m_Type)) - m_WG->GetGraveyardById(m_Type)->GiveControlTo(TEAM_HORDE); - - m_TeamControl = team; - break; - } - } - if (!init) - m_WG->UpdateCounterVehicle(false); - } + void GiveControlTo(uint8 team, bool init /*for first call in setup*/); - void UpdateGraveyardAndWorkshop() - { - if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - m_WG->GetGraveyardById(m_Type)->GiveControlTo(TeamId(m_TeamControl)); - else - GiveControlTo(m_WG->GetDefenderTeam(), true); - } + void UpdateGraveyardAndWorkshop(); - void Save() - { - sWorld->setWorldState(m_WorldState, m_State); - } + void Save(); }; #endif diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp new file mode 100644 index 00000000000..0dcd4997bde --- /dev/null +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include "Arena.h" +#include "ArenaScore.h" +#include "ArenaTeamMgr.h" +#include "GuildMgr.h" +#include "Guild.h" +#include "Language.h" +#include "ObjectAccessor.h" +#include "Player.h" +#include "World.h" +#include "WorldSession.h" + +Arena::Arena() +{ + StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; + StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; + StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; + StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; + + StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; + StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; + StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; + StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; +} + +void Arena::AddPlayer(Player* player) +{ + Battleground::AddPlayer(player); + PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); + + if (player->GetBGTeam() == ALLIANCE) // gold + { + if (player->GetTeam() == HORDE) + player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true); + else + player->CastSpell(player, SPELL_ALLIANCE_GOLD_FLAG, true); + } + else // green + { + if (player->GetTeam() == HORDE) + player->CastSpell(player, SPELL_HORDE_GREEN_FLAG, true); + else + player->CastSpell(player, SPELL_ALLIANCE_GREEN_FLAG, true); + } + + UpdateArenaWorldState(); +} + +void Arena::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) +{ + if (GetStatus() == STATUS_WAIT_LEAVE) + return; + + UpdateArenaWorldState(); + CheckWinConditions(); +} + +void Arena::FillInitialWorldStates(WorldPacket& data) +{ + data << uint32(ARENA_WORLD_STATE_ALIVE_PLAYERS_GREEN) << uint32(GetAlivePlayersCountByTeam(HORDE)); + data << uint32(ARENA_WORLD_STATE_ALIVE_PLAYERS_GOLD) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); +} + +void Arena::UpdateArenaWorldState() +{ + UpdateWorldState(ARENA_WORLD_STATE_ALIVE_PLAYERS_GREEN, GetAlivePlayersCountByTeam(HORDE)); + UpdateWorldState(ARENA_WORLD_STATE_ALIVE_PLAYERS_GOLD, GetAlivePlayersCountByTeam(ALLIANCE)); +} + +void Arena::HandleKillPlayer(Player* player, Player* killer) +{ + if (GetStatus() != STATUS_IN_PROGRESS) + return; + + Battleground::HandleKillPlayer(player, killer); + + UpdateArenaWorldState(); + CheckWinConditions(); +} + +void Arena::RemovePlayerAtLeave(uint64 guid, bool transport, bool sendPacket) +{ + if (isRated() && GetStatus() == STATUS_IN_PROGRESS) + { + BattlegroundPlayerMap::const_iterator itr = m_Players.find(guid); + if (itr != m_Players.end()) // check if the player was a participant of the match, or only entered through gm command (appear) + { + // if the player was a match participant, calculate rating + uint32 team = itr->second.Team; + + ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team))); + ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(team)); + + // left a rated match while the encounter was in progress, consider as loser + if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) + { + if (Player* player = _GetPlayer(itr->first, itr->second.OfflineRemoveTime, "Arena::RemovePlayerAtLeave")) + loserArenaTeam->MemberLost(player, GetArenaMatchmakerRating(GetOtherTeam(team))); + else + loserArenaTeam->OfflineMemberLost(guid, GetArenaMatchmakerRating(GetOtherTeam(team))); + } + } + } + + // remove player + Battleground::RemovePlayerAtLeave(guid, transport, sendPacket); +} + +void Arena::CheckWinConditions() +{ + if (!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE)) + EndBattleground(HORDE); + else if (GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE)) + EndBattleground(ALLIANCE); +} + +void Arena::EndBattleground(uint32 winner) +{ + // arena rating calculation + if (isRated()) + { + uint32 loserTeamRating = 0; + uint32 loserMatchmakerRating = 0; + int32 loserChange = 0; + int32 loserMatchmakerChange = 0; + uint32 winnerTeamRating = 0; + uint32 winnerMatchmakerRating = 0; + int32 winnerChange = 0; + int32 winnerMatchmakerChange = 0; + bool guildAwarded = false; + + ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner)); + ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner))); + + if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) + { + loserTeamRating = loserArenaTeam->GetRating(); + loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); + winnerTeamRating = winnerArenaTeam->GetRating(); + winnerMatchmakerRating = GetArenaMatchmakerRating(winner); + + if (winner != 0) + { + winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange); + loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange); + + TC_LOG_DEBUG("bg.arena", "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", + GetArenaType(), winnerTeamRating, winnerChange, winnerMatchmakerRating, winnerMatchmakerChange, + loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange); + + SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange); + SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange); + + // bg team that the client expects is different to TeamId + // alliance 1, horde 0 + uint8 winnerTeam = winner == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; + uint8 loserTeam = winner == ALLIANCE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; + + _arenaTeamScores[winnerTeam].Assign(winnerChange, winnerMatchmakerRating, winnerArenaTeam->GetName()); + _arenaTeamScores[loserTeam].Assign(loserChange, loserMatchmakerRating, loserArenaTeam->GetName()); + + TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", + GetArenaType(), GetArenaTeamIdByIndex(TEAM_ALLIANCE), GetArenaTeamIdByIndex(TEAM_HORDE), winnerArenaTeam->GetId(), winnerChange, loserChange); + + if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) + for (auto const& score : PlayerScores) + if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(score.first, 0, HIGHGUID_PLAYER))) + { + TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", + GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3), + player->GetSession()->GetRemoteAddress().c_str(), score.second->ToString().c_str()); + } + } + // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes + else + { + _arenaTeamScores[BG_TEAM_ALLIANCE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating, winnerArenaTeam->GetName()); + _arenaTeamScores[BG_TEAM_HORDE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating, loserArenaTeam->GetName()); + + winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); + loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); + } + + uint8 aliveWinners = GetAlivePlayersCountByTeam(winner); + + for (auto const& i : GetPlayers()) + { + uint32 team = i.second.Team; + + if (i.second.OfflineRemoveTime) + { + // if rated arena match - make member lost! + if (team == winner) + winnerArenaTeam->OfflineMemberLost(i.first, loserMatchmakerRating, winnerMatchmakerChange); + else + loserArenaTeam->OfflineMemberLost(i.first, winnerMatchmakerRating, loserMatchmakerChange); + continue; + } + + Player* player = _GetPlayer(i.first, i.second.OfflineRemoveTime, "Arena::EndBattleground"); + if (!player) + continue; + + // per player calculation + if (team == winner) + { + // update achievement BEFORE personal rating update + uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot()); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId()); + player->ModifyCurrency(CURRENCY_TYPE_CONQUEST_META_ARENA, sWorld->getIntConfig(CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD)); + + // Last standing - Rated 5v5 arena & be solely alive player + if (GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) + player->CastSpell(player, SPELL_LAST_MAN_STANDING, true); + + if (!guildAwarded) + { + guildAwarded = true; + if (uint32 guildId = GetBgMap()->GetOwnerGuildId(player->GetTeam())) + if (Guild* guild = sGuildMgr->GetGuildById(guildId)) + { + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1, 0, 0, NULL, player); + if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, std::max<uint32>(winnerArenaTeam->GetRating(), 1), 0, 0, NULL, player); + } + } + + winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); + } + else + { + loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); + + // Arena lost => reset the win_rated_arena having the "no_lose" condition + player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE); + } + } + + // save the stat changes + winnerArenaTeam->SaveToDB(); + loserArenaTeam->SaveToDB(); + // send updated arena team stats to players + // this way all arena team members will get notified, not only the ones who participated in this match + winnerArenaTeam->NotifyStatsChanged(); + loserArenaTeam->NotifyStatsChanged(); + } + } + + // end battleground + Battleground::EndBattleground(winner); +} diff --git a/src/server/game/Battlegrounds/Arena.h b/src/server/game/Battlegrounds/Arena.h new file mode 100644 index 00000000000..8aea92d496d --- /dev/null +++ b/src/server/game/Battlegrounds/Arena.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_ARENA_H +#define TRINITY_ARENA_H + +#include "Battleground.h" + +enum ArenaSpellIds +{ + SPELL_ALLIANCE_GOLD_FLAG = 32724, + SPELL_ALLIANCE_GREEN_FLAG = 32725, + SPELL_HORDE_GOLD_FLAG = 35774, + SPELL_HORDE_GREEN_FLAG = 35775, + + SPELL_LAST_MAN_STANDING = 26549 // Achievement Credit +}; + +enum ArenaWorldStates +{ + ARENA_WORLD_STATE_ALIVE_PLAYERS_GREEN = 3600, + ARENA_WORLD_STATE_ALIVE_PLAYERS_GOLD = 3601 +}; + +class Arena : public Battleground +{ + protected: + Arena(); + + void AddPlayer(Player* player) override; + void RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) override; + + void FillInitialWorldStates(WorldPacket& data) override; + void UpdateArenaWorldState(); + + void HandleKillPlayer(Player* player, Player* killer) override; + + private: + void RemovePlayerAtLeave(uint64 guid, bool transport, bool sendPacket) override; + void CheckWinConditions() override; + void EndBattleground(uint32 winner) override; +}; + +#endif // TRINITY_ARENA_H diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h index 6dad251d948..162cf729181 100644 --- a/src/server/game/Battlegrounds/ArenaScore.h +++ b/src/server/game/Battlegrounds/ArenaScore.h @@ -25,14 +25,10 @@ struct ArenaScore : public BattlegroundScore { - friend class BattlegroundBE; - friend class BattlegroundDS; - friend class BattlegroundNA; - friend class BattlegroundRL; - friend class BattlegroundRV; + friend class Arena; protected: - ArenaScore(uint64 playerGuid, uint32 team) : BattlegroundScore(playerGuid, team), TeamId(team == ALLIANCE ? 1 : 0) { } + ArenaScore(uint64 playerGuid, uint32 team) : BattlegroundScore(playerGuid, team), TeamId(team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE) { } void AppendToPacket(WorldPacket& data, ByteBuffer& content) final { @@ -104,7 +100,57 @@ struct ArenaScore : public BattlegroundScore return stream.str(); } - uint8 TeamId; // bgTeamId + uint8 TeamId; // BattlegroundTeamId +}; + +struct ArenaTeamScore +{ + friend class Arena; + friend class Battleground; + + protected: + ArenaTeamScore() : RatingChange(0), MatchmakerRating(0) { } + + virtual ~ArenaTeamScore() { } + + void Reset() + { + RatingChange = 0; + MatchmakerRating = 0; + TeamName.clear(); + } + + void Assign(int32 ratingChange, uint32 matchMakerRating, std::string const& teamName) + { + RatingChange = ratingChange; + MatchmakerRating = matchMakerRating; + TeamName = teamName; + } + + void BuildRatingInfoBlock(WorldPacket& data) + { + uint32 ratingLost = std::abs(std::min(RatingChange, 0)); + uint32 ratingWon = std::max(RatingChange, 0); + + // should be old rating, new rating, and client will calculate rating change itself + data << uint32(MatchmakerRating); + data << uint32(ratingLost); + data << uint32(ratingWon); + } + + void BuildTeamInfoLengthBlock(WorldPacket& data) + { + data.WriteBits(TeamName.length(), 8); + } + + void BuildTeamInfoBlock(WorldPacket& data) + { + data.WriteString(TeamName); + } + + int32 RatingChange; + uint32 MatchmakerRating; + std::string TeamName; }; #endif // TRINITY_ARENA_SCORE_H diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 7a9848c55dd..ca8892d04bf 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -17,8 +17,6 @@ */ #include "ArenaScore.h" -#include "ArenaTeam.h" -#include "ArenaTeamMgr.h" #include "Battleground.h" #include "BattlegroundMgr.h" #include "BattlegroundScore.h" @@ -28,8 +26,6 @@ #include "Formulas.h" #include "GridNotifiersImpl.h" #include "Group.h" -#include "Guild.h" -#include "GuildMgr.h" #include "MapManager.h" #include "Object.h" #include "ObjectMgr.h" @@ -38,7 +34,6 @@ #include "SpellAuraEffects.h" #include "SpellAuras.h" #include "Util.h" -#include "World.h" #include "WorldPacket.h" namespace Trinity @@ -130,7 +125,7 @@ Battleground::Battleground() m_InvitedHorde = 0; m_ArenaType = 0; m_IsArena = false; - m_Winner = 2; + _winnerTeamId = BG_TEAM_NEUTRAL; m_StartTime = 0; m_CountdownTimer = 0; m_ResetStatTimer = 0; @@ -253,8 +248,7 @@ void Battleground::Update(uint32 diff) { if (GetElapsedTime() >= 47 * MINUTE*IN_MILLISECONDS) { - UpdateArenaWorldState(); - CheckArenaAfterTimerConditions(); + EndBattleground(0); return; } } @@ -555,7 +549,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) } } - CheckArenaWinConditions(); + CheckWinConditions(); } else { @@ -748,18 +742,6 @@ void Battleground::EndBattleground(uint32 winner) { RemoveFromBGFreeSlotQueue(); - ArenaTeam* winnerArenaTeam = NULL; - ArenaTeam* loserArenaTeam = NULL; - - uint32 loserTeamRating = 0; - uint32 loserMatchmakerRating = 0; - int32 loserChange = 0; - int32 loserMatchmakerChange = 0; - uint32 winnerTeamRating = 0; - uint32 winnerMatchmakerRating = 0; - int32 winnerChange = 0; - int32 winnerMatchmakerChange = 0; - int32 winmsg_id = 0; if (winner == ALLIANCE) @@ -768,7 +750,7 @@ void Battleground::EndBattleground(uint32 winner) PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound - SetWinner(WINNER_ALLIANCE); + SetWinner(BG_TEAM_ALLIANCE); } else if (winner == HORDE) { @@ -776,93 +758,26 @@ void Battleground::EndBattleground(uint32 winner) PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound - SetWinner(WINNER_HORDE); + SetWinner(BG_TEAM_HORDE); } else { - SetWinner(3); // weird + SetWinner(BG_TEAM_NEUTRAL); } SetStatus(STATUS_WAIT_LEAVE); //we must set it this way, because end time is sent in packet! SetRemainingTime(TIME_AUTOCLOSE_BATTLEGROUND); - - // arena rating calculation - if (isArena() && isRated()) - { - winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner)); - loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner))); - - if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - { - loserTeamRating = loserArenaTeam->GetRating(); - loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); - winnerTeamRating = winnerArenaTeam->GetRating(); - winnerMatchmakerRating = GetArenaMatchmakerRating(winner); - - if (winner != WINNER_NONE) - { - winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange); - loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange); - TC_LOG_DEBUG("bg.arena", "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", m_ArenaType, winnerTeamRating, winnerChange, winnerMatchmakerRating, - winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange); - SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange); - SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange); - - // bg team that the client expects is different to TeamId - // alliance 1, horde 0 - uint8 winnerTeam = winner == ALLIANCE ? WINNER_ALLIANCE : WINNER_HORDE; - uint8 loserTeam = winner == ALLIANCE ? WINNER_HORDE : WINNER_ALLIANCE; - - _arenaTeamScores[winnerTeam].Assign(winnerChange, winnerMatchmakerRating, winnerArenaTeam->GetName()); - _arenaTeamScores[loserTeam].Assign(loserChange, loserMatchmakerRating, loserArenaTeam->GetName()); - - TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", m_ArenaType, m_ArenaTeamIds[TEAM_ALLIANCE], m_ArenaTeamIds[TEAM_HORDE], winnerArenaTeam->GetId(), winnerChange, loserChange); - if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) - for (auto const& score : PlayerScores) - if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(score.first, 0, HIGHGUID_PLAYER))) - { - TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", - m_ArenaType, player->GetName().c_str(), score.first, player->GetArenaTeamId(m_ArenaType == 5 ? 2 : m_ArenaType == 3), - player->GetSession()->GetRemoteAddress().c_str(), score.second->ToString().c_str()); - } - } - // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes - else - { - _arenaTeamScores[WINNER_ALLIANCE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating, winnerArenaTeam->GetName()); - _arenaTeamScores[WINNER_HORDE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating, loserArenaTeam->GetName()); - - winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); - loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); - } - } - } - - bool guildAwarded = false; + WorldPacket pvpLogData; BuildPvPLogDataPacket(pvpLogData); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); - uint8 aliveWinners = GetAlivePlayersCountByTeam(winner); for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { uint32 team = itr->second.Team; - if (itr->second.OfflineRemoveTime) - { - //if rated arena match - make member lost! - if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - { - if (team == winner) - winnerArenaTeam->OfflineMemberLost(itr->first, loserMatchmakerRating, winnerMatchmakerChange); - else - loserArenaTeam->OfflineMemberLost(itr->first, winnerMatchmakerRating, loserMatchmakerChange); - } - continue; - } - Player* player = _GetPlayer(itr, "EndBattleground"); if (!player) continue; @@ -871,10 +786,6 @@ void Battleground::EndBattleground(uint32 winner) if (player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); - // Last standing - Rated 5v5 arena & be solely alive player - if (team == winner && isArena() && isRated() && GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) - player->CastSpell(player, SPELL_THE_LAST_STANDING, true); - if (!player->IsAlive()) { player->ResurrectPlayer(1.0f); @@ -887,35 +798,13 @@ void Battleground::EndBattleground(uint32 winner) player->getHostileRefManager().deleteReferences(); } - // per player calculation - if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - { - if (team == winner) - { - // update achievement BEFORE personal rating update - uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot()); - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId()); - player->ModifyCurrency(CURRENCY_TYPE_CONQUEST_META_ARENA, sWorld->getIntConfig(CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD)); - - winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); - } - else - { - loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); - - // Arena lost => reset the win_rated_arena having the "no_lose" condition - player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE); - } - } - - uint32 winnerKills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_FIRST); - uint32 loserKills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_FIRST); - // remove temporary currency bonus auras before rewarding player player->RemoveAura(SPELL_HONORABLE_DEFENDER_25Y); player->RemoveAura(SPELL_HONORABLE_DEFENDER_60Y); + uint32 winnerKills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_FIRST); + uint32 loserKills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_FIRST); + // Reward winner team if (team == winner) { @@ -933,17 +822,6 @@ void Battleground::EndBattleground(uint32 winner) player->ModifyCurrency(CURRENCY_TYPE_CONQUEST_META_ARENA, sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_CONQUEST_LAST)); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1); - if (!guildAwarded) - { - guildAwarded = true; - if (uint32 guildId = GetBgMap()->GetOwnerGuildId(player->GetTeam())) - if (Guild* guild = sGuildMgr->GetGuildById(guildId)) - { - guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1, 0, 0, NULL, player); - if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, std::max<uint32>(winnerArenaTeam->GetRating(), 1), 0, 0, NULL, player); - } - } } else { @@ -965,17 +843,6 @@ void Battleground::EndBattleground(uint32 winner) player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } - if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - { - // save the stat changes - winnerArenaTeam->SaveToDB(); - loserArenaTeam->SaveToDB(); - // send updated arena team stats to players - // this way all arena team members will get notified, not only the ones who participated in this match - winnerArenaTeam->NotifyStatsChanged(); - loserArenaTeam->NotifyStatsChanged(); - } - if (winmsg_id) SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL); } @@ -1043,26 +910,16 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac { player->ClearAfkReports(); - if (!team) team = player->GetTeam(); - // if arena, remove the specific arena auras if (isArena()) { - bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) + bgTypeId = BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) // unsummon current and summon old pet if there was one and there isn't a current pet player->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT); player->ResummonPetTemporaryUnSummonedIfAny(); - - if (isRated() && GetStatus() == STATUS_IN_PROGRESS) - { - //left a rated match while the encounter was in progress, consider as loser - ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team))); - ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(team)); - if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - loserArenaTeam->MemberLost(player, GetArenaMatchmakerRating(GetOtherTeam(team))); - } } + if (SendPacket) { WorldPacket data; @@ -1073,26 +930,12 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg player->RemoveBattlegroundQueueId(bgQueueTypeId); } - else - // removing offline participant - { - if (isRated() && GetStatus() == STATUS_IN_PROGRESS) - { - //left a rated match while the encounter was in progress, consider as loser - ArenaTeam* others_arena_team = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(team))); - ArenaTeam* players_arena_team = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(team)); - if (others_arena_team && players_arena_team) - players_arena_team->OfflineMemberLost(guid, GetArenaMatchmakerRating(GetOtherTeam(team))); - } - } // remove from raid group if player is member if (Group* group = GetBgRaid(team)) { if (!group->RemoveMember(guid)) // group was disbanded - { SetBgRaid(team, NULL); - } } DecreaseInvitedCount(team); //we should update battleground queue, but only if bg isn't ending @@ -1128,7 +971,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac // this method is called when no players remains in battleground void Battleground::Reset() { - SetWinner(WINNER_NONE); + SetWinner(BG_TEAM_NEUTRAL); SetStatus(STATUS_WAIT_QUEUE); SetElapsedTime(0); SetRemainingTime(0); @@ -1210,21 +1053,6 @@ void Battleground::AddPlayer(Player* player) if (isArena()) { player->RemoveArenaEnchantments(TEMP_ENCHANTMENT_SLOT); - if (team == ALLIANCE) // gold - { - if (player->GetTeam() == HORDE) - player->CastSpell(player, SPELL_HORDE_GOLD_FLAG, true); - else - player->CastSpell(player, SPELL_ALLIANCE_GOLD_FLAG, true); - } - else // green - { - if (player->GetTeam() == HORDE) - player->CastSpell(player, SPELL_HORDE_GREEN_FLAG, true); - else - player->CastSpell(player, SPELL_ALLIANCE_GREEN_FLAG, true); - } - player->DestroyConjuredItems(true); player->UnsummonPetTemporaryIfAny(); @@ -1475,10 +1303,10 @@ bool Battleground::UpdatePlayerScore(Player* player, uint32 type, uint32 value, if (itr == PlayerScores.end()) // player not found... return false; - itr->second->UpdateScore(type, value); - if (type == SCORE_BONUS_HONOR && doAddHonor && isBattleground()) player->RewardHonor(NULL, 1, value); // RewardHonor calls UpdatePlayerScore with doAddHonor = false + else + itr->second->UpdateScore(type, value); return true; } @@ -1998,27 +1826,6 @@ int32 Battleground::GetObjectType(uint64 guid) return -1; } -void Battleground::HandleKillUnit(Creature* /*victim*/, Player* /*killer*/) { } - -void Battleground::CheckArenaAfterTimerConditions() -{ - EndBattleground(WINNER_NONE); -} - -void Battleground::CheckArenaWinConditions() -{ - if (!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE)) - EndBattleground(HORDE); - else if (GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE)) - EndBattleground(ALLIANCE); -} - -void Battleground::UpdateArenaWorldState() -{ - UpdateWorldState(0xe10, GetAlivePlayersCountByTeam(HORDE)); - UpdateWorldState(0xe11, GetAlivePlayersCountByTeam(ALLIANCE)); -} - void Battleground::SetBgRaid(uint32 TeamID, Group* bg_raid) { Group*& old_raid = TeamID == ALLIANCE ? m_BgRaids[TEAM_ALLIANCE] : m_BgRaids[TEAM_HORDE]; diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index fdbd4d0cfc3..214a9cd7645 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -19,6 +19,7 @@ #ifndef __BATTLEGROUND_H #define __BATTLEGROUND_H +#include "ArenaScore.h" #include "Common.h" #include "SharedDefines.h" #include "DBCEnums.h" @@ -34,7 +35,6 @@ class WorldObject; class WorldPacket; class BattlegroundMap; -struct BattlegroundScore; struct PvPDifficultyEntry; struct WorldSafeLocsEntry; @@ -104,17 +104,12 @@ enum BattlegroundSpells SPELL_SPIRIT_HEAL = 22012, // Spirit Heal SPELL_RESURRECTION_VISUAL = 24171, // Resurrection Impact Visual SPELL_ARENA_PREPARATION = 32727, // use this one, 32728 not correct - SPELL_ALLIANCE_GOLD_FLAG = 32724, - SPELL_ALLIANCE_GREEN_FLAG = 32725, - SPELL_HORDE_GOLD_FLAG = 35774, - SPELL_HORDE_GREEN_FLAG = 35775, SPELL_PREPARATION = 44521, // Preparation SPELL_SPIRIT_HEAL_MANA = 44535, // Spirit Heal SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag SPELL_AURA_PLAYER_INACTIVE = 43681, // Inactive SPELL_HONORABLE_DEFENDER_25Y = 68652, // +50% honor when standing at a capture point that you control, 25yards radius (added in 3.2) - SPELL_HONORABLE_DEFENDER_60Y = 66157, // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds - SPELL_THE_LAST_STANDING = 26549 // Arena achievement related + SPELL_HONORABLE_DEFENDER_60Y = 66157 // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds }; enum BattlegroundTimeIntervals @@ -183,21 +178,6 @@ enum ArenaType ARENA_TYPE_5v5 = 5 }; -enum BattlegroundType -{ - TYPE_BATTLEGROUND = 3, - TYPE_ARENA = 4 -}; - -enum BattlegroundWinner -{ - WINNER_HORDE = 0, - WINNER_ALLIANCE = 1, - WINNER_NONE = 2 -}; - -#define BG_TEAMS_COUNT 2 - enum BattlegroundStartingEvents { BG_STARTING_EVENT_NONE = 0x00, @@ -280,7 +260,7 @@ class Battleground int32 GetStartDelayTime() const { return m_StartDelayTime; } uint8 GetArenaType() const { return m_ArenaType; } - uint8 GetWinner() const { return m_Winner; } + BattlegroundTeamId GetWinner() const { return _winnerTeamId; } uint32 GetScriptId() const { return ScriptId; } uint32 GetBonusHonorFromKill(uint32 kills) const; bool IsRandom() const { return m_IsRandom; } @@ -304,7 +284,7 @@ class Battleground void SetRated(bool state) { m_IsRated = state; } void SetArenaType(uint8 type) { m_ArenaType = type; } void SetArenaorBGType(bool _isArena) { m_IsArena = _isArena; } - void SetWinner(uint8 winner) { m_Winner = winner; } + void SetWinner(BattlegroundTeamId winnerTeamId) { _winnerTeamId = winnerTeamId; } void SetScriptId(uint32 scriptId) { ScriptId = scriptId; } void ModifyStartDelayTime(int diff) { m_StartDelayTime -= diff; } @@ -383,7 +363,7 @@ class Battleground void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID); void UpdateWorldState(uint32 Field, uint32 Value); void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player); - void EndBattleground(uint32 winner); + virtual void EndBattleground(uint32 winner); void BlockMovement(Player* player); void SendWarningToAll(int32 entry, ...); @@ -411,22 +391,21 @@ class Battleground ++m_PlayersCount[GetTeamIndexByTeamId(Team)]; } + virtual void CheckWinConditions() { } + // used for rated arena battles void SetArenaTeamIdForTeam(uint32 Team, uint32 ArenaTeamId) { m_ArenaTeamIds[GetTeamIndexByTeamId(Team)] = ArenaTeamId; } uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; } uint32 GetArenaTeamIdByIndex(uint32 index) const { return m_ArenaTeamIds[index]; } void SetArenaMatchmakerRating(uint32 Team, uint32 MMR){ m_ArenaTeamMMR[GetTeamIndexByTeamId(Team)] = MMR; } uint32 GetArenaMatchmakerRating(uint32 Team) const { return m_ArenaTeamMMR[GetTeamIndexByTeamId(Team)]; } - void CheckArenaAfterTimerConditions(); - void CheckArenaWinConditions(); - void UpdateArenaWorldState(); // Triggers handle // must be implemented in BG subclass virtual void HandleAreaTrigger(Player* /*player*/, uint32 /*Trigger*/); // must be implemented in BG subclass if need AND call base class generic code virtual void HandleKillPlayer(Player* player, Player* killer); - virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/); + virtual void HandleKillUnit(Creature* /*creature*/, Player* /*killer*/) { } // Battleground events virtual void EventPlayerDroppedFlag(Player* /*player*/) { } @@ -535,6 +514,8 @@ class Battleground BGHonorMode m_HonorMode; int32 m_TeamScores[BG_TEAMS_COUNT]; + ArenaTeamScore _arenaTeamScores[BG_TEAMS_COUNT]; + private: // Battleground BattlegroundTypeId m_TypeID; @@ -553,7 +534,7 @@ class Battleground bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattlegroundMgr.BGFreeSlotQueue[bgTypeId] deque bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave bool m_IsArena; - uint8 m_Winner; // 0=alliance, 1=horde, 2=none + BattlegroundTeamId _winnerTeamId; int32 m_StartDelayTime; bool m_IsRated; // is this battle rated? bool m_PrematureCountDown; @@ -612,57 +593,6 @@ class Battleground uint32 m_ArenaTeamMMR[BG_TEAMS_COUNT]; - struct ArenaTeamScore - { - friend class Battleground; - - protected: - ArenaTeamScore() : RatingChange(0), MatchmakerRating(0) { } - - virtual ~ArenaTeamScore() { } - - void Assign(int32 ratingChange, uint32 matchMakerRating, std::string const& teamName) - { - RatingChange = ratingChange; - MatchmakerRating = matchMakerRating; - TeamName = teamName; - } - - void BuildRatingInfoBlock(WorldPacket& data) - { - uint32 ratingLost = std::abs(std::min(RatingChange, 0)); - uint32 ratingWon = std::max(RatingChange, 0); - - // should be old rating, new rating, and client will calculate rating change itself - data << uint32(MatchmakerRating); - data << uint32(ratingLost); - data << uint32(ratingWon); - } - - void BuildTeamInfoLengthBlock(WorldPacket& data) - { - data.WriteBits(TeamName.length(), 8); - } - - void BuildTeamInfoBlock(WorldPacket& data) - { - data.WriteString(TeamName); - } - - void Reset() - { - RatingChange = 0; - MatchmakerRating = 0; - TeamName.clear(); - } - - int32 RatingChange; - uint32 MatchmakerRating; - std::string TeamName; - }; - - ArenaTeamScore _arenaTeamScores[BG_TEAMS_COUNT]; - // Limits uint32 m_LevelMin; uint32 m_LevelMax; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index c6514b834f0..9a22052e17d 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -1234,7 +1234,7 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId) // there is only one bg to select if (selectionWeights.size() == 1) - return bgTypeId; + return selectionWeights.begin()->first; if (weight) { diff --git a/src/server/game/Battlegrounds/BattlegroundScore.h b/src/server/game/Battlegrounds/BattlegroundScore.h index c532c8e8eb9..86ed320f8c6 100644 --- a/src/server/game/Battlegrounds/BattlegroundScore.h +++ b/src/server/game/Battlegrounds/BattlegroundScore.h @@ -53,6 +53,7 @@ enum ScoreType struct BattlegroundScore { + friend class Arena; friend class Battleground; protected: diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp index 548e0bf463b..916531e3947 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp @@ -16,32 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "BattlegroundBE.h" -#include "Language.h" -#include "Object.h" -#include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" BattlegroundBE::BattlegroundBE() { BgObjects.resize(BG_BE_OBJECT_MAX); - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - //we must set messageIds - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; -} - -BattlegroundBE::~BattlegroundBE() -{ - } void BattlegroundBE::StartingEventCloseDoors() @@ -62,39 +43,6 @@ void BattlegroundBE::StartingEventOpenDoors() SpawnBGObject(i, 60); } -void BattlegroundBE::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - UpdateArenaWorldState(); -} - -void BattlegroundBE::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - -void BattlegroundBE::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - void BattlegroundBE::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -111,16 +59,10 @@ void BattlegroundBE::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundBE::FillInitialWorldStates(WorldPacket &data) -{ - data << uint32(0x9f3) << uint32(1); // 9 - UpdateArenaWorldState(); -} - -void BattlegroundBE::Reset() +void BattlegroundBE::FillInitialWorldStates(WorldPacket& data) { - //call parent's class reset - Battleground::Reset(); + data << uint32(0x9f3) << uint32(1); // 9 show + Arena::FillInitialWorldStates(data); } bool BattlegroundBE::SetupBattleground() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h index 6fd4dc37fc8..f391edbf747 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h @@ -19,7 +19,7 @@ #ifndef __BATTLEGROUNDBE_H #define __BATTLEGROUNDBE_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundBEObjectTypes { @@ -32,7 +32,7 @@ enum BattlegroundBEObjectTypes BG_BE_OBJECT_MAX = 6 }; -enum BattlegroundBEObjects +enum BattlegroundBEGameObjects { BG_BE_OBJECT_TYPE_DOOR_1 = 183971, BG_BE_OBJECT_TYPE_DOOR_2 = 183973, @@ -42,22 +42,17 @@ enum BattlegroundBEObjects BG_BE_OBJECT_TYPE_BUFF_2 = 184664 }; -class BattlegroundBE : public Battleground +class BattlegroundBE : public Arena { public: BattlegroundBE(); - ~BattlegroundBE(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void Reset(); void FillInitialWorldStates(WorldPacket &d); - void HandleKillPlayer(Player* player, Player* killer); }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp index 1d6970f8317..864faa30916 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp @@ -16,12 +16,9 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "BattlegroundDS.h" #include "Creature.h" #include "GameObject.h" -#include "Language.h" -#include "ObjectAccessor.h" #include "Player.h" #include "WorldPacket.h" @@ -30,25 +27,8 @@ BattlegroundDS::BattlegroundDS() BgObjects.resize(BG_DS_OBJECT_MAX); BgCreatures.resize(BG_DS_NPC_MAX); - _waterfallTimer = 0; - _waterfallStatus = 0; - _waterfallKnockbackTimer = 0; _pipeKnockBackTimer = 0; _pipeKnockBackCount = 0; - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; -} - -BattlegroundDS::~BattlegroundDS() -{ - } void BattlegroundDS::PostUpdateImpl(uint32 diff) @@ -56,64 +36,58 @@ void BattlegroundDS::PostUpdateImpl(uint32 diff) if (GetStatus() != STATUS_IN_PROGRESS) return; - if (getPipeKnockBackCount() < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT) - { - if (getPipeKnockBackTimer() < diff) - { - for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i) - if (Creature* waterSpout = GetBgMap()->GetCreature(BgCreatures[i])) - waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true); - - setPipeKnockBackCount(getPipeKnockBackCount() + 1); - setPipeKnockBackTimer(BG_DS_PIPE_KNOCKBACK_DELAY); - } - else - setPipeKnockBackTimer(getPipeKnockBackTimer() - diff); - } + _events.Update(diff); - if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_ON) // Repeat knockback while the waterfall still active + while (uint32 eventId = _events.ExecuteEvent()) { - if (getWaterFallKnockbackTimer() < diff) + switch (eventId) { - if (Creature* waterSpout = GetBgMap()->GetCreature(BgCreatures[BG_DS_NPC_WATERFALL_KNOCKBACK])) - waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true); - - setWaterFallKnockbackTimer(BG_DS_WATERFALL_KNOCKBACK_TIMER); + case BG_DS_EVENT_WATERFALL_WARNING: + // Add the water + DoorClose(BG_DS_OBJECT_WATER_2); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_ON, BG_DS_WATERFALL_WARNING_DURATION); + break; + case BG_DS_EVENT_WATERFALL_ON: + // Active collision and start knockback timer + DoorClose(BG_DS_OBJECT_WATER_1); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_OFF, BG_DS_WATERFALL_DURATION); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK, BG_DS_WATERFALL_KNOCKBACK_TIMER); + break; + case BG_DS_EVENT_WATERFALL_OFF: + // Remove collision and water + DoorOpen(BG_DS_OBJECT_WATER_1); + DoorOpen(BG_DS_OBJECT_WATER_2); + _events.CancelEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX)); + break; + case BG_DS_EVENT_WATERFALL_KNOCKBACK: + // Repeat knockback while the waterfall still active + if (Creature* waterSpout = GetBGCreature(BG_DS_NPC_WATERFALL_KNOCKBACK)) + waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true); + _events.ScheduleEvent(eventId, BG_DS_WATERFALL_KNOCKBACK_TIMER); + break; + case BG_DS_EVENT_PIPE_KNOCKBACK: + for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i) + if (Creature* waterSpout = GetBGCreature(i)) + waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true); + break; } - else - setWaterFallKnockbackTimer(getWaterFallKnockbackTimer() - diff); } - if (getWaterFallTimer() < diff) + if (_pipeKnockBackCount < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT) { - if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_OFF) // Add the water - { - DoorClose(BG_DS_OBJECT_WATER_2); - setWaterFallTimer(BG_DS_WATERFALL_WARNING_DURATION); - setWaterFallStatus(BG_DS_WATERFALL_STATUS_WARNING); - } - else if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_WARNING) // Active collision and start knockback timer - { - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1])) - gob->SetGoState(GO_STATE_READY); - - setWaterFallTimer(BG_DS_WATERFALL_DURATION); - setWaterFallStatus(BG_DS_WATERFALL_STATUS_ON); - setWaterFallKnockbackTimer(BG_DS_WATERFALL_KNOCKBACK_TIMER); - } - else //if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_ON) // Remove collision and water + if (_pipeKnockBackTimer < diff) { - // turn off collision - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1])) - gob->SetGoState(GO_STATE_ACTIVE); + for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i) + if (Creature* waterSpout = GetBGCreature(i)) + waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true); - DoorOpen(BG_DS_OBJECT_WATER_2); - setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX)); - setWaterFallStatus(BG_DS_WATERFALL_STATUS_OFF); + ++_pipeKnockBackCount; + _pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_DELAY; } + else + _pipeKnockBackTimer -= diff; } - else - setWaterFallTimer(getWaterFallTimer() - diff); } void BattlegroundDS::StartingEventCloseDoors() @@ -130,57 +104,22 @@ void BattlegroundDS::StartingEventOpenDoors() for (uint32 i = BG_DS_OBJECT_BUFF_1; i <= BG_DS_OBJECT_BUFF_2; ++i) SpawnBGObject(i, 60); - setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX)); - setWaterFallStatus(BG_DS_WATERFALL_STATUS_OFF); + _events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX)); + //for (uint8 i = 0; i < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT; ++i) + // _events.ScheduleEvent(BG_DS_EVENT_PIPE_KNOCKBACK, BG_DS_PIPE_KNOCKBACK_FIRST_DELAY + i * BG_DS_PIPE_KNOCKBACK_DELAY); - setPipeKnockBackTimer(BG_DS_PIPE_KNOCKBACK_FIRST_DELAY); - setPipeKnockBackCount(0); + _pipeKnockBackCount = 0; + _pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_FIRST_DELAY; SpawnBGObject(BG_DS_OBJECT_WATER_2, RESPAWN_IMMEDIATELY); - DoorOpen(BG_DS_OBJECT_WATER_2); - // Turn off collision - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1])) - gob->SetGoState(GO_STATE_ACTIVE); + DoorOpen(BG_DS_OBJECT_WATER_1); // Turn off collision + DoorOpen(BG_DS_OBJECT_WATER_2); // Remove effects of Demonic Circle Summon for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer(itr->first)) - if (player->HasAura(48018)) - player->RemoveAurasDueToSpell(48018); -} - -void BattlegroundDS::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - UpdateArenaWorldState(); -} - -void BattlegroundDS::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - -void BattlegroundDS::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "BattlegroundDS: Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateArenaWorldState(); - CheckArenaWinConditions(); + if (Player* player = _GetPlayer(itr, "BattlegroundDS::StartingEventOpenDoors")) + player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE); } void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger) @@ -193,13 +132,12 @@ void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger) case 5347: case 5348: // Remove effects of Demonic Circle Summon - if (player->HasAura(48018)) - player->RemoveAurasDueToSpell(48018); + player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE); // Someone has get back into the pipes and the knockback has already been performed, // so we reset the knockback count for kicking the player again into the arena. - if (getPipeKnockBackCount() >= BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT) - setPipeKnockBackCount(0); + if (_pipeKnockBackCount >= BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT) + _pipeKnockBackCount = 0; break; default: Battleground::HandleAreaTrigger(player, trigger); @@ -207,16 +145,10 @@ void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundDS::FillInitialWorldStates(WorldPacket &data) -{ - data << uint32(3610) << uint32(1); // 9 show - UpdateArenaWorldState(); -} - -void BattlegroundDS::Reset() +void BattlegroundDS::FillInitialWorldStates(WorldPacket& data) { - //call parent's class reset - Battleground::Reset(); + data << uint32(3610) << uint32(1); // 9 show + Arena::FillInitialWorldStates(data); } bool BattlegroundDS::SetupBattleground() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h index cb71300dc5d..4c763316d83 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h @@ -19,7 +19,7 @@ #ifndef __BATTLEGROUNDDS_H #define __BATTLEGROUNDDS_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundDSObjectTypes { @@ -32,7 +32,7 @@ enum BattlegroundDSObjectTypes BG_DS_OBJECT_MAX = 6 }; -enum BattlegroundDSObjects +enum BattlegroundDSGameObjects { BG_DS_OBJECT_TYPE_DOOR_1 = 192642, BG_DS_OBJECT_TYPE_DOOR_2 = 192643, @@ -59,61 +59,54 @@ enum BattlegroundDSSpells { BG_DS_SPELL_FLUSH = 57405, // Visual and target selector for the starting knockback from the pipe BG_DS_SPELL_FLUSH_KNOCKBACK = 61698, // Knockback effect for previous spell (triggered, not needed to be cast) - BG_DS_SPELL_WATER_SPOUT = 58873 // Knockback effect of the central waterfall + BG_DS_SPELL_WATER_SPOUT = 58873, // Knockback effect of the central waterfall + + SPELL_WARL_DEMONIC_CIRCLE = 48018 // Demonic Circle Summon }; enum BattlegroundDSData -{ // These values are NOT blizzlike... need the correct data! - BG_DS_WATERFALL_TIMER_MIN = 30000, - BG_DS_WATERFALL_TIMER_MAX = 60000, - BG_DS_WATERFALL_WARNING_DURATION = 5000, - BG_DS_WATERFALL_DURATION = 30000, - BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500, - - BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000, - BG_DS_PIPE_KNOCKBACK_DELAY = 3000, - BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT = 2, - - BG_DS_WATERFALL_STATUS_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking - BG_DS_WATERFALL_STATUS_ON = 2, // LoS and Movement blocking active - BG_DS_WATERFALL_STATUS_OFF = 3 +{ + // These values are NOT blizzlike... need the correct data! + BG_DS_WATERFALL_TIMER_MIN = 30000, + BG_DS_WATERFALL_TIMER_MAX = 60000, + BG_DS_WATERFALL_WARNING_DURATION = 5000, + BG_DS_WATERFALL_DURATION = 30000, + BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500, + + BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000, + BG_DS_PIPE_KNOCKBACK_DELAY = 3000, + BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT = 2, +}; + +enum BattlegroundDSEvents +{ + BG_DS_EVENT_WATERFALL_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking + BG_DS_EVENT_WATERFALL_ON = 2, // LoS and Movement blocking active + BG_DS_EVENT_WATERFALL_OFF = 3, + BG_DS_EVENT_WATERFALL_KNOCKBACK = 4, + + BG_DS_EVENT_PIPE_KNOCKBACK = 5 }; -class BattlegroundDS : public Battleground +class BattlegroundDS : public Arena { public: BattlegroundDS(); - ~BattlegroundDS(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void Reset(); void FillInitialWorldStates(WorldPacket &d); - void HandleKillPlayer(Player* player, Player* killer); + private: - uint32 _waterfallTimer; - uint8 _waterfallStatus; - uint32 _waterfallKnockbackTimer; + void PostUpdateImpl(uint32 diff); + + EventMap _events; + uint32 _pipeKnockBackTimer; uint8 _pipeKnockBackCount; - - void PostUpdateImpl(uint32 diff); - protected: - uint32 getWaterFallStatus() { return _waterfallStatus; } - void setWaterFallStatus(uint8 status) { _waterfallStatus = status; } - uint32 getWaterFallTimer() { return _waterfallTimer; } - void setWaterFallTimer(uint32 timer) { _waterfallTimer = timer; } - uint32 getWaterFallKnockbackTimer() { return _waterfallKnockbackTimer; } - void setWaterFallKnockbackTimer(uint32 timer) { _waterfallKnockbackTimer = timer; } - uint8 getPipeKnockBackCount() { return _pipeKnockBackCount; } - void setPipeKnockBackCount(uint8 count) { _pipeKnockBackCount = count; } - uint32 getPipeKnockBackTimer() { return _pipeKnockBackTimer; } - void setPipeKnockBackTimer(uint32 timer) { _pipeKnockBackTimer = timer; } }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index 5be74dcca92..e5de2e86a2e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -500,7 +500,7 @@ void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* target if (!AddObject(nodePoint[i].gameobject_type, nodePoint[i].gameobject_entry, cords[0], cords[1], cords[2], cords[3], 0, 0, 0, 0, RESPAWN_ONE_DAY)) { TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a banner (type: %u, entry: %u). Isle of Conquest BG cancelled.", nodePoint[i].gameobject_type, nodePoint[i].gameobject_entry); - Battleground::EndBattleground(WINNER_NONE); + EndBattleground(0); } GetBGObject(nodePoint[i].gameobject_type)->SetUInt32Value(GAMEOBJECT_FACTION, nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp index 82fcb2f6f91..46128c44d69 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp @@ -16,32 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "BattlegroundNA.h" -#include "Language.h" -#include "Object.h" -#include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" BattlegroundNA::BattlegroundNA() { BgObjects.resize(BG_NA_OBJECT_MAX); - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - //we must set messageIds - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; -} - -BattlegroundNA::~BattlegroundNA() -{ - } void BattlegroundNA::StartingEventCloseDoors() @@ -59,39 +40,6 @@ void BattlegroundNA::StartingEventOpenDoors() SpawnBGObject(i, 60); } -void BattlegroundNA::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - UpdateArenaWorldState(); -} - -void BattlegroundNA::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - -void BattlegroundNA::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "BattlegroundNA: Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - void BattlegroundNA::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -108,16 +56,10 @@ void BattlegroundNA::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundNA::FillInitialWorldStates(WorldPacket &data) -{ - data << uint32(0xa11) << uint32(1); // 9 - UpdateArenaWorldState(); -} - -void BattlegroundNA::Reset() +void BattlegroundNA::FillInitialWorldStates(WorldPacket& data) { - //call parent's class reset - Battleground::Reset(); + data << uint32(0xa11) << uint32(1); // 9 show + Arena::FillInitialWorldStates(data); } bool BattlegroundNA::SetupBattleground() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h index dd21e44f593..2fa93a07651 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h @@ -18,7 +18,7 @@ #ifndef __BATTLEGROUNDNA_H #define __BATTLEGROUNDNA_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundNAObjectTypes { @@ -31,7 +31,7 @@ enum BattlegroundNAObjectTypes BG_NA_OBJECT_MAX = 6 }; -enum BattlegroundNAObjects +enum BattlegroundNAGameObjects { BG_NA_OBJECT_TYPE_DOOR_1 = 183978, BG_NA_OBJECT_TYPE_DOOR_2 = 183980, @@ -41,22 +41,17 @@ enum BattlegroundNAObjects BG_NA_OBJECT_TYPE_BUFF_2 = 184664 }; -class BattlegroundNA : public Battleground +class BattlegroundNA : public Arena { public: BattlegroundNA(); - ~BattlegroundNA(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void Reset(); void FillInitialWorldStates(WorldPacket &d); - void HandleKillPlayer(Player* player, Player* killer); }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp index 712d9a6e296..f474946e069 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp @@ -16,32 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "BattlegroundRL.h" -#include "Language.h" -#include "Object.h" -#include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" BattlegroundRL::BattlegroundRL() { BgObjects.resize(BG_RL_OBJECT_MAX); - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - //we must set messageIds - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; -} - -BattlegroundRL::~BattlegroundRL() -{ - } void BattlegroundRL::StartingEventCloseDoors() @@ -59,39 +40,6 @@ void BattlegroundRL::StartingEventOpenDoors() SpawnBGObject(i, 60); } -void BattlegroundRL::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - UpdateArenaWorldState(); -} - -void BattlegroundRL::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - -void BattlegroundRL::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateArenaWorldState(); - CheckArenaWinConditions(); -} - void BattlegroundRL::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -108,16 +56,10 @@ void BattlegroundRL::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundRL::FillInitialWorldStates(WorldPacket &data) -{ - data << uint32(0xbba) << uint32(1); // 9 - UpdateArenaWorldState(); -} - -void BattlegroundRL::Reset() +void BattlegroundRL::FillInitialWorldStates(WorldPacket& data) { - //call parent's reset - Battleground::Reset(); + data << uint32(0xbba) << uint32(1); // 9 show + Arena::FillInitialWorldStates(data); } bool BattlegroundRL::SetupBattleground() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h index 27974108168..ad4fe18a3c7 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h @@ -18,7 +18,7 @@ #ifndef __BATTLEGROUNDRL_H #define __BATTLEGROUNDRL_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundRLObjectTypes { @@ -29,7 +29,7 @@ enum BattlegroundRLObjectTypes BG_RL_OBJECT_MAX = 4 }; -enum BattlegroundRLObjects +enum BattlegroundRLGameObjects { BG_RL_OBJECT_TYPE_DOOR_1 = 185918, BG_RL_OBJECT_TYPE_DOOR_2 = 185917, @@ -37,22 +37,17 @@ enum BattlegroundRLObjects BG_RL_OBJECT_TYPE_BUFF_2 = 184664 }; -class BattlegroundRL : public Battleground +class BattlegroundRL : public Arena { public: BattlegroundRL(); - ~BattlegroundRL(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); - void Reset(); void FillInitialWorldStates(WorldPacket &d); void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void HandleKillPlayer(Player* player, Player* killer); }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp index 1059124d041..9609009d610 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp @@ -16,70 +16,54 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" -#include "Battleground.h" #include "BattlegroundRV.h" +#include "GameObject.h" #include "ObjectAccessor.h" -#include "Language.h" #include "Player.h" #include "WorldPacket.h" -#include "GameObject.h" BattlegroundRV::BattlegroundRV() { BgObjects.resize(BG_RV_OBJECT_MAX); - Timer = 0; - State = 0; - PillarCollision = false; - - StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; - StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; - StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; - StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE; - StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE; - StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS; - StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; - StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; + _timer = 0; + _state = 0; + _pillarCollision = false; } -BattlegroundRV::~BattlegroundRV() { } - void BattlegroundRV::PostUpdateImpl(uint32 diff) { if (GetStatus() != STATUS_IN_PROGRESS) return; - if (getTimer() < diff) + if (_timer < diff) { - switch (getState()) + switch (_state) { case BG_RV_STATE_OPEN_FENCES: // Open fire (only at game start) for (uint8 i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i) DoorOpen(i); - setTimer(BG_RV_CLOSE_FIRE_TIMER); - setState(BG_RV_STATE_CLOSE_FIRE); + _timer = BG_RV_CLOSE_FIRE_TIMER; + _state = BG_RV_STATE_CLOSE_FIRE; break; case BG_RV_STATE_CLOSE_FIRE: for (uint8 i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i) DoorClose(i); // Fire got closed after five seconds, leaves twenty seconds before toggling pillars - setTimer(BG_RV_FIRE_TO_PILLAR_TIMER); - setState(BG_RV_STATE_SWITCH_PILLARS); + _timer = BG_RV_FIRE_TO_PILLAR_TIMER; + _state = BG_RV_STATE_SWITCH_PILLARS; break; case BG_RV_STATE_SWITCH_PILLARS: TogglePillarCollision(); - setTimer(BG_RV_PILLAR_SWITCH_TIMER); + _timer = BG_RV_PILLAR_SWITCH_TIMER; break; } } else - setTimer(getTimer() - diff); + _timer -= diff; } -void BattlegroundRV::StartingEventCloseDoors() { } - void BattlegroundRV::StartingEventOpenDoors() { // Buff respawn @@ -89,53 +73,14 @@ void BattlegroundRV::StartingEventOpenDoors() DoorOpen(BG_RV_OBJECT_ELEVATOR_1); DoorOpen(BG_RV_OBJECT_ELEVATOR_2); - setState(BG_RV_STATE_OPEN_FENCES); - setTimer(BG_RV_FIRST_TIMER); + _state = BG_RV_STATE_OPEN_FENCES; + _timer = BG_RV_FIRST_TIMER; // Should be false at first, TogglePillarCollision will do it. - SetPillarCollision(true); + _pillarCollision = true; TogglePillarCollision(); } -void BattlegroundRV::AddPlayer(Player* player) -{ - Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); - - UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE)); - UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE)); -} - -void BattlegroundRV::RemovePlayer(Player* /*player*/, uint64 /*guid*/, uint32 /*team*/) -{ - if (GetStatus() == STATUS_WAIT_LEAVE) - return; - - UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE)); - UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE)); - - CheckArenaWinConditions(); -} - -void BattlegroundRV::HandleKillPlayer(Player* player, Player* killer) -{ - if (GetStatus() != STATUS_IN_PROGRESS) - return; - - if (!killer) - { - TC_LOG_ERROR("bg.battleground", "BattlegroundRV: Killer player not found"); - return; - } - - Battleground::HandleKillPlayer(player, killer); - - UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(ALLIANCE)); - UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(HORDE)); - - CheckArenaWinConditions(); -} - void BattlegroundRV::HandleAreaTrigger(Player* player, uint32 trigger) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -155,17 +100,10 @@ void BattlegroundRV::HandleAreaTrigger(Player* player, uint32 trigger) } } -void BattlegroundRV::FillInitialWorldStates(WorldPacket &data) +void BattlegroundRV::FillInitialWorldStates(WorldPacket& data) { - data << uint32(BG_RV_WORLD_STATE_A) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); - data << uint32(BG_RV_WORLD_STATE_H) << uint32(GetAlivePlayersCountByTeam(HORDE)); data << uint32(BG_RV_WORLD_STATE) << uint32(1); -} - -void BattlegroundRV::Reset() -{ - //call parent's class reset - Battleground::Reset(); + Arena::FillInitialWorldStates(data); } bool BattlegroundRV::SetupBattleground() @@ -197,9 +135,7 @@ bool BattlegroundRV::SetupBattleground() || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_1, BG_RV_OBJECT_TYPE_PILAR_COLLISION_1, 763.632385f, -306.162384f, 30.639660f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY) || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_2, BG_RV_OBJECT_TYPE_PILAR_COLLISION_2, 723.644287f, -284.493256f, 32.382710f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY) || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_3, BG_RV_OBJECT_TYPE_PILAR_COLLISION_3, 763.611145f, -261.856750f, 30.639660f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY) - || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_4, BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY) - -) + || !AddObject(BG_RV_OBJECT_PILAR_COLLISION_4, BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)) { TC_LOG_ERROR("sql.sql", "BatteGroundRV: Failed to spawn some object!"); return false; @@ -207,38 +143,30 @@ bool BattlegroundRV::SetupBattleground() return true; } - void BattlegroundRV::TogglePillarCollision() { - bool apply = GetPillarCollision(); - // Toggle visual pillars, pulley, gear, and collision based on previous state for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_GEAR_2; ++i) - apply ? DoorOpen(i) : DoorClose(i); + _pillarCollision ? DoorOpen(i) : DoorClose(i); for (uint8 i = BG_RV_OBJECT_PILAR_2; i <= BG_RV_OBJECT_PULLEY_2; ++i) - apply ? DoorClose(i) : DoorOpen(i); + _pillarCollision ? DoorClose(i) : DoorOpen(i); for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PILAR_COLLISION_4; ++i) { - if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[i])) + if (GameObject* go = GetBGObject(i)) { if (i >= BG_RV_OBJECT_PILAR_COLLISION_1) { - uint32 _state = GO_STATE_READY; - if (gob->GetGOInfo()->door.startOpen) - _state = GO_STATE_ACTIVE; - gob->SetGoState(apply ? (GOState)_state : (GOState)(!_state)); - - if (gob->GetGOInfo()->door.startOpen) - gob->EnableCollision(!apply); // Forced collision toggle + GOState state = (bool(go->GetGOInfo()->door.startOpen) == _pillarCollision) ? GO_STATE_ACTIVE : GO_STATE_READY; + go->SetGoState(state); } - for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) - gob->SendUpdateToPlayer(player); + for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if (Player* player = ObjectAccessor::FindPlayer(itr->first)) + go->SendUpdateToPlayer(player); } } - SetPillarCollision(!apply); + _pillarCollision = !_pillarCollision; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h index 454ea723f8b..d23f6757b83 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h @@ -18,7 +18,7 @@ #ifndef __BATTLEGROUNDRV_H #define __BATTLEGROUNDRV_H -#include "Battleground.h" +#include "Arena.h" enum BattlegroundRVObjectTypes { @@ -49,7 +49,7 @@ enum BattlegroundRVObjectTypes BG_RV_OBJECT_MAX }; -enum BattlegroundRVObjects +enum BattlegroundRVGameObjects { BG_RV_OBJECT_TYPE_BUFF_1 = 184663, BG_RV_OBJECT_TYPE_BUFF_2 = 184664, @@ -86,44 +86,29 @@ enum BattlegroundRVData BG_RV_FIRE_TO_PILLAR_TIMER = 20000, BG_RV_CLOSE_FIRE_TIMER = 5000, BG_RV_FIRST_TIMER = 20133, - BG_RV_WORLD_STATE_A = 0xe10, - BG_RV_WORLD_STATE_H = 0xe11, + BG_RV_WORLD_STATE = 0xe1a }; -class BattlegroundRV : public Battleground +class BattlegroundRV : public Arena { public: BattlegroundRV(); - ~BattlegroundRV(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); - void StartingEventCloseDoors(); void StartingEventOpenDoors(); - void Reset(); void FillInitialWorldStates(WorldPacket &d); - void RemovePlayer(Player* player, uint64 guid, uint32 team); void HandleAreaTrigger(Player* Source, uint32 Trigger); bool SetupBattleground(); - void HandleKillPlayer(Player* player, Player* killer); private: - uint32 Timer; - uint32 State; - bool PillarCollision; - void PostUpdateImpl(uint32 diff); - protected: - uint32 getTimer() { return Timer; } - void setTimer(uint32 timer) { Timer = timer; } - - uint32 getState() { return State; } - void setState(uint32 state) { State = state; } void TogglePillarCollision(); - bool GetPillarCollision() { return PillarCollision; } - void SetPillarCollision(bool apply) { PillarCollision = apply; } + + uint32 _timer; + uint32 _state; + bool _pillarCollision; }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 740350dd10b..bcf7093a640 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -82,7 +82,7 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff) if (GetTeamScore(TEAM_ALLIANCE) == 0) { if (GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie - EndBattleground(WINNER_NONE); + EndBattleground(0); else // Horde has more points and thus wins EndBattleground(HORDE); } diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index 7354be4a9b4..e47a23d467c 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -441,8 +441,8 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite) if (!calendarEvent) // Pre-invite { - if (Player* player = ObjectAccessor::FindPlayer(invite.GetSenderGUID())) - player->SendDirectMessage(&data); + if (Player* playerSender = ObjectAccessor::FindPlayer(invite.GetSenderGUID())) + playerSender->SendDirectMessage(&data); } else { diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 91733168f50..cc1cc20d3ce 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -655,7 +655,7 @@ struct BattlemasterListEntry { uint32 id; // 0 int32 mapid[8]; // 1-8 mapid - uint32 type; // 9 (3 - BG, 4 - arena) + uint32 type; // 9 map type (3 - BG, 4 - arena) //uint32 canJoinAsGroup; // 10 (0 or 1) char* name; // 11 uint32 maxGroupSize; // 12 maxGroupSize, used for checking if queue as group diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index a7332422c07..4be90d7e082 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -49,8 +49,8 @@ #include "DynamicTree.h" #include "Unit.h" #include "Group.h" -#include "Battlefield.h" #include "BattlefieldMgr.h" +#include "Battleground.h" #include "Chat.h" uint32 GuidHigh2TypeId(uint32 guid_hi) @@ -732,7 +732,7 @@ uint32 Object::GetUpdateFieldData(Player const* target, uint32*& flags) const case TYPEID_ITEM: case TYPEID_CONTAINER: flags = ItemUpdateFieldFlags; - if (((Item*)this)->GetOwnerGUID() == target->GetGUID()) + if (((Item const*)this)->GetOwnerGUID() == target->GetGUID()) visibleFlag |= UF_FLAG_OWNER | UF_FLAG_ITEM_OWNER; break; case TYPEID_UNIT: @@ -758,7 +758,7 @@ uint32 Object::GetUpdateFieldData(Player const* target, uint32*& flags) const break; case TYPEID_DYNAMICOBJECT: flags = DynamicObjectUpdateFieldFlags; - if (((DynamicObject*)this)->GetCasterGUID() == target->GetGUID()) + if (ToDynObject()->GetCasterGUID() == target->GetGUID()) visibleFlag |= UF_FLAG_OWNER; break; case TYPEID_CORPSE: diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index c1b0ef43dbf..91c1aa52592 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -523,6 +523,7 @@ void Pet::setDeathState(DeathState s) // overwrite virtual // pet corpse non lootable and non skinnable SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b866dcc7a67..2a1635aea41 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17570,7 +17570,6 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) if (!map) { - PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass()); mapId = info->mapId; Relocate(info->positionX, info->positionY, info->positionZ, 0.0f); map = sMapMgr->CreateMap(mapId, this); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 81aef2c0f2f..da721cfc575 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -10382,8 +10382,8 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co } // can't assist non-friendly targets - if (GetReactionTo(target) <= REP_NEUTRAL - && target->GetReactionTo(this) <= REP_NEUTRAL + if (GetReactionTo(target) < REP_NEUTRAL + && target->GetReactionTo(this) < REP_NEUTRAL && (!ToCreature() || !(ToCreature()->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER))) return false; @@ -11289,7 +11289,7 @@ float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit const* source = casterOwner ? casterOwner : caster; if ((target->GetTypeId() == TYPEID_PLAYER - || ((Creature*)target)->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH) + || target->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH) && source->GetTypeId() == TYPEID_PLAYER) duration = limitduration; } diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 508635af25f..48ae15285a9 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -957,13 +957,13 @@ namespace Trinity if (owner) check = owner; i_targetForPlayer = (check->GetTypeId() == TYPEID_PLAYER); - if (i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT) - _spellInfo = sSpellMgr->GetSpellInfo(((DynamicObject*)i_obj)->GetSpellId()); + if (DynamicObject const* dynObj = i_obj->ToDynObject()) + _spellInfo = sSpellMgr->GetSpellInfo(dynObj->GetSpellId()); } bool operator()(Unit* u) { // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems - if (u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->IsTotem()) + if (u->GetTypeId() == TYPEID_UNIT && u->ToCreature()->IsTotem()) return false; if (i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : NULL) && i_obj->IsWithinDistInMap(u, i_range)) diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index c8d495baab2..46e1352df3f 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 ce9b2448dd4..7e9be651e61 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<GameObject*> DoorSet; -typedef std::set<Creature*> MinionSet; +typedef std::set<uint64> DoorSet; +typedef std::set<uint64> MinionSet; enum EncounterFrameType { diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 0bfd804eed5..7e4bc05ee6e 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3796,6 +3796,15 @@ enum BanReturn BAN_NOTFOUND }; +enum BattlegroundTeamId +{ + BG_TEAM_HORDE = 0, // Battleground: Horde, Arena: Green + BG_TEAM_ALLIANCE = 1, // Battleground: Alliance, Arena: Gold + BG_TEAM_NEUTRAL = 2 // Battleground: Neutral, Arena: None +}; + +#define BG_TEAMS_COUNT 2 + // indexes of BattlemasterList.dbc enum BattlegroundTypeId { @@ -3958,6 +3967,7 @@ enum DuelCompleteType DUEL_WON = 1, DUEL_FLED = 2 }; + // handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time enum BattlegroundQueueTypeId { diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index ab962b69869..58accad1bf7 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -377,7 +377,9 @@ public: static bool HandleBanListAccountCommand(ChatHandler* handler, char const* args) { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS); + PreparedStatement* stmt = NULL; + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS); LoginDatabase.Execute(stmt); char* filterStr = strtok((char*)args, " "); @@ -387,12 +389,12 @@ public: if (filter.empty()) { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_ALL); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_ALL); result = LoginDatabase.Query(stmt); } else { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME); stmt->setString(0, filter); result = LoginDatabase.Query(stmt); } @@ -577,7 +579,8 @@ public: static bool HandleBanListIPCommand(ChatHandler* handler, char const* args) { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS); + PreparedStatement* stmt = NULL; + stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS); LoginDatabase.Execute(stmt); char* filterStr = strtok((char*)args, " "); @@ -588,12 +591,12 @@ public: if (filter.empty()) { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_ALL); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_ALL); result = LoginDatabase.Query(stmt); } else { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_BY_IP); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_BY_IP); stmt->setString(0, filter); result = LoginDatabase.Query(stmt); } diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp index d3f1e6bb092..ff0a5519495 100644 --- a/src/server/scripts/Commands/cs_list.cpp +++ b/src/server/scripts/Commands/cs_list.cpp @@ -471,6 +471,7 @@ public: Player* target; uint64 targetGuid; std::string targetName; + PreparedStatement* stmt = NULL; if (!*args) return false; @@ -485,35 +486,38 @@ public: else if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_LIST_COUNT); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_LIST_COUNT); stmt->setUInt32(0, targetGuid); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - if (result) + PreparedQueryResult queryResult = CharacterDatabase.Query(stmt); + if (queryResult) { - Field* fields = result->Fetch(); - uint32 countMail = fields[0].GetUInt64(); + Field* fields = queryResult->Fetch(); + uint32 countMail = fields[0].GetUInt64(); + std::string nameLink = handler->playerLink(targetName); handler->PSendSysMessage(LANG_LIST_MAIL_HEADER, countMail, nameLink.c_str(), targetGuid); handler->PSendSysMessage(LANG_ACCOUNT_LIST_BAR); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_LIST_INFO); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_LIST_INFO); stmt->setUInt32(0, targetGuid); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - if (result) + PreparedQueryResult queryResult = CharacterDatabase.Query(stmt); + + if (queryResult) { do { - Field* fields = result->Fetch(); - uint32 messageId = fields[0].GetUInt32(); - uint32 senderId = fields[1].GetUInt32(); - std::string sender = fields[2].GetString(); - uint32 receiverId = fields[3].GetUInt32(); - std::string receiver = fields[4].GetString(); - std::string subject = fields[5].GetString(); - uint64 deliverTime = fields[6].GetUInt32(); - uint64 expireTime = fields[7].GetUInt32(); - uint32 money = fields[8].GetUInt32(); - int hasItem = fields[9].GetUInt8(); - uint32 gold = money /GOLD; + Field* queryFields = queryResult->Fetch(); + uint32 messageId = queryFields[0].GetUInt32(); + uint32 senderId = queryFields[1].GetUInt32(); + std::string sender = queryFields[2].GetString(); + uint32 receiverId = queryFields[3].GetUInt32(); + std::string receiver = queryFields[4].GetString(); + std::string subject = queryFields[5].GetString(); + uint64 deliverTime = queryFields[6].GetUInt32(); + uint64 expireTime = queryFields[7].GetUInt32(); + uint32 money = queryFields[8].GetUInt32(); + uint8 hasItem = queryFields[9].GetUInt8(); + uint32 gold = money / GOLD; uint32 silv = (money % GOLD) / SILVER; uint32 copp = (money % GOLD) % SILVER; std::string receiverStr = handler->playerLink(receiver); @@ -521,6 +525,7 @@ public: handler->PSendSysMessage(LANG_LIST_MAIL_INFO_1, messageId, subject.c_str(), gold, silv, copp); handler->PSendSysMessage(LANG_LIST_MAIL_INFO_2, senderStr.c_str(), senderId, receiverStr.c_str(), receiverId); handler->PSendSysMessage(LANG_LIST_MAIL_INFO_3, TimeToTimestampStr(deliverTime).c_str(), TimeToTimestampStr(expireTime).c_str()); + if (hasItem == 1) { QueryResult result2; @@ -529,17 +534,17 @@ public: { do { - uint32 item_guid = (*result2)[0].GetUInt32(); - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_LIST_ITEMS); + uint32 item_guid = (*result2)[0].GetUInt32(); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_LIST_ITEMS); stmt->setUInt32(0, item_guid); PreparedQueryResult result3 = CharacterDatabase.Query(stmt); if (result3) { do { - Field* fields = result3->Fetch(); - uint32 item_entry = fields[0].GetUInt32(); - uint32 item_count = fields[1].GetUInt32(); + Field* fields3 = result3->Fetch(); + uint32 item_entry = fields3[0].GetUInt32(); + uint32 item_count = fields3[1].GetUInt32(); QueryResult result4; result4 = WorldDatabase.PQuery("SELECT name, quality FROM item_template WHERE entry = '%u'", item_entry); Field* fields1 = result4->Fetch(); @@ -563,7 +568,7 @@ public: } handler->PSendSysMessage(LANG_ACCOUNT_LIST_BAR); } - while (result->NextRow()); + while (queryResult->NextRow()); } else handler->PSendSysMessage(LANG_LIST_MAIL_NOT_FOUND); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 1d812a8f4eb..a3e8649854b 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1384,6 +1384,7 @@ public: Player* target; uint64 targetGuid; std::string targetName; + PreparedStatement* stmt = NULL; // To make sure we get a target, we convert our guid to an omniversal... uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); @@ -1513,7 +1514,7 @@ public: return false; // Query informations from the DB - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); stmt->setUInt32(0, lowguid); PreparedQueryResult result = CharacterDatabase.Query(stmt); @@ -1540,7 +1541,7 @@ public: } // Query the prepared statement for login data - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); stmt->setInt32(0, int32(realmID)); stmt->setUInt32(1, accId); PreparedQueryResult result = LoginDatabase.Query(stmt); @@ -1564,7 +1565,7 @@ public: EndianConvertReverse(ip); // If ip2nation table is populated, it displays the country - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP2NATION_COUNTRY); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP2NATION_COUNTRY); stmt->setUInt32(0, ip); if (PreparedQueryResult result2 = LoginDatabase.Query(stmt)) { @@ -1641,13 +1642,13 @@ public: PreparedQueryResult result5 = CharacterDatabase.Query(stmt3); if (result5) { - Field* fields = result5->Fetch(); - guildId = fields[0].GetUInt32(); - guildName = fields[1].GetString(); - guildRank = fields[2].GetString(); - guildRankId = fields[3].GetUInt8(); - note = fields[4].GetString(); - officeNote = fields[5].GetString(); + Field* fields5 = result5->Fetch(); + guildId = fields5[0].GetUInt32(); + guildName = fields5[1].GetString(); + guildRank = fields5[2].GetString(); + guildRankId = fields5[3].GetUInt8(); + note = fields5[4].GetString(); + officeNote = fields5[5].GetString(); } } } diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index 080e868a924..95ef5ab6984 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -369,8 +369,8 @@ public: handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMS_LINKED_HEADER));
rbac::RBACPermissionContainer const& permissions = permission->GetLinkedPermissions();
for (rbac::RBACPermissionContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it)
- if (rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*it))
- handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
+ if (rbac::RBACPermission const* rbacPermission = sAccountMgr->GetRBACPermission(*it))
+ handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, rbacPermission->GetId(), rbacPermission->GetName().c_str());
}
return true;
diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 210c47a7d3d..b1a90cf6f2e 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -238,6 +238,7 @@ public: { Creature* target = handler->getSelectedCreature(); + PreparedStatement* stmt = NULL; if (!target) { @@ -259,19 +260,15 @@ public: return true; } - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON); stmt->setUInt32(0, guidLow); - WorldDatabase.Execute(stmt); target->UpdateWaypointID(0); stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE); - stmt->setUInt8(0, uint8(IDLE_MOTION_TYPE)); stmt->setUInt32(1, guidLow); - WorldDatabase.Execute(stmt); target->LoadPath(0); @@ -289,6 +286,7 @@ public: char* show_str = strtok((char*)args, " "); std::string show = show_str; + PreparedStatement* stmt = NULL; // Check if ((show != "add") && (show != "mod") && (show != "del") && (show != "listid")) @@ -304,16 +302,14 @@ public: if (id) { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); stmt->setUInt32(0, id); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_SCRIPT); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_SCRIPT); stmt->setUInt32(0, id); - WorldDatabase.Execute(stmt); handler->PSendSysMessage("%s%s%u|r", "|cff00ff00", "Wp Event: New waypoint event added: ", id); @@ -323,16 +319,11 @@ public: } else { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID); PreparedQueryResult result = WorldDatabase.Query(stmt); - id = result->Fetch()->GetUInt32(); - stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_SCRIPT); - stmt->setUInt32(0, id + 1); - WorldDatabase.Execute(stmt); handler->PSendSysMessage("%s%s%u|r", "|cff00ff00", "Wp Event: New waypoint event added: |r|cff00ffff", id+1); @@ -355,7 +346,7 @@ public: float a8, a9, a10, a11; char const* a7; - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID); stmt->setUInt32(0, id); PreparedQueryResult result = WorldDatabase.Query(stmt); @@ -390,18 +381,14 @@ public: { id = atoi(arg_id); - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); stmt->setUInt32(0, id); - PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_SCRIPT); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_SCRIPT); stmt->setUInt32(0, id); - WorldDatabase.Execute(stmt); handler->PSendSysMessage("%s%s%u|r", "|cff00ff00", "Wp Event: Waypoint script removed: ", id); @@ -461,18 +448,16 @@ public: uint32 newid = atoi(arg_3); handler->PSendSysMessage("%s%s|r|cff00ffff%u|r|cff00ff00%s|r|cff00ffff%u|r", "|cff00ff00", "Wp Event: Wypoint scipt guid: ", newid, " id changed: ", id); - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_ID); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_ID); stmt->setUInt32(0, newid); stmt->setUInt32(1, id); - WorldDatabase.Execute(stmt); return true; } else { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); stmt->setUInt32(0, id); PreparedQueryResult result = WorldDatabase.Query(stmt); @@ -484,8 +469,7 @@ public: if (arg_str_2 == "posx") { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_X); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_X); stmt->setFloat(0, float(atof(arg_3))); stmt->setUInt32(1, id); @@ -496,8 +480,7 @@ public: } else if (arg_str_2 == "posy") { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_Y); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_Y); stmt->setFloat(0, float(atof(arg_3))); stmt->setUInt32(1, id); @@ -508,8 +491,7 @@ public: } else if (arg_str_2 == "posz") { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_Z); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_Z); stmt->setFloat(0, float(atof(arg_3))); stmt->setUInt32(1, id); @@ -520,8 +502,7 @@ public: } else if (arg_str_2 == "orientation") { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_O); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_SCRIPT_O); stmt->setFloat(0, float(atof(arg_3))); stmt->setUInt32(1, id); @@ -581,6 +562,7 @@ public: uint32 point = 0; uint32 wpGuid = 0; Creature* target = handler->getSelectedCreature(); + PreparedStatement* stmt = NULL; if (!target || target->GetEntry() != VISUAL_WAYPOINT) { @@ -594,7 +576,7 @@ public: // User did select a visual waypoint? // Check the creature - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID); stmt->setUInt32(0, wpGuid); PreparedQueryResult result = WorldDatabase.Query(stmt); @@ -609,16 +591,16 @@ public: // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html std::string maxDiff = "0.01"; - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_POS); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_POS); stmt->setFloat(0, target->GetPositionX()); stmt->setString(1, maxDiff); stmt->setFloat(2, target->GetPositionY()); stmt->setString(3, maxDiff); stmt->setFloat(4, target->GetPositionZ()); stmt->setString(5, maxDiff); - PreparedQueryResult result = WorldDatabase.Query(stmt); + PreparedQueryResult queryResult = WorldDatabase.Query(stmt); - if (!result) + if (!queryResult) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid); return true; @@ -656,18 +638,14 @@ public: wpCreature->AddObjectToRemoveList(); } - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA); stmt->setUInt32(0, pathid); stmt->setUInt32(1, point); - WorldDatabase.Execute(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POINT); - stmt->setUInt32(0, pathid); stmt->setUInt32(1, point); - WorldDatabase.Execute(stmt); handler->PSendSysMessage(LANG_WAYPOINT_REMOVED); @@ -718,14 +696,12 @@ public: //sMapMgr->GetMap(npcCreature->GetMapId())->Add(wpCreature2); } - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POSITION); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POSITION); stmt->setFloat(0, chr->GetPositionX()); stmt->setFloat(1, chr->GetPositionY()); stmt->setFloat(2, chr->GetPositionZ()); stmt->setUInt32(3, pathid); stmt->setUInt32(4, point); - WorldDatabase.Execute(stmt); handler->PSendSysMessage(LANG_WAYPOINT_CHANGED); @@ -767,6 +743,7 @@ public: uint32 pathid = 0; Creature* target = handler->getSelectedCreature(); + PreparedStatement* stmt = NULL; // Did player provide a PathID? @@ -810,10 +787,8 @@ public: return false; } - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID); stmt->setUInt32(0, target->GetGUIDLow()); - PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) @@ -846,10 +821,8 @@ public: if (show == "on") { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_BY_ID); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_BY_ID); stmt->setUInt32(0, pathid); - PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) @@ -882,10 +855,8 @@ public: handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid); hasError = true; - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); stmt->setUInt32(0, wpguid); - WorldDatabase.Execute(stmt); } else @@ -932,12 +903,10 @@ public: wpCreature->SetInPhase(phase, false, true); // Set "wpguid" column to the visual waypoint - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); stmt->setInt32(0, int32(wpCreature->GetGUIDLow())); stmt->setUInt32(1, pathid); stmt->setUInt32(2, point); - WorldDatabase.Execute(stmt); wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); @@ -966,7 +935,7 @@ public: { handler->PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid); - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result = WorldDatabase.Query(stmt); @@ -1019,7 +988,7 @@ public: { handler->PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid); - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result = WorldDatabase.Query(stmt); @@ -1069,7 +1038,7 @@ public: if (show == "off") { - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_BY_ID); + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_BY_ID); stmt->setUInt32(0, 1); PreparedQueryResult result = WorldDatabase.Query(stmt); @@ -1090,10 +1059,8 @@ public: handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid); hasError = true; - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); - + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); stmt->setUInt32(0, guid); - WorldDatabase.Execute(stmt); } else |