1 | /* |
---|
2 | * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> |
---|
3 | * |
---|
4 | * This program is free software; you can redistribute it and/or modify |
---|
5 | * it under the terms of the GNU General Public License as published by |
---|
6 | * the Free Software Foundation; either version 2 of the License, or |
---|
7 | * (at your option) any later version. |
---|
8 | * |
---|
9 | * This program is distributed in the hope that it will be useful, |
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | * GNU General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU General Public License |
---|
15 | * along with this program; if not, write to the Free Software |
---|
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
17 | */ |
---|
18 | |
---|
19 | #include "Common.h" |
---|
20 | #include "Player.h" |
---|
21 | #include "BattleGroundMgr.h" |
---|
22 | #include "BattleGroundAV.h" |
---|
23 | #include "BattleGroundAB.h" |
---|
24 | #include "BattleGroundEY.h" |
---|
25 | #include "BattleGroundWS.h" |
---|
26 | #include "BattleGroundNA.h" |
---|
27 | #include "BattleGroundBE.h" |
---|
28 | #include "BattleGroundAA.h" |
---|
29 | #include "BattleGroundRL.h" |
---|
30 | #include "SharedDefines.h" |
---|
31 | #include "Policies/SingletonImp.h" |
---|
32 | #include "MapManager.h" |
---|
33 | #include "ObjectMgr.h" |
---|
34 | #include "ProgressBar.h" |
---|
35 | #include "World.h" |
---|
36 | #include "Chat.h" |
---|
37 | |
---|
38 | INSTANTIATE_SINGLETON_1( BattleGroundMgr ); |
---|
39 | |
---|
40 | /*********************************************************/ |
---|
41 | /*** BATTLEGROUND QUEUE SYSTEM ***/ |
---|
42 | /*********************************************************/ |
---|
43 | |
---|
44 | BattleGroundQueue::BattleGroundQueue() |
---|
45 | { |
---|
46 | //queues are empty, we don't have to call clear() |
---|
47 | for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++) |
---|
48 | { |
---|
49 | m_QueuedPlayers[i].Horde = 0; |
---|
50 | m_QueuedPlayers[i].Alliance = 0; |
---|
51 | //m_QueuedPlayers[i].AverageTime = 0; |
---|
52 | } |
---|
53 | } |
---|
54 | |
---|
55 | BattleGroundQueue::~BattleGroundQueue() |
---|
56 | { |
---|
57 | for (int i = 0; i < MAX_BATTLEGROUND_QUEUES; i++) |
---|
58 | { |
---|
59 | m_QueuedPlayers[i].clear(); |
---|
60 | } |
---|
61 | } |
---|
62 | |
---|
63 | void BattleGroundQueue::AddPlayer(Player *plr, uint32 bgTypeId) |
---|
64 | { |
---|
65 | uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(); |
---|
66 | |
---|
67 | //if player isn't in queue, he is added, if already is, then values are overwritten, no memory leak |
---|
68 | PlayerQueueInfo& info = m_QueuedPlayers[queue_id][plr->GetGUID()]; |
---|
69 | info.InviteTime = 0; |
---|
70 | info.IsInvitedToBGInstanceGUID = 0; |
---|
71 | info.LastInviteTime = 0; |
---|
72 | info.LastOnlineTime = getMSTime(); |
---|
73 | info.Team = plr->GetTeam(); |
---|
74 | |
---|
75 | //add player to waiting order queue |
---|
76 | m_PlayersSortedByWaitTime[queue_id].push_back(plr->GetGUID()); |
---|
77 | |
---|
78 | if(plr->GetTeam() == ALLIANCE) |
---|
79 | ++m_QueuedPlayers[queue_id].Alliance; |
---|
80 | else |
---|
81 | ++m_QueuedPlayers[queue_id].Horde; |
---|
82 | |
---|
83 | this->Update(bgTypeId, queue_id); |
---|
84 | |
---|
85 | if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) ) |
---|
86 | { |
---|
87 | BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgTypeId); |
---|
88 | char const* bgName = bg->GetName(); |
---|
89 | |
---|
90 | uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id); |
---|
91 | uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id); |
---|
92 | |
---|
93 | // replace hardcoded max level by player max level for nice output |
---|
94 | if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) |
---|
95 | q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); |
---|
96 | |
---|
97 | int8 MinPlayers = bg->GetMinPlayersPerTeam(); |
---|
98 | |
---|
99 | uint8 qHorde = m_QueuedPlayers[queue_id].Horde; |
---|
100 | uint8 qAlliance = m_QueuedPlayers[queue_id].Alliance; |
---|
101 | |
---|
102 | // Show queue status to player only (when joining queue) |
---|
103 | if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) |
---|
104 | { |
---|
105 | ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, |
---|
106 | bgName, q_min_level, q_max_level, qAlliance, MinPlayers - qAlliance, qHorde, MinPlayers - qHorde); |
---|
107 | } |
---|
108 | // System message |
---|
109 | else |
---|
110 | { |
---|
111 | sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, |
---|
112 | bgName, q_min_level, q_max_level, qAlliance, MinPlayers - qAlliance, qHorde, MinPlayers - qHorde); |
---|
113 | } |
---|
114 | } |
---|
115 | } |
---|
116 | |
---|
117 | void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) |
---|
118 | { |
---|
119 | Player *plr = objmgr.GetPlayer(guid); |
---|
120 | |
---|
121 | uint32 queue_id = 0; |
---|
122 | QueuedPlayersMap::iterator itr; |
---|
123 | bool IsSet = false; |
---|
124 | if(!plr) |
---|
125 | { //player is offline, we need to find him somewhere in queues |
---|
126 | /// there is something wrong if this code is run, because we have in queue only online players! |
---|
127 | sLog.outError("Battleground: removing offline player from BG queue - this might not happen, but it should not cause crash"); |
---|
128 | for (uint32 i = 0; i < MAX_BATTLEGROUND_QUEUES; i++) |
---|
129 | { |
---|
130 | itr = m_QueuedPlayers[i].find(guid); |
---|
131 | if(itr != m_QueuedPlayers[i].end()) |
---|
132 | { |
---|
133 | queue_id = i; |
---|
134 | IsSet = true; |
---|
135 | break; |
---|
136 | } |
---|
137 | } |
---|
138 | } |
---|
139 | else |
---|
140 | { //player is online, we have his level, so we can find exact queue from his level |
---|
141 | queue_id = plr->GetBattleGroundQueueIdFromLevel(); |
---|
142 | itr = m_QueuedPlayers[queue_id].find(guid); |
---|
143 | IsSet = true; |
---|
144 | } |
---|
145 | |
---|
146 | //all variables are set, so remove player |
---|
147 | //remove player from time queue |
---|
148 | m_PlayersSortedByWaitTime[queue_id].remove(guid); |
---|
149 | |
---|
150 | if (IsSet && itr != m_QueuedPlayers[queue_id].end()) |
---|
151 | { |
---|
152 | if (!itr->second.IsInvitedToBGInstanceGUID) |
---|
153 | { |
---|
154 | if(itr->second.Team == ALLIANCE) |
---|
155 | --m_QueuedPlayers[queue_id].Alliance; |
---|
156 | else |
---|
157 | --m_QueuedPlayers[queue_id].Horde; |
---|
158 | } |
---|
159 | else |
---|
160 | { |
---|
161 | if (decreaseInvitedCount) |
---|
162 | { |
---|
163 | BattleGround* bg = sBattleGroundMgr.GetBattleGround(itr->second.IsInvitedToBGInstanceGUID); |
---|
164 | if (bg) |
---|
165 | bg->DecreaseInvitedCount(itr->second.Team); |
---|
166 | } |
---|
167 | } |
---|
168 | m_QueuedPlayers[queue_id].erase(itr); |
---|
169 | } |
---|
170 | } |
---|
171 | |
---|
172 | /* |
---|
173 | this method is called when player is inserted, or removed from BG Queue - there is only one player's status changed, so we don't use while(true) cycles to invite whole queue |
---|
174 | add method calls this by itself, the remove method could works in other way, so you have to call this method from other code after calling remove method |
---|
175 | */ |
---|
176 | void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id) |
---|
177 | { |
---|
178 | if (queue_id >= MAX_BATTLEGROUND_QUEUES) |
---|
179 | { |
---|
180 | //this is error, that caused crashes (not in , but now it shouldn't) |
---|
181 | sLog.outError("BattleGroundQueue::Update() called for non existing queue type - this can cause crash, pls report problem, if this is the last line of error log before crash"); |
---|
182 | return; |
---|
183 | } |
---|
184 | |
---|
185 | //if no players in queue ... do nothing |
---|
186 | if (this->m_QueuedPlayers[queue_id].Alliance == 0 && this->m_QueuedPlayers[queue_id].Horde == 0) |
---|
187 | return; |
---|
188 | |
---|
189 | //battleground with free slot for player should be always the last in this queue |
---|
190 | for (BGFreeSlotQueueType::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); ++itr) |
---|
191 | { |
---|
192 | // battleground is running, so if: |
---|
193 | // DO NOT allow queue manager to invite new player to running arena |
---|
194 | if ((*itr)->isBattleGround() && (*itr)->GetQueueType() == queue_id && (*itr)->GetStatus() > STATUS_WAIT_QUEUE && (*itr)->GetStatus() < STATUS_WAIT_LEAVE) |
---|
195 | { |
---|
196 | //we must check both teams |
---|
197 | BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!) |
---|
198 | // and iterator is invalid |
---|
199 | |
---|
200 | //check if there are some players in queue |
---|
201 | if (m_QueuedPlayers[queue_id].Alliance > 0 || m_QueuedPlayers[queue_id].Horde > 0) |
---|
202 | { |
---|
203 | for (PlayerGuidsSortedByTimeQueue::iterator itr2 = m_PlayersSortedByWaitTime[queue_id].begin(); itr2 != m_PlayersSortedByWaitTime[queue_id].end();) |
---|
204 | { |
---|
205 | Player* plr = objmgr.GetPlayer(*itr2); |
---|
206 | if (!plr) |
---|
207 | { |
---|
208 | //something is wrong!, kick player from queue |
---|
209 | sLog.outError("BATTLEGROUND: problem with inviting offline player to Battleground queue .... pls report bug"); |
---|
210 | uint64 oldval = *itr2; |
---|
211 | itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2); |
---|
212 | RemovePlayer(oldval, true); |
---|
213 | continue; |
---|
214 | } |
---|
215 | |
---|
216 | // player will be invited, if in bg there is a free slot for him |
---|
217 | if (bg->HasFreeSlotsForTeam(plr->GetTeam())) |
---|
218 | { |
---|
219 | // iterator to player's queue status |
---|
220 | QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2); |
---|
221 | |
---|
222 | // remove him from time queue |
---|
223 | itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2); |
---|
224 | |
---|
225 | // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and pls report it) |
---|
226 | if (itrPlayerStatus == m_QueuedPlayers[queue_id].end()) |
---|
227 | continue; |
---|
228 | |
---|
229 | // check if player is not already invited |
---|
230 | if (!itrPlayerStatus->second.IsInvitedToBGInstanceGUID) |
---|
231 | { |
---|
232 | itrPlayerStatus->second.IsInvitedToBGInstanceGUID = bg->GetInstanceID(); |
---|
233 | itrPlayerStatus->second.InviteTime = getMSTime(); |
---|
234 | itrPlayerStatus->second.LastInviteTime = getMSTime(); |
---|
235 | if(itrPlayerStatus->second.Team == ALLIANCE) |
---|
236 | --m_QueuedPlayers[queue_id].Alliance; |
---|
237 | else |
---|
238 | --m_QueuedPlayers[queue_id].Horde; |
---|
239 | sBattleGroundMgr.InvitePlayer(plr, bg->GetInstanceID()); |
---|
240 | |
---|
241 | WorldPacket data; |
---|
242 | uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgTypeId); |
---|
243 | sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0); |
---|
244 | plr->GetSession()->SendPacket(&data); |
---|
245 | } |
---|
246 | } |
---|
247 | else |
---|
248 | ++itr2; |
---|
249 | |
---|
250 | //if battleground is FULL, then it is removed from free slot queue - not yet implemented! |
---|
251 | if (!bg->HasFreeSlots()) |
---|
252 | { |
---|
253 | //if bg is full, there is no need to invite other players, so break |
---|
254 | break; |
---|
255 | //remove BG from BGFreeSlotQueue - not used now, in this system we don't remove BGs from free queue |
---|
256 | //bg->RemoveFromBGFreeSlotQueue() --- do not uncomment this - not yet implemented |
---|
257 | } |
---|
258 | } |
---|
259 | } |
---|
260 | } |
---|
261 | } |
---|
262 | |
---|
263 | /* THIS IS A CASE THAT IN QUEUE THERE IS ENOUGHT PLAYERS TO START NEW BG */ |
---|
264 | //itr->end is the last BG - template, which is not already started! |
---|
265 | |
---|
266 | /* here will be a most of change, when we create battlegrounds instantiated */ |
---|
267 | /* if (there is enough players to start new BG) |
---|
268 | Battleground* newbg = sBattleGroundMgr.CreateNewBattleGround(bgTypeId) |
---|
269 | - that function will use the COPY constructor on BattleGround class ( in bg manager we should have one battleground as a template |
---|
270 | (battleground template will be used only to create new BGs, it will be an instance of BG class, but it won't ever start) */ |
---|
271 | |
---|
272 | /* following code is working with current Battleground system and it should be removed, when BGs will work like instances */ |
---|
273 | BattleGround* bg2 = sBattleGroundMgr.GetBattleGround(bgTypeId); |
---|
274 | if (bg2->GetQueueType() != MAX_BATTLEGROUND_QUEUES || bg2->GetStatus() != STATUS_WAIT_QUEUE) |
---|
275 | return; |
---|
276 | if (m_QueuedPlayers[queue_id].Alliance >= bg2->GetMinPlayersPerTeam() && m_QueuedPlayers[queue_id].Horde >= bg2->GetMinPlayersPerTeam()) |
---|
277 | { |
---|
278 | bg2->SetStatus(STATUS_WAIT_JOIN); |
---|
279 | bg2->SetQueueType(queue_id); |
---|
280 | |
---|
281 | for (PlayerGuidsSortedByTimeQueue::iterator itr2 = m_PlayersSortedByWaitTime[queue_id].begin(); itr2 != m_PlayersSortedByWaitTime[queue_id].end();) |
---|
282 | { |
---|
283 | Player* plr = objmgr.GetPlayer(*itr2); |
---|
284 | if (!plr) |
---|
285 | { |
---|
286 | //something is wrong!, kick player from queue |
---|
287 | sLog.outError("BATTLEGROUND: problem with inviting offline player to Battleground queue .... pls report bug"); |
---|
288 | uint64 oldval = *itr2; |
---|
289 | itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2); |
---|
290 | RemovePlayer(oldval, true); |
---|
291 | continue; |
---|
292 | } |
---|
293 | |
---|
294 | /* TODO: (i'm not sure this code will be useful: |
---|
295 | here should be some condition like if (bg2->isArena() && bg2->isRated()) |
---|
296 | { |
---|
297 | invite players from 1 certain group on each faction to play arena match |
---|
298 | } else if ....and existing code |
---|
299 | */ |
---|
300 | // player will be invited, if in bg there is a free slot for him |
---|
301 | if (bg2->HasFreeSlotsForTeam(plr->GetTeam())) |
---|
302 | { |
---|
303 | // iterator to player's queue status |
---|
304 | QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2); |
---|
305 | |
---|
306 | // remove him from time queue |
---|
307 | itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2); |
---|
308 | |
---|
309 | // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and report it) |
---|
310 | if (itrPlayerStatus == m_QueuedPlayers[queue_id].end()) |
---|
311 | continue; |
---|
312 | |
---|
313 | //check if player is not already invited |
---|
314 | if (!itrPlayerStatus->second.IsInvitedToBGInstanceGUID) |
---|
315 | { |
---|
316 | itrPlayerStatus->second.IsInvitedToBGInstanceGUID = bg2->GetInstanceID(); |
---|
317 | itrPlayerStatus->second.InviteTime = getMSTime(); |
---|
318 | itrPlayerStatus->second.LastInviteTime = getMSTime(); |
---|
319 | |
---|
320 | if(itrPlayerStatus->second.Team == ALLIANCE) |
---|
321 | --m_QueuedPlayers[queue_id].Alliance; |
---|
322 | else |
---|
323 | --m_QueuedPlayers[queue_id].Horde; |
---|
324 | |
---|
325 | sBattleGroundMgr.InvitePlayer(plr, bg2->GetInstanceID()); |
---|
326 | |
---|
327 | WorldPacket data; |
---|
328 | uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgTypeId); |
---|
329 | sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0); |
---|
330 | plr->GetSession()->SendPacket(&data); |
---|
331 | } |
---|
332 | } |
---|
333 | else |
---|
334 | ++itr2; |
---|
335 | } |
---|
336 | bg2->StartBattleGround(); |
---|
337 | } |
---|
338 | } |
---|
339 | |
---|
340 | /*********************************************************/ |
---|
341 | /*** BATTLEGROUND QUEUE EVENTS ***/ |
---|
342 | /*********************************************************/ |
---|
343 | |
---|
344 | bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 p_time) |
---|
345 | { |
---|
346 | Player* plr = objmgr.GetPlayer( m_PlayerGuid ); |
---|
347 | |
---|
348 | // player logged off (we should do nothing, he is correctly removed from queue in another procedure) |
---|
349 | if (!plr) |
---|
350 | return true; |
---|
351 | |
---|
352 | // Player can be in another BG queue and must be removed in normal way in any case |
---|
353 | // // player is already in battleground ... do nothing (battleground queue status is deleted when player is teleported to BG) |
---|
354 | // if (plr->GetBattleGroundId() > 0) |
---|
355 | // return true; |
---|
356 | |
---|
357 | BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID); |
---|
358 | if (!bg) |
---|
359 | return true; |
---|
360 | |
---|
361 | uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID()); |
---|
362 | if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue |
---|
363 | { |
---|
364 | // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems |
---|
365 | BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()]; |
---|
366 | BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid); |
---|
367 | if (qItr != qpMap.end() && qItr->second.IsInvitedToBGInstanceGUID == m_BgInstanceGUID) |
---|
368 | { |
---|
369 | WorldPacket data; |
---|
370 | sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME/2, 0); |
---|
371 | plr->GetSession()->SendPacket(&data); |
---|
372 | } |
---|
373 | } |
---|
374 | return true; //event will be deleted |
---|
375 | } |
---|
376 | |
---|
377 | void BGQueueInviteEvent::Abort(uint64 /*e_time*/) |
---|
378 | { |
---|
379 | //this should not be called |
---|
380 | sLog.outError("Battleground invite event ABORTED!"); |
---|
381 | } |
---|
382 | |
---|
383 | bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) |
---|
384 | { |
---|
385 | Player* plr = objmgr.GetPlayer( m_PlayerGuid ); |
---|
386 | if (!plr) |
---|
387 | // player logged off (we should do nothing, he is correctly removed from queue in another procedure) |
---|
388 | return true; |
---|
389 | |
---|
390 | // Player can be in another BG queue and must be removed in normal way in any case |
---|
391 | //if (plr->InBattleGround()) |
---|
392 | // // player is already in battleground ... do nothing (battleground queue status is deleted when player is teleported to BG) |
---|
393 | // return true; |
---|
394 | |
---|
395 | BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID); |
---|
396 | if (!bg) |
---|
397 | return true; |
---|
398 | |
---|
399 | uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID()); |
---|
400 | if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue (base at player data |
---|
401 | { |
---|
402 | // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems |
---|
403 | BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()]; |
---|
404 | BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid); |
---|
405 | if (qItr!=qpMap.end() && qItr->second.IsInvitedToBGInstanceGUID == m_BgInstanceGUID) |
---|
406 | { |
---|
407 | plr->RemoveBattleGroundQueueId(bg->GetTypeID()); |
---|
408 | sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].RemovePlayer(m_PlayerGuid, true); |
---|
409 | sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].Update(bg->GetTypeID(), bg->GetQueueType()); |
---|
410 | |
---|
411 | WorldPacket data; |
---|
412 | sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr->GetTeam(), queueSlot, STATUS_NONE, 0, 0); |
---|
413 | plr->GetSession()->SendPacket(&data); |
---|
414 | } |
---|
415 | } |
---|
416 | |
---|
417 | //event will be deleted |
---|
418 | return true; |
---|
419 | } |
---|
420 | |
---|
421 | void BGQueueRemoveEvent::Abort(uint64 /*e_time*/) |
---|
422 | { |
---|
423 | //this should not be called |
---|
424 | sLog.outError("Battleground remove event ABORTED!"); |
---|
425 | } |
---|
426 | |
---|
427 | /*********************************************************/ |
---|
428 | /*** BATTLEGROUND MANAGER ***/ |
---|
429 | /*********************************************************/ |
---|
430 | |
---|
431 | BattleGroundMgr::BattleGroundMgr() |
---|
432 | { |
---|
433 | m_BattleGrounds.clear(); |
---|
434 | } |
---|
435 | |
---|
436 | BattleGroundMgr::~BattleGroundMgr() |
---|
437 | { |
---|
438 | for(std::map<uint32, BattleGround*>::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr) |
---|
439 | delete itr->second; |
---|
440 | m_BattleGrounds.clear(); |
---|
441 | } |
---|
442 | |
---|
443 | void BattleGroundMgr::Update(time_t diff) |
---|
444 | { |
---|
445 | for(BattleGroundSet::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr) |
---|
446 | itr->second->Update(diff); |
---|
447 | } |
---|
448 | |
---|
449 | void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2) |
---|
450 | { |
---|
451 | // we can be in 3 queues in same time... |
---|
452 | if(StatusID == 0) |
---|
453 | { |
---|
454 | data->Initialize(SMSG_BATTLEFIELD_STATUS, 4*3); |
---|
455 | *data << uint32(QueueSlot); // queue id (0...2) |
---|
456 | *data << uint64(0); |
---|
457 | return; |
---|
458 | } |
---|
459 | |
---|
460 | data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+1+1+4+2+4+1+4+4+4)); |
---|
461 | *data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time |
---|
462 | // uint64 in client |
---|
463 | *data << uint64( uint64(bg->GetArenaType()) | (uint64(0x0D) << 8) | (uint64(bg->GetTypeID()) << 16) | (uint64(0x1F90) << 48) ); |
---|
464 | *data << uint32(0); // unknown |
---|
465 | // alliance/horde for BG and skirmish/rated for Arenas |
---|
466 | *data << uint8(bg->isArena() ? (bg->isRated() ? 1 : 0) : bg->GetTeamIndexByTeamId(team)); |
---|
467 | *data << uint32(StatusID); // status |
---|
468 | switch(StatusID) |
---|
469 | { |
---|
470 | case STATUS_WAIT_QUEUE: // status_in_queue |
---|
471 | *data << uint32(Time1); // average wait time, milliseconds |
---|
472 | *data << uint32(Time2); // time in queue, updated every minute? |
---|
473 | break; |
---|
474 | case STATUS_WAIT_JOIN: // status_invite |
---|
475 | *data << uint32(bg->GetMapId()); // map id |
---|
476 | *data << uint32(Time1); // time to remove from queue, milliseconds |
---|
477 | break; |
---|
478 | case STATUS_IN_PROGRESS: // status_in_progress |
---|
479 | *data << uint32(bg->GetMapId()); // map id |
---|
480 | *data << uint32(Time1); // 0 at bg start, 120000 after bg end, time to bg auto leave, milliseconds |
---|
481 | *data << uint32(Time2); // time from bg start, milliseconds |
---|
482 | *data << uint8(0x1); // unk sometimes 0x0! |
---|
483 | break; |
---|
484 | default: |
---|
485 | sLog.outError("Unknown BG status!"); |
---|
486 | break; |
---|
487 | } |
---|
488 | } |
---|
489 | |
---|
490 | void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg) |
---|
491 | { |
---|
492 | uint8 type = (bg->isArena() ? 1 : 0); |
---|
493 | // last check on 2.4.1 |
---|
494 | data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize())); |
---|
495 | *data << uint8(type); // seems to be type (battleground=0/arena=1) |
---|
496 | if(type) // arena |
---|
497 | { |
---|
498 | for(uint8 i = 0; i < 2; i++) |
---|
499 | { |
---|
500 | *data << uint32(3000+1+i); // rating change: showed value - 3000 |
---|
501 | *data << uint32(0); // 2.4.0, has some to do with rating change... |
---|
502 | *data << uint8(0); // some unknown string |
---|
503 | } |
---|
504 | } |
---|
505 | |
---|
506 | if(bg->GetWinner() == 2) |
---|
507 | { |
---|
508 | *data << uint8(0); // bg in progress |
---|
509 | } |
---|
510 | else |
---|
511 | { |
---|
512 | *data << uint8(1); // bg ended |
---|
513 | *data << uint8(bg->GetWinner()); // who win |
---|
514 | } |
---|
515 | |
---|
516 | *data << (int32)(bg->GetPlayerScoresSize()); |
---|
517 | |
---|
518 | for(std::map<uint64, BattleGroundScore*>::const_iterator itr = bg->GetPlayerScoresBegin(); itr != bg->GetPlayerScoresEnd(); ++itr) |
---|
519 | { |
---|
520 | *data << (uint64)itr->first; |
---|
521 | *data << (int32)itr->second->KillingBlows; |
---|
522 | if(type) |
---|
523 | { |
---|
524 | // this value is team (green/gold)? |
---|
525 | // that part probably wrong |
---|
526 | Player *plr = objmgr.GetPlayer(itr->first); |
---|
527 | if(plr) |
---|
528 | { |
---|
529 | if(plr->GetTeam() == HORDE) |
---|
530 | *data << uint8(0); |
---|
531 | else if(plr->GetTeam() == ALLIANCE) |
---|
532 | *data << uint8(1); |
---|
533 | else |
---|
534 | *data << uint8(0); |
---|
535 | } |
---|
536 | else |
---|
537 | *data << uint8(0); |
---|
538 | } |
---|
539 | else |
---|
540 | { |
---|
541 | *data << (int32)itr->second->HonorableKills; |
---|
542 | *data << (int32)itr->second->Deaths; |
---|
543 | *data << (int32)itr->second->BonusHonor; // bonus honor |
---|
544 | } |
---|
545 | *data << (int32)itr->second->DamageDone; // damage done |
---|
546 | *data << (int32)itr->second->HealingDone; // healing done |
---|
547 | switch(bg->GetTypeID()) // battleground specific things |
---|
548 | { |
---|
549 | case BATTLEGROUND_AV: |
---|
550 | *data << (uint32)0x00000005; // count of next fields |
---|
551 | *data << (uint32)((BattleGroundAVScore*)itr->second)->GraveyardsAssaulted; // GraveyardsAssaulted |
---|
552 | *data << (uint32)((BattleGroundAVScore*)itr->second)->GraveyardsDefended; // GraveyardsDefended |
---|
553 | *data << (uint32)((BattleGroundAVScore*)itr->second)->TowersAssaulted; // TowersAssaulted |
---|
554 | *data << (uint32)((BattleGroundAVScore*)itr->second)->TowersDefended; // TowersDefended |
---|
555 | *data << (uint32)((BattleGroundAVScore*)itr->second)->MinesCaptured; // MinesCaptured |
---|
556 | break; |
---|
557 | case BATTLEGROUND_WS: |
---|
558 | *data << (uint32)0x00000002; // count of next fields |
---|
559 | *data << (uint32)((BattleGroundWGScore*)itr->second)->FlagCaptures; // flag captures |
---|
560 | *data << (uint32)((BattleGroundWGScore*)itr->second)->FlagReturns; // flag returns |
---|
561 | break; |
---|
562 | case BATTLEGROUND_AB: |
---|
563 | *data << (uint32)0x00000002; // count of next fields |
---|
564 | *data << (uint32)((BattleGroundABScore*)itr->second)->BasesAssaulted; // bases asssulted |
---|
565 | *data << (uint32)((BattleGroundABScore*)itr->second)->BasesDefended; // bases defended |
---|
566 | break; |
---|
567 | case BATTLEGROUND_EY: |
---|
568 | *data << (uint32)0x00000001; // count of next fields |
---|
569 | *data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures; // flag captures |
---|
570 | break; |
---|
571 | case BATTLEGROUND_NA: |
---|
572 | case BATTLEGROUND_BE: |
---|
573 | case BATTLEGROUND_AA: |
---|
574 | case BATTLEGROUND_RL: |
---|
575 | *data << (int32)0; // 0 |
---|
576 | break; |
---|
577 | default: |
---|
578 | sLog.outDebug("Unhandled MSG_PVP_LOG_DATA for BG id %u", bg->GetTypeID()); |
---|
579 | *data << (int32)0; |
---|
580 | break; |
---|
581 | } |
---|
582 | } |
---|
583 | } |
---|
584 | |
---|
585 | void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId) |
---|
586 | { |
---|
587 | /*bgTypeId is: |
---|
588 | 0 - Your group has joined a battleground queue, but you are not eligible |
---|
589 | 1 - Your group has joined the queue for AV |
---|
590 | 2 - Your group has joined the queue for WS |
---|
591 | 3 - Your group has joined the queue for AB |
---|
592 | 4 - Your group has joined the queue for NA |
---|
593 | 5 - Your group has joined the queue for BE Arena |
---|
594 | 6 - Your group has joined the queue for All Arenas |
---|
595 | 7 - Your group has joined the queue for EotS*/ |
---|
596 | data->Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4); |
---|
597 | *data << uint32(bgTypeId); |
---|
598 | } |
---|
599 | |
---|
600 | void BattleGroundMgr::BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value) |
---|
601 | { |
---|
602 | data->Initialize(SMSG_UPDATE_WORLD_STATE, 4+4); |
---|
603 | *data << uint32(field); |
---|
604 | *data << uint32(value); |
---|
605 | } |
---|
606 | |
---|
607 | void BattleGroundMgr::BuildPlaySoundPacket(WorldPacket *data, uint32 soundid) |
---|
608 | { |
---|
609 | data->Initialize(SMSG_PLAY_SOUND, 4); |
---|
610 | *data << uint32(soundid); |
---|
611 | } |
---|
612 | |
---|
613 | void BattleGroundMgr::BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr) |
---|
614 | { |
---|
615 | data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8); |
---|
616 | *data << uint64(plr->GetGUID()); |
---|
617 | } |
---|
618 | |
---|
619 | void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr) |
---|
620 | { |
---|
621 | data->Initialize(SMSG_BATTLEGROUND_PLAYER_JOINED, 8); |
---|
622 | *data << uint64(plr->GetGUID()); |
---|
623 | } |
---|
624 | |
---|
625 | void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID) |
---|
626 | { |
---|
627 | // set invited player counters: |
---|
628 | BattleGround* bg = this->GetBattleGround(bgInstanceGUID); |
---|
629 | if(!bg) |
---|
630 | return; |
---|
631 | |
---|
632 | bg->IncreaseInvitedCount(plr->GetTeam()); |
---|
633 | plr->SetInviteForBattleGroundType(bg->GetTypeID()); |
---|
634 | // create invite events: |
---|
635 | //add events to player's counters ---- this is not good way - there should be something like global event processor, where we should add those events |
---|
636 | BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), bgInstanceGUID); |
---|
637 | plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME/2)); |
---|
638 | BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), bgInstanceGUID, plr->GetTeam()); |
---|
639 | plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME)); |
---|
640 | } |
---|
641 | |
---|
642 | uint32 BattleGroundMgr::CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO) |
---|
643 | { |
---|
644 | // Create the BG |
---|
645 | BattleGround *bg = NULL; |
---|
646 | |
---|
647 | switch(bgTypeId) |
---|
648 | { |
---|
649 | case BATTLEGROUND_AV: bg = new BattleGroundAV; break; |
---|
650 | case BATTLEGROUND_WS: bg = new BattleGroundWS; break; |
---|
651 | case BATTLEGROUND_AB: bg = new BattleGroundAB; break; |
---|
652 | case BATTLEGROUND_NA: bg = new BattleGroundNA; break; |
---|
653 | case BATTLEGROUND_BE: bg = new BattleGroundBE; break; |
---|
654 | case BATTLEGROUND_AA: bg = new BattleGroundAA; break; |
---|
655 | case BATTLEGROUND_EY: bg = new BattleGroundEY; break; |
---|
656 | case BATTLEGROUND_RL: bg = new BattleGroundRL; break; |
---|
657 | default:bg = new BattleGround; break; // placeholder for non implemented BG |
---|
658 | } |
---|
659 | |
---|
660 | bg->SetMapId(MapID); |
---|
661 | bg->Reset(); |
---|
662 | if(!bg->SetupBattleGround()) |
---|
663 | { |
---|
664 | delete bg; |
---|
665 | return 0; |
---|
666 | } |
---|
667 | |
---|
668 | BattlemasterListEntry const *bl = sBattlemasterListStore.LookupEntry(bgTypeId); |
---|
669 | //in previous method is checked if exists entry in sBattlemasterListStore, so no check needed |
---|
670 | if (bl) |
---|
671 | { |
---|
672 | bg->SetArenaorBGType(bl->type == TYPE_ARENA); |
---|
673 | } |
---|
674 | |
---|
675 | bg->SetTypeID(bgTypeId); |
---|
676 | bg->SetInstanceID(bgTypeId); // temporary |
---|
677 | bg->SetMinPlayersPerTeam(MinPlayersPerTeam); |
---|
678 | bg->SetMaxPlayersPerTeam(MaxPlayersPerTeam); |
---|
679 | bg->SetMinPlayers(MinPlayersPerTeam*2); |
---|
680 | bg->SetMaxPlayers(MaxPlayersPerTeam*2); |
---|
681 | bg->SetName(BattleGroundName); |
---|
682 | bg->SetTeamStartLoc(ALLIANCE, Team1StartLocX, Team1StartLocY, Team1StartLocZ, Team1StartLocO); |
---|
683 | bg->SetTeamStartLoc(HORDE, Team2StartLocX, Team2StartLocY, Team2StartLocZ, Team2StartLocO); |
---|
684 | bg->SetLevelRange(LevelMin, LevelMax); |
---|
685 | //add BaggleGround instance to FreeSlotQueue |
---|
686 | bg->AddToBGFreeSlotQueue(); |
---|
687 | |
---|
688 | AddBattleGround(bg->GetInstanceID(), bg); |
---|
689 | //sLog.outDetail("BattleGroundMgr: Created new battleground: %u %s (Map %u, %u players per team, Levels %u-%u)", bg_TypeID, bg->m_Name, bg->m_MapId, bg->m_MaxPlayersPerTeam, bg->m_LevelMin, bg->m_LevelMax); |
---|
690 | return bg->GetInstanceID(); |
---|
691 | } |
---|
692 | |
---|
693 | void BattleGroundMgr::CreateInitialBattleGrounds() |
---|
694 | { |
---|
695 | float AStartLoc[4]; |
---|
696 | float HStartLoc[4]; |
---|
697 | uint32 MaxPlayersPerTeam, MinPlayersPerTeam, MinLvl, MaxLvl, start1, start2; |
---|
698 | BattlemasterListEntry const *bl; |
---|
699 | WorldSafeLocsEntry const *start; |
---|
700 | |
---|
701 | uint32 count = 0; |
---|
702 | |
---|
703 | // 0 1 2 3 4 5 6 7 8 |
---|
704 | QueryResult *result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template"); |
---|
705 | |
---|
706 | if(!result) |
---|
707 | { |
---|
708 | barGoLink bar(1); |
---|
709 | |
---|
710 | bar.step(); |
---|
711 | |
---|
712 | sLog.outString(); |
---|
713 | sLog.outErrorDb(">> Loaded 0 battlegrounds. DB table `battleground_template` is empty."); |
---|
714 | return; |
---|
715 | } |
---|
716 | |
---|
717 | barGoLink bar(result->GetRowCount()); |
---|
718 | |
---|
719 | do |
---|
720 | { |
---|
721 | Field *fields = result->Fetch(); |
---|
722 | bar.step(); |
---|
723 | |
---|
724 | uint32 bgTypeID = fields[0].GetUInt32(); |
---|
725 | |
---|
726 | // can be overwrited by values from DB |
---|
727 | bl = sBattlemasterListStore.LookupEntry(bgTypeID); |
---|
728 | if(!bl) |
---|
729 | { |
---|
730 | sLog.outError("Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.",bgTypeID); |
---|
731 | continue; |
---|
732 | } |
---|
733 | |
---|
734 | MaxPlayersPerTeam = bl->maxplayersperteam; |
---|
735 | MinPlayersPerTeam = bl->maxplayersperteam/2; |
---|
736 | MinLvl = bl->minlvl; |
---|
737 | MaxLvl = bl->maxlvl; |
---|
738 | |
---|
739 | if(fields[1].GetUInt32()) |
---|
740 | MinPlayersPerTeam = fields[1].GetUInt32(); |
---|
741 | |
---|
742 | if(fields[2].GetUInt32()) |
---|
743 | MaxPlayersPerTeam = fields[2].GetUInt32(); |
---|
744 | |
---|
745 | if(fields[3].GetUInt32()) |
---|
746 | MinLvl = fields[3].GetUInt32(); |
---|
747 | |
---|
748 | if(fields[4].GetUInt32()) |
---|
749 | MaxLvl = fields[4].GetUInt32(); |
---|
750 | |
---|
751 | start1 = fields[5].GetUInt32(); |
---|
752 | |
---|
753 | start = sWorldSafeLocsStore.LookupEntry(start1); |
---|
754 | if(start) |
---|
755 | { |
---|
756 | AStartLoc[0] = start->x; |
---|
757 | AStartLoc[1] = start->y; |
---|
758 | AStartLoc[2] = start->z; |
---|
759 | AStartLoc[3] = fields[6].GetFloat(); |
---|
760 | } |
---|
761 | else if(bgTypeID == BATTLEGROUND_AA) |
---|
762 | { |
---|
763 | AStartLoc[0] = 0; |
---|
764 | AStartLoc[1] = 0; |
---|
765 | AStartLoc[2] = 0; |
---|
766 | AStartLoc[3] = fields[6].GetFloat(); |
---|
767 | } |
---|
768 | else |
---|
769 | { |
---|
770 | sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.",bgTypeID,start1); |
---|
771 | continue; |
---|
772 | } |
---|
773 | |
---|
774 | start2 = fields[7].GetUInt32(); |
---|
775 | |
---|
776 | start = sWorldSafeLocsStore.LookupEntry(start2); |
---|
777 | if(start) |
---|
778 | { |
---|
779 | HStartLoc[0] = start->x; |
---|
780 | HStartLoc[1] = start->y; |
---|
781 | HStartLoc[2] = start->z; |
---|
782 | HStartLoc[3] = fields[8].GetFloat(); |
---|
783 | } |
---|
784 | else if(bgTypeID == BATTLEGROUND_AA) |
---|
785 | { |
---|
786 | HStartLoc[0] = 0; |
---|
787 | HStartLoc[1] = 0; |
---|
788 | HStartLoc[2] = 0; |
---|
789 | HStartLoc[3] = fields[8].GetFloat(); |
---|
790 | } |
---|
791 | else |
---|
792 | { |
---|
793 | sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.",bgTypeID,start2); |
---|
794 | continue; |
---|
795 | } |
---|
796 | |
---|
797 | //sLog.outDetail("Creating battleground %s, %u-%u", bl->name[sWorld.GetDBClang()], MinLvl, MaxLvl); |
---|
798 | if(!CreateBattleGround(bgTypeID, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, bl->name[sWorld.GetDefaultDbcLocale()], bl->mapid[0], AStartLoc[0], AStartLoc[1], AStartLoc[2], AStartLoc[3], HStartLoc[0], HStartLoc[1], HStartLoc[2], HStartLoc[3])) |
---|
799 | continue; |
---|
800 | |
---|
801 | ++count; |
---|
802 | } while (result->NextRow()); |
---|
803 | |
---|
804 | delete result; |
---|
805 | |
---|
806 | sLog.outString(); |
---|
807 | sLog.outString( ">> Loaded %u battlegrounds", count ); |
---|
808 | } |
---|
809 | |
---|
810 | void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player* plr, uint32 bgTypeId) |
---|
811 | { |
---|
812 | uint32 PlayerLevel = 10; |
---|
813 | |
---|
814 | if(plr) |
---|
815 | PlayerLevel = plr->getLevel(); |
---|
816 | |
---|
817 | data->Initialize(SMSG_BATTLEFIELD_LIST); |
---|
818 | *data << uint64(guid); // battlemaster guid |
---|
819 | *data << uint32(bgTypeId); // battleground id |
---|
820 | if(bgTypeId == BATTLEGROUND_AA) // arena |
---|
821 | { |
---|
822 | *data << uint8(5); // unk |
---|
823 | *data << uint32(0); // unk |
---|
824 | } |
---|
825 | else // battleground |
---|
826 | { |
---|
827 | *data << uint8(0x00); // unk |
---|
828 | |
---|
829 | size_t count_pos = data->wpos(); |
---|
830 | uint32 count = 0; |
---|
831 | *data << uint32(0x00); // number of bg instances |
---|
832 | |
---|
833 | for(std::map<uint32, BattleGround*>::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr) |
---|
834 | { |
---|
835 | if(itr->second->GetTypeID() == bgTypeId && (PlayerLevel >= itr->second->GetMinLevel()) && (PlayerLevel <= itr->second->GetMaxLevel())) |
---|
836 | { |
---|
837 | *data << uint32(itr->second->GetInstanceID()); |
---|
838 | ++count; |
---|
839 | } |
---|
840 | } |
---|
841 | data->put<uint32>( count_pos , count); |
---|
842 | } |
---|
843 | } |
---|
844 | |
---|
845 | void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 bgTypeId) |
---|
846 | { |
---|
847 | BattleGround *bg = GetBattleGround(bgTypeId); |
---|
848 | if(bg) |
---|
849 | { |
---|
850 | uint32 mapid = bg->GetMapId(); |
---|
851 | float x, y, z, O; |
---|
852 | bg->GetTeamStartLoc(pl->GetTeam(), x, y, z, O); |
---|
853 | |
---|
854 | sLog.outDetail("BATTLEGROUND: Sending %s to map %u, X %f, Y %f, Z %f, O %f", pl->GetName(), mapid, x, y, z, O); |
---|
855 | pl->TeleportTo(mapid, x, y, z, O); |
---|
856 | } |
---|
857 | } |
---|
858 | |
---|
859 | void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid) |
---|
860 | { |
---|
861 | WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12); |
---|
862 | uint32 time_ = 30000 - bg->GetLastResurrectTime(); // resurrect every 30 seconds |
---|
863 | if(time_ == uint32(-1)) |
---|
864 | time_ = 0; |
---|
865 | data << guid << time_; |
---|
866 | pl->GetSession()->SendPacket(&data); |
---|
867 | } |
---|