1. /*
  2. * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
  3. * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* ScriptData
  19. Name: Arena Spectator
  20. Complete: 80%
  21. Comment: This script allow to spectate games
  22. Category: Custom Script
  23. Future Developing: 5v5, Specific Player
  24. Credits: Flameshot http://flameshot.tk
  25. LilleCarl
  26. EndScriptData */
  27. #include "Chat.h"
  28. #include "ArenaTeamMgr.h"
  29. #include "BattlegroundMgr.h"
  30. #include "WorldSession.h"
  31. #include "Player.h"
  32. #include "ArenaTeam.h"
  33. #include "Battleground.h"
  34. #include "BattlegroundMgr.h"
  35. #include "CreatureTextMgr.h"
  36. #include "Config.h"
  37. #include "ScriptedGossip.h"
  38. #include "ScriptMgr.h"
  39. int8 UsingGossip;
  40. class arena_spectator_commands : public CommandScript
  41. {
  42. public:
  43. arena_spectator_commands() : CommandScript("arena_spectator_commands") { }
  44. static bool HandleSpectateCommand(ChatHandler* handler, char const* args)
  45. {
  46. Player* target;
  47. ObjectGuid target_guid;
  48. std::string target_name;
  49. if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
  50. return false;
  51. Player* player = handler->GetSession()->GetPlayer();
  52. if (target == player || target_guid == player->GetGUID())
  53. {
  54. handler->PSendSysMessage("You can't spectate yourself.");
  55. handler->SetSentErrorMessage(true);
  56. return false;
  57. }
  58. if (player->IsInCombat())
  59. {
  60. handler->PSendSysMessage("You are in combat.");
  61. handler->SetSentErrorMessage(true);
  62. return false;
  63. }
  64. if (!target)
  65. {
  66. handler->PSendSysMessage("Target is not online or does not exist.");
  67. handler->SetSentErrorMessage(true);
  68. return false;
  69. }
  70. if (player->GetPet())
  71. {
  72. handler->PSendSysMessage("You must hide your pet.");
  73. handler->SetSentErrorMessage(true);
  74. return false;
  75. }
  76. if (player->GetMap()->IsBattlegroundOrArena() && !player->IsSpectator())
  77. {
  78. handler->PSendSysMessage("You are already in a battleground or arena.");
  79. handler->SetSentErrorMessage(true);
  80. return false;
  81. }
  82. Map* cMap = target->GetMap();
  83. if (!cMap->IsBattleArena())
  84. {
  85. handler->PSendSysMessage("Player is not in an Arena match.");
  86. handler->SetSentErrorMessage(true);
  87. return false;
  88. }
  89. if (player->GetMap()->IsBattleground())
  90. {
  91. handler->PSendSysMessage("You can't do that while in a battleground.");
  92. handler->SetSentErrorMessage(true);
  93. return false;
  94. }
  95. if (target->HasAura(32728) || target->HasAura(32727))
  96. {
  97. handler->PSendSysMessage("You can't do that. The Arena match didn't start yet.");
  98. handler->SetSentErrorMessage(true);
  99. return false;
  100. }
  101. if (target->IsSpectator())
  102. {
  103. handler->PSendSysMessage("You can't do that. Your target is a spectator.");
  104. handler->SetSentErrorMessage(true);
  105. return false;
  106. }
  107. if (player->IsMounted())
  108. {
  109. handler->PSendSysMessage("Cannot Spectate while mounted.");
  110. handler->SetSentErrorMessage(true);
  111. return false;
  112. }
  113. // all's well, set bg id
  114. // when porting out from the bg, it will be reset to 0
  115. player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId());
  116. // remember current position as entry point for return at bg end teleportation
  117. if (!player->GetMap()->IsBattlegroundOrArena())
  118. player->SetBattlegroundEntryPoint();
  119. // stop flight if need
  120. if (player->IsInFlight())
  121. {
  122. player->GetMotionMaster()->MovementExpired();
  123. player->CleanupAfterTaxiFlight();
  124. }
  125. // save only in non-flight case
  126. else
  127. player->SaveRecallPosition();
  128. // search for two teams
  129. Battleground *bGround = target->GetBattleground();
  130. if (bGround->isRated())
  131. {
  132. uint32 slot = bGround->GetArenaType() - 2;
  133. if (bGround->GetArenaType() > 3)
  134. slot = 2;
  135. uint32 firstTeamID = target->GetArenaTeamId(slot);
  136. uint32 secondTeamID = 0;
  137. Player *firstTeamMember = target;
  138. Player *secondTeamMember = NULL;
  139. for (Battleground::BattlegroundPlayerMap::const_iterator itr = bGround->GetPlayers().begin(); itr != bGround->GetPlayers().end(); ++itr)
  140. if (Player* tmpPlayer = ObjectAccessor::FindPlayer(itr->first))
  141. {
  142. if (tmpPlayer->IsSpectator())
  143. continue;
  144. uint32 tmpID = tmpPlayer->GetArenaTeamId(slot);
  145. if (tmpID != firstTeamID && tmpID > 0)
  146. {
  147. secondTeamID = tmpID;
  148. secondTeamMember = tmpPlayer;
  149. break;
  150. }
  151. }
  152. if (firstTeamID > 0 && secondTeamID > 0 && secondTeamMember)
  153. {
  154. ArenaTeam *firstTeam = sArenaTeamMgr->GetArenaTeamById(firstTeamID);
  155. ArenaTeam *secondTeam = sArenaTeamMgr->GetArenaTeamById(secondTeamID);
  156. if (firstTeam && secondTeam)
  157. {
  158. handler->PSendSysMessage("You entered a Rated Arena.");
  159. handler->PSendSysMessage("Teams:");
  160. handler->PSendSysMessage("|cFFffffff%s|r vs |cFFffffff%s|r", firstTeam->GetName().c_str(), secondTeam->GetName().c_str());
  161. handler->PSendSysMessage("|cFFffffff%u(%u)|r -- |cFFffffff%u(%u)|r", firstTeam->GetRating(), firstTeam->GetAverageMMR(firstTeamMember->GetGroup()),
  162. secondTeam->GetRating(), secondTeam->GetAverageMMR(secondTeamMember->GetGroup()));
  163. }
  164. }
  165. }
  166. // to point to see at target with same orientation
  167. float x, y, z;
  168. target->GetContactPoint(player, x, y, z);
  169. player->TeleportTo(target->GetMapId(), x, y, z, player->GetAngle(target), TELE_TO_GM_MODE);
  170. player->SetPhaseMask(target->GetPhaseMask(), true);
  171. player->SetSpectate(true);
  172. target->GetBattleground()->AddSpectator(player->GetGUID());
  173. return true;
  174. }
  175. static bool HandleSpectateCancelCommand(ChatHandler* handler, const char* /*args*/)
  176. {
  177. Player* player = handler->GetSession()->GetPlayer();
  178. if (!player->IsSpectator())
  179. {
  180. handler->PSendSysMessage("You are not a spectator.");
  181. handler->SetSentErrorMessage(true);
  182. return false;
  183. }
  184. player->GetBattleground()->RemoveSpectator(player->GetGUID());
  185. player->CancelSpectate();
  186. player->TeleportToBGEntryPoint();
  187. return true;
  188. }
  189. static bool HandleSpectateFromCommand(ChatHandler* handler, const char *args)
  190. {
  191. Player* target;
  192. ObjectGuid target_guid;
  193. std::string target_name;
  194. if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
  195. return false;
  196. Player* player = handler->GetSession()->GetPlayer();
  197. if (target->HasAuraType(SPELL_AURA_MOD_STEALTH))
  198. {
  199. handler->PSendSysMessage("You can't target stealthed players.");
  200. handler->SetSentErrorMessage(true);
  201. return false;
  202. }
  203. if (!target)
  204. {
  205. handler->PSendSysMessage("Player is not online or does not exist.");
  206. handler->SetSentErrorMessage(true);
  207. return false;
  208. }
  209. if (!player->IsSpectator())
  210. {
  211. handler->PSendSysMessage("You are not a spectator, spectate someone first.");
  212. handler->SetSentErrorMessage(true);
  213. return false;
  214. }
  215. if (target->IsSpectator() && target != player)
  216. {
  217. handler->PSendSysMessage("You can't do that. Your target is a spectator.");
  218. handler->SetSentErrorMessage(true);
  219. return false;
  220. }
  221. if (player->GetMap() != target->GetMap())
  222. {
  223. handler->PSendSysMessage("You can't do that. Your target might be in a different arena match.");
  224. handler->SetSentErrorMessage(true);
  225. return false;
  226. }
  227. // check for arena preperation
  228. // if exists than battle didn`t begin
  229. if (target->HasAura(32728) || target->HasAura(32727))
  230. {
  231. handler->PSendSysMessage("You can't do that. The Arena match didn't start yet.");
  232. handler->SetSentErrorMessage(true);
  233. return false;
  234. }
  235. (target == player && player->GetSpectateFrom()) ? player->SetViewpoint(player->GetSpectateFrom(), false) :
  236. player->SetViewpoint(target, true);
  237. return true;
  238. }
  239. static bool HandleSpectateResetCommand(ChatHandler* handler, const char *args)
  240. {
  241. Player* player = handler->GetSession()->GetPlayer();
  242. if (!player)
  243. {
  244. handler->PSendSysMessage("Cant find player.");
  245. handler->SetSentErrorMessage(true);
  246. return false;
  247. }
  248. if (!player->IsSpectator())
  249. {
  250. handler->PSendSysMessage("You are not a spectator!");
  251. handler->SetSentErrorMessage(true);
  252. return false;
  253. }
  254. Battleground *bGround = player->GetBattleground();
  255. if (!bGround)
  256. return false;
  257. if (bGround->GetStatus() != STATUS_IN_PROGRESS)
  258. return true;
  259. for (Battleground::BattlegroundPlayerMap::const_iterator itr = bGround->GetPlayers().begin(); itr != bGround->GetPlayers().end(); ++itr)
  260. if (Player* tmpPlayer = ObjectAccessor::FindPlayer(itr->first))
  261. {
  262. if (tmpPlayer->IsSpectator())
  263. continue;
  264. uint32 tmpID = bGround->GetPlayerTeam(tmpPlayer->GetGUID());
  265. // generate addon massage
  266. std::string pName = tmpPlayer->GetName();
  267. std::string tName = "";
  268. if (Player *target = tmpPlayer->GetSelectedPlayer())
  269. tName = target->GetName();
  270. SpectatorAddonMsg msg; // Travis
  271. msg.SetPlayer(pName);
  272. if (tName != "")
  273. msg.SetTarget(tName);
  274. msg.SetStatus(tmpPlayer->IsAlive());
  275. msg.SetClass(tmpPlayer->getClass());
  276. msg.SetCurrentHP(tmpPlayer->GetHealth());
  277. msg.SetMaxHP(tmpPlayer->GetMaxHealth());
  278. Powers powerType = tmpPlayer->getPowerType();
  279. msg.SetMaxPower(tmpPlayer->GetMaxPower(powerType));
  280. msg.SetCurrentPower(tmpPlayer->GetPower(powerType));
  281. msg.SetPowerType(powerType);
  282. msg.SetTeam(tmpID);
  283. msg.SendPacket(player->GetGUID());
  284. }
  285. return true;
  286. }
  287. std::vector<ChatCommand> GetCommands() const override
  288. {
  289. static std::vector<ChatCommand> spectateCommandTable =
  290. {
  291. { "player", rbac::RBAC_PERM_COMMAND_SPECTATE_PLAYER, true, &HandleSpectateCommand, "" },
  292. { "view", rbac::RBAC_PERM_COMMAND_SPECTATE_VIEW, true, &HandleSpectateFromCommand, "" },
  293. { "reset", rbac::RBAC_PERM_COMMAND_SPECTATE_RESET, true, &HandleSpectateResetCommand, "" },
  294. { "leave", rbac::RBAC_PERM_COMMAND_SPECTATE_LEAVE, true, &HandleSpectateCancelCommand, "" }
  295. };
  296. static std::vector<ChatCommand> commandTable =
  297. {
  298. { "spectate", rbac::RBAC_PERM_COMMAND_SPECTATE, false, NULL, "", spectateCommandTable }
  299. };
  300. return commandTable;
  301. }
  302. };
  303. enum NpcSpectatorAtions {
  304. // will be used for scrolling
  305. NPC_SPECTATOR_ACTION_2V2_GAMES = 1000, //NPC_SPECTATOR_ACTION_LIST_GAMES = 1000,
  306. NPC_SPECTATOR_ACTION_3V3_GAMES = 2000, // NPC_SPECTATOR_ACTION_LIST_TOP_GAMES = 2000,
  307. // Disabled till I fix 2v2 , 3v3
  308. //NPC_SPECTATOR_ACTION_5V5_GAMES = 3000,
  309. //NPC_SPECTATOR_ACTION_SPECIFIC = 500,
  310. // NPC_SPECTATOR_ACTION_SELECTED_PLAYER + player.Guid()
  311. NPC_SPECTATOR_ACTION_SELECTED_PLAYER = 3000
  312. };
  313. const uint8 GamesOnPage = 15;
  314. class npc_arena_spectator : public CreatureScript
  315. {
  316. public:
  317. npc_arena_spectator() : CreatureScript("npc_arena_spectator") { }
  318. bool OnGossipHello(Player* pPlayer, Creature* pCreature)
  319. {
  320. pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "|TInterface\\icons\\Achievement_Arena_2v2_7:35:35:-30:0|tGames: 2v2", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_2V2_GAMES);
  321. pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "|TInterface\\icons\\Achievement_Arena_3v3_7:35:35:-30:0|tGames: 3v3", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_3V3_GAMES);
  322. //pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "|TInterface\\icons\\Achievement_Arena_5v5_7:35:35:-30:0|tGames: 5v5", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_5V5_GAMES);
  323. //pPlayer->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_CHAT, "|TInterface\\icons\\Spell_Holy_DevineAegis:35:35:-30:0|tSpectate Specific Player.", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_SPECIFIC, "", 0, true);
  324. pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
  325. return true;
  326. }
  327. bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
  328. {
  329. player->PlayerTalkClass->ClearMenus();
  330. /*if (action == NPC_SPECTATOR_ACTION_SPECIFIC)
  331. {
  332. }*/
  333. if (action >= NPC_SPECTATOR_ACTION_2V2_GAMES && action < NPC_SPECTATOR_ACTION_3V3_GAMES)
  334. {
  335. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, " Refresh", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_2V2_GAMES);
  336. ShowPage(player, action - NPC_SPECTATOR_ACTION_2V2_GAMES, false /*ARENA_TYPE_2v2*/);
  337. player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
  338. }
  339. //else if (action >= NPC_SPECTATOR_ACTION_3V3_GAMES && action < NPC_SPECTATOR_ACTION_5V5_GAMES)
  340. else if (action >= NPC_SPECTATOR_ACTION_3V3_GAMES && action < NPC_SPECTATOR_ACTION_2V2_GAMES)
  341. {
  342. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Refresh", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_3V3_GAMES);
  343. ShowPage(player, action - NPC_SPECTATOR_ACTION_3V3_GAMES, true/*ARENA_TYPE_3v3*/);
  344. player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
  345. }
  346. /*else if (action >= NPC_SPECTATOR_ACTION_5V5_GAMES && action < NPC_SPECTATOR_ACTION_SELECTED_PLAYER)
  347. {
  348. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Refresh", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_5V5_GAMES);
  349. ShowPage(player, action - NPC_SPECTATOR_ACTION_5V5_GAMES, ARENA_TYPE_5v5);
  350. player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
  351. }*/
  352. else
  353. {
  354. ObjectGuid guid = ObjectGuid(HighGuid::Player, action - NPC_SPECTATOR_ACTION_SELECTED_PLAYER);
  355. if (Player* target = ObjectAccessor::FindPlayer(guid))
  356. {
  357. ChatHandler handler(player->GetSession());
  358. char const* pTarget = target->GetName().c_str();
  359. arena_spectator_commands::HandleSpectateCommand(&handler, pTarget);
  360. }
  361. }
  362. return true;
  363. }
  364. std::string GetClassNameById(uint8 id)
  365. {
  366. std::string sClass = "";
  367. switch (id)
  368. {
  369. case CLASS_WARRIOR: sClass = "Warrior "; break;
  370. case CLASS_PALADIN: sClass = "Paladin "; break;
  371. case CLASS_HUNTER: sClass = "Hunter "; break;
  372. case CLASS_ROGUE: sClass = "Rogue "; break;
  373. case CLASS_PRIEST: sClass = "Priest "; break;
  374. case CLASS_DEATH_KNIGHT: sClass = "DKnight "; break;
  375. case CLASS_SHAMAN: sClass = "Shaman "; break;
  376. case CLASS_MAGE: sClass = "Mage "; break;
  377. case CLASS_WARLOCK: sClass = "Warlock "; break;
  378. case CLASS_DRUID: sClass = "Druid "; break;
  379. }
  380. return sClass;
  381. }
  382. std::string GetGamesStringData(Battleground* team, uint16 mmr , uint16 mmrTwo)
  383. {
  384. std::string teamsMember[BG_TEAMS_COUNT];
  385. uint32 firstTeamId = 0;
  386. for (Battleground::BattlegroundPlayerMap::const_iterator itr = team->GetPlayers().begin(); itr != team->GetPlayers().end(); ++itr)
  387. if (Player* player = ObjectAccessor::FindPlayer(itr->first))
  388. {
  389. if (player->IsSpectator())
  390. continue;
  391. if (player->IsGameMaster())
  392. continue;
  393. uint32 team = itr->second.Team;
  394. if (!firstTeamId)
  395. firstTeamId = team;
  396. // Try to get ArenaTeamName
  397. std::string name;
  398. ArenaTeam* arena = sArenaTeamMgr->GetArenaTeamByName(name);
  399. //
  400. teamsMember[firstTeamId == team] += GetClassNameById(player->getClass());
  401. }
  402. std::string data = teamsMember[0] + "(";
  403. std::stringstream ss;
  404. std::stringstream sstwo;
  405. ss << mmr;
  406. sstwo << mmrTwo;
  407. data += ss.str();
  408. data += ") - ";
  409. data += teamsMember[1] + "(" + sstwo.str();
  410. data += ")";
  411. return data;
  412. }
  413. ObjectGuid GetFirstPlayerGuid(Battleground* team)
  414. {
  415. for (Battleground::BattlegroundPlayerMap::const_iterator itr = team->GetPlayers().begin(); itr != team->GetPlayers().end(); ++itr)
  416. if (Player* player = ObjectAccessor::FindPlayer(itr->first))
  417. return itr->first;
  418. return ObjectGuid::Empty;
  419. }
  420. //void ShowPage(Player* player, uint16 page, uint32 IsTop)
  421. void ShowPage(Player* player, uint16 page, bool IsTop)
  422. {
  423. uint32 firstTeamId = 0;
  424. uint16 TypeOne = 0;
  425. uint16 TypeTwo = 0;
  426. uint16 TypeThree = 0;
  427. uint16 mmr = 0;
  428. uint16 mmrTwo = 0;
  429. bool haveNextPage = false;
  430. for (uint8 i = 0; i <= MAX_BATTLEGROUND_TYPE_ID; ++i)
  431. {
  432. if (!sBattlegroundMgr->IsArenaType(BattlegroundTypeId(i)))
  433. continue;
  434. //BattlegroundContainer arenas = sBattlegroundMgr->GetBattlegroundsByType((BattlegroundTypeId)i);
  435. BattlegroundData* arenas = sBattlegroundMgr->GetAllBattlegroundsWithTypeId(BattlegroundTypeId(i));
  436. if (!arenas || arenas->m_Battlegrounds.empty())
  437. continue;
  438. for (BattlegroundContainer::const_iterator itr = arenas->m_Battlegrounds.begin(); itr != arenas->m_Battlegrounds.end(); ++itr)
  439. {
  440. Battleground* arena = itr->second;
  441. Player* target = ObjectAccessor::FindPlayer(GetFirstPlayerGuid(arena));
  442. if (target && (target->HasAura(32728) || target->HasAura(32727)))
  443. continue;
  444. if (!arena->GetPlayersSize())
  445. continue;
  446. //uint16 mmrTwo = arena->GetArenaMatchmakerRating(0);
  447. //uint16 mmrThree = arena->GetArenaMatchmakerRating(1);
  448. // This shows the mmr of both teams on ARENA_TYPE_2v2
  449. if (arena->GetArenaType() == ARENA_TYPE_2v2)
  450. {
  451. mmr = arena->GetArenaMatchmakerRating(0);
  452. firstTeamId = target->GetArenaTeamId(0);
  453. Battleground::BattlegroundPlayerMap::const_iterator citr = arena->GetPlayers().begin();
  454. for (; citr != arena->GetPlayers().end(); ++citr)
  455. if (Player* plrs = ObjectAccessor::FindPlayer(citr->first))
  456. if (plrs->GetArenaTeamId(0) != firstTeamId)
  457. mmrTwo = arena->GetArenaMatchmakerRating(citr->second.Team);
  458. }
  459. // This shows the mmr of both teams on ARENA_TYPE_3v3
  460. else if (arena->GetArenaType() == ARENA_TYPE_3v3)
  461. {
  462. mmr = arena->GetArenaMatchmakerRating(1);
  463. firstTeamId = target->GetArenaTeamId(1);
  464. Battleground::BattlegroundPlayerMap::const_iterator citr = arena->GetPlayers().begin();
  465. for (; citr != arena->GetPlayers().end(); ++citr)
  466. if (Player* plrs = ObjectAccessor::FindPlayer(citr->first))
  467. if (plrs->GetArenaTeamId(1) != firstTeamId)
  468. mmrTwo = arena->GetArenaMatchmakerRating(citr->second.Team);
  469. }/*
  470. else if (arena->GetArenaType() == ARENA_TYPE_5v5)
  471. {
  472. mmr = arena->GetArenaMatchmakerRating(2);
  473. firstTeamId = target->GetArenaTeamId(2);
  474. Battleground::BattlegroundPlayerMap::const_iterator citr = arena->GetPlayers().begin();
  475. for (; citr != arena->GetPlayers().end(); ++citr)
  476. if (Player* plrs = ObjectAccessor::FindPlayer(citr->first))
  477. if (plrs->GetArenaTeamId(2) != firstTeamId)
  478. mmrTwo = arena->GetArenaMatchmakerRating(citr->second.Team);
  479. }
  480. if (IsTop == 1 && arena->GetArenaType() == ARENA_TYPE_2v2)
  481. {
  482. TypeOne++;
  483. if (TypeOne > (page + 1) * GamesOnPage)
  484. {
  485. haveNextPage = true;
  486. break;
  487. }
  488. if (TypeOne >= page * GamesOnPage)
  489. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_BATTLE, GetGamesStringData(arena, mmr, mmrTwo), GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_SELECTED_PLAYER + GetFirstPlayerGuid(arena));
  490. }
  491. else if (IsTop == 2 && arena->GetArenaType() == ARENA_TYPE_3v3)
  492. {
  493. TypeTwo++;
  494. if (TypeTwo > (page + 1) * GamesOnPage)
  495. {
  496. haveNextPage = true;
  497. break;
  498. }
  499. if (TypeTwo >= page * GamesOnPage)
  500. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_BATTLE, GetGamesStringData(arena, mmr, mmrTwo), GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_SELECTED_PLAYER + GetFirstPlayerGuid(arena));
  501. }
  502. else if (IsTop == 3 && arena->GetArenaType() == ARENA_TYPE_5v5)
  503. {
  504. TypeThree++;
  505. if (TypeThree > (page + 1) * GamesOnPage)
  506. {
  507. haveNextPage = true;
  508. break;
  509. }
  510. if (TypeThree >= page * GamesOnPage)
  511. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_BATTLE, GetGamesStringData(arena, mmr, mmrTwo), GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_SELECTED_PLAYER + GetFirstPlayerGuid(arena));
  512. }
  513. }
  514. }
  515. if (page > 0)
  516. {
  517. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Prev..", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_2V2_GAMES + page - 1);
  518. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Prev..", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_3V3_GAMES + page - 1);
  519. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Prev..", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_5V5_GAMES + page - 1);
  520. }
  521. if (haveNextPage)
  522. {
  523. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Next..", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_2V2_GAMES + page + 1);
  524. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Next..", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_3V3_GAMES + page + 1);
  525. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Next..", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_5V5_GAMES + page + 1);
  526. }
  527. }
  528. bool OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code)
  529. {
  530. if (!player)
  531. return true;
  532. player->PlayerTalkClass->ClearMenus();
  533. player->CLOSE_GOSSIP_MENU();
  534. if (sender == GOSSIP_SENDER_MAIN)
  535. {
  536. switch (action)
  537. {
  538. case NPC_SPECTATOR_ACTION_SPECIFIC: // choosing a player
  539. const char* plrName = code;
  540. char playerName[50];
  541. strcpy(playerName, plrName);
  542. for (int i = 0; i < 13; i++)
  543. {
  544. if (playerName[i] == NULL)
  545. break;
  546. if (i == 0 && playerName[i] > 96)
  547. playerName[0] -= 32;
  548. else if (playerName[i] < 97)
  549. playerName[i] += 32;
  550. }
  551. if (Player* target = ObjectAccessor::FindPlayerByName(playerName))
  552. {
  553. ChatHandler handler(player->GetSession());
  554. char const* pTarget = target->GetName().c_str();
  555. arena_spectator_commands::HandleSpectateCommand(&handler, pTarget);
  556. }
  557. ChatHandler(player->GetSession()).PSendSysMessage("Player is not online or does not exist.");
  558. return true;
  559. }
  560. }
  561. return false;
  562. }*/
  563. if (IsTop && arena->GetArenaType() == ARENA_TYPE_3v3)
  564. {
  565. TypeThree++;
  566. if (TypeThree > (page + 1) * GamesOnPage)
  567. {
  568. haveNextPage = true;
  569. break;
  570. }
  571. if (TypeThree >= page * GamesOnPage)
  572. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_BATTLE, GetGamesStringData(arena, mmr, mmrTwo/*mmrThree*/), GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_SELECTED_PLAYER + GetFirstPlayerGuid(arena));
  573. }
  574. else if (!IsTop && arena->GetArenaType() == ARENA_TYPE_2v2)
  575. {
  576. TypeTwo++;
  577. if (TypeTwo > (page + 1) * GamesOnPage)
  578. {
  579. haveNextPage = true;
  580. break;
  581. }
  582. if (TypeTwo >= page * GamesOnPage)
  583. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_BATTLE, GetGamesStringData(arena, mmr, mmrTwo), GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_SELECTED_PLAYER + GetFirstPlayerGuid(arena));
  584. }
  585. }
  586. }
  587. if (page > 0)
  588. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Prev..", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_2V2_GAMES + page - 1);
  589. if (haveNextPage)
  590. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, "Next..", GOSSIP_SENDER_MAIN, NPC_SPECTATOR_ACTION_2V2_GAMES + page + 1);
  591. }
  592. };
  593. void AddSC_arena_spectator_script()
  594. {
  595. new arena_spectator_commands();
  596. new npc_arena_spectator();
  597. }