TvTEvent.java 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187
  1. /*
  2. * Copyright (C) 2004-2014 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.model.entity;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Map.Entry;
  24. import java.util.logging.Level;
  25. import java.util.logging.Logger;
  26. import javolution.util.FastMap;
  27. import com.l2jserver.Config;
  28. import com.l2jserver.gameserver.cache.HtmCache;
  29. import com.l2jserver.gameserver.datatables.DoorTable;
  30. import com.l2jserver.gameserver.datatables.ItemTable;
  31. import com.l2jserver.gameserver.datatables.NpcData;
  32. import com.l2jserver.gameserver.datatables.SkillData;
  33. import com.l2jserver.gameserver.datatables.SpawnTable;
  34. import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
  35. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  36. import com.l2jserver.gameserver.model.L2Spawn;
  37. import com.l2jserver.gameserver.model.L2World;
  38. import com.l2jserver.gameserver.model.actor.L2Character;
  39. import com.l2jserver.gameserver.model.actor.L2Npc;
  40. import com.l2jserver.gameserver.model.actor.L2Summon;
  41. import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
  42. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  43. import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
  44. import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
  45. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  46. import com.l2jserver.gameserver.model.events.EventDispatcher;
  47. import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventFinish;
  48. import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventKill;
  49. import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventRegistrationStart;
  50. import com.l2jserver.gameserver.model.events.impl.events.OnTvTEventStart;
  51. import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
  52. import com.l2jserver.gameserver.model.skills.Skill;
  53. import com.l2jserver.gameserver.network.SystemMessageId;
  54. import com.l2jserver.gameserver.network.clientpackets.Say2;
  55. import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
  56. import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
  57. import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
  58. import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
  59. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  60. import com.l2jserver.util.Rnd;
  61. import com.l2jserver.util.StringUtil;
  62. /**
  63. * @author FBIagent
  64. */
  65. public class TvTEvent
  66. {
  67. enum EventState
  68. {
  69. INACTIVE,
  70. INACTIVATING,
  71. PARTICIPATING,
  72. STARTING,
  73. STARTED,
  74. REWARDING
  75. }
  76. protected static final Logger _log = Logger.getLogger(TvTEvent.class.getName());
  77. /** html path **/
  78. private static final String htmlPath = "data/html/mods/TvTEvent/";
  79. /** The teams of the TvTEvent<br> */
  80. private static TvTEventTeam[] _teams = new TvTEventTeam[2];
  81. /** The state of the TvTEvent<br> */
  82. private static EventState _state = EventState.INACTIVE;
  83. /** The spawn of the participation npc<br> */
  84. private static L2Spawn _npcSpawn = null;
  85. /** the npc instance of the participation npc<br> */
  86. private static L2Npc _lastNpcSpawn = null;
  87. /** Instance id<br> */
  88. private static int _TvTEventInstance = 0;
  89. /**
  90. * No instance of this class!<br>
  91. */
  92. private TvTEvent()
  93. {
  94. }
  95. /**
  96. * Teams initializing<br>
  97. */
  98. public static void init()
  99. {
  100. AntiFeedManager.getInstance().registerEvent(AntiFeedManager.TVT_ID);
  101. _teams[0] = new TvTEventTeam(Config.TVT_EVENT_TEAM_1_NAME, Config.TVT_EVENT_TEAM_1_COORDINATES);
  102. _teams[1] = new TvTEventTeam(Config.TVT_EVENT_TEAM_2_NAME, Config.TVT_EVENT_TEAM_2_COORDINATES);
  103. }
  104. /**
  105. * Starts the participation of the TvTEvent<br>
  106. * 1. Get L2NpcTemplate by Config.TVT_EVENT_PARTICIPATION_NPC_ID<br>
  107. * 2. Try to spawn a new npc of it<br>
  108. * <br>
  109. * @return boolean: true if success, otherwise false<br>
  110. */
  111. public static boolean startParticipation()
  112. {
  113. L2NpcTemplate tmpl = NpcData.getInstance().getTemplate(Config.TVT_EVENT_PARTICIPATION_NPC_ID);
  114. if (tmpl == null)
  115. {
  116. _log.warning("TvTEventEngine[TvTEvent.startParticipation()]: L2NpcTemplate is a NullPointer -> Invalid npc id in configs?");
  117. return false;
  118. }
  119. try
  120. {
  121. _npcSpawn = new L2Spawn(tmpl);
  122. _npcSpawn.setX(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0]);
  123. _npcSpawn.setY(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1]);
  124. _npcSpawn.setZ(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
  125. _npcSpawn.setAmount(1);
  126. _npcSpawn.setHeading(Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[3]);
  127. _npcSpawn.setRespawnDelay(1);
  128. // later no need to delete spawn from db, we don't store it (false)
  129. SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
  130. _npcSpawn.init();
  131. _lastNpcSpawn = _npcSpawn.getLastSpawn();
  132. _lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
  133. _lastNpcSpawn.setTitle("TvT Event Participation");
  134. _lastNpcSpawn.isAggressive();
  135. _lastNpcSpawn.decayMe();
  136. _lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
  137. _lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
  138. }
  139. catch (Exception e)
  140. {
  141. _log.log(Level.WARNING, "TvTEventEngine[TvTEvent.startParticipation()]: exception: " + e.getMessage(), e);
  142. return false;
  143. }
  144. setState(EventState.PARTICIPATING);
  145. EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventRegistrationStart());
  146. return true;
  147. }
  148. private static int highestLevelPcInstanceOf(Map<Integer, L2PcInstance> players)
  149. {
  150. int maxLevel = Integer.MIN_VALUE, maxLevelId = -1;
  151. for (L2PcInstance player : players.values())
  152. {
  153. if (player.getLevel() >= maxLevel)
  154. {
  155. maxLevel = player.getLevel();
  156. maxLevelId = player.getObjectId();
  157. }
  158. }
  159. return maxLevelId;
  160. }
  161. /**
  162. * Starts the TvTEvent fight<br>
  163. * 1. Set state EventState.STARTING<br>
  164. * 2. Close doors specified in configs<br>
  165. * 3. Abort if not enought participants(return false)<br>
  166. * 4. Set state EventState.STARTED<br>
  167. * 5. Teleport all participants to team spot<br>
  168. * <br>
  169. * @return boolean: true if success, otherwise false<br>
  170. */
  171. public static boolean startFight()
  172. {
  173. // Set state to STARTING
  174. setState(EventState.STARTING);
  175. // Randomize and balance team distribution
  176. Map<Integer, L2PcInstance> allParticipants = new FastMap<>();
  177. allParticipants.putAll(_teams[0].getParticipatedPlayers());
  178. allParticipants.putAll(_teams[1].getParticipatedPlayers());
  179. _teams[0].cleanMe();
  180. _teams[1].cleanMe();
  181. L2PcInstance player;
  182. Iterator<L2PcInstance> iter;
  183. if (needParticipationFee())
  184. {
  185. iter = allParticipants.values().iterator();
  186. while (iter.hasNext())
  187. {
  188. player = iter.next();
  189. if (!hasParticipationFee(player))
  190. {
  191. iter.remove();
  192. }
  193. }
  194. }
  195. int balance[] =
  196. {
  197. 0,
  198. 0
  199. }, priority = 0, highestLevelPlayerId;
  200. L2PcInstance highestLevelPlayer;
  201. // TODO: allParticipants should be sorted by level instead of using highestLevelPcInstanceOf for every fetch
  202. while (!allParticipants.isEmpty())
  203. {
  204. // Priority team gets one player
  205. highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
  206. highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
  207. allParticipants.remove(highestLevelPlayerId);
  208. _teams[priority].addPlayer(highestLevelPlayer);
  209. balance[priority] += highestLevelPlayer.getLevel();
  210. // Exiting if no more players
  211. if (allParticipants.isEmpty())
  212. {
  213. break;
  214. }
  215. // The other team gets one player
  216. // TODO: Code not dry
  217. priority = 1 - priority;
  218. highestLevelPlayerId = highestLevelPcInstanceOf(allParticipants);
  219. highestLevelPlayer = allParticipants.get(highestLevelPlayerId);
  220. allParticipants.remove(highestLevelPlayerId);
  221. _teams[priority].addPlayer(highestLevelPlayer);
  222. balance[priority] += highestLevelPlayer.getLevel();
  223. // Recalculating priority
  224. priority = balance[0] > balance[1] ? 1 : 0;
  225. }
  226. // Check for enought participants
  227. if ((_teams[0].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS) || (_teams[1].getParticipatedPlayerCount() < Config.TVT_EVENT_MIN_PLAYERS_IN_TEAMS))
  228. {
  229. // Set state INACTIVE
  230. setState(EventState.INACTIVE);
  231. // Cleanup of teams
  232. _teams[0].cleanMe();
  233. _teams[1].cleanMe();
  234. // Unspawn the event NPC
  235. unSpawnNpc();
  236. AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
  237. return false;
  238. }
  239. if (needParticipationFee())
  240. {
  241. iter = _teams[0].getParticipatedPlayers().values().iterator();
  242. while (iter.hasNext())
  243. {
  244. player = iter.next();
  245. if (!payParticipationFee(player))
  246. {
  247. iter.remove();
  248. }
  249. }
  250. iter = _teams[1].getParticipatedPlayers().values().iterator();
  251. while (iter.hasNext())
  252. {
  253. player = iter.next();
  254. if (!payParticipationFee(player))
  255. {
  256. iter.remove();
  257. }
  258. }
  259. }
  260. if (Config.TVT_EVENT_IN_INSTANCE)
  261. {
  262. try
  263. {
  264. _TvTEventInstance = InstanceManager.getInstance().createDynamicInstance(Config.TVT_EVENT_INSTANCE_FILE);
  265. InstanceManager.getInstance().getInstance(_TvTEventInstance).setAllowSummon(false);
  266. InstanceManager.getInstance().getInstance(_TvTEventInstance).setPvPInstance(true);
  267. InstanceManager.getInstance().getInstance(_TvTEventInstance).setEmptyDestroyTime((Config.TVT_EVENT_START_LEAVE_TELEPORT_DELAY * 1000) + 60000L);
  268. }
  269. catch (Exception e)
  270. {
  271. _TvTEventInstance = 0;
  272. _log.log(Level.WARNING, "TvTEventEngine[TvTEvent.createDynamicInstance]: exception: " + e.getMessage(), e);
  273. }
  274. }
  275. // Opens all doors specified in configs for tvt
  276. openDoors(Config.TVT_DOORS_IDS_TO_OPEN);
  277. // Closes all doors specified in configs for tvt
  278. closeDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
  279. // Set state STARTED
  280. setState(EventState.STARTED);
  281. // Iterate over all teams
  282. for (TvTEventTeam team : _teams)
  283. {
  284. // Iterate over all participated player instances in this team
  285. for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
  286. {
  287. if (playerInstance != null)
  288. {
  289. // Disable player revival.
  290. playerInstance.setCanRevive(false);
  291. // Teleporter implements Runnable and starts itself
  292. new TvTEventTeleporter(playerInstance, team.getCoordinates(), false, false);
  293. }
  294. }
  295. }
  296. // Notify to scripts.
  297. EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventStart());
  298. return true;
  299. }
  300. /**
  301. * Calculates the TvTEvent reward<br>
  302. * 1. If both teams are at a tie(points equals), send it as system message to all participants, if one of the teams have 0 participants left online abort rewarding<br>
  303. * 2. Wait till teams are not at a tie anymore<br>
  304. * 3. Set state EvcentState.REWARDING<br>
  305. * 4. Reward team with more points<br>
  306. * 5. Show win html to wining team participants<br>
  307. * <br>
  308. * @return String: winning team name<br>
  309. */
  310. public static String calculateRewards()
  311. {
  312. if (_teams[0].getPoints() == _teams[1].getPoints())
  313. {
  314. // Check if one of the teams have no more players left
  315. if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0))
  316. {
  317. // set state to rewarding
  318. setState(EventState.REWARDING);
  319. // return here, the fight can't be completed
  320. return "TvT Event: Event has ended. No team won due to inactivity!";
  321. }
  322. // Both teams have equals points
  323. sysMsgToAllParticipants("TvT Event: Event has ended, both teams have tied.");
  324. if (Config.TVT_REWARD_TEAM_TIE)
  325. {
  326. rewardTeam(_teams[0]);
  327. rewardTeam(_teams[1]);
  328. return "TvT Event: Event has ended with both teams tying.";
  329. }
  330. return "TvT Event: Event has ended with both teams tying.";
  331. }
  332. // Set state REWARDING so nobody can point anymore
  333. setState(EventState.REWARDING);
  334. // Get team which has more points
  335. TvTEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
  336. rewardTeam(team);
  337. // Notify to scripts.
  338. EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventFinish());
  339. return "TvT Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
  340. }
  341. private static void rewardTeam(TvTEventTeam team)
  342. {
  343. // Iterate over all participated player instances of the winning team
  344. for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
  345. {
  346. // Check for nullpointer
  347. if (playerInstance == null)
  348. {
  349. continue;
  350. }
  351. SystemMessage systemMessage = null;
  352. // Iterate over all tvt event rewards
  353. for (int[] reward : Config.TVT_EVENT_REWARDS)
  354. {
  355. PcInventory inv = playerInstance.getInventory();
  356. // Check for stackable item, non stackabe items need to be added one by one
  357. if (ItemTable.getInstance().createDummyItem(reward[0]).isStackable())
  358. {
  359. inv.addItem("TvT Event", reward[0], reward[1], playerInstance, playerInstance);
  360. if (reward[1] > 1)
  361. {
  362. systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
  363. systemMessage.addItemName(reward[0]);
  364. systemMessage.addLong(reward[1]);
  365. }
  366. else
  367. {
  368. systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
  369. systemMessage.addItemName(reward[0]);
  370. }
  371. playerInstance.sendPacket(systemMessage);
  372. }
  373. else
  374. {
  375. for (int i = 0; i < reward[1]; ++i)
  376. {
  377. inv.addItem("TvT Event", reward[0], 1, playerInstance, playerInstance);
  378. systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
  379. systemMessage.addItemName(reward[0]);
  380. playerInstance.sendPacket(systemMessage);
  381. }
  382. }
  383. }
  384. StatusUpdate statusUpdate = new StatusUpdate(playerInstance);
  385. final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
  386. statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, playerInstance.getCurrentLoad());
  387. npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Reward.htm"));
  388. playerInstance.sendPacket(statusUpdate);
  389. playerInstance.sendPacket(npcHtmlMessage);
  390. }
  391. }
  392. /**
  393. * Stops the TvTEvent fight<br>
  394. * 1. Set state EventState.INACTIVATING<br>
  395. * 2. Remove tvt npc from world<br>
  396. * 3. Open doors specified in configs<br>
  397. * 4. Teleport all participants back to participation npc location<br>
  398. * 5. Teams cleaning<br>
  399. * 6. Set state EventState.INACTIVE<br>
  400. */
  401. public static void stopFight()
  402. {
  403. // Set state INACTIVATING
  404. setState(EventState.INACTIVATING);
  405. // Unspawn event npc
  406. unSpawnNpc();
  407. // Opens all doors specified in configs for tvt
  408. openDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
  409. // Closes all doors specified in Configs for tvt
  410. closeDoors(Config.TVT_DOORS_IDS_TO_OPEN);
  411. // Iterate over all teams
  412. for (TvTEventTeam team : _teams)
  413. {
  414. for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
  415. {
  416. // Check for nullpointer
  417. if (playerInstance != null)
  418. {
  419. // Enable player revival.
  420. playerInstance.setCanRevive(true);
  421. // Teleport back.
  422. new TvTEventTeleporter(playerInstance, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
  423. }
  424. }
  425. }
  426. // Cleanup of teams
  427. _teams[0].cleanMe();
  428. _teams[1].cleanMe();
  429. // Set state INACTIVE
  430. setState(EventState.INACTIVE);
  431. AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
  432. }
  433. /**
  434. * Adds a player to a TvTEvent team<br>
  435. * 1. Calculate the id of the team in which the player should be added<br>
  436. * 2. Add the player to the calculated team<br>
  437. * <br>
  438. * @param playerInstance as L2PcInstance<br>
  439. * @return boolean: true if success, otherwise false<br>
  440. */
  441. public static synchronized boolean addParticipant(L2PcInstance playerInstance)
  442. {
  443. // Check for nullpoitner
  444. if (playerInstance == null)
  445. {
  446. return false;
  447. }
  448. byte teamId = 0;
  449. // Check to which team the player should be added
  450. if (_teams[0].getParticipatedPlayerCount() == _teams[1].getParticipatedPlayerCount())
  451. {
  452. teamId = (byte) (Rnd.get(2));
  453. }
  454. else
  455. {
  456. teamId = (byte) (_teams[0].getParticipatedPlayerCount() > _teams[1].getParticipatedPlayerCount() ? 1 : 0);
  457. }
  458. playerInstance.addEventListener(new TvTEventListener(playerInstance));
  459. return _teams[teamId].addPlayer(playerInstance);
  460. }
  461. /**
  462. * Removes a TvTEvent player from it's team<br>
  463. * 1. Get team id of the player<br>
  464. * 2. Remove player from it's team<br>
  465. * <br>
  466. * @param playerObjectId
  467. * @return boolean: true if success, otherwise false
  468. */
  469. public static boolean removeParticipant(int playerObjectId)
  470. {
  471. // Get the teamId of the player
  472. byte teamId = getParticipantTeamId(playerObjectId);
  473. // Check if the player is participant
  474. if (teamId != -1)
  475. {
  476. // Remove the player from team
  477. _teams[teamId].removePlayer(playerObjectId);
  478. final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
  479. if (player != null)
  480. {
  481. player.removeEventListener(TvTEventListener.class);
  482. }
  483. return true;
  484. }
  485. return false;
  486. }
  487. public static boolean needParticipationFee()
  488. {
  489. return (Config.TVT_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.TVT_EVENT_PARTICIPATION_FEE[1] != 0);
  490. }
  491. public static boolean hasParticipationFee(L2PcInstance playerInstance)
  492. {
  493. return playerInstance.getInventory().getInventoryItemCount(Config.TVT_EVENT_PARTICIPATION_FEE[0], -1) >= Config.TVT_EVENT_PARTICIPATION_FEE[1];
  494. }
  495. public static boolean payParticipationFee(L2PcInstance playerInstance)
  496. {
  497. return playerInstance.destroyItemByItemId("TvT Participation Fee", Config.TVT_EVENT_PARTICIPATION_FEE[0], Config.TVT_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
  498. }
  499. public static String getParticipationFee()
  500. {
  501. int itemId = Config.TVT_EVENT_PARTICIPATION_FEE[0];
  502. int itemNum = Config.TVT_EVENT_PARTICIPATION_FEE[1];
  503. if ((itemId == 0) || (itemNum == 0))
  504. {
  505. return "-";
  506. }
  507. return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
  508. }
  509. /**
  510. * Send a SystemMessage to all participated players<br>
  511. * 1. Send the message to all players of team number one<br>
  512. * 2. Send the message to all players of team number two<br>
  513. * <br>
  514. * @param message as String<br>
  515. */
  516. public static void sysMsgToAllParticipants(String message)
  517. {
  518. for (L2PcInstance playerInstance : _teams[0].getParticipatedPlayers().values())
  519. {
  520. if (playerInstance != null)
  521. {
  522. playerInstance.sendMessage(message);
  523. }
  524. }
  525. for (L2PcInstance playerInstance : _teams[1].getParticipatedPlayers().values())
  526. {
  527. if (playerInstance != null)
  528. {
  529. playerInstance.sendMessage(message);
  530. }
  531. }
  532. }
  533. private static L2DoorInstance getDoor(int doorId)
  534. {
  535. L2DoorInstance door = null;
  536. if (_TvTEventInstance <= 0)
  537. {
  538. door = DoorTable.getInstance().getDoor(doorId);
  539. }
  540. else
  541. {
  542. final Instance inst = InstanceManager.getInstance().getInstance(_TvTEventInstance);
  543. if (inst != null)
  544. {
  545. door = inst.getDoor(doorId);
  546. }
  547. }
  548. return door;
  549. }
  550. /**
  551. * Close doors specified in configs
  552. * @param doors
  553. */
  554. private static void closeDoors(List<Integer> doors)
  555. {
  556. for (int doorId : doors)
  557. {
  558. final L2DoorInstance doorInstance = getDoor(doorId);
  559. if (doorInstance != null)
  560. {
  561. doorInstance.closeMe();
  562. }
  563. }
  564. }
  565. /**
  566. * Open doors specified in configs
  567. * @param doors
  568. */
  569. private static void openDoors(List<Integer> doors)
  570. {
  571. for (int doorId : doors)
  572. {
  573. final L2DoorInstance doorInstance = getDoor(doorId);
  574. if (doorInstance != null)
  575. {
  576. doorInstance.openMe();
  577. }
  578. }
  579. }
  580. /**
  581. * UnSpawns the TvTEvent npc
  582. */
  583. private static void unSpawnNpc()
  584. {
  585. // Delete the npc
  586. _lastNpcSpawn.deleteMe();
  587. SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
  588. // Stop respawning of the npc
  589. _npcSpawn.stopRespawn();
  590. _npcSpawn = null;
  591. _lastNpcSpawn = null;
  592. }
  593. /**
  594. * Called when a player logs in<br>
  595. * <br>
  596. * @param playerInstance as L2PcInstance<br>
  597. */
  598. public static void onLogin(L2PcInstance playerInstance)
  599. {
  600. if ((playerInstance == null) || (!isStarting() && !isStarted()))
  601. {
  602. return;
  603. }
  604. byte teamId = getParticipantTeamId(playerInstance.getObjectId());
  605. if (teamId == -1)
  606. {
  607. return;
  608. }
  609. _teams[teamId].addPlayer(playerInstance);
  610. new TvTEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
  611. }
  612. /**
  613. * Called when a player logs out<br>
  614. * <br>
  615. * @param playerInstance as L2PcInstance<br>
  616. */
  617. public static void onLogout(L2PcInstance playerInstance)
  618. {
  619. if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
  620. {
  621. if (removeParticipant(playerInstance.getObjectId()))
  622. {
  623. playerInstance.setXYZInvisible((Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[0] + Rnd.get(101)) - 50, (Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[1] + Rnd.get(101)) - 50, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES[2]);
  624. }
  625. }
  626. }
  627. /**
  628. * Called on every onAction in L2PcIstance<br>
  629. * <br>
  630. * @param playerInstance
  631. * @param targetedPlayerObjectId
  632. * @return boolean: true if player is allowed to target, otherwise false
  633. */
  634. public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
  635. {
  636. if ((playerInstance == null) || !isStarted())
  637. {
  638. return true;
  639. }
  640. if (playerInstance.isGM())
  641. {
  642. return true;
  643. }
  644. byte playerTeamId = getParticipantTeamId(playerInstance.getObjectId());
  645. byte targetedPlayerTeamId = getParticipantTeamId(targetedPlayerObjectId);
  646. if (((playerTeamId != -1) && (targetedPlayerTeamId == -1)) || ((playerTeamId == -1) && (targetedPlayerTeamId != -1)))
  647. {
  648. return false;
  649. }
  650. if ((playerTeamId != -1) && (targetedPlayerTeamId != -1) && (playerTeamId == targetedPlayerTeamId) && (playerInstance.getObjectId() != targetedPlayerObjectId) && !Config.TVT_EVENT_TARGET_TEAM_MEMBERS_ALLOWED)
  651. {
  652. return false;
  653. }
  654. return true;
  655. }
  656. /**
  657. * Called on every scroll use<br>
  658. * <br>
  659. * @param playerObjectId
  660. * @return boolean: true if player is allowed to use scroll, otherwise false
  661. */
  662. public static boolean onScrollUse(int playerObjectId)
  663. {
  664. if (!isStarted())
  665. {
  666. return true;
  667. }
  668. if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SCROLL_ALLOWED)
  669. {
  670. return false;
  671. }
  672. return true;
  673. }
  674. /**
  675. * Called on every potion use
  676. * @param playerObjectId
  677. * @return boolean: true if player is allowed to use potions, otherwise false
  678. */
  679. public static boolean onPotionUse(int playerObjectId)
  680. {
  681. if (!isStarted())
  682. {
  683. return true;
  684. }
  685. if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_POTIONS_ALLOWED)
  686. {
  687. return false;
  688. }
  689. return true;
  690. }
  691. /**
  692. * Called on every escape use(thanks to nbd)
  693. * @param playerObjectId
  694. * @return boolean: true if player is not in tvt event, otherwise false
  695. */
  696. public static boolean onEscapeUse(int playerObjectId)
  697. {
  698. if (!isStarted())
  699. {
  700. return true;
  701. }
  702. if (isPlayerParticipant(playerObjectId))
  703. {
  704. return false;
  705. }
  706. return true;
  707. }
  708. /**
  709. * Called on every summon item use
  710. * @param playerObjectId
  711. * @return boolean: true if player is allowed to summon by item, otherwise false
  712. */
  713. public static boolean onItemSummon(int playerObjectId)
  714. {
  715. if (!isStarted())
  716. {
  717. return true;
  718. }
  719. if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SUMMON_BY_ITEM_ALLOWED)
  720. {
  721. return false;
  722. }
  723. return true;
  724. }
  725. /**
  726. * Is called when a player is killed<br>
  727. * <br>
  728. * @param killerCharacter as L2Character<br>
  729. * @param killedPlayerInstance as L2PcInstance<br>
  730. */
  731. public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
  732. {
  733. if ((killedPlayerInstance == null) || !isStarted())
  734. {
  735. return;
  736. }
  737. byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId());
  738. if (killedTeamId == -1)
  739. {
  740. return;
  741. }
  742. new TvTEventTeleporter(killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false);
  743. if (killerCharacter == null)
  744. {
  745. return;
  746. }
  747. L2PcInstance killerPlayerInstance = null;
  748. if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
  749. {
  750. killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
  751. if (killerPlayerInstance == null)
  752. {
  753. return;
  754. }
  755. }
  756. else if (killerCharacter instanceof L2PcInstance)
  757. {
  758. killerPlayerInstance = (L2PcInstance) killerCharacter;
  759. }
  760. else
  761. {
  762. return;
  763. }
  764. byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId());
  765. if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId))
  766. {
  767. TvTEventTeam killerTeam = _teams[killerTeamId];
  768. killerTeam.increasePoints();
  769. CreatureSay cs = new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!");
  770. for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values())
  771. {
  772. if (playerInstance != null)
  773. {
  774. playerInstance.sendPacket(cs);
  775. }
  776. }
  777. // Notify to scripts.
  778. EventDispatcher.getInstance().notifyEventAsync(new OnTvTEventKill(killerPlayerInstance, killedPlayerInstance, killerTeam));
  779. }
  780. }
  781. /**
  782. * Called on Appearing packet received (player finished teleporting)
  783. * @param playerInstance
  784. */
  785. public static void onTeleported(L2PcInstance playerInstance)
  786. {
  787. if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
  788. {
  789. return;
  790. }
  791. if (playerInstance.isMageClass())
  792. {
  793. if ((Config.TVT_EVENT_MAGE_BUFFS != null) && !Config.TVT_EVENT_MAGE_BUFFS.isEmpty())
  794. {
  795. for (Entry<Integer, Integer> e : Config.TVT_EVENT_MAGE_BUFFS.entrySet())
  796. {
  797. Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
  798. if (skill != null)
  799. {
  800. skill.applyEffects(playerInstance, playerInstance);
  801. }
  802. }
  803. }
  804. }
  805. else
  806. {
  807. if ((Config.TVT_EVENT_FIGHTER_BUFFS != null) && !Config.TVT_EVENT_FIGHTER_BUFFS.isEmpty())
  808. {
  809. for (Entry<Integer, Integer> e : Config.TVT_EVENT_FIGHTER_BUFFS.entrySet())
  810. {
  811. Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
  812. if (skill != null)
  813. {
  814. skill.applyEffects(playerInstance, playerInstance);
  815. }
  816. }
  817. }
  818. }
  819. }
  820. /**
  821. * @param source
  822. * @param target
  823. * @param skill
  824. * @return true if player valid for skill
  825. */
  826. public static final boolean checkForTvTSkill(L2PcInstance source, L2PcInstance target, Skill skill)
  827. {
  828. if (!isStarted())
  829. {
  830. return true;
  831. }
  832. // TvT is started
  833. final int sourcePlayerId = source.getObjectId();
  834. final int targetPlayerId = target.getObjectId();
  835. final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
  836. final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
  837. // both players not participating
  838. if (!isSourceParticipant && !isTargetParticipant)
  839. {
  840. return true;
  841. }
  842. // one player not participating
  843. if (!(isSourceParticipant && isTargetParticipant))
  844. {
  845. return false;
  846. }
  847. // players in the different teams ?
  848. if (getParticipantTeamId(sourcePlayerId) != getParticipantTeamId(targetPlayerId))
  849. {
  850. if (!skill.isBad())
  851. {
  852. return false;
  853. }
  854. }
  855. return true;
  856. }
  857. /**
  858. * Sets the TvTEvent state<br>
  859. * <br>
  860. * @param state as EventState<br>
  861. */
  862. private static void setState(EventState state)
  863. {
  864. synchronized (_state)
  865. {
  866. _state = state;
  867. }
  868. }
  869. /**
  870. * Is TvTEvent inactive?<br>
  871. * <br>
  872. * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
  873. */
  874. public static boolean isInactive()
  875. {
  876. boolean isInactive;
  877. synchronized (_state)
  878. {
  879. isInactive = _state == EventState.INACTIVE;
  880. }
  881. return isInactive;
  882. }
  883. /**
  884. * Is TvTEvent in inactivating?<br>
  885. * <br>
  886. * @return boolean: true if event is in inactivating progress, otherwise false<br>
  887. */
  888. public static boolean isInactivating()
  889. {
  890. boolean isInactivating;
  891. synchronized (_state)
  892. {
  893. isInactivating = _state == EventState.INACTIVATING;
  894. }
  895. return isInactivating;
  896. }
  897. /**
  898. * Is TvTEvent in participation?<br>
  899. * <br>
  900. * @return boolean: true if event is in participation progress, otherwise false<br>
  901. */
  902. public static boolean isParticipating()
  903. {
  904. boolean isParticipating;
  905. synchronized (_state)
  906. {
  907. isParticipating = _state == EventState.PARTICIPATING;
  908. }
  909. return isParticipating;
  910. }
  911. /**
  912. * Is TvTEvent starting?<br>
  913. * <br>
  914. * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
  915. */
  916. public static boolean isStarting()
  917. {
  918. boolean isStarting;
  919. synchronized (_state)
  920. {
  921. isStarting = _state == EventState.STARTING;
  922. }
  923. return isStarting;
  924. }
  925. /**
  926. * Is TvTEvent started?<br>
  927. * <br>
  928. * @return boolean: true if event is started, otherwise false<br>
  929. */
  930. public static boolean isStarted()
  931. {
  932. boolean isStarted;
  933. synchronized (_state)
  934. {
  935. isStarted = _state == EventState.STARTED;
  936. }
  937. return isStarted;
  938. }
  939. /**
  940. * Is TvTEvent rewarding?<br>
  941. * <br>
  942. * @return boolean: true if event is currently rewarding, otherwise false<br>
  943. */
  944. public static boolean isRewarding()
  945. {
  946. boolean isRewarding;
  947. synchronized (_state)
  948. {
  949. isRewarding = _state == EventState.REWARDING;
  950. }
  951. return isRewarding;
  952. }
  953. /**
  954. * Returns the team id of a player, if player is not participant it returns -1
  955. * @param playerObjectId
  956. * @return byte: team name of the given playerName, if not in event -1
  957. */
  958. public static byte getParticipantTeamId(int playerObjectId)
  959. {
  960. return (byte) (_teams[0].containsPlayer(playerObjectId) ? 0 : (_teams[1].containsPlayer(playerObjectId) ? 1 : -1));
  961. }
  962. /**
  963. * Returns the team of a player, if player is not participant it returns null
  964. * @param playerObjectId
  965. * @return TvTEventTeam: team of the given playerObjectId, if not in event null
  966. */
  967. public static TvTEventTeam getParticipantTeam(int playerObjectId)
  968. {
  969. return (_teams[0].containsPlayer(playerObjectId) ? _teams[0] : (_teams[1].containsPlayer(playerObjectId) ? _teams[1] : null));
  970. }
  971. /**
  972. * Returns the enemy team of a player, if player is not participant it returns null
  973. * @param playerObjectId
  974. * @return TvTEventTeam: enemy team of the given playerObjectId, if not in event null
  975. */
  976. public static TvTEventTeam getParticipantEnemyTeam(int playerObjectId)
  977. {
  978. return (_teams[0].containsPlayer(playerObjectId) ? _teams[1] : (_teams[1].containsPlayer(playerObjectId) ? _teams[0] : null));
  979. }
  980. /**
  981. * Returns the team coordinates in which the player is in, if player is not in a team return null
  982. * @param playerObjectId
  983. * @return int[]: coordinates of teams, 2 elements, index 0 for team 1 and index 1 for team 2
  984. */
  985. public static int[] getParticipantTeamCoordinates(int playerObjectId)
  986. {
  987. return _teams[0].containsPlayer(playerObjectId) ? _teams[0].getCoordinates() : (_teams[1].containsPlayer(playerObjectId) ? _teams[1].getCoordinates() : null);
  988. }
  989. /**
  990. * Is given player participant of the event?
  991. * @param playerObjectId
  992. * @return boolean: true if player is participant, ohterwise false
  993. */
  994. public static boolean isPlayerParticipant(int playerObjectId)
  995. {
  996. if (!isParticipating() && !isStarting() && !isStarted())
  997. {
  998. return false;
  999. }
  1000. return _teams[0].containsPlayer(playerObjectId) || _teams[1].containsPlayer(playerObjectId);
  1001. }
  1002. /**
  1003. * Returns participated player count<br>
  1004. * <br>
  1005. * @return int: amount of players registered in the event<br>
  1006. */
  1007. public static int getParticipatedPlayersCount()
  1008. {
  1009. if (!isParticipating() && !isStarting() && !isStarted())
  1010. {
  1011. return 0;
  1012. }
  1013. return _teams[0].getParticipatedPlayerCount() + _teams[1].getParticipatedPlayerCount();
  1014. }
  1015. /**
  1016. * Returns teams names<br>
  1017. * <br>
  1018. * @return String[]: names of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
  1019. */
  1020. public static String[] getTeamNames()
  1021. {
  1022. return new String[]
  1023. {
  1024. _teams[0].getName(),
  1025. _teams[1].getName()
  1026. };
  1027. }
  1028. /**
  1029. * Returns player count of both teams<br>
  1030. * <br>
  1031. * @return int[]: player count of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
  1032. */
  1033. public static int[] getTeamsPlayerCounts()
  1034. {
  1035. return new int[]
  1036. {
  1037. _teams[0].getParticipatedPlayerCount(),
  1038. _teams[1].getParticipatedPlayerCount()
  1039. };
  1040. }
  1041. /**
  1042. * Returns points count of both teams
  1043. * @return int[]: points of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
  1044. */
  1045. public static int[] getTeamsPoints()
  1046. {
  1047. return new int[]
  1048. {
  1049. _teams[0].getPoints(),
  1050. _teams[1].getPoints()
  1051. };
  1052. }
  1053. public static int getTvTEventInstance()
  1054. {
  1055. return _TvTEventInstance;
  1056. }
  1057. }