1. /*
  2. *
  3. */
  4. #include "OutdoorPvPCA.h"
  5. #include "Player.h"
  6. #include "ObjectMgr.h"
  7. #include "OutdoorPvPMgr.h"
  8. #include "WorldPacket.h"
  9. #include "Language.h"
  10. #include "World.h"
  11. #include "ScriptPCH.h"
  12. #include "ScriptedEscortAI.h"
  13. const uint32 CA_LANG_LOOSE_TOWER[CA_TOWER_NUM] =
  14. {
  15. LANG_OPVP_CA_LOOSE_TOWER_A_A,
  16. LANG_OPVP_CA_LOOSE_TOWER_B_A,
  17. LANG_OPVP_CA_LOOSE_TOWER_C_A,
  18. LANG_OPVP_CA_LOOSE_TOWER_D_H,
  19. LANG_OPVP_CA_LOOSE_TOWER_E_H,
  20. LANG_OPVP_CA_LOOSE_TOWER_F_H
  21. };
  22. const uint32 CA_LANG_KILLED_N_BOSS[CA_BOSSES_NUM] =
  23. {
  24. LANG_OPVP_CA_KILLED_N_BOSS_A,
  25. LANG_OPVP_CA_KILLED_N_BOSS_H
  26. };
  27. OutdoorPvPCA::OutdoorPvPCA()
  28. {
  29. m_TypeId = OUTDOOR_PVP_CA;
  30. }
  31. bool OutdoorPvPCA::SetupOutdoorPvP()
  32. {
  33. RegisterZone(CA_OUTDOORPVP_ZONE);
  34. AddTowersToCA();
  35. AddCreepsSummonNpcToCA();
  36. AddNeutrallBossToCA();
  37. AddNeutrallCreepsToCA();
  38. AddCreatureTeleporter();
  39. AddBossesToCA();
  40. AddObjectBuffs();
  41. for (CreatureSet::iterator itr = m_creature.begin(); itr != m_creature.end(); itr++)
  42. {
  43. UpdateCreatureInfo(*itr);
  44. };
  45. return true;
  46. }
  47. void OutdoorPvPCA::AddTowersToCA()
  48. {
  49. for (int i = 0; i < CA_TOWER_NUM; i++)
  50. {
  51. AddCreature(i,creatures[i].entry,creatures[i].teamval,creatures[i].map,creatures[i].x,creatures[i].y,creatures[i].z,creatures[i].o,1000000);
  52. check_towers[i] = 0;
  53. }
  54. }
  55. void OutdoorPvPCA::AddObjectBuffs()
  56. {
  57. for (int i = 0; i < CA_OBJ_NUM; i++)
  58. {
  59. AddObject(i,objects[i].entry,objects[i].map,objects[i].x,objects[i].y,objects[i].z,objects[i].o,objects[i].rot0,objects[i].rot1,objects[i].rot2,objects[i].rot3);
  60. }
  61. }
  62. void OutdoorPvPCA::AddBossesToCA()
  63. {
  64. for (int i = CA_TOWER_NUM; i < (CA_TOWER_NUM,CA_BOSSES_NUM); i++)
  65. {
  66. AddCreature(i,creatures[i].entry,creatures[i].teamval,creatures[i].map,creatures[i].x,creatures[i].y,creatures[i].z,creatures[i].o,1000000);
  67. }
  68. }
  69. void OutdoorPvPCA::AddCreepsSummonNpcToCA()
  70. {
  71. for (int i = (CA_TOWER_NUM,CA_BOSSES_NUM); i < (CA_TOWER_NUM,CA_BOSSES_NUM,CA_SUMMON_NPC_NUM); i++)
  72. {
  73. AddCreature(i,creatures[i].entry,creatures[i].teamval,creatures[i].map,creatures[i].x,creatures[i].y,creatures[i].z,creatures[i].o,1000000);
  74. }
  75. }
  76. void OutdoorPvPCA::AddNeutrallBossToCA()
  77. {
  78. for (int i = (CA_TOWER_NUM,CA_BOSSES_NUM,CA_SUMMON_NPC_NUM); i < (CA_TOWER_NUM,CA_BOSSES_NUM,CA_SUMMON_NPC_NUM,CA_NEUTRALL_BOSS_NUM); i++)
  79. {
  80. AddCreature(i,creatures[i].entry,creatures[i].teamval,creatures[i].map,creatures[i].x,creatures[i].y,creatures[i].z,creatures[i].o,1000000);
  81. }
  82. }
  83. void OutdoorPvPCA::AddNeutrallCreepsToCA()
  84. {
  85. for (int i = (CA_TOWER_NUM,CA_BOSSES_NUM,CA_SUMMON_NPC_NUM,CA_NEUTRALL_BOSS_NUM); i < (CA_TOWER_NUM,CA_BOSSES_NUM,CA_SUMMON_NPC_NUM,CA_NEUTRALL_BOSS_NUM,CA_NEUTRALL_CREEP_NUM); i++)
  86. {
  87. AddCreature(i,creatures[i].entry,creatures[i].teamval,creatures[i].map,creatures[i].x,creatures[i].y,creatures[i].z,creatures[i].o,1000000);
  88. }
  89. }
  90. void OutdoorPvPCA::AddCreatureTeleporter()
  91. {
  92. AddCreature(CREATURE_OTHER, 500006, 0, 37, 66.929f, 906.698f, 343.026f, 2.244f, 1000000);
  93. AddCreature(CREATURE_OTHER, 500006, 0, 37, 1215.098f, 249.887f, 355.152f, 5.710f, 1000000);
  94. }
  95. void OutdoorPvPCA::TeleportPlayersOnCA(TeamId team)
  96. {
  97. for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); itr++)
  98. {
  99. uint64 playerGuid = *itr;
  100. ++itr;
  101. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  102. if (player->isDead())
  103. {
  104. player->ResurrectPlayer(100,false);
  105. player->TeleportTo(SPAWN[player->GetTeamId()].map,SPAWN[player->GetTeamId()].x,SPAWN[player->GetTeamId()].y,SPAWN[player->GetTeamId()].z,SPAWN[player->GetTeamId()].o,0);
  106. } }
  107. }
  108. OutdoorPvPCACreType OutdoorPvPCA::GetCreatureType(uint32 entry) const
  109. {
  110. switch(entry)
  111. {
  112. case 500100:
  113. case 500101:
  114. case 500102:
  115. case 500110:
  116. case 500111:
  117. case 500112:
  118. return CREATURE_TOWER;
  119. case 500109:
  120. case 500119:
  121. return CREATURE_BOSS;
  122. case 500107:
  123. case 500117:
  124. return CREATURE_CREEPS;
  125. default:
  126. return CREATURE_OTHER;
  127. }
  128. }
  129. void OutdoorPvPCA::OnCreatureCreate(Creature *creature)
  130. {
  131. uint32 entry = creature->GetEntry();
  132. switch(GetCreatureType(entry))
  133. {
  134. case CREATURE_TOWER:
  135. case CREATURE_BOSS:
  136. case CREATURE_OTHER:
  137. case CREATURE_CREEPS:
  138. {
  139. UpdateCreatureInfo(creature);
  140. m_creature.insert(creature);
  141. break;
  142. }
  143. }
  144. }
  145. void OutdoorPvPCA::OnCreatureRemove(Creature *creature)
  146. {
  147. uint32 entry = creature->GetEntry();
  148. switch(GetCreatureType(entry))
  149. {
  150. case CREATURE_TOWER:
  151. case CREATURE_BOSS:
  152. case CREATURE_OTHER:
  153. case CREATURE_CREEPS:
  154. {
  155. m_creature.erase(creature);
  156. break;
  157. }
  158. }
  159. }
  160. bool OutdoorPvPCA::UpdateCreatureInfo(Creature* creature)
  161. {
  162. if (!creature)
  163. return false;
  164. uint32 entry = creature->GetEntry();
  165. switch(GetCreatureType(entry))
  166. {
  167. case CREATURE_BOSS:
  168. case CREATURE_TOWER:
  169. case CREATURE_OTHER:
  170. case CREATURE_CREEPS:
  171. if (!creature->IsAlive())
  172. {
  173. creature->Respawn(true);
  174. creature->SetVisible(true);
  175. }
  176. return false;
  177. default:
  178. return false;
  179. }
  180. }
  181. void OutdoorPvPCA::RespawnAllCreaturesOnCA()
  182. {
  183. for (CreatureSet::iterator itr = m_creature.begin(); itr != m_creature.end(); itr++)
  184. if(((*itr)->GetEntry() == 500107) || ((*itr)->GetEntry() == 500117))
  185. (*itr)->DespawnOrUnsummon(true);
  186. else
  187. (*itr)->Respawn(true);
  188. }
  189. void OutdoorPvPCA::CheckNPC()
  190. {
  191. for (CreatureSet::iterator itr = m_creature.begin(); itr != m_creature.end(); itr++)
  192. {
  193. if((*itr)->isDead())
  194. {
  195. for(int i = 0; i < CA_TOWER_NUM; i++)
  196. {
  197. if((*itr)->GetEntry() == CA_NPC[i].entry && check_towers[i] == 0)
  198. {
  199. check_towers[i] = 1;
  200. sWorld->SendZoneText(CA_OUTDOORPVP_ZONE,sObjectMgr->GetTrinityStringForDBCLocale(CA_LANG_LOOSE_TOWER[i]));
  201. break;
  202. }
  203. }
  204. if((*itr)->GetEntry() == CA_NPC[6].entry)
  205. {
  206. Rewards(TEAM_HORDE);
  207. RestartCA();
  208. }
  209. if((*itr)->GetEntry() == CA_NPC[7].entry)
  210. {
  211. Rewards(TEAM_ALLIANCE);
  212. RestartCA();
  213. }
  214. }
  215. }
  216. }
  217. void OutdoorPvPCA::RestartCA()
  218. {
  219. TeleportPlayersOnCA(TEAM_HORDE);
  220. TeleportPlayersOnCA(TEAM_ALLIANCE);
  221. for (int i = 0; i < CA_TOWER_NUM; i++)
  222. {
  223. check_towers[i] = 0;
  224. }
  225. RespawnAllCreaturesOnCA();
  226. }
  227. void OutdoorPvPCA::HandleKill(Player* killer, Unit* killed)
  228. {
  229. uint32 entry = killed->GetEntry();
  230. for (int i = (CA_TOWER_NUM,CA_SUMMON_NPC_NUM,CA_BOSSES_NUM); i < (CA_NEUTRALL_BOSS_NUM,CA_TOWER_NUM,CA_SUMMON_NPC_NUM,CA_BOSSES_NUM); i++)
  231. {
  232. if (entry == CA_NPC[i].entry)
  233. {
  234. sWorld->SendZoneText(CA_OUTDOORPVP_ZONE,sObjectMgr->GetTrinityStringForDBCLocale(CA_LANG_KILLED_N_BOSS[killer->GetTeamId()]));
  235. killer->CastSpell(killer,SPELL_KILL_BOSS_NEUTRAL,true);
  236. TeamCastSpell(killer->GetTeamId(),SPELL_KILL_BOSS_NEUTRAL_ALL);
  237. break;
  238. }
  239. }
  240. for (int i = (CA_TOWER_NUM,CA_SUMMON_NPC_NUM,CA_BOSSES_NUM,CA_NEUTRALL_BOSS_NUM); i < (CA_NEUTRALL_BOSS_NUM,CA_TOWER_NUM,CA_SUMMON_NPC_NUM,CA_BOSSES_NUM,CA_NEUTRALL_CREEP_NUM); i++)
  241. {
  242. if (entry == CA_NPC[i].entry)
  243. {
  244. killer->CastSpell(killer,SPELL_KILL_CREEP_NEUTRAL,true);
  245. break;
  246. }
  247. }
  248. }
  249. void OutdoorPvPCA::UpdateTenacityStack()
  250. {
  251. TeamId team = TEAM_NEUTRAL;
  252. uint32 allianceNum = 0;
  253. uint32 hordeNum = 0;
  254. int32 newStack = 0;
  255. for (PlayerSet::iterator itr = m_players[TEAM_ALLIANCE].begin(); itr != m_players[TEAM_ALLIANCE].end(); itr++)
  256. {
  257. uint64 playerGuid = *itr;
  258. ++itr;
  259. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  260. if (player->getLevel() > 79)
  261. allianceNum;
  262. }
  263. for (PlayerSet::iterator itr = m_players[TEAM_HORDE].begin(); itr != m_players[TEAM_HORDE].end(); itr++)
  264. {
  265. uint64 playerGuid = *itr;
  266. ++itr;
  267. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  268. if (player->getLevel() > 79)
  269. hordeNum;
  270. }
  271. if (allianceNum && hordeNum)
  272. {
  273. if (allianceNum < hordeNum)
  274. newStack = int32((float(hordeNum) / float(allianceNum) - 1)*4); // positive, should cast on alliance
  275. else if (allianceNum > hordeNum)
  276. newStack = int32((1 - float(allianceNum) / float(hordeNum))*4); // negative, should cast on horde
  277. }
  278. if (newStack == m_tenacityStack)
  279. return;
  280. if (m_tenacityStack > 0 && newStack <= 0) // old buff was on alliance
  281. team = TEAM_ALLIANCE;
  282. else if (m_tenacityStack < 0 && newStack >= 0) // old buff was on horde
  283. team = TEAM_HORDE;
  284. m_tenacityStack = newStack;
  285. // Remove old buff
  286. if (team != TEAM_NEUTRAL)
  287. {
  288. for (PlayerSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); itr++)
  289. {
  290. uint64 playerGuid = *itr;
  291. ++itr;
  292. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  293. if (player->getLevel() > 79)
  294. player->RemoveAurasDueToSpell(SPELL_TENACITY);
  295. for (CreatureSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); itr++)
  296. (*itr)->RemoveAurasDueToSpell(SPELL_TENACITY_VEHICLE);
  297. }
  298. }
  299. // Apply new buff
  300. if (newStack)
  301. {
  302. team = newStack > 0 ? TEAM_ALLIANCE : TEAM_HORDE;
  303. if (newStack < 0)
  304. newStack = -newStack;
  305. if (newStack > 20)
  306. newStack = 20;
  307. for (PlayerSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); itr++)
  308. {
  309. uint64 playerGuid = *itr;
  310. ++itr;
  311. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  312. if (player->getLevel() > 79)
  313. {
  314. player->SetAuraStack(SPELL_TENACITY, player , newStack);
  315. }
  316. }
  317. for (CreatureSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); itr++)
  318. (*itr)->SetAuraStack(SPELL_TENACITY_VEHICLE, (*itr), newStack);
  319. }
  320. }
  321. void OutdoorPvPCA::HandlePlayerEnterZone(Player * plr, uint32 zone)
  322. {
  323. const creature_type* creatures = CA_NPC;
  324. if (plr->GetTeam() == ALLIANCE)
  325. {
  326. int i = 0;
  327. while (i < (CA_TOWER_NUM/2))
  328. {
  329. if (check_towers[i] == 0)
  330. plr->CastSpell(plr,Buff[i],true);
  331. i;
  332. }
  333. }
  334. else
  335. {
  336. int i = (CA_TOWER_NUM/2);
  337. while (i < CA_TOWER_NUM)
  338. {
  339. if (check_towers[i] == 0)
  340. plr->CastSpell(plr,Buff[i],true);
  341. i;
  342. }
  343. }
  344. OutdoorPvP::HandlePlayerEnterZone(plr,zone);
  345. UpdateTenacityStack();
  346. }
  347. void OutdoorPvPCA::HandlePlayerLeaveZone(Player * plr, uint32 zone)
  348. {
  349. if (plr->GetTeam() == ALLIANCE)
  350. {
  351. for (int i = 0; i < (CA_TOWER_NUM/2); i++)
  352. plr->RemoveAurasDueToSpell(Buff[i]);
  353. }
  354. else
  355. {
  356. for (int i = 0; i < (CA_TOWER_NUM/2); i++)
  357. plr->RemoveAurasDueToSpell(Buff[i]);
  358. }
  359. plr->RemoveAurasDueToSpell(SPELL_TENACITY);
  360. OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
  361. UpdateTenacityStack();
  362. }
  363. void OutdoorPvPCA::HandleKillImpl(Player *plr, Unit * killed)
  364. {
  365. if (killed->GetTypeId() == TYPEID_PLAYER && plr->GetTeam() != killed->ToPlayer()->GetTeam())
  366. plr->AddItem(KILLREWARD,1);
  367. }
  368. void OutdoorPvPCA::Rewards(TeamId team)
  369. {
  370. for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); itr++)
  371. {
  372. uint64 playerGuid = *itr;
  373. ++itr;
  374. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  375. player->AddItem(WINREWARD,10);
  376. }
  377. }
  378. void OutdoorPvPCA::ResurrectSystem(TeamId team)
  379. {
  380. for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); itr++)
  381. {
  382. uint64 playerGuid = *itr;
  383. ++itr;
  384. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  385. if (player->isDead())
  386. {
  387. player->TeleportTo(SPAWN[player->GetTeamId()].map,SPAWN[player->GetTeamId()].x,SPAWN[player->GetTeamId()].y,SPAWN[player->GetTeamId()].z,SPAWN[player->GetTeamId()].o,0);
  388. player->ResurrectPlayer(100, false);
  389. }
  390. }
  391. }
  392. void OutdoorPvPCA::AddCre(uint32 type, uint32 guid, uint32 entry)
  393. {
  394. if (!entry)
  395. {
  396. const CreatureData *data = sObjectMgr->GetCreatureData(guid);
  397. if (!data)
  398. return;
  399. entry = data->id;
  400. }
  401. m_Creatures[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_UNIT);
  402. m_CreatureTypes[m_Creatures[type]] = type;
  403. }
  404. bool OutdoorPvPCA::AddCreature(uint32 type, uint32 entry, uint32 team, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay)
  405. {
  406. if (uint32 guid = sObjectMgr->AddCreData(entry, team, map, x, y, z, o, spawntimedelay))
  407. {
  408. AddCre(type, guid, entry);
  409. return true;
  410. }
  411. return false;
  412. }
  413. bool OutdoorPvPCA::DelCreature(uint32 type)
  414. {
  415. if (!m_Creatures[type])
  416. {
  417. return false;
  418. }
  419. Creature *cr = HashMapHolder<Creature>::Find(m_Creatures[type]);
  420. if (!cr)
  421. {
  422. // can happen when closing the core
  423. m_Creatures[type] = 0;
  424. return false;
  425. }
  426. uint32 guid = cr->GetDBTableGUIDLow();
  427. // Don't save respawn time
  428. cr->SetRespawnTime(0);
  429. cr->RemoveCorpse();
  430. PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);
  431. stmt->setUInt32(0, guid);
  432. CharacterDatabase.Execute(stmt);
  433. cr->AddObjectToRemoveList();
  434. sObjectMgr->DeleteCreatureData(guid);
  435. m_CreatureTypes[m_Creatures[type]] = 0;
  436. m_Creatures[type] = 0;
  437. return true;
  438. }
  439. bool OutdoorPvPCA::AddObject(uint32 type, uint32 entry, uint32 map, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3)
  440. {
  441. if (uint32 guid = sObjectMgr->AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3))
  442. {
  443. AddGO(type, guid, entry);
  444. return true;
  445. }
  446. return false;
  447. }
  448. void OutdoorPvPCA::AddGO(uint32 type, uint32 guid, uint32 entry)
  449. {
  450. if (!entry)
  451. {
  452. const GameObjectData *data = sObjectMgr->GetGOData(guid);
  453. if (!data)
  454. return;
  455. entry = data->id;
  456. }
  457. m_Objects[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT);
  458. m_ObjectTypes[m_Objects[type]]=type;
  459. }
  460. bool OutdoorPvPCA::DelObject(uint32 type)
  461. {
  462. if (!m_Objects[type])
  463. return false;
  464. GameObject *obj = HashMapHolder<GameObject>::Find(m_Objects[type]);
  465. if (!obj)
  466. {
  467. m_Objects[type] = 0;
  468. return false;
  469. }
  470. uint32 guid = obj->GetDBTableGUIDLow();
  471. obj->SetRespawnTime(0); // not save respawn time
  472. obj->Delete();
  473. sObjectMgr->DeleteGOData(guid);
  474. m_ObjectTypes[m_Objects[type]] = 0;
  475. m_Objects[type] = 0;
  476. return true;
  477. }
  478. bool OutdoorPvPCA::Update(uint32 diff)
  479. {
  480. bool changed = OutdoorPvP::Update(diff);
  481. if (!changed)
  482. {
  483. int i = 0;
  484. while (i < CA_TOWER_NUM)
  485. {
  486. if (i < (CA_TOWER_NUM/2))
  487. if (check_towers[i] == 0)
  488. {
  489. for (PlayerSet::iterator itr = m_players[TEAM_ALLIANCE].begin(); itr != m_players[TEAM_ALLIANCE].end(); itr++)
  490. {
  491. uint64 playerGuid = *itr;
  492. ++itr;
  493. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  494. if(!player->HasAura(Buff[i]))
  495. {
  496. player->CastSpell(player, Buff[i], true);
  497. } }
  498. }
  499. else
  500. {
  501. for (PlayerSet::iterator itr = m_players[TEAM_ALLIANCE].begin(); itr != m_players[TEAM_ALLIANCE].end(); itr++)
  502. {
  503. uint64 playerGuid = *itr;
  504. ++itr;
  505. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  506. (player->RemoveAura(Buff[i]));
  507. }
  508. }
  509. else
  510. if (check_towers[i] == 0)
  511. {
  512. for (PlayerSet::iterator itr = m_players[TEAM_HORDE].begin(); itr != m_players[TEAM_HORDE].end(); itr++)
  513. {
  514. uint64 playerGuid = *itr;
  515. ++itr;
  516. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  517. if(!player->HasAura(Buff[i]))
  518. {
  519. player->CastSpell(player, Buff[i], true);
  520. } }
  521. }
  522. else
  523. for (PlayerSet::iterator itr = m_players[TEAM_HORDE].begin(); itr != m_players[TEAM_HORDE].end(); itr++)
  524. {
  525. uint64 playerGuid = *itr;
  526. ++itr;
  527. if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
  528. (player->RemoveAura(Buff[i]));
  529. i;
  530. } }
  531. for(int i = 0; i < (CA_TOWER_NUM/2 - 1); i)
  532. {
  533. if(check_towers[i] == 0)
  534. {
  535. for (CreatureSet::iterator itr = m_creature.begin(); itr != m_creature.end(); itr++)
  536. {
  537. if((*itr)->GetEntry() == CA_NPC[(i)].entry)
  538. (*itr)->SetFullHealth();
  539. }
  540. }
  541. }
  542. for(int i = (CA_TOWER_NUM/2); i < (CA_TOWER_NUM - 1); i)
  543. {
  544. if(check_towers[i] == 0)
  545. {
  546. for (CreatureSet::iterator itr = m_creature.begin(); itr != m_creature.end(); itr++)
  547. {
  548. if((*itr)->GetEntry() == CA_NPC[(i)].entry)
  549. (*itr)->SetFullHealth();
  550. }
  551. }
  552. }
  553. if(check_towers[2] == 0)
  554. {
  555. for (CreatureSet::iterator itr = m_creature.begin(); itr != m_creature.end(); itr++)
  556. {
  557. if((*itr)->GetEntry() == CA_NPC[6].entry)
  558. (*itr)->SetFullHealth();
  559. if((*itr)->GetEntry() == CA_NPC[8].entry)
  560. (*itr)->SetFullHealth();
  561. }
  562. }
  563. if(check_towers[5] == 0)
  564. {
  565. for (CreatureSet::iterator itr = m_creature.begin(); itr != m_creature.end(); itr++)
  566. {
  567. if((*itr)->GetEntry() == CA_NPC[7].entry)
  568. (*itr)->SetFullHealth();
  569. if((*itr)->GetEntry() == CA_NPC[9].entry)
  570. (*itr)->SetFullHealth();
  571. }
  572. }
  573. ResurrectSystem(TEAM_HORDE);
  574. ResurrectSystem(TEAM_ALLIANCE);
  575. CheckNPC();
  576. }
  577. return changed;
  578. }
  579. class OutdoorPvP_crater : public OutdoorPvPScript
  580. {
  581. public:
  582. OutdoorPvP_crater ()
  583. : OutdoorPvPScript("outdoorpvp_ca")
  584. {
  585. }
  586. OutdoorPvP* GetOutdoorPvP() const
  587. {
  588. return new OutdoorPvPCA();
  589. }
  590. };
  591. class npc_control_tower : public CreatureScript
  592. {
  593. public:
  594. npc_control_tower() : CreatureScript("npc_control_tower") { }
  595. struct npc_control_towerAI : CasterAI
  596. {
  597. npc_control_towerAI(Creature* c) : CasterAI(c) {}
  598. void InitializeAI()
  599. {
  600. CasterAI::InitializeAI();
  601. std::list<Unit*> targets;
  602. Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 55);
  603. Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check);
  604. me->VisitNearbyObject(55, searcher);
  605. me->m_CombatDistance = 55;
  606. me->m_SightDistance = 55;
  607. me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_DMG, true);
  608. me->CastSpell(me,SPELL_BUFF_TOWER,true);
  609. for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); iter++)
  610. {
  611. //(*iter)->IsAlwaysDetectableFor(me);
  612. //(*iter)->IsAlwaysVisibleFor(me);
  613. me->Attack((*iter), false);
  614. break;
  615. }
  616. }
  617. void UpdateAI(uint32 diff)
  618. {
  619. CasterAI::UpdateAI(diff);
  620. }
  621. };
  622. CreatureAI *GetAI(Creature* creature) const
  623. {
  624. return new npc_control_towerAI(creature);
  625. }
  626. };
  627. class npc_summon_npc : public CreatureScript
  628. {
  629. public:
  630. npc_summon_npc() : CreatureScript("npc_summon_npc") { }
  631. struct npc_summon_npcAI : CasterAI
  632. {
  633. npc_summon_npcAI(Creature* c) : CasterAI(c) {}
  634. uint32 m_uiTimer;
  635. void InitializeAI()
  636. {
  637. CasterAI::InitializeAI();
  638. me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_DMG, true);
  639. me->setActive(true);
  640. }
  641. void Reset()
  642. {
  643. m_uiTimer = 60000;
  644. }
  645. void UpdateAI(uint32 diff)
  646. {
  647. CasterAI::UpdateAI(diff);
  648. if (m_uiTimer <= diff)
  649. {
  650. m_uiTimer = 60000;
  651. if(me->GetEntry() == 500118)
  652. {
  653. me->SummonCreature(500117, me->GetPositionX()+2.0f, me->GetPositionY()+7.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 1000);
  654. me->SummonCreature(500117, me->GetPositionX()+6.0f, me->GetPositionY()+12.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 1000);
  655. me->SummonCreature(500117, me->GetPositionX()-2.0f, me->GetPositionY()+2.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 1000);
  656. me->SummonCreature(500117, me->GetPositionX()-6.0f, me->GetPositionY()-3.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 1000);
  657. }
  658. if(me->GetEntry() == 500108)
  659. {
  660. me->SummonCreature(500107, me->GetPositionX()+2.0f, me->GetPositionY(), me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 1000);
  661. me->SummonCreature(500107, me->GetPositionX()+6.0f, me->GetPositionY(), me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 1000);
  662. me->SummonCreature(500107, me->GetPositionX()-2.0f, me->GetPositionY(), me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 1000);
  663. me->SummonCreature(500107, me->GetPositionX()-6.0f, me->GetPositionY(), me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 1000);
  664. }
  665. }
  666. else
  667. m_uiTimer -= diff;
  668. }
  669. };
  670. CreatureAI *GetAI(Creature* creature) const
  671. {
  672. return new npc_summon_npcAI(creature);
  673. }
  674. };
  675. class npc_creeps : public CreatureScript
  676. {
  677. public:
  678. npc_creeps()
  679. : CreatureScript("npc_creeps")
  680. {
  681. }
  682. struct npc_creepsAI : public npc_escortAI
  683. {
  684. npc_creepsAI(Creature* creature) : npc_escortAI(creature) { }
  685. void WaypointReached(uint32 uiWP)
  686. {
  687. switch (uiWP)
  688. {
  689. case 1:
  690. break;
  691. }
  692. }
  693. void Reset()
  694. {
  695. me->setActive(true);
  696. SetDespawnAtFar(false);
  697. npc_creepsAI* pEscortAI = CAST_AI(npc_creeps::npc_creepsAI, me->AI());
  698. if (pEscortAI)
  699. pEscortAI->Start(true,true);
  700. }
  701. void UpdateEscortAI(const uint32 diff)
  702. {
  703. }
  704. };
  705. CreatureAI* GetAI(Creature* creature) const
  706. {
  707. return new npc_creepsAI(creature);
  708. }
  709. };
  710. #define GOSSIP_ITEM_1 "Îòïðàâèòñÿ íà Ïîëå áèòâû: Êðàòåð Àçøàðû"
  711. #define SPELL_VISUAL_TELEPORT 35517
  712. class npc_tp_ca : public CreatureScript
  713. {
  714. public:
  715. npc_tp_ca() : CreatureScript("npc_tp_ca") { }
  716. void Teleport(Player* const player, const uint16 &map, const float &X, const float &Y, const float &Z, const float &orient)
  717. {
  718. player->CastSpell(player, SPELL_VISUAL_TELEPORT, true);
  719. player->TeleportTo(map, X, Y, Z, orient);
  720. }
  721. bool OnGossipHello(Player* player, Creature* creature)
  722. {
  723. player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
  724. player->SEND_GOSSIP_MENU(3961,creature->GetGUID());
  725. return true;
  726. }
  727. bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
  728. {
  729. switch (action)
  730. {
  731. case GOSSIP_ACTION_INFO_DEF+1:
  732. if (player->getLevel() < 80)
  733. {
  734. creature->MonsterTextEmote("Äëÿ Îòïðàâëåíèÿ âû äîëæíû áûòü 80-îãî óðîâíÿ!", player->GetGUID(), true);
  735. player->CLOSE_GOSSIP_MENU();
  736. return false;
  737. }
  738. if (player->GetHonorPoints() < 300)
  739. {
  740. creature->MonsterTextEmote("Äëÿ Îòïðàâëåíèÿ âàì ïîòðåáóåòñÿ 300 Î÷êîâ ×åñòè!", player->GetGUID(), true);
  741. player->CLOSE_GOSSIP_MENU();
  742. return false;
  743. }
  744. if (player->GetTeamId() == TEAM_ALLIANCE)
  745. {
  746. Teleport(player, 37,1245.12f,248.638f,355.214f,3.1f);
  747. player->ModifyHonorPoints(-300);
  748. }
  749. else
  750. {
  751. Teleport(player, 37,39.38f,916.849f,339.394f,5.93f);
  752. player->ModifyHonorPoints(-300);
  753. }
  754. break;
  755. }
  756. return true;
  757. }
  758. };
  759. #define GOSSIP_ITEM_2 "Îêîí÷èòü áîé è îòïðàâèòüñÿ â ñòîëèöó"
  760. class npc_tp_capital : public CreatureScript
  761. {
  762. public:
  763. npc_tp_capital() : CreatureScript("npc_tp_capital") { }
  764. void Teleport(Player* const player, const uint16 &map, const float &X, const float &Y, const float &Z, const float &orient)
  765. {
  766. player->CastSpell(player, SPELL_VISUAL_TELEPORT, true);
  767. player->TeleportTo(map, X, Y, Z, orient);
  768. }
  769. bool OnGossipHello(Player* player, Creature* creature)
  770. {
  771. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
  772. player->SEND_GOSSIP_MENU(3962,creature->GetGUID());
  773. return true;
  774. }
  775. bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
  776. {
  777. switch (action)
  778. {
  779. case GOSSIP_ACTION_INFO_DEF+1:
  780. if (player->GetTeamId() == TEAM_ALLIANCE)
  781. Teleport(player, 0, -8830.62f, 622.80f, 93.85f, 3.9f);
  782. else
  783. Teleport(player, 1, 1629.35f, -4373.42f, 31.26f, 3.5f);
  784. break;
  785. }
  786. return true;
  787. }
  788. };
  789. void AddSC_outdoorpvp_ca()
  790. {
  791. new OutdoorPvP_crater();
  792. new npc_control_tower;
  793. new npc_summon_npc;
  794. new npc_creeps;
  795. new npc_tp_ca;
  796. new npc_tp_capital;
  797. }