diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index c7aae6ebd0..677b5ec6c8 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -34,10 +34,9 @@ #include "ObjectMgr.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "WorldStatePackets.h" #include -Battlefield::Battlefield() +Battlefield::Battlefield(Map* map) { m_Timer = 0; m_IsEnabled = true; @@ -47,8 +46,8 @@ Battlefield::Battlefield() m_TypeId = 0; m_BattleId = 0; m_ZoneId = 0; - m_Map = nullptr; - m_MapId = 0; + m_Map = map; + m_MapId = map->GetId(); m_MaxPlayer = 0; m_MinPlayer = 0; m_MinLevel = 0; diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 7752b99557..f63719fb94 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -209,7 +209,7 @@ class TC_GAME_API Battlefield : public ZoneScript public: /// Constructor - Battlefield(); + explicit Battlefield(Map* map); /// Destructor virtual ~Battlefield(); diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp index 7d2de60a67..6749ce2cb0 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.cpp +++ b/src/server/game/Battlefield/BattlefieldMgr.cpp @@ -16,24 +16,27 @@ */ #include "BattlefieldMgr.h" +#include "Containers.h" #include "DatabaseEnv.h" -#include "ObjectMgr.h" #include "Log.h" +#include "Map.h" +#include "ObjectMgr.h" #include "Player.h" #include "ScriptMgr.h" +namespace +{ + constexpr std::array BattlefieldIdToMapId = { 0, 571, 732 }; + constexpr std::array BattlefieldIdToZoneId = { 0, 4197, 5095 }; // imitate World_PVP_Area.db2 + std::array BattlefieldIdToScriptId = { 0, 0, 0 }; +} + BattlefieldMgr::BattlefieldMgr() { _updateTimer = 0; } -BattlefieldMgr::~BattlefieldMgr() -{ - for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr) - delete *itr; - - _battlefieldMap.clear(); -} +BattlefieldMgr::~BattlefieldMgr() = default; BattlefieldMgr* BattlefieldMgr::instance() { @@ -61,22 +64,7 @@ void BattlefieldMgr::InitBattlefield() continue; } - uint32 scriptId = sObjectMgr->GetScriptId(fields[1].GetString()); - - Battlefield* bf = sScriptMgr->CreateBattlefield(scriptId); - if (!bf) - continue; - - if (!bf->SetupBattlefield()) - { - TC_LOG_INFO("bg.battlefield", "Setting up battlefield with TypeId %u failed.", typeId); - delete bf; - } - else - { - _battlefieldSet.push_back(bf); - TC_LOG_INFO("bg.battlefield", "Setting up battlefield with TypeId %u succeeded.", typeId); - } + BattlefieldIdToScriptId[typeId] = sObjectMgr->GetScriptId(fields[1].GetString()); ++count; } while (result->NextRow()); @@ -85,15 +73,45 @@ void BattlefieldMgr::InitBattlefield() TC_LOG_INFO("server.loading", ">> Loaded %u battlefields in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void BattlefieldMgr::CreateBattlefieldsForMap(Map* map) +{ + for (uint32 i = 0; i < BATTLEFIELD_MAX; ++i) + { + if (!BattlefieldIdToScriptId[i]) + continue; + + if (BattlefieldIdToMapId[i] != map->GetId()) + continue; + + Battlefield* bf = sScriptMgr->CreateBattlefield(BattlefieldIdToScriptId[i], map); + if (!bf) + continue; + + if (!bf->SetupBattlefield()) + { + TC_LOG_INFO("bg.battlefield", "Setting up battlefield with TypeId %u on map %u instance id %u failed.", i, map->GetId(), map->GetInstanceId()); + delete bf; + } + + _battlefieldsByMap[map].emplace_back(bf); + TC_LOG_INFO("bg.battlefield", "Setting up battlefield with TypeId %u on map %u instance id %u succeeded.", i, map->GetId(), map->GetInstanceId()); + } +} + +void BattlefieldMgr::DestroyBattlefieldsForMap(Map const* map) +{ + _battlefieldsByMap.erase(map); +} + void BattlefieldMgr::AddZone(uint32 zoneId, Battlefield* bf) { - _battlefieldMap[zoneId] = bf; + _battlefieldsByZone[{ bf->GetMap(), zoneId }] = bf; } void BattlefieldMgr::HandlePlayerEnterZone(Player* player, uint32 zoneId) { - BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId); - if (itr == _battlefieldMap.end()) + auto itr = _battlefieldsByZone.find({ player->GetMap(), zoneId }); + if (itr == _battlefieldsByZone.end()) return; Battlefield* bf = itr->second; @@ -106,8 +124,8 @@ void BattlefieldMgr::HandlePlayerEnterZone(Player* player, uint32 zoneId) void BattlefieldMgr::HandlePlayerLeaveZone(Player* player, uint32 zoneId) { - BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId); - if (itr == _battlefieldMap.end()) + auto itr = _battlefieldsByZone.find({ player->GetMap(), zoneId }); + if (itr == _battlefieldsByZone.end()) return; // teleport: remove once in removefromworld, once in updatezone @@ -118,10 +136,15 @@ void BattlefieldMgr::HandlePlayerLeaveZone(Player* player, uint32 zoneId) TC_LOG_DEBUG("bg.battlefield", "Player %u left battlefield id %u", player->GetGUID().GetCounter(), itr->second->GetTypeId()); } -Battlefield* BattlefieldMgr::GetBattlefieldToZoneId(uint32 zoneId) +bool BattlefieldMgr::IsWorldPvpArea(uint32 zoneId) const { - BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId); - if (itr == _battlefieldMap.end()) + return std::find(BattlefieldIdToZoneId.begin(), BattlefieldIdToZoneId.end(), zoneId) != BattlefieldIdToZoneId.end(); +} + +Battlefield* BattlefieldMgr::GetBattlefieldToZoneId(Map const* map, uint32 zoneId) +{ + auto itr = _battlefieldsByZone.find({ map, zoneId }); + if (itr == _battlefieldsByZone.end()) { // no handle for this zone, return return nullptr; @@ -133,30 +156,12 @@ Battlefield* BattlefieldMgr::GetBattlefieldToZoneId(uint32 zoneId) return itr->second; } -Battlefield* BattlefieldMgr::GetBattlefieldByBattleId(uint32 battleId) +Battlefield* BattlefieldMgr::GetBattlefieldByBattleId(Map const* map, uint32 battleId) { - for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr) - { - if ((*itr)->GetBattleId() == battleId) - return *itr; - } - return nullptr; -} - -Battlefield* BattlefieldMgr::GetBattlefieldByGUID(ObjectGuid guid) -{ - for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr) - if ((*itr)->GetGUID() == guid) - return *itr; - - return nullptr; -} - -ZoneScript* BattlefieldMgr::GetZoneScript(uint32 zoneId) -{ - BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId); - if (itr != _battlefieldMap.end()) - return itr->second; + if (BattlefieldsMapByMap::mapped_type const* battlefields = Trinity::Containers::MapGetValuePtr(_battlefieldsByMap, map)) + for (std::unique_ptr const& battlefield : *battlefields) + if (battlefield->GetBattleId() == battleId) + return battlefield.get(); return nullptr; } @@ -166,9 +171,11 @@ void BattlefieldMgr::Update(uint32 diff) _updateTimer += diff; if (_updateTimer > BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL) { - for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr) - if ((*itr)->IsEnabled()) - (*itr)->Update(_updateTimer); + for (auto const& [map, battlefields] : _battlefieldsByMap) + for (std::unique_ptr const& bfItr : battlefields) + if (bfItr->IsEnabled()) + bfItr->Update(_updateTimer); + _updateTimer = 0; } } diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h index e0baf0c79a..9f34d419dd 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.h +++ b/src/server/game/Battlefield/BattlefieldMgr.h @@ -19,6 +19,10 @@ #define BATTLEFIELD_MGR_H_ #include "Battlefield.h" +#include "Hash.h" +#include +#include +#include class Player; class ZoneScript; @@ -27,22 +31,31 @@ class ZoneScript; class TC_GAME_API BattlefieldMgr { public: + BattlefieldMgr(BattlefieldMgr const&) = delete; + BattlefieldMgr(BattlefieldMgr&&) = delete; + + BattlefieldMgr& operator=(BattlefieldMgr const&) = delete; + BattlefieldMgr& operator=(BattlefieldMgr&&) = delete; + static BattlefieldMgr* instance(); // create battlefield events void InitBattlefield(); + void CreateBattlefieldsForMap(Map* map); + + void DestroyBattlefieldsForMap(Map const* map); + // called when a player enters an battlefield area void HandlePlayerEnterZone(Player* player, uint32 zoneId); // called when player leaves an battlefield area void HandlePlayerLeaveZone(Player* player, uint32 zoneId); - // return assigned battlefield - Battlefield* GetBattlefieldToZoneId(uint32 zoneId); - Battlefield* GetBattlefieldByBattleId(uint32 battleId); - Battlefield* GetBattlefieldByGUID(ObjectGuid guid); + bool IsWorldPvpArea(uint32 zoneId) const; - ZoneScript* GetZoneScript(uint32 zoneId); + // return assigned battlefield + Battlefield* GetBattlefieldToZoneId(Map const* map, uint32 zoneId); + Battlefield* GetBattlefieldByBattleId(Map const* map, uint32 battleId); void AddZone(uint32 zoneId, Battlefield* bf); @@ -52,14 +65,14 @@ class TC_GAME_API BattlefieldMgr BattlefieldMgr(); ~BattlefieldMgr(); - typedef std::vector BattlefieldSet; - typedef std::map BattlefieldMap; + typedef std::unordered_map>> BattlefieldsMapByMap; + typedef std::unordered_map, Battlefield*> BattlefieldMapByZone; // contains all initiated battlefield events // used when initing / cleaning up - BattlefieldSet _battlefieldSet; + BattlefieldsMapByMap _battlefieldsByMap; // maps the zone ids to an battlefield event // used in player event handling - BattlefieldMap _battlefieldMap; + BattlefieldMapByZone _battlefieldsByZone; // update interval uint32 _updateTimer; }; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index bd645e9d0a..cd0d6b3436 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2151,7 +2151,7 @@ ZoneScript* WorldObject::FindZoneScript() const return reinterpret_cast(instanceMap->GetInstanceScript()); else if (!map->IsBattlegroundOrArena()) { - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(map, GetZoneId())) return bf; else return sOutdoorPvPMgr->GetOutdoorPvPToZoneId(map, GetZoneId()); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c1db786c80..7ce3878ccd 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4559,7 +4559,7 @@ void Player::RepopAtGraveyard() ClosestGrave = bg->GetClosestGraveyard(this); else { - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetMap(), GetZoneId())) ClosestGrave = bf->GetClosestGraveyard(this); else ClosestGrave = sObjectMgr->GetClosestGraveyard(*this, GetTeam(), this); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c49f712895..bc201eed83 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11206,7 +11206,7 @@ void Unit::PlayOneShotAnimKitId(uint16 animKitId) if (OutdoorPvP* pvp = player->GetOutdoorPvP()) pvp->HandleKill(player, victim); - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId())) bf->HandleKill(player, victim); } diff --git a/src/server/game/Handlers/BattlefieldHandler.cpp b/src/server/game/Handlers/BattlefieldHandler.cpp index 742be82872..ba05e722da 100644 --- a/src/server/game/Handlers/BattlefieldHandler.cpp +++ b/src/server/game/Handlers/BattlefieldHandler.cpp @@ -263,7 +263,7 @@ void WorldSession::HandleBfQueueInviteResponse(WorldPacket& recvData) TC_LOG_ERROR("misc", "HandleQueueInviteResponse: %s, accepted: %u", guid.ToString().c_str(), accepted); - Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetMap(), _player->GetZoneId()); if (!bf) return; @@ -302,7 +302,7 @@ void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData) TC_LOG_ERROR("misc", "HandleBattlefieldInviteResponse: GUID: " UI64FMTD ", accepted: %u", uint64(guid), accepted); - Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetMap(), _player->GetZoneId()); if (!bf) return; @@ -347,7 +347,7 @@ void WorldSession::HandleBfExitRequest(WorldPacket& recvData) TC_LOG_ERROR("misc", "HandleBfExitRequest: GUID: " UI64FMTD, uint64(guid)); - Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetMap(), _player->GetZoneId()); if (!bf) return; @@ -381,6 +381,6 @@ void WorldSession::HandleBfQueueRequest(WorldPacket & recvData) recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[0]); - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid)) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetMap(), _player->GetZoneId())) SendBfQueueInviteResponse(guid, bf->GetZoneId(), true, false); } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index b9e5cdc56a..8a6cb3c348 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1368,7 +1368,7 @@ void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData) if (bg) sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid); - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetMap(), _player->GetZoneId())) bf->SendAreaSpiritHealerQueryOpcode(_player, guid); } @@ -1391,7 +1391,7 @@ void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket& recvData) if (bg) bg->AddPlayerToResurrectQueue(guid, _player->GetGUID()); - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetMap(), _player->GetZoneId())) bf->AddPlayerToResurrectQueue(guid, _player->GetGUID()); } @@ -1400,7 +1400,7 @@ void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recvData*/) if (_player->IsInFlight()) return; - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetMap(), _player->GetZoneId())) { bf->PlayerAskToLeave(_player); return; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index a81e14223e..60764b396d 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -16,6 +16,7 @@ */ #include "Map.h" +#include "BattlefieldMgr.h" #include "Battleground.h" #include "CellImpl.h" #include "DatabaseEnv.h" @@ -39,6 +40,7 @@ #include "ObjectAccessor.h" #include "ObjectGridLoader.h" #include "ObjectMgr.h" +#include "OutdoorPvPMgr.h" #include "Pet.h" #include "PoolMgr.h" #include "PhasingHandler.h" @@ -90,6 +92,9 @@ Map::~Map() if (!m_scriptSchedule.empty()) sMapMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size()); + sOutdoorPvPMgr->DestroyOutdoorPvPForMap(this); + sBattlefieldMgr->DestroyBattlefieldsForMap(this); + MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId); } @@ -147,6 +152,9 @@ i_scriptLock(false), _respawnCheckTimer(0) _worldStateValues = sWorldStateMgr->GetInitialWorldStatesForMap(this); + sOutdoorPvPMgr->CreateOutdoorPvPForMap(this); + sBattlefieldMgr->CreateBattlefieldsForMap(this); + sScriptMgr->OnCreateMap(this); } diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index deabeba11e..174aa7379d 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1573,10 +1573,10 @@ bool ScriptMgr::OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger) return tmpscript->OnTrigger(player, trigger); } -Battlefield* ScriptMgr::CreateBattlefield(uint32 scriptId) +Battlefield* ScriptMgr::CreateBattlefield(uint32 scriptId, Map* map) { GET_SCRIPT_RET(BattlefieldScript, scriptId, tmpscript, nullptr); - return tmpscript->GetBattlefield(); + return tmpscript->GetBattlefield(map); } Battleground* ScriptMgr::CreateBattleground(BattlegroundTypeId /*typeId*/) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 4d11e090be..bb6e9e5746 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -462,7 +462,7 @@ class TC_GAME_API BattlefieldScript : public ScriptObject public: - virtual Battlefield* GetBattlefield() const = 0; + virtual Battlefield* GetBattlefield(Map* map) const = 0; }; class TC_GAME_API BattlegroundScript : public ScriptObject @@ -948,7 +948,7 @@ class TC_GAME_API ScriptMgr public: /* BattlefieldScript */ - Battlefield* CreateBattlefield(uint32 scriptId); + Battlefield* CreateBattlefield(uint32 scriptId, Map* map); public: /* BattlegroundScript */ diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 6c52bac3a8..cf75013934 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -4659,7 +4659,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool { if (Battleground* bg = target->ToPlayer()->GetBattleground()) bg->RemovePlayerFromResurrectQueue(target->GetGUID()); - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(target->GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(target->GetMap(), target->GetZoneId())) bf->RemovePlayerFromResurrectQueue(target->GetGUID()); } break; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 39b121f885..fdb0a940d8 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6451,7 +6451,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint // allow always ghost flight spells if (m_originalCaster && m_originalCaster->GetTypeId() == TYPEID_PLAYER && m_originalCaster->IsAlive()) { - Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId()); + Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetMap(), m_originalCaster->GetZoneId()); if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId())) if (area->Flags & AREA_FLAG_NO_FLY_ZONE || (Bf && !Bf->CanFlyIn())) return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 91db9b8e0a..e5bf86c741 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -718,7 +718,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 if (!player) return false; - Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId()); + Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId()); if (!Bf || Bf->CanFlyIn() || (!player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !player->HasAuraType(SPELL_AURA_FLY))) return false; break; @@ -729,7 +729,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 if (!player) return false; - Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId()); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId()); if (!bf || bf->GetTypeId() != BATTLEFIELD_WG) return false; @@ -749,7 +749,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 if (!player) return false; - if (Battlefield* battlefieldWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) + if (Battlefield* battlefieldWG = sBattlefieldMgr->GetBattlefieldByBattleId(player->GetMap(), BATTLEFIELD_BATTLEID_WG)) return battlefieldWG->IsEnabled() && (player->GetTeamId() == battlefieldWG->GetDefenderTeam()) && !battlefieldWG->IsWarTime(); break; } @@ -758,7 +758,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 if (!player) return false; - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId())) return bf->IsWarTime(); break; } diff --git a/src/server/scripts/Battlefield/BattlefieldTB.cpp b/src/server/scripts/Battlefield/BattlefieldTB.cpp index a13cc535bb..a6987d9805 100644 --- a/src/server/scripts/Battlefield/BattlefieldTB.cpp +++ b/src/server/scripts/Battlefield/BattlefieldTB.cpp @@ -270,8 +270,6 @@ bool BattlefieldTB::SetupBattlefield() m_TypeId = BATTLEFIELD_TB; // See enum BattlefieldTypes m_BattleId = BATTLEFIELD_BATTLEID_TB; m_ZoneId = BATTLEFIELD_TB_ZONEID; - m_MapId = BATTLEFIELD_TB_MAPID; - m_Map = sMapMgr->CreateBaseMap(m_MapId); InitStalker(NPC_DEBUG_ANNOUNCER, TolBaradDebugAnnouncerPos); @@ -982,9 +980,9 @@ class Battlefield_tol_barad : public BattlefieldScript public: Battlefield_tol_barad() : BattlefieldScript("battlefield_tb") { } - Battlefield* GetBattlefield() const override + Battlefield* GetBattlefield(Map* map) const override { - return new BattlefieldTB(); + return new BattlefieldTB(map); } }; diff --git a/src/server/scripts/Battlefield/BattlefieldTB.h b/src/server/scripts/Battlefield/BattlefieldTB.h index 79ae6c986c..e395d3886a 100644 --- a/src/server/scripts/Battlefield/BattlefieldTB.h +++ b/src/server/scripts/Battlefield/BattlefieldTB.h @@ -346,6 +346,7 @@ class TolBaradCapturePoint : public BfCapturePoint class BattlefieldTB : public Battlefield { public: + using Battlefield::Battlefield; ~BattlefieldTB(); void OnStartGrouping() override; diff --git a/src/server/scripts/Battlefield/BattlefieldWG.cpp b/src/server/scripts/Battlefield/BattlefieldWG.cpp index 54e05f31a6..ce75b550d0 100644 --- a/src/server/scripts/Battlefield/BattlefieldWG.cpp +++ b/src/server/scripts/Battlefield/BattlefieldWG.cpp @@ -412,8 +412,6 @@ bool BattlefieldWG::SetupBattlefield() m_TypeId = BATTLEFIELD_WG; // See enum BattlefieldTypes m_BattleId = BATTLEFIELD_BATTLEID_WG; m_ZoneId = AREA_WINTERGRASP; - m_MapId = BATTLEFIELD_WG_MAPID; - m_Map = sMapMgr->CreateBaseMap(m_MapId); InitStalker(BATTLEFIELD_WG_NPC_STALKER, WintergraspStalkerPos); @@ -1454,6 +1452,26 @@ void BfWGGameObjectBuilding::Init(GameObject* go) } _state = WintergraspGameObjectState(sWorldStateMgr->GetValue(_worldState, _wg->GetMap())); + if (_state == BATTLEFIELD_WG_OBJECTSTATE_NONE) + { + // set to default state based on type + switch (_teamControl) + { + case TEAM_ALLIANCE: + _state = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT; + break; + case TEAM_HORDE: + _state = BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT; + break; + case TEAM_NEUTRAL: + _state = BATTLEFIELD_WG_OBJECTSTATE_NEUTRAL_INTACT; + break; + default: + break; + } + sWorldStateMgr->SetValueAndSaveInDb(_worldState, _state, false, _wg->GetMap()); + } + switch (_state) { case BATTLEFIELD_WG_OBJECTSTATE_NEUTRAL_INTACT: @@ -1751,9 +1769,9 @@ class Battlefield_wintergrasp : public BattlefieldScript public: Battlefield_wintergrasp() : BattlefieldScript("battlefield_wg") { } - Battlefield* GetBattlefield() const override + Battlefield* GetBattlefield(Map* map) const override { - return new BattlefieldWG(); + return new BattlefieldWG(map); } }; @@ -1771,7 +1789,7 @@ public: if (!killer || killer->GetTypeId() != TYPEID_PLAYER) return; - BattlefieldWG* wintergrasp = static_cast(sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)); + BattlefieldWG* wintergrasp = static_cast(sBattlefieldMgr->GetBattlefieldByBattleId(killer->GetMap(), BATTLEFIELD_BATTLEID_WG)); if (!wintergrasp) return; diff --git a/src/server/scripts/Battlefield/BattlefieldWG.h b/src/server/scripts/Battlefield/BattlefieldWG.h index 4f2b816dbe..bd52334d0f 100644 --- a/src/server/scripts/Battlefield/BattlefieldWG.h +++ b/src/server/scripts/Battlefield/BattlefieldWG.h @@ -209,6 +209,7 @@ class WintergraspCapturePoint : public BfCapturePoint class BattlefieldWG : public Battlefield { public: + using Battlefield::Battlefield; ~BattlefieldWG(); /** * \brief Called when the battle start diff --git a/src/server/scripts/Commands/cs_bf.cpp b/src/server/scripts/Commands/cs_bf.cpp index d885b69bad..c227418e54 100644 --- a/src/server/scripts/Commands/cs_bf.cpp +++ b/src/server/scripts/Commands/cs_bf.cpp @@ -25,7 +25,9 @@ EndScriptData */ #include "ScriptMgr.h" #include "BattlefieldMgr.h" #include "Chat.h" +#include "Player.h" #include "RBAC.h" +#include "WorldSession.h" class bf_commandscript : public CommandScript { @@ -51,123 +53,133 @@ public: static bool HandleBattlefieldStart(ChatHandler* handler, char const* args) { - uint32 battleid = 0; - char* battleid_str = strtok((char*)args, " "); - if (!battleid_str) - return false; + if (WorldSession* session = handler->GetSession()) + { + uint32 battleid = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; - battleid = atoi(battleid_str); + battleid = atoi(battleid_str); - Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(session->GetPlayer()->GetMap(), battleid); - if (!bf) - return false; + if (!bf) + return false; - bf->StartBattle(); - - if (battleid == 1) - handler->SendGlobalGMSysMessage("Wintergrasp (Command start used)"); + bf->StartBattle(); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp (Command start used)"); + } return true; } static bool HandleBattlefieldEnd(ChatHandler* handler, char const* args) { - uint32 battleid = 0; - char* battleid_str = strtok((char*)args, " "); - if (!battleid_str) - return false; + if (WorldSession* session = handler->GetSession()) + { + uint32 battleid = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; - battleid = atoi(battleid_str); + battleid = atoi(battleid_str); - Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(session->GetPlayer()->GetMap(), battleid); - if (!bf) - return false; + if (!bf) + return false; - bf->EndBattle(true); - - if (battleid == 1) - handler->SendGlobalGMSysMessage("Wintergrasp (Command stop used)"); + bf->EndBattle(true); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp (Command stop used)"); + } return true; } static bool HandleBattlefieldEnable(ChatHandler* handler, char const* args) { - uint32 battleid = 0; - char* battleid_str = strtok((char*)args, " "); - if (!battleid_str) - return false; - - battleid = atoi(battleid_str); - - Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); - - if (!bf) - return false; - - if (bf->IsEnabled()) + if (WorldSession* session = handler->GetSession()) { - bf->ToggleBattlefield(false); - if (battleid == 1) - handler->SendGlobalGMSysMessage("Wintergrasp is disabled"); - } - else - { - bf->ToggleBattlefield(true); - if (battleid == 1) - handler->SendGlobalGMSysMessage("Wintergrasp is enabled"); - } + uint32 battleid = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; + battleid = atoi(battleid_str); + + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(session->GetPlayer()->GetMap(), battleid); + + if (!bf) + return false; + + if (bf->IsEnabled()) + { + bf->ToggleBattlefield(false); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp is disabled"); + } + else + { + bf->ToggleBattlefield(true); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp is enabled"); + } + } return true; } static bool HandleBattlefieldSwitch(ChatHandler* handler, char const* args) { - uint32 battleid = 0; - char* battleid_str = strtok((char*)args, " "); - if (!battleid_str) - return false; + if (WorldSession* session = handler->GetSession()) + { + uint32 battleid = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; - battleid = atoi(battleid_str); + battleid = atoi(battleid_str); - Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(session->GetPlayer()->GetMap(), battleid); - if (!bf) - return false; - - bf->EndBattle(false); - if (battleid == 1) - handler->SendGlobalGMSysMessage("Wintergrasp (Command switch used)"); + if (!bf) + return false; + bf->EndBattle(false); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp (Command switch used)"); + } return true; } static bool HandleBattlefieldTimer(ChatHandler* handler, char const* args) { - uint32 battleid = 0; - uint32 time = 0; - char* battleid_str = strtok((char*)args, " "); - if (!battleid_str) - return false; - char* time_str = strtok(nullptr, " "); - if (!time_str) - return false; + if (WorldSession* session = handler->GetSession()) + { + uint32 battleid = 0; + uint32 time = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; + char* time_str = strtok(nullptr, " "); + if (!time_str) + return false; - battleid = atoi(battleid_str); + battleid = atoi(battleid_str); - time = atoi(time_str); + time = atoi(time_str); - Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(session->GetPlayer()->GetMap(), battleid); - if (!bf) - return false; - - bf->SetTimer(time * IN_MILLISECONDS); - if (battleid == 1) - handler->SendGlobalGMSysMessage("Wintergrasp (Command timer used)"); + if (!bf) + return false; + bf->SetTimer(time * IN_MILLISECONDS); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp (Command timer used)"); + } return true; } }; diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index c95294b4af..534af49c35 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -1722,7 +1722,7 @@ public: nearestLoc = bg->GetClosestGraveyard(player); else { - if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId())) + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId())) nearestLoc = bf->GetClosestGraveyard(player); else nearestLoc = sObjectMgr->GetClosestGraveyard(*player, player->GetTeam(), player); diff --git a/src/server/scripts/Northrend/zone_wintergrasp.cpp b/src/server/scripts/Northrend/zone_wintergrasp.cpp index 6c119dcdf7..b9f2730c07 100644 --- a/src/server/scripts/Northrend/zone_wintergrasp.cpp +++ b/src/server/scripts/Northrend/zone_wintergrasp.cpp @@ -173,7 +173,7 @@ class npc_wg_demolisher_engineer : public CreatureScript private: bool CanBuild() const { - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG); if (!wintergrasp) return false; @@ -215,7 +215,7 @@ class npc_wg_spirit_guide : public CreatureScript if (me->IsQuestGiver()) player->PrepareQuestMenu(me->GetGUID()); - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG); if (!wintergrasp) return true; @@ -233,7 +233,7 @@ class npc_wg_spirit_guide : public CreatureScript uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); CloseGossipMenuFor(player); - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG); if (wintergrasp) { GraveyardVect gy = wintergrasp->GetGraveyardVector(); @@ -295,7 +295,7 @@ class npc_wg_queue : public CreatureScript if (me->IsQuestGiver()) player->PrepareQuestMenu(me->GetGUID()); - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG); if (!wintergrasp) return true; @@ -323,7 +323,7 @@ class npc_wg_queue : public CreatureScript { CloseGossipMenuFor(player); - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(me->GetMap(), BATTLEFIELD_BATTLEID_WG); if (!wintergrasp) return true; @@ -496,10 +496,10 @@ class spell_wintergrasp_defender_teleport : public SpellScriptLoader { SpellCastResult CheckCast() { - if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) - if (Player* target = GetExplTargetUnit()->ToPlayer()) + if (Player* target = GetExplTargetUnit()->ToPlayer()) + if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(target->GetMap(), BATTLEFIELD_BATTLEID_WG)) // check if we are in Wintergrasp at all, SotA uses same teleport spells - if ((target->GetZoneId() == 4197 && target->GetTeamId() != wg->GetDefenderTeam()) || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER)) + if ((target->GetZoneId() == AREA_WINTERGRASP && target->GetTeamId() != wg->GetDefenderTeam()) || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER)) return SPELL_FAILED_BAD_TARGETS; return SPELL_CAST_OK; } @@ -549,10 +549,12 @@ class condition_is_wintergrasp_horde : public ConditionScript public: condition_is_wintergrasp_horde() : ConditionScript("condition_is_wintergrasp_horde") { } - bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& /* sourceInfo */) + bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& sourceInfo) { - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (wintergrasp && wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_HORDE) + if (!sourceInfo.mConditionMap) + return false; + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(sourceInfo.mConditionMap, BATTLEFIELD_BATTLEID_WG); + if (wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_HORDE) return true; return false; } @@ -563,10 +565,12 @@ class condition_is_wintergrasp_alliance : public ConditionScript public: condition_is_wintergrasp_alliance() : ConditionScript("condition_is_wintergrasp_alliance") { } - bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& /* sourceInfo */) + bool OnConditionCheck(Condition const* /* condition */, ConditionSourceInfo& sourceInfo) { - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (wintergrasp && wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE) + if (!sourceInfo.mConditionMap) + return false; + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(sourceInfo.mConditionMap, BATTLEFIELD_BATTLEID_WG); + if (wintergrasp->IsEnabled() && wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE) return true; return false; }