/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * 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 3 of the License, or * 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 . * */ #ifndef __BATTLEGROUNDMGR_H #define __BATTLEGROUNDMGR_H #include "../shared/Threading/RWLock.h" class CBattleground; class MapMgr; class Player; class Map; class Group; enum BattleGroundTypes { BATTLEGROUND_ALTERAC_VALLEY = 1, BATTLEGROUND_WARSUNG_GULCH, BATTLEGROUND_ARATHI_BASIN, BATTLEGROUND_ARENA_2V2, BATTLEGROUND_ARENA_3V3, BATTLEGROUND_ARENA_5V5, BATTLEGROUND_EYE_OF_THE_STORM, BATTLEGROUND_NUM_TYPES, }; struct BGScore { uint32 KillingBlows; uint32 HonorableKills; uint32 Deaths; uint32 BonusHonor; uint32 DamageDone; uint32 HealingDone; uint32 Misc1; uint32 Misc2; }; #define SOUND_BATTLEGROUND_BEGIN 0xD6F #define SOUND_HORDE_SCORES 8213 #define SOUND_ALLIANCE_SCORES 8173 #define SOUND_ALLIANCE_CAPTURE 8174 #define SOUND_HORDE_CAPTURE 8212 #define SOUND_ALLIANCE_RETURNED 8192 #define SOUND_HORDE_RETURNED 8192 // huh? #define SOUND_HORDEWINS 8454 #define SOUND_ALLIANCEWINS 8455 #define SOUND_HORDE_BGALMOSTEND 0x2108 #define SOUND_ALLIANCE_BGALMOSTEND 0x2109 // AB define's #define AB_CAPTURED_STABLES_ALLIANCE 0x6E7 #define AB_CAPTURED_STABLES_HORDE 0x6E8 #define AB_CAPTURING_STABLES_ALLIANCE 0x6E9 #define AB_CAPTURING_STABLES_HORDE 0x6EA // 0x6EB is unknown #define AB_CAPTURED_FARM_ALLIANCE 0x6EC // 1 is captured by the alliance #define AB_CAPTURED_FARM_HORDE 0x6ED // 1 is captured by the horde #define AB_CAPTURING_FARM_ALLIANCE 0x6EE // 1 is capturing by the alliance #define AB_CAPTURING_FARM_HORDE 0x6EF // 1 is capturing by the horde #define AB_ALLIANCE_RESOURCES 0x6F0 #define AB_HORDE_RESOURCES 0x6F1 #define AB_HORDE_CAPTUREBASE 0x6F2 #define AB_ALLIANCE_CAPTUREBASE 0x6F3 #define AB_MAX_SCORE 0x6F4 #define AB_CAPTURED_BLACKSMITH_ALLIANCE 0x6F6 #define AB_CAPTURED_BLACKSMITH_HORDE 0x6F7 #define AB_CAPTURING_BLACKSMITH_ALLIANCE 0x6F8 #define AB_CAPTURING_BLACKSMITH_HORDE 0x6F9 // 0x6FA is unknown #define AB_CAPTURED_GOLDMINE_ALLIANCE 0x6FB #define AB_CAPTURED_GOLDMINE_HORDE 0x6FC #define AB_CAPTURING_GOLDMINE_ALLIANCE 0x6FD #define AB_CAPTURING_GOLDMINE_HORDE 0x6FE // 0x6FF is unknown #define AB_CAPTURED_LUMBERMILL_ALLIANCE 0x700 #define AB_CAPTURED_LUMBERMILL_HORDE 0x701 #define AB_CAPTURING_LUMBERMILL_ALLIANCE 0x702 #define AB_CAPTURING_LUMBERMILL_HORDE 0x703 #define AB_SHOW_STABLE_ICON 0x732 #define AB_SHOW_GOLDMINE_ICON 0x733 #define AB_SHOW_LUMBERMILL_ICON 0x734 #define AB_SHOW_FARM_ICON 0x735 #define AB_SHOW_BACKSMITH_ICON 0x736 // WSG define's #define WSG_ALLIANCE_FLAG_CAPTURED 0x922 #define WSG_HORDE_FLAG_CAPTURED 0x923 #define WSG_CURRENT_HORDE_SCORE 0x62E #define WSG_CURRENT_ALLIANCE_SCORE 0x62D #define WSG_MAX_SCORE 0x641 // AV define's #define AV_UNCONTROLED_SNOWFALL_GRAVE 0x7AE //1 -> show uncontrolled #define AV_CONTROLED_ICEBLOOD_TOWER_HORDE 0x569 //1 -> horde controled #define AV_CONTROLED_TOWER_POINT_HORDE 0x568 //1 -> horde controled #define AV_CONTROLED_FROSTWOLF_RELIFHUNT_HORDE 0x532 //1 -> horde controled #define AV_CONTROLED_EAST_FROSTWOLF_TOWER_HORDE 0x567 //1 -> horde controled #define AV_CONTROLED_WEST_FROSTWOLF_TOWER_HORDE 0x566 //1 -> horde controled #define AV_CONTROLED_ICEBLOOD_GRAVE_HORDE 0x543 //1 -> horde controled #define AV_CONTROLED_FROSTWOLF_GRAVE_HORDE 0x53A //1 -> horde controled #define AV_CONTROLED_IRONDEEP_MINE_TROGG 0x550 //1 -> trogg controled #define AV_CONTROLED_COLDTHOOT_MINE_KOBOLT 0x54D //1 -> kobolt controled #define AV_CONTROLED_STORMPIKE_GRAVE_ALLIANCE 0x535 //1 -> alliance controled #define AV_CONTROLED_STONEHEART_BUNKER_ALLIANCE 0x554 //1 -> alliance controled #define AV_CONTROLED_ICEWING_BUNKER_ALLIANCE 0x553 //1 -> alliance controled #define AV_CONTROLED_DUBALDER_NORTH_BUNKER_ALLIANCE 0x552 //1 -> alliance controled #define AV_CONTROLED_DUBALDER_SOUTH_BUNKER_ALLIANCE 0x551 //1 -> alliance controled #define AV_CONTROLED_STORMPIKE_AID_STATION_ALLIANCE 0x52D //1 -> alliance controled #define AV_CONTROLED_STONEHEART_GRAVE_ALLIANCE 0x516 //1 -> alliance controled /* get level grouping for player */ inline static uint32 GetLevelGrouping(uint32 level) { if(level < 10) return 0; else if(level < 20) return 1; else if(level < 30) return 2; else if(level < 40) return 3; else if(level < 50) return 4; else if(level < 60) return 5; else if(level < 70) return 6; else return 7; } #define MAX_LEVEL_GROUP 8 #define MINIMUM_PLAYERS_ON_EACH_SIDE_FOR_BG 1 #define MAXIMUM_BATTLEGROUNDS_PER_LEVEL_GROUP 3 class CBattlegroundManager : public Singleton, public EventableObject { /* Battleground Instance Map */ map m_instances[BATTLEGROUND_NUM_TYPES]; RWLock m_instanceLock; /* Max Id */ uint32 m_maxBattlegroundId; /* Queue System */ // Instance Id -> list [ BattlegroundType ] [ Level Group ] (instance 0 - first available) map > m_queuedPlayers[BATTLEGROUND_NUM_TYPES][MAX_LEVEL_GROUP]; Mutex m_queueLock; public: CBattlegroundManager(); ~CBattlegroundManager(); /* Packet Handlers */ void HandleBattlegroundListPacket(WorldSession * m_session, uint32 BattlegroundType); void HandleArenaJoin(WorldSession * m_session, uint32 BattlegroundType); /* Player Logout Handler */ void OnPlayerLogout(Player * plr); /* Handler On Update Event */ void EventQueueUpdate(); /* Handle Battleground Join */ void HandleBattlegroundJoin(WorldSession * m_session, WorldPacket & pck); /* Remove Player From All Queues */ void RemovePlayerFromQueues(Player * plr); /* Create a battleground instance of type x */ CBattleground * CreateInstance(uint32 Type, uint32 LevelGroup); /* Can we create a new instance of type x level group y? (NO LOCK!) */ bool CanCreateInstance(uint32 Type, uint32 LevelGroup); /* Deletes a battleground (called from MapMgr) */ void DeleteBattleground(CBattleground * bg); /* Build SMSG_BATTLEFIELD_STATUS */ void SendBattlefieldStatus(Player * plr, uint32 Status, uint32 Type, uint32 InstanceID, uint32 Time, uint32 MapId); }; class CBattleground : public EventableObject { protected: /* Groups */ Group * m_groups[2]; time_t m_nextPvPUpdateTime; MapMgr * m_mapMgr; uint32 m_id; uint32 m_type; uint32 m_levelGroup; /* Team->Player Map */ set m_players[2]; /* World States. This should be moved to mapmgr instead for world pvp :/ */ map m_worldStates; /* PvP Log Data Map */ map m_pvpData; /* Lock for all player data */ Mutex m_mainLock; /* Player count per team */ uint32 m_playerCountPerTeam; /* "pending" players */ set m_pendPlayers[2]; /* starting time */ uint32 m_startTime; /* countdown stuff */ uint32 m_countdownStage; /* winner stuff */ bool m_ended; uint8 m_winningteam; /* resurrect queue */ set m_resurrectQueue[2]; uint32 m_lastResurrect; public: void SendChatMessage(uint32 Type, uint64 Guid, const char * Format, ...); /* Hook Functions */ virtual void HookOnPlayerDeath(Player * plr) = 0; /* Repopping - different battlegrounds have different ways of handling this */ virtual bool HookHandleRepop(Player * plr) = 0; /* In CTF battlegrounds mounting will cause you to lose your flag. */ virtual void HookOnMount(Player * plr) = 0; /* Only used in CTF (as far as I know) */ virtual void HookFlagDrop(Player * plr, GameObject * obj) = 0; virtual void HookFlagStand(Player * plr, GameObject * obj) = 0; /* Used when a player kills a unit/player */ virtual void HookOnPlayerKill(Player * plr, Unit * pVictim) = 0; virtual void HookOnHK(Player * plr) = 0; /* On Area Trigger */ virtual void HookOnAreaTrigger(Player * plr, uint32 id) = 0; /* Retreival Functions */ inline uint32 GetId() { return m_id; } inline uint32 GetLevelGroup() { return m_levelGroup; } inline MapMgr* GetMapMgr() { return m_mapMgr; } /* Creating a battleground requires a pre-existing map manager */ CBattleground(MapMgr * mgr, uint32 id, uint32 levelgroup, uint32 type); virtual ~CBattleground(); /* Send our current world states to a player . */ void SendWorldStates(Player * plr); /* Send the pvp log data of all players to this player. */ void SendPVPData(Player * plr); /* Get the starting position for this team. */ virtual LocationVector GetStartingCoords(uint32 Team) = 0; /* Send a packet to the entire battleground */ void DistributePacketToAll(WorldPacket * packet); /* send a packet to only this team */ void DistributePacketToTeam(WorldPacket * packet, uint32 Team); /* play sound to this team only */ void PlaySoundToTeam(uint32 Team, uint32 Sound); /* play sound to all */ void PlaySoundToAll(uint32 Sound); /* Full? */ inline bool IsFull() { return !(HasFreeSlots(0) && HasFreeSlots(1)); } /* Are we full? */ inline bool HasFreeSlots(uint32 Team) { m_mainLock.Acquire(); bool res = ((m_players[Team].size() + m_pendPlayers[Team].size()) < m_playerCountPerTeam); m_mainLock.Release(); return res; } /* Add Player */ void AddPlayer(Player * plr); virtual void OnAddPlayer(Player * plr) = 0; /* Remove Player */ void RemovePlayer(Player * plr, bool logout); virtual void OnRemovePlayer(Player * plr) = 0; /* Port Player */ void PortPlayer(Player * plr, bool skip_teleport = false); virtual void OnCreate() = 0; /* Remove pending player */ void RemovePendingPlayer(Player * plr); /* Gets the number of free slots */ inline uint32 GetFreeSlots(uint32 t) { m_mainLock.Acquire(); uint32 s = m_playerCountPerTeam - m_players[t].size() - m_pendPlayers[t].size(); m_mainLock.Release(); return s; } GameObject * SpawnGameObject(uint32 entry,uint32 MapId , float x, float y, float z, float o, uint32 flags, uint32 faction, float scale); void UpdatePvPData(); inline uint32 GetStartTime() { return m_startTime; } inline uint32 GetType() { return m_type; } // events should execute in the correct context int32 event_GetInstanceID(); void EventCreate(); virtual const char * GetName() = 0; void EventCountdown(); virtual void Start(); virtual void OnStart() {} void Close(); virtual void OnClose() {} void SetWorldState(uint32 Index, uint32 Value); void SpawnSpiritGuide(float x, float y, float z, float o, uint32 horde); inline uint32 GetLastResurrect() { return m_lastResurrect; } void QueuePlayerForResurrect(Player * plr); void EventResurrectPlayers(); virtual bool CanPlayerJoin(Player * plr) { return true; } virtual bool CreateCorpse(Player * plr) { return true; } }; #define BattlegroundManager CBattlegroundManager::getSingleton( ) #endif