diff options
author | maximius <none@none> | 2009-10-17 15:51:44 -0700 |
---|---|---|
committer | maximius <none@none> | 2009-10-17 15:51:44 -0700 |
commit | e585187b248f48b3c6e9247b49fa07c6565d65e5 (patch) | |
tree | 637c5b7ddacf41040bef4ea4f75a97da64c6a9bc /src/game/BattleGroundAB.cpp | |
parent | 26b5e033ffde3d161382fc9addbfa99738379641 (diff) |
*Backed out changeset 3be01fb200a5
--HG--
branch : trunk
Diffstat (limited to 'src/game/BattleGroundAB.cpp')
-rw-r--r-- | src/game/BattleGroundAB.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp index 16eda4b9e94..6609c3400be 100644 --- a/src/game/BattleGroundAB.cpp +++ b/src/game/BattleGroundAB.cpp @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "World.h" #include "WorldPacket.h" #include "ObjectMgr.h" @@ -28,34 +29,42 @@ #include "Object.h" #include "Player.h" #include "Util.h" + // these variables aren't used outside of this file, so declare them only here uint32 BG_AB_HonorScoreTicks[BG_HONOR_MODE_NUM] = { 330, // normal honor 200 // holiday }; + uint32 BG_AB_ReputationScoreTicks[BG_HONOR_MODE_NUM] = { 200, // normal honor 150 // holiday }; + BattleGroundAB::BattleGroundAB() { m_BuffChange = true; m_BgObjects.resize(BG_AB_OBJECT_MAX); m_BgCreatures.resize(BG_AB_ALL_NODES_COUNT); + m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AB_START_TWO_MINUTES; m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AB_START_ONE_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AB_START_HALF_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AB_HAS_BEGUN; } + BattleGroundAB::~BattleGroundAB() { } + void BattleGroundAB::Update(uint32 diff) { BattleGround::Update(diff); + if (GetStatus() == STATUS_IN_PROGRESS) { int team_points[BG_TEAMS_COUNT] = { 0, 0 }; + for (int node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) { // 3 sec delay to spawn new banner instead previous despawned one @@ -69,6 +78,7 @@ void BattleGroundAB::Update(uint32 diff) _CreateBanner(node, m_BannerTimers[node].type, m_BannerTimers[node].teamIndex, false); } } + // 1-minute to occupy a node from contested state if (m_NodeTimers[node]) { @@ -88,6 +98,7 @@ void BattleGroundAB::Update(uint32 diff) _SendNodeUpdate(node); _NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE); // Message to chatlog + if (teamIndex == 0) { // FIXME: team and node names not localized @@ -102,10 +113,12 @@ void BattleGroundAB::Update(uint32 diff) } } } + for (int team = 0; team < BG_TEAMS_COUNT; ++team) if (m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED) ++team_points[team]; } + // Accumulate points for (int team = 0; team < BG_TEAMS_COUNT; ++team) { @@ -138,6 +151,7 @@ void BattleGroundAB::Update(uint32 diff) PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY); m_IsInformedNearVictory = true; } + if (m_TeamScores[team] > BG_AB_MAX_TEAM_SCORE) m_TeamScores[team] = BG_AB_MAX_TEAM_SCORE; if (team == BG_TEAM_ALLIANCE) @@ -151,6 +165,7 @@ void BattleGroundAB::Update(uint32 diff) m_TeamScores500Disadvantage[otherTeam] = true; } } + // Test win condition if (m_TeamScores[BG_TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE) EndBattleGround(ALLIANCE); @@ -158,6 +173,7 @@ void BattleGroundAB::Update(uint32 diff) EndBattleGround(HORDE); } } + void BattleGroundAB::StartingEventCloseDoors() { // despawn banners, auras and buffs @@ -165,15 +181,18 @@ void BattleGroundAB::StartingEventCloseDoors() SpawnBGObject(obj, RESPAWN_ONE_DAY); for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i) SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY); + // Starting doors DoorClose(BG_AB_OBJECT_GATE_A); DoorClose(BG_AB_OBJECT_GATE_H); SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY); SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY); + // Starting base spirit guides _NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE); _NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE); } + void BattleGroundAB::StartingEventOpenDoors() { // spawn neutral banners @@ -188,20 +207,26 @@ void BattleGroundAB::StartingEventOpenDoors() DoorOpen(BG_AB_OBJECT_GATE_A); DoorOpen(BG_AB_OBJECT_GATE_H); } + void BattleGroundAB::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in the constructor BattleGroundABScore* sc = new BattleGroundABScore; + m_PlayerScores[plr->GetGUID()] = sc; } + void BattleGroundAB::RemovePlayer(Player * /*plr*/, uint64 /*guid*/) { + } + void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; + switch(Trigger) { case 3948: // Arathi Basin Alliance Exit. @@ -230,6 +255,7 @@ void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger) break; } } + /* type: 0-neutral, 1-contested, 3-occupied teamIndex: 0-ally, 1-horde */ void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay) @@ -242,24 +268,30 @@ void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool m_BannerTimers[node].teamIndex = teamIndex; return; } + uint8 obj = node*8 + type + teamIndex; + SpawnBGObject(obj, RESPAWN_IMMEDIATELY); + // handle aura with banner if (!type) return; obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7); SpawnBGObject(obj, RESPAWN_IMMEDIATELY); } + void BattleGroundAB::_DelBanner(uint8 node, uint8 type, uint8 teamIndex) { uint8 obj = node*8 + type + teamIndex; SpawnBGObject(obj, RESPAWN_ONE_DAY); + // handle aura with banner if (!type) return; obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7); SpawnBGObject(obj, RESPAWN_ONE_DAY); } + int32 BattleGroundAB::_GetNodeNameId(uint8 node) { switch (node) @@ -274,16 +306,20 @@ int32 BattleGroundAB::_GetNodeNameId(uint8 node) } return 0; } + void BattleGroundAB::FillInitialWorldStates(WorldPacket& data) { const uint8 plusArray[] = {0, 2, 3, 0, 1}; + // Node icons for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) data << uint32(BG_AB_OP_NODEICONS[node]) << uint32((m_Nodes[node]==0)?1:0); + // Node occupied states for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) for (uint8 i = 1; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) data << uint32(BG_AB_OP_NODESTATES[node] + plusArray[i]) << uint32((m_Nodes[node]==i)?1:0); + // How many bases each team owns uint8 ally = 0, horde = 0; for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) @@ -291,25 +327,32 @@ void BattleGroundAB::FillInitialWorldStates(WorldPacket& data) ++ally; else if (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_OCCUPIED) ++horde; + data << uint32(BG_AB_OP_OCCUPIED_BASES_ALLY) << uint32(ally); data << uint32(BG_AB_OP_OCCUPIED_BASES_HORDE) << uint32(horde); + // Team scores data << uint32(BG_AB_OP_RESOURCES_MAX) << uint32(BG_AB_MAX_TEAM_SCORE); data << uint32(BG_AB_OP_RESOURCES_WARNING) << uint32(BG_AB_WARNING_NEAR_VICTORY_SCORE); data << uint32(BG_AB_OP_RESOURCES_ALLY) << uint32(m_TeamScores[BG_TEAM_ALLIANCE]); data << uint32(BG_AB_OP_RESOURCES_HORDE) << uint32(m_TeamScores[BG_TEAM_HORDE]); + // other unknown data << uint32(0x745) << uint32(0x2); // 37 1861 unk } + void BattleGroundAB::_SendNodeUpdate(uint8 node) { // Send node owner state update to refresh map icons on client const uint8 plusArray[] = {0, 2, 3, 0, 1}; + if (m_prevNodes[node]) UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_prevNodes[node]], 0); else UpdateWorldState(BG_AB_OP_NODEICONS[node], 0); + UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_Nodes[node]], 1); + // How many bases each team owns uint8 ally = 0, horde = 0; for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) @@ -317,14 +360,17 @@ void BattleGroundAB::_SendNodeUpdate(uint8 node) ++ally; else if (m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED) ++horde; + UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_ALLY, ally); UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_HORDE, horde); } + void BattleGroundAB::_NodeOccupied(uint8 node,Team team) { if (!AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], team)) sLog.outError("Failed to spawn spirit guide! point: %u, team: %u,", node, team); // SpawnBGCreature(node,RESPAWN_IMMEDIATELY); + uint8 capturedNodes = 0; for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) { @@ -336,10 +382,12 @@ void BattleGroundAB::_NodeOccupied(uint8 node,Team team) if (capturedNodes >= 4) CastSpellOnTeam(SPELL_AB_QUEST_REWARD_4_BASES, team); } + void BattleGroundAB::_NodeDeOccupied(uint8 node) { if (node >= BG_AB_DYNAMIC_NODES_COUNT) return; + // Those who are waiting to resurrect at this node are taken to the closest own node's graveyard std::vector<uint64> ghost_list = m_ReviveQueue[m_BgCreatures[node]]; if (!ghost_list.empty()) @@ -350,21 +398,27 @@ void BattleGroundAB::_NodeDeOccupied(uint8 node) Player* plr = objmgr.GetPlayer(*itr); if (!plr) continue; + if (!ClosestGrave) // cache ClosestGrave = GetClosestGraveYard(plr); + if (ClosestGrave) plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation()); } } + if (m_BgCreatures[node]) DelCreature(node); + // buff object isn't despawned } + /* Invoked if a player used a banner as a gameobject */ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/) { if (GetStatus() != STATUS_IN_PROGRESS) return; + uint8 node = BG_AB_NODE_STABLES; GameObject* obj=HashMapHolder<GameObject>::Find(m_BgObjects[node*8+7]); while ( (node < BG_AB_DYNAMIC_NODES_COUNT) && ((!obj) || (!source->IsWithinDistInMap(obj,10)))) @@ -372,15 +426,19 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ ++node; obj=HashMapHolder<GameObject>::Find(m_BgObjects[node*8+BG_AB_OBJECT_AURA_CONTESTED]); } + if (node == BG_AB_DYNAMIC_NODES_COUNT) { // this means our player isn't close to any of banners - maybe cheater ?? return; } + BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(source->GetTeam()); + // Check if player really could use this banner, not cheated if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2)) return; + source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); uint32 sound = 0; // If node is neutral, change to contested @@ -395,11 +453,13 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true); _SendNodeUpdate(node); m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; + // FIXME: team and node names not localized if (teamIndex == 0) SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node), LANG_BG_AB_ALLY); else SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node), LANG_BG_AB_HORDE); + sound = BG_AB_SOUND_NODE_CLAIMED; } // If node is contested @@ -417,6 +477,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true); _SendNodeUpdate(node); m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; + // FIXME: node names not localized if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); @@ -436,6 +497,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _SendNodeUpdate(node); m_NodeTimers[node] = 0; _NodeOccupied(node,(teamIndex == BG_TEAM_ALLIANCE) ? ALLIANCE:HORDE); + // FIXME: node names not localized if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); @@ -457,13 +519,16 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _SendNodeUpdate(node); _NodeDeOccupied(node); m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; + // FIXME: node names not localized if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); else SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node)); + sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE; } + // If node is occupied again, send "X has taken the Y" msg. if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED) { @@ -475,6 +540,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ } PlaySoundToAll(sound); } + bool BattleGroundAB::SetupBattleGround() { for (int i = 0 ; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) @@ -509,12 +575,15 @@ bool BattleGroundAB::SetupBattleGround() ) sLog.outErrorDb("BatteGroundAB: Failed to spawn buff object!"); } + return true; } + void BattleGroundAB::Reset() { //call parent's class reset BattleGround::Reset(); + m_TeamScores[BG_TEAM_ALLIANCE] = 0; m_TeamScores[BG_TEAM_HORDE] = 0; m_lastTick[BG_TEAM_ALLIANCE] = 0; @@ -529,6 +598,7 @@ void BattleGroundAB::Reset() m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks; m_TeamScores500Disadvantage[BG_TEAM_ALLIANCE] = false; m_TeamScores500Disadvantage[BG_TEAM_HORDE] = false; + for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) { m_Nodes[i] = 0; @@ -536,10 +606,12 @@ void BattleGroundAB::Reset() m_NodeTimers[i] = 0; m_BannerTimers[i].timer = 0; } + for (uint8 i = 0; i < BG_AB_ALL_NODES_COUNT; ++i) if (m_BgCreatures[i]) DelCreature(i); } + void BattleGroundAB::EndBattleGround(uint32 winner) { //win reward @@ -550,22 +622,27 @@ void BattleGroundAB::EndBattleGround(uint32 winner) //complete map_end rewards (even if no team wins) RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE); RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE); + BattleGround::EndBattleGround(winner); } + WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player) { BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam()); + // Is there any occupied node for this team? std::vector<uint8> nodes; for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) if (m_Nodes[i] == teamIndex + 3) nodes.push_back(i); + WorldSafeLocsEntry const* good_entry = NULL; // If so, select the closest node to place ghost on if (!nodes.empty()) { float plr_x = player->GetPositionX(); float plr_y = player->GetPositionY(); + float mindist = 999999.0f; for (uint8 i = 0; i < nodes.size(); ++i) { @@ -584,13 +661,16 @@ WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player) // If not, place ghost on starting location if (!good_entry) good_entry = sWorldSafeLocsStore.LookupEntry( BG_AB_GraveyardIds[teamIndex+5] ); + return good_entry; } + void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) { BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID()); if( itr == m_PlayerScores.end() ) // player not found... return; + switch(type) { case SCORE_BASES_ASSAULTED: @@ -604,6 +684,7 @@ void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value break; } } + bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const { uint32 count = 0; @@ -611,5 +692,6 @@ bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const if ((team == ALLIANCE && m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED) || (team == HORDE && m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)) ++count; + return count == BG_AB_DYNAMIC_NODES_COUNT; } |