/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2023 MaNGOS * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #ifndef MANGOS_H_BATTLEGROUND #define MANGOS_H_BATTLEGROUND #include "Common.h" #include "SharedDefines.h" #include "Map.h" #include "ByteBuffer.h" #include "ObjectGuid.h" // magic event-numbers #define BG_EVENT_NONE 255 // those generic events should get a high event id #define BG_EVENT_DOOR 254 class Creature; class GameObject; class Group; class Player; class WorldPacket; class BattleGroundMap; struct WorldSafeLocsEntry; /** * @brief * */ struct BattleGroundEventIdx { uint8 event1; /**< TODO */ uint8 event2; /**< TODO */ }; /** * @brief * */ enum BattleGroundSounds { SOUND_HORDE_WINS = 8454, SOUND_ALLIANCE_WINS = 8455, SOUND_BG_START = 3439 }; /** * @brief * */ enum BattleGroundQuests { SPELL_WS_QUEST_REWARD = 43483, SPELL_AB_QUEST_REWARD = 43484, SPELL_AV_QUEST_REWARD = 43475, SPELL_AV_QUEST_KILLED_BOSS = 23658, SPELL_AB_QUEST_REWARD_4_BASES = 24061, SPELL_AB_QUEST_REWARD_5_BASES = 24064 }; /** * @brief * */ enum BattleGroundMarks { SPELL_WS_MARK_LOSER = 24950, SPELL_WS_MARK_WINNER = 24951, SPELL_AB_MARK_LOSER = 24952, SPELL_AB_MARK_WINNER = 24953, SPELL_AV_MARK_LOSER = 24954, SPELL_AV_MARK_WINNER = 24955, }; /** * @brief * */ enum BattleGroundMarksCount { ITEM_WINNER_COUNT = 3, ITEM_LOSER_COUNT = 1 }; /** * @brief * */ enum BattleGroundTimeIntervals { CHECK_PLAYER_POSITION_INVERVAL = 1000, // ms RESURRECTION_INTERVAL = 30000, // ms INVITATION_REMIND_TIME = 60000, // ms INVITE_ACCEPT_WAIT_TIME = 80000, // ms TIME_TO_AUTOREMOVE = 120000, // ms MAX_OFFLINE_TIME = 300, // secs RESPAWN_ONE_DAY = 86400, // secs RESPAWN_IMMEDIATELY = 0, // secs BUFF_RESPAWN_TIME = 180 // secs }; /** * @brief * */ enum BattleGroundStartTimeIntervals { BG_START_DELAY_2M = 120000, // ms (2 minutes) BG_START_DELAY_1M = 60000, // ms (1 minute) BG_START_DELAY_30S = 30000, // ms (30 seconds) BG_START_DELAY_NONE = 0, // ms }; /** * @brief * */ enum BattleGroundBuffObjects { BG_OBJECTID_SPEEDBUFF_ENTRY = 179871, BG_OBJECTID_REGENBUFF_ENTRY = 179904, BG_OBJECTID_BERSERKERBUFF_ENTRY = 179905 }; const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY }; /**< TODO */ /** * @brief * */ enum BattleGroundStatus { STATUS_NONE = 0, // first status, should mean bg is not instance STATUS_WAIT_QUEUE = 1, // means bg is empty and waiting for queue STATUS_WAIT_JOIN = 2, // this means, that BG has already started and it is waiting for more players STATUS_IN_PROGRESS = 3, // means bg is running STATUS_WAIT_LEAVE = 4 // means some faction has won BG and it is ending }; /** * @brief * */ struct BattleGroundPlayer { time_t OfflineRemoveTime; /**< for tracking and removing offline players from queue after 5 minutes */ Team PlayerTeam; /**< Player's team */ }; /** * @brief * */ struct BattleGroundObjectInfo { /** * @brief * */ BattleGroundObjectInfo() : object(NULL), timer(0), spellid(0) {} GameObject* object; /**< TODO */ int32 timer; /**< TODO */ uint32 spellid; /**< TODO */ }; /** * @brief handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time * */ enum BattleGroundQueueTypeId { BATTLEGROUND_QUEUE_NONE = 0, BATTLEGROUND_QUEUE_AV = 1, BATTLEGROUND_QUEUE_WS = 2, BATTLEGROUND_QUEUE_AB = 3, }; #define MAX_BATTLEGROUND_QUEUE_TYPES 4 /** * @brief * */ enum BattleGroundBracketId // bracketId for level ranges { BG_BRACKET_ID_TEMPLATE = -1, // used to mark bg as template BG_BRACKET_ID_FIRST = 0, // brackets start from specific BG min level and each include 10 levels range BG_BRACKET_ID_LAST = 5 // so for start level 10 will be 10-19, 20-29, ... all greater max bg level included in last breaket }; #define MAX_BATTLEGROUND_BRACKETS 6 /** * @brief * */ enum ScoreType { SCORE_KILLING_BLOWS = 1, SCORE_DEATHS = 2, SCORE_HONORABLE_KILLS = 3, SCORE_BONUS_HONOR = 4, // WS SCORE_FLAG_CAPTURES = 7, SCORE_FLAG_RETURNS = 8, // AB SCORE_BASES_ASSAULTED = 9, SCORE_BASES_DEFENDED = 10, // AV SCORE_GRAVEYARDS_ASSAULTED = 11, SCORE_GRAVEYARDS_DEFENDED = 12, SCORE_TOWERS_ASSAULTED = 13, SCORE_TOWERS_DEFENDED = 14, SCORE_SECONDARY_OBJECTIVES = 15 }; /** * @brief * */ enum BattleGroundStartingEvents { BG_STARTING_EVENT_NONE = 0x00, BG_STARTING_EVENT_1 = 0x01, BG_STARTING_EVENT_2 = 0x02, BG_STARTING_EVENT_3 = 0x04, BG_STARTING_EVENT_4 = 0x08 }; /** * @brief * */ enum BattleGroundStartingEventsIds { BG_STARTING_EVENT_FIRST = 0, BG_STARTING_EVENT_SECOND = 1, BG_STARTING_EVENT_THIRD = 2, BG_STARTING_EVENT_FOURTH = 3 }; #define BG_STARTING_EVENT_COUNT 4 /** * @brief * */ enum BattleGroundJoinError { BG_JOIN_ERR_OK = 0, BG_JOIN_ERR_OFFLINE_MEMBER = 1, BG_JOIN_ERR_GROUP_TOO_MANY = 2, BG_JOIN_ERR_MIXED_FACTION = 3, BG_JOIN_ERR_MIXED_LEVELS = 4, // BG_JOIN_ERR_MIXED_ARENATEAM = 5, BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE = 6, BG_JOIN_ERR_GROUP_DESERTER = 7, BG_JOIN_ERR_ALL_QUEUES_USED = 8, BG_JOIN_ERR_GROUP_NOT_ENOUGH = 9 }; /** * @brief * */ class BattleGroundScore { public: /** * @brief * */ BattleGroundScore() : KillingBlows(0), Deaths(0), HonorableKills(0), DishonorableKills(0), BonusHonor(0) {} /** * @brief virtual destructor is used when deleting score from scores map * */ virtual ~BattleGroundScore() {} uint32 GetKillingBlows() const { return KillingBlows; } uint32 GetDeaths() const { return Deaths; } uint32 GetHonorableKills() const { return HonorableKills; } uint32 GetBonusHonor() const { return BonusHonor; } uint32 GetDamageDone() const { return 0; } uint32 GetHealingDone() const { return 0; } virtual uint32 GetAttr1() const { return 0; } virtual uint32 GetAttr2() const { return 0; } virtual uint32 GetAttr3() const { return 0; } virtual uint32 GetAttr4() const { return 0; } virtual uint32 GetAttr5() const { return 0; } uint32 KillingBlows; /**< TODO */ uint32 Deaths; /**< TODO */ uint32 HonorableKills; /**< TODO */ uint32 DishonorableKills; /**< TODO */ uint32 BonusHonor; /**< TODO */ }; /** * @brief This class is used to: * 1. Add player to battleground * 2. Remove player from battleground * 3. some certain cases, same for all battlegrounds * 4. It has properties same for all battlegrounds * */ class BattleGround { friend class BattleGroundMgr; public: /** * @brief Construction * */ BattleGround(); /** * @brief * */ virtual ~BattleGround(); /** * @brief * * @param diff */ virtual void Update(uint32 diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version /** * @brief * */ virtual void Reset(); // resets all common properties for battlegrounds, must be implemented and called in BG subclass /** * @brief * */ virtual void StartingEventCloseDoors() {} /** * @brief * */ virtual void StartingEventOpenDoors() {} /* Battleground */ // Get methods: /** * @brief * * @return const char */ char const* GetName() const { return m_Name; } /** * @brief * * @return BattleGroundTypeId */ BattleGroundTypeId GetTypeID() const { return m_TypeID; } /** * @brief * * @return BattleGroundBracketId */ BattleGroundBracketId GetBracketId() const { return m_BracketId; } // the instanceId check is also used to determine a bg-template // that's why the m_map hack is here.. /** * @brief * * @return uint32 */ uint32 GetInstanceID() { return m_Map ? GetBgMap()->GetInstanceId() : 0; } /** * @brief * * @return BattleGroundStatus */ BattleGroundStatus GetStatus() const { return m_Status; } /** * @brief * * @return uint32 */ uint32 GetClientInstanceID() const { return m_ClientInstanceID; } /** * @brief * * @return uint32 */ uint32 GetStartTime() const { return m_StartTime; } /** * @brief * * @return uint32 */ uint32 GetEndTime() const { return m_EndTime; } /** * @brief * * @return uint32 */ uint32 GetMaxPlayers() const { return m_MaxPlayers; } /** * @brief * * @return uint32 */ uint32 GetMinPlayers() const { return m_MinPlayers; } /** * @brief * * @return uint32 */ uint32 GetMinLevel() const { return m_LevelMin; } /** * @brief * * @return uint32 */ uint32 GetMaxLevel() const { return m_LevelMax; } /** * @brief * * @return uint32 */ uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam; } /** * @brief * * @return uint32 */ uint32 GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam; } /** * @brief * * @return int32 */ int32 GetStartDelayTime() const { return m_StartDelayTime; } /** * @brief * * @return Team */ Team GetWinner() const { return m_Winner; } /** * @brief * * @return Team */ virtual Team GetPrematureWinner(); /** * @brief * * @return uint32 */ uint32 GetBattlemasterEntry() const; /** * @brief * * @param kills * @return uint32 */ uint32 GetBonusHonorFromKill(uint32 kills) const; // Set methods: /** * @brief * * @param Name */ void SetName(char const* Name) { m_Name = Name; } /** * @brief * * @param TypeID */ void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; } /** * @brief * * @param ID */ void SetBracketId(BattleGroundBracketId ID) { m_BracketId = ID; } /** * @brief * * @param Status */ void SetStatus(BattleGroundStatus Status) { m_Status = Status; } /** * @brief * * @param InstanceID */ void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; } /** * @brief * * @param Time */ void SetStartTime(uint32 Time) { m_StartTime = Time; } /** * @brief * * @param Time */ void SetEndTime(uint32 Time) { m_EndTime = Time; } /** * @brief * * @param MaxPlayers */ void SetMaxPlayers(uint32 MaxPlayers) { m_MaxPlayers = MaxPlayers; } /** * @brief * * @param MinPlayers */ void SetMinPlayers(uint32 MinPlayers) { m_MinPlayers = MinPlayers; } /** * @brief * * @param min * @param max */ void SetLevelRange(uint32 min, uint32 max) { m_LevelMin = min; m_LevelMax = max; } /** * @brief * * @param winner */ void SetWinner(Team winner) { m_Winner = winner; } /** * @brief * * @param diff */ void ModifyStartDelayTime(int diff) { m_StartDelayTime -= diff; } /** * @brief * * @param Time */ void SetStartDelayTime(int Time) { m_StartDelayTime = Time; } /** * @brief * * @param MaxPlayers */ void SetMaxPlayersPerTeam(uint32 MaxPlayers) { m_MaxPlayersPerTeam = MaxPlayers; } /** * @brief * * @param MinPlayers */ void SetMinPlayersPerTeam(uint32 MinPlayers) { m_MinPlayersPerTeam = MinPlayers; } /** * @brief * */ void AddToBGFreeSlotQueue(); // this queue will be useful when more battlegrounds instances will be available /** * @brief * */ void RemoveFromBGFreeSlotQueue(); // this method could delete whole BG instance, if another free is available /** * @brief * * @param team */ void DecreaseInvitedCount(Team team) { (team == ALLIANCE) ? --m_InvitedAlliance : --m_InvitedHorde; } /** * @brief * * @param team */ void IncreaseInvitedCount(Team team) { (team == ALLIANCE) ? ++m_InvitedAlliance : ++m_InvitedHorde; } /** * @brief * * @param team * @return uint32 */ uint32 GetInvitedCount(Team team) const { if (team == ALLIANCE) { return m_InvitedAlliance; } else { return m_InvitedHorde; } } /** * @brief * * @return bool */ bool HasFreeSlots() const; /** * @brief * * @param team * @return uint32 */ uint32 GetFreeSlotsForTeam(Team team) const; /** * @brief * */ typedef std::map BattleGroundPlayerMap; /** * @brief * * @return const BattleGroundPlayerMap */ BattleGroundPlayerMap const& GetPlayers() const { return m_Players; } /** * @brief * * @return uint32 */ uint32 GetPlayersSize() const { return m_Players.size(); } /** * @brief * */ typedef std::map BattleGroundScoreMap; /** * @brief * * @return BattleGroundScoreMap::const_iterator */ BattleGroundScoreMap::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); } /** * @brief * * @return BattleGroundScoreMap::const_iterator */ BattleGroundScoreMap::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); } /** * @brief * * @return uint32 */ uint32 GetPlayerScoresSize() const { return m_PlayerScores.size(); } /** * @brief * */ void StartBattleGround(); /* Location */ /** * @brief * * @param MapID */ void SetMapId(uint32 MapID) { m_MapId = MapID; } /** * @brief * * @return uint32 */ uint32 GetMapId() const { return m_MapId; } /* Map pointers */ /** * @brief * * @param map */ void SetBgMap(BattleGroundMap* map) { m_Map = map; } /** * @brief * * @return BattleGroundMap */ BattleGroundMap* GetBgMap() { MANGOS_ASSERT(m_Map); return m_Map; } /** * @brief * * @param team * @param X * @param Y * @param Z * @param O */ void SetTeamStartLoc(Team team, float X, float Y, float Z, float O); /** * @brief * * @param team * @param X * @param Y * @param Z * @param O */ void GetTeamStartLoc(Team team, float& X, float& Y, float& Z, float& O) const { PvpTeamIndex idx = GetTeamIndexByTeamId(team); X = m_TeamStartLocX[idx]; Y = m_TeamStartLocY[idx]; Z = m_TeamStartLocZ[idx]; O = m_TeamStartLocO[idx]; } void SetStartMaxDist(float startMaxDist) { m_startMaxDist = startMaxDist; } float GetStartMaxDist() const { return m_startMaxDist; } /* Packet Transfer */ // method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!) /** * @brief * * @param * @param */ virtual void FillInitialWorldStates(WorldPacket& /*data*/, uint32& /*count*/) {} /** * @brief * * @param team * @param packet * @param sender * @param self */ void SendPacketToTeam(Team team, WorldPacket* packet, Player* sender = NULL, bool self = true); /** * @brief * * @param packet */ void SendPacketToAll(WorldPacket* packet); template /** * @brief * * @param _do */ void BroadcastWorker(Do& _do); /** * @brief * * @param SoundID * @param team */ void PlaySoundToTeam(uint32 SoundID, Team team); /** * @brief * * @param SoundID */ void PlaySoundToAll(uint32 SoundID); /** * @brief * * @param SpellID * @param team */ void CastSpellOnTeam(uint32 SpellID, Team team); /** * @brief * * @param Honor * @param team */ void RewardHonorToTeam(uint32 Honor, Team team); /** * @brief * * @param faction_id * @param Reputation * @param team */ void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, Team team); /** * @brief * * @param plr * @param count */ void RewardMark(Player* plr, uint32 count); /** * @brief * * @param plr * @param mark * @param count */ void SendRewardMarkByMail(Player* plr, uint32 mark, uint32 count); /** * @brief * * @param plr * @param item_id * @param count */ void RewardItem(Player* plr, uint32 item_id, uint32 count); /** * @brief * * @param plr */ void RewardQuestComplete(Player* plr); /** * @brief * * @param plr * @param spell_id */ void RewardSpellCast(Player* plr, uint32 spell_id); /** * @brief * * @param Field * @param Value */ void UpdateWorldState(uint32 Field, uint32 Value); /** * @brief * * @param Field * @param Value * @param Source */ void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* Source); /** * @brief * * @param winner */ virtual void EndBattleGround(Team winner); /** * @brief * * @param plr */ void BlockMovement(Player* plr); /** * @brief * * @param entry * @param type * @param source */ void SendMessageToAll(int32 entry, ChatMsg type, Player const* source = NULL); /** * @brief * * @param entry * @param language * @param guid */ void SendYellToAll(int32 entry, uint32 language, ObjectGuid guid); /** * @brief * * @param entry * @param type * @param source... */ void PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ...); // specialized version with 2 string id args /** * @brief * * @param entry * @param type * @param source * @param strId1 * @param strId2 */ void SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 strId1 = 0, int32 strId2 = 0); /** * @brief * * @param entry * @param language * @param guid * @param arg1 * @param arg2 */ void SendYell2ToAll(int32 entry, uint32 language, ObjectGuid guid, int32 arg1, int32 arg2); /* Raid Group */ /** * @brief * * @param team * @return Group */ Group* GetBgRaid(Team team) const { return m_BgRaids[GetTeamIndexByTeamId(team)]; } /** * @brief * * @param team * @param bg_raid */ void SetBgRaid(Team team, Group* bg_raid); /** * @brief * * @param Source * @param type * @param value */ virtual void UpdatePlayerScore(Player* Source, uint32 type, uint32 value); /** * @brief * * @param team * @return BattleGroundTeamIndex */ static PvpTeamIndex GetTeamIndexByTeamId(Team team) { return team == ALLIANCE ? TEAM_INDEX_ALLIANCE : TEAM_INDEX_HORDE; } /** * @brief * * @param team * @return uint32 */ uint32 GetPlayersCountByTeam(Team team) const { return m_PlayersCount[GetTeamIndexByTeamId(team)]; } /** * @brief * * @param team * @return uint32 */ uint32 GetAlivePlayersCountByTeam(Team team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases /** * @brief * * @param team * @param remove */ void UpdatePlayersCountByTeam(Team team, bool remove) { if (remove) { --m_PlayersCount[GetTeamIndexByTeamId(team)]; } else { ++m_PlayersCount[GetTeamIndexByTeamId(team)]; } } /* Triggers handle */ // must be implemented in BG subclass /** * @brief * * @param * @param uint32 */ virtual bool HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) { return false; } // must be implemented in BG subclass if need AND call base class generic code /** * @brief * * @param player * @param killer */ virtual void HandleKillPlayer(Player* player, Player* killer); /** * @brief * * @param * @param */ virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/) {} // Process Capture event /** * @brief * * @param uint32 * @param * @return bool */ virtual bool HandleEvent(uint32 /*eventId*/, GameObject* /*go*/) { return false; } // Called when a gameobject is created /** * @brief * * @param */ virtual void HandleGameObjectCreate(GameObject* /*go*/) {} /* Battleground events */ /** * @brief * * @param */ virtual void EventPlayerDroppedFlag(Player* /*player*/) {} /** * @brief * * @param * @param */ virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) {} /** * @brief * * @param */ virtual void EventPlayerCapturedFlag(Player* /*player*/) {} /** * @brief * * @param player */ void EventPlayerLoggedIn(Player* player); /** * @brief * * @param player */ void EventPlayerLoggedOut(Player* player); /* Death related */ /** * @brief * * @param player * @return const WorldSafeLocsEntry */ virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); /** * @brief * * @param plr */ virtual void AddPlayer(Player* plr); // must be implemented in BG subclass /** * @brief * * @param plr * @param plr_guid * @param team */ void AddOrSetPlayerToCorrectBgGroup(Player* plr, ObjectGuid plr_guid, Team team); /** * @brief * * @param guid * @param Transport * @param SendPacket */ virtual void RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool SendPacket); // can be extended in in BG subclass /* event related */ // called when a creature gets added to map (NOTE: only triggered if // a player activates the cell of the creature) /** * @brief * * @param */ void OnObjectDBLoad(Creature* /*creature*/); /** * @brief * * @param */ void OnObjectDBLoad(GameObject* /*obj*/); // (de-)spawns creatures and gameobjects from an event /** * @brief * * @param event1 * @param event2 * @param spawn */ void SpawnEvent(uint8 event1, uint8 event2, bool spawn); /** * @brief * * @param event1 * @param event2 * @return bool */ bool IsActiveEvent(uint8 event1, uint8 event2) { if (m_ActiveEvents.find(event1) == m_ActiveEvents.end()) { return false; } return m_ActiveEvents[event1] == event2; } /** * @brief * * @param event1 * @param event2 * @return ObjectGuid */ ObjectGuid GetSingleCreatureGuid(uint8 event1, uint8 event2); /** * @brief * * @param event1 * @param event2 */ void OpenDoorEvent(uint8 event1, uint8 event2 = 0); /** * @brief * * @param event1 * @param event2 * @return bool */ bool IsDoor(uint8 event1, uint8 event2); /** * @brief * * @param go_guid */ void HandleTriggerBuff(ObjectGuid go_guid); /** * @brief * * @param guid * @param respawntime */ void SpawnBGObject(ObjectGuid guid, uint32 respawntime); /** * @brief * * @param guid * @param respawntime */ void SpawnBGCreature(ObjectGuid guid, uint32 respawntime); /** * @brief * * @param guid */ void DoorOpen(ObjectGuid guid); /** * @brief * * @param guid */ void DoorClose(ObjectGuid guid); /** * @brief * * @param * @return bool */ virtual bool HandlePlayerUnderMap(Player* /*plr*/) { return false; } // since arenas can be AvA or Hvh, we have to get the "temporary" team of a player /** * @brief * * @param guid * @return Team */ Team GetPlayerTeam(ObjectGuid guid); /** * @brief * * @param team * @return Team */ static Team GetOtherTeam(Team team) { return team ? ((team == ALLIANCE) ? HORDE : ALLIANCE) : TEAM_NONE; } /** * @brief * * @param teamIdx * @return BattleGroundTeamIndex */ static PvpTeamIndex GetOtherTeamIndex(PvpTeamIndex teamIdx) { return teamIdx == TEAM_INDEX_ALLIANCE ? TEAM_INDEX_HORDE : TEAM_INDEX_ALLIANCE; } /** * @brief * * @param guid * @return bool */ bool IsPlayerInBattleGround(ObjectGuid guid); /* virtual score-array - get's used in bg-subclasses */ int32 m_TeamScores[PVP_TEAM_COUNT]; /** * @brief * */ struct EventObjects { GuidVector gameobjects; /**< TODO */ GuidVector creatures; /**< TODO */ }; // cause we create it dynamicly i use a map - to avoid resizing when // using vector - also it contains 2*events concatenated with PAIR32 // this is needed to avoid overhead of a 2dimensional std::map std::map m_EventObjects; /**< TODO */ // this must be filled first in BattleGroundXY::Reset().. else // creatures will get added wrong // door-events are automaticly added - but _ALL_ other must be in this vector std::map m_ActiveEvents; /**< TODO */ protected: /** * @brief Ends a battleground * * This method is called, when BG can not spawn its own spirit guide, or * something is wrong, It correctly ends BattleGround */ void EndNow(); /** * @brief * * @param plr */ void PlayerAddedToBGCheckIfBGIsRunning(Player* plr); /* Scorekeeping */ BattleGroundScoreMap m_PlayerScores; /**< Player scores */ // must be implemented in BG subclass /** * @brief * * @param * @param ObjectGuid */ virtual void RemovePlayer(Player* /*player*/, ObjectGuid /*guid*/) {} /* Player lists, those need to be accessible by inherited classes */ BattleGroundPlayerMap m_Players; /**< TODO */ /* these are important variables used for starting messages */ uint8 m_Events; /**< TODO */ BattleGroundStartTimeIntervals m_StartDelayTimes[BG_STARTING_EVENT_COUNT]; /**< TODO */ // this must be filled in constructors! uint32 m_StartMessageIds[BG_STARTING_EVENT_COUNT]; /**< TODO */ bool m_BuffChange; /**< TODO */ private: /* Battleground */ BattleGroundTypeId m_TypeID; /**< TODO */ BattleGroundStatus m_Status; /**< TODO */ uint32 m_ClientInstanceID; /**< the instance-id which is sent to the client and without any other internal use */ uint32 m_StartTime; /**< TODO */ uint32 m_validStartPositionTimer; int32 m_EndTime; /**< it is set to 120000 when bg is ending and it decreases itself */ BattleGroundBracketId m_BracketId; /**< TODO */ bool m_InBGFreeSlotQueue; /**< used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque */ Team m_Winner; /**< 0=alliance, 1=horde, 2=none */ int32 m_StartDelayTime; /**< TODO */ bool m_PrematureCountDown; /**< TODO */ uint32 m_PrematureCountDownTimer; /**< TODO */ char const* m_Name; /**< TODO */ /* Player lists */ /** * @brief * */ typedef std::deque OfflineQueue; OfflineQueue m_OfflineQueue; /**< Player GUID */ /* Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction */ /* Invited counters will be changed only when removing already invited player from queue, removing player from battleground and inviting player to BG */ /* Invited players counters*/ uint32 m_InvitedAlliance; /**< TODO */ uint32 m_InvitedHorde; /**< TODO */ /* Raid Group */ Group* m_BgRaids[PVP_TEAM_COUNT]; /**< 0 - alliance, 1 - horde */ /* Players count by team */ uint32 m_PlayersCount[PVP_TEAM_COUNT]; /**< TODO */ /* Limits */ uint32 m_LevelMin; /**< TODO */ uint32 m_LevelMax; /**< TODO */ uint32 m_MaxPlayersPerTeam; /**< TODO */ uint32 m_MaxPlayers; /**< TODO */ uint32 m_MinPlayersPerTeam; /**< TODO */ uint32 m_MinPlayers; /**< TODO */ /* Start location */ uint32 m_MapId; /**< TODO */ BattleGroundMap* m_Map; /**< TODO */ float m_startMaxDist; float m_TeamStartLocX[PVP_TEAM_COUNT]; /**< TODO */ float m_TeamStartLocY[PVP_TEAM_COUNT]; /**< TODO */ float m_TeamStartLocZ[PVP_TEAM_COUNT]; /**< TODO */ float m_TeamStartLocO[PVP_TEAM_COUNT]; /**< TODO */ }; // helper functions for world state list fill /** * @brief * * @param data * @param count * @param state * @param value */ inline void FillInitialWorldState(ByteBuffer& data, uint32& count, uint32 state, uint32 value) { data << uint32(state); data << uint32(value); ++count; } /** * @brief * * @param data * @param count * @param state * @param value */ inline void FillInitialWorldState(ByteBuffer& data, uint32& count, uint32 state, int32 value) { data << uint32(state); data << int32(value); ++count; } /** * @brief * * @param data * @param count * @param state * @param value */ inline void FillInitialWorldState(ByteBuffer& data, uint32& count, uint32 state, bool value) { data << uint32(state); data << uint32(value ? 1 : 0); ++count; } /** * @brief * */ struct WorldStatePair { uint32 state; /**< TODO */ uint32 value; /**< TODO */ }; /** * @brief * * @param data * @param count * @param array */ inline void FillInitialWorldState(ByteBuffer& data, uint32& count, WorldStatePair const* array) { for (WorldStatePair const* itr = array; itr->state; ++itr) { data << uint32(itr->state); data << uint32(itr->value); ++count; } } #endif