TvTEvent.java 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265
  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.FastList;
  27. import javolution.util.FastMap;
  28. import com.l2jserver.Config;
  29. import com.l2jserver.gameserver.cache.HtmCache;
  30. import com.l2jserver.gameserver.datatables.DoorTable;
  31. import com.l2jserver.gameserver.datatables.ItemTable;
  32. import com.l2jserver.gameserver.datatables.NpcData;
  33. import com.l2jserver.gameserver.datatables.SkillData;
  34. import com.l2jserver.gameserver.datatables.SpawnTable;
  35. import com.l2jserver.gameserver.instancemanager.AntiFeedManager;
  36. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  37. import com.l2jserver.gameserver.model.L2Spawn;
  38. import com.l2jserver.gameserver.model.L2World;
  39. import com.l2jserver.gameserver.model.actor.L2Character;
  40. import com.l2jserver.gameserver.model.actor.L2Npc;
  41. import com.l2jserver.gameserver.model.actor.L2Summon;
  42. import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
  43. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  44. import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
  45. import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
  46. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  47. import com.l2jserver.gameserver.model.itemcontainer.PcInventory;
  48. import com.l2jserver.gameserver.model.skills.Skill;
  49. import com.l2jserver.gameserver.network.SystemMessageId;
  50. import com.l2jserver.gameserver.network.clientpackets.Say2;
  51. import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
  52. import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
  53. import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
  54. import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
  55. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  56. import com.l2jserver.gameserver.scripting.scriptengine.events.TvtKillEvent;
  57. import com.l2jserver.gameserver.scripting.scriptengine.impl.L2Script.EventStage;
  58. import com.l2jserver.gameserver.scripting.scriptengine.listeners.events.TvTListener;
  59. import com.l2jserver.util.Rnd;
  60. import com.l2jserver.util.StringUtil;
  61. /**
  62. * @author FBIagent
  63. */
  64. public class TvTEvent
  65. {
  66. enum EventState
  67. {
  68. INACTIVE,
  69. INACTIVATING,
  70. PARTICIPATING,
  71. STARTING,
  72. STARTED,
  73. REWARDING
  74. }
  75. protected static final Logger _log = Logger.getLogger(TvTEvent.class.getName());
  76. /** html path **/
  77. private static final String htmlPath = "data/html/mods/TvTEvent/";
  78. /** The teams of the TvTEvent<br> */
  79. private static TvTEventTeam[] _teams = new TvTEventTeam[2];
  80. /** The state of the TvTEvent<br> */
  81. private static EventState _state = EventState.INACTIVE;
  82. /** The spawn of the participation npc<br> */
  83. private static L2Spawn _npcSpawn = null;
  84. /** the npc instance of the participation npc<br> */
  85. private static L2Npc _lastNpcSpawn = null;
  86. /** Instance id<br> */
  87. private static int _TvTEventInstance = 0;
  88. private static FastList<TvTListener> tvtListeners = new FastList<TvTListener>().shared();
  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. fireTvtEventListeners(EventStage.REGISTRATION_BEGIN);
  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. fireTvtEventListeners(EventStage.START);
  297. return true;
  298. }
  299. /**
  300. * Calculates the TvTEvent reward<br>
  301. * 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>
  302. * 2. Wait till teams are not at a tie anymore<br>
  303. * 3. Set state EvcentState.REWARDING<br>
  304. * 4. Reward team with more points<br>
  305. * 5. Show win html to wining team participants<br>
  306. * <br>
  307. * @return String: winning team name<br>
  308. */
  309. public static String calculateRewards()
  310. {
  311. if (_teams[0].getPoints() == _teams[1].getPoints())
  312. {
  313. // Check if one of the teams have no more players left
  314. if ((_teams[0].getParticipatedPlayerCount() == 0) || (_teams[1].getParticipatedPlayerCount() == 0))
  315. {
  316. // set state to rewarding
  317. setState(EventState.REWARDING);
  318. // return here, the fight can't be completed
  319. return "TvT Event: Event has ended. No team won due to inactivity!";
  320. }
  321. // Both teams have equals points
  322. sysMsgToAllParticipants("TvT Event: Event has ended, both teams have tied.");
  323. if (Config.TVT_REWARD_TEAM_TIE)
  324. {
  325. rewardTeam(_teams[0]);
  326. rewardTeam(_teams[1]);
  327. return "TvT Event: Event has ended with both teams tying.";
  328. }
  329. return "TvT Event: Event has ended with both teams tying.";
  330. }
  331. // Set state REWARDING so nobody can point anymore
  332. setState(EventState.REWARDING);
  333. // Get team which has more points
  334. TvTEventTeam team = _teams[_teams[0].getPoints() > _teams[1].getPoints() ? 0 : 1];
  335. rewardTeam(team);
  336. fireTvtEventListeners(EventStage.END);
  337. return "TvT Event: Event finish. Team " + team.getName() + " won with " + team.getPoints() + " kills.";
  338. }
  339. private static void rewardTeam(TvTEventTeam team)
  340. {
  341. // Iterate over all participated player instances of the winning team
  342. for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
  343. {
  344. // Check for nullpointer
  345. if (playerInstance == null)
  346. {
  347. continue;
  348. }
  349. SystemMessage systemMessage = null;
  350. // Iterate over all tvt event rewards
  351. for (int[] reward : Config.TVT_EVENT_REWARDS)
  352. {
  353. PcInventory inv = playerInstance.getInventory();
  354. // Check for stackable item, non stackabe items need to be added one by one
  355. if (ItemTable.getInstance().createDummyItem(reward[0]).isStackable())
  356. {
  357. inv.addItem("TvT Event", reward[0], reward[1], playerInstance, playerInstance);
  358. if (reward[1] > 1)
  359. {
  360. systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_S2_S1_S);
  361. systemMessage.addItemName(reward[0]);
  362. systemMessage.addLong(reward[1]);
  363. }
  364. else
  365. {
  366. systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
  367. systemMessage.addItemName(reward[0]);
  368. }
  369. playerInstance.sendPacket(systemMessage);
  370. }
  371. else
  372. {
  373. for (int i = 0; i < reward[1]; ++i)
  374. {
  375. inv.addItem("TvT Event", reward[0], 1, playerInstance, playerInstance);
  376. systemMessage = SystemMessage.getSystemMessage(SystemMessageId.EARNED_ITEM_S1);
  377. systemMessage.addItemName(reward[0]);
  378. playerInstance.sendPacket(systemMessage);
  379. }
  380. }
  381. }
  382. StatusUpdate statusUpdate = new StatusUpdate(playerInstance);
  383. final NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage();
  384. statusUpdate.addAttribute(StatusUpdate.CUR_LOAD, playerInstance.getCurrentLoad());
  385. npcHtmlMessage.setHtml(HtmCache.getInstance().getHtm(playerInstance.getHtmlPrefix(), htmlPath + "Reward.htm"));
  386. playerInstance.sendPacket(statusUpdate);
  387. playerInstance.sendPacket(npcHtmlMessage);
  388. }
  389. }
  390. /**
  391. * Stops the TvTEvent fight<br>
  392. * 1. Set state EventState.INACTIVATING<br>
  393. * 2. Remove tvt npc from world<br>
  394. * 3. Open doors specified in configs<br>
  395. * 4. Teleport all participants back to participation npc location<br>
  396. * 5. Teams cleaning<br>
  397. * 6. Set state EventState.INACTIVE<br>
  398. */
  399. public static void stopFight()
  400. {
  401. // Set state INACTIVATING
  402. setState(EventState.INACTIVATING);
  403. // Unspawn event npc
  404. unSpawnNpc();
  405. // Opens all doors specified in configs for tvt
  406. openDoors(Config.TVT_DOORS_IDS_TO_CLOSE);
  407. // Closes all doors specified in Configs for tvt
  408. closeDoors(Config.TVT_DOORS_IDS_TO_OPEN);
  409. // Iterate over all teams
  410. for (TvTEventTeam team : _teams)
  411. {
  412. for (L2PcInstance playerInstance : team.getParticipatedPlayers().values())
  413. {
  414. // Check for nullpointer
  415. if (playerInstance != null)
  416. {
  417. // Enable player revival.
  418. playerInstance.setCanRevive(true);
  419. // Teleport back.
  420. new TvTEventTeleporter(playerInstance, Config.TVT_EVENT_PARTICIPATION_NPC_COORDINATES, false, false);
  421. }
  422. }
  423. }
  424. // Cleanup of teams
  425. _teams[0].cleanMe();
  426. _teams[1].cleanMe();
  427. // Set state INACTIVE
  428. setState(EventState.INACTIVE);
  429. AntiFeedManager.getInstance().clear(AntiFeedManager.TVT_ID);
  430. }
  431. /**
  432. * Adds a player to a TvTEvent team<br>
  433. * 1. Calculate the id of the team in which the player should be added<br>
  434. * 2. Add the player to the calculated team<br>
  435. * <br>
  436. * @param playerInstance as L2PcInstance<br>
  437. * @return boolean: true if success, otherwise false<br>
  438. */
  439. public static synchronized boolean addParticipant(L2PcInstance playerInstance)
  440. {
  441. // Check for nullpoitner
  442. if (playerInstance == null)
  443. {
  444. return false;
  445. }
  446. byte teamId = 0;
  447. // Check to which team the player should be added
  448. if (_teams[0].getParticipatedPlayerCount() == _teams[1].getParticipatedPlayerCount())
  449. {
  450. teamId = (byte) (Rnd.get(2));
  451. }
  452. else
  453. {
  454. teamId = (byte) (_teams[0].getParticipatedPlayerCount() > _teams[1].getParticipatedPlayerCount() ? 1 : 0);
  455. }
  456. playerInstance.addEventListener(new TvTEventListener(playerInstance));
  457. return _teams[teamId].addPlayer(playerInstance);
  458. }
  459. /**
  460. * Removes a TvTEvent player from it's team<br>
  461. * 1. Get team id of the player<br>
  462. * 2. Remove player from it's team<br>
  463. * <br>
  464. * @param playerObjectId
  465. * @return boolean: true if success, otherwise false
  466. */
  467. public static boolean removeParticipant(int playerObjectId)
  468. {
  469. // Get the teamId of the player
  470. byte teamId = getParticipantTeamId(playerObjectId);
  471. // Check if the player is participant
  472. if (teamId != -1)
  473. {
  474. // Remove the player from team
  475. _teams[teamId].removePlayer(playerObjectId);
  476. final L2PcInstance player = L2World.getInstance().getPlayer(playerObjectId);
  477. if (player != null)
  478. {
  479. player.removeEventListener(TvTEventListener.class);
  480. }
  481. return true;
  482. }
  483. return false;
  484. }
  485. public static boolean needParticipationFee()
  486. {
  487. return (Config.TVT_EVENT_PARTICIPATION_FEE[0] != 0) && (Config.TVT_EVENT_PARTICIPATION_FEE[1] != 0);
  488. }
  489. public static boolean hasParticipationFee(L2PcInstance playerInstance)
  490. {
  491. return playerInstance.getInventory().getInventoryItemCount(Config.TVT_EVENT_PARTICIPATION_FEE[0], -1) >= Config.TVT_EVENT_PARTICIPATION_FEE[1];
  492. }
  493. public static boolean payParticipationFee(L2PcInstance playerInstance)
  494. {
  495. return playerInstance.destroyItemByItemId("TvT Participation Fee", Config.TVT_EVENT_PARTICIPATION_FEE[0], Config.TVT_EVENT_PARTICIPATION_FEE[1], _lastNpcSpawn, true);
  496. }
  497. public static String getParticipationFee()
  498. {
  499. int itemId = Config.TVT_EVENT_PARTICIPATION_FEE[0];
  500. int itemNum = Config.TVT_EVENT_PARTICIPATION_FEE[1];
  501. if ((itemId == 0) || (itemNum == 0))
  502. {
  503. return "-";
  504. }
  505. return StringUtil.concat(String.valueOf(itemNum), " ", ItemTable.getInstance().getTemplate(itemId).getName());
  506. }
  507. /**
  508. * Send a SystemMessage to all participated players<br>
  509. * 1. Send the message to all players of team number one<br>
  510. * 2. Send the message to all players of team number two<br>
  511. * <br>
  512. * @param message as String<br>
  513. */
  514. public static void sysMsgToAllParticipants(String message)
  515. {
  516. for (L2PcInstance playerInstance : _teams[0].getParticipatedPlayers().values())
  517. {
  518. if (playerInstance != null)
  519. {
  520. playerInstance.sendMessage(message);
  521. }
  522. }
  523. for (L2PcInstance playerInstance : _teams[1].getParticipatedPlayers().values())
  524. {
  525. if (playerInstance != null)
  526. {
  527. playerInstance.sendMessage(message);
  528. }
  529. }
  530. }
  531. private static L2DoorInstance getDoor(int doorId)
  532. {
  533. L2DoorInstance door = null;
  534. if (_TvTEventInstance <= 0)
  535. {
  536. door = DoorTable.getInstance().getDoor(doorId);
  537. }
  538. else
  539. {
  540. final Instance inst = InstanceManager.getInstance().getInstance(_TvTEventInstance);
  541. if (inst != null)
  542. {
  543. door = inst.getDoor(doorId);
  544. }
  545. }
  546. return door;
  547. }
  548. /**
  549. * Close doors specified in configs
  550. * @param doors
  551. */
  552. private static void closeDoors(List<Integer> doors)
  553. {
  554. for (int doorId : doors)
  555. {
  556. final L2DoorInstance doorInstance = getDoor(doorId);
  557. if (doorInstance != null)
  558. {
  559. doorInstance.closeMe();
  560. }
  561. }
  562. }
  563. /**
  564. * Open doors specified in configs
  565. * @param doors
  566. */
  567. private static void openDoors(List<Integer> doors)
  568. {
  569. for (int doorId : doors)
  570. {
  571. final L2DoorInstance doorInstance = getDoor(doorId);
  572. if (doorInstance != null)
  573. {
  574. doorInstance.openMe();
  575. }
  576. }
  577. }
  578. /**
  579. * UnSpawns the TvTEvent npc
  580. */
  581. private static void unSpawnNpc()
  582. {
  583. // Delete the npc
  584. _lastNpcSpawn.deleteMe();
  585. SpawnTable.getInstance().deleteSpawn(_lastNpcSpawn.getSpawn(), false);
  586. // Stop respawning of the npc
  587. _npcSpawn.stopRespawn();
  588. _npcSpawn = null;
  589. _lastNpcSpawn = null;
  590. }
  591. /**
  592. * Called when a player logs in<br>
  593. * <br>
  594. * @param playerInstance as L2PcInstance<br>
  595. */
  596. public static void onLogin(L2PcInstance playerInstance)
  597. {
  598. if ((playerInstance == null) || (!isStarting() && !isStarted()))
  599. {
  600. return;
  601. }
  602. byte teamId = getParticipantTeamId(playerInstance.getObjectId());
  603. if (teamId == -1)
  604. {
  605. return;
  606. }
  607. _teams[teamId].addPlayer(playerInstance);
  608. new TvTEventTeleporter(playerInstance, _teams[teamId].getCoordinates(), true, false);
  609. }
  610. /**
  611. * Called when a player logs out<br>
  612. * <br>
  613. * @param playerInstance as L2PcInstance<br>
  614. */
  615. public static void onLogout(L2PcInstance playerInstance)
  616. {
  617. if ((playerInstance != null) && (isStarting() || isStarted() || isParticipating()))
  618. {
  619. if (removeParticipant(playerInstance.getObjectId()))
  620. {
  621. 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]);
  622. }
  623. }
  624. }
  625. /**
  626. * Called on every onAction in L2PcIstance<br>
  627. * <br>
  628. * @param playerInstance
  629. * @param targetedPlayerObjectId
  630. * @return boolean: true if player is allowed to target, otherwise false
  631. */
  632. public static boolean onAction(L2PcInstance playerInstance, int targetedPlayerObjectId)
  633. {
  634. if ((playerInstance == null) || !isStarted())
  635. {
  636. return true;
  637. }
  638. if (playerInstance.isGM())
  639. {
  640. return true;
  641. }
  642. byte playerTeamId = getParticipantTeamId(playerInstance.getObjectId());
  643. byte targetedPlayerTeamId = getParticipantTeamId(targetedPlayerObjectId);
  644. if (((playerTeamId != -1) && (targetedPlayerTeamId == -1)) || ((playerTeamId == -1) && (targetedPlayerTeamId != -1)))
  645. {
  646. return false;
  647. }
  648. if ((playerTeamId != -1) && (targetedPlayerTeamId != -1) && (playerTeamId == targetedPlayerTeamId) && (playerInstance.getObjectId() != targetedPlayerObjectId) && !Config.TVT_EVENT_TARGET_TEAM_MEMBERS_ALLOWED)
  649. {
  650. return false;
  651. }
  652. return true;
  653. }
  654. /**
  655. * Called on every scroll use<br>
  656. * <br>
  657. * @param playerObjectId
  658. * @return boolean: true if player is allowed to use scroll, otherwise false
  659. */
  660. public static boolean onScrollUse(int playerObjectId)
  661. {
  662. if (!isStarted())
  663. {
  664. return true;
  665. }
  666. if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SCROLL_ALLOWED)
  667. {
  668. return false;
  669. }
  670. return true;
  671. }
  672. /**
  673. * Called on every potion use
  674. * @param playerObjectId
  675. * @return boolean: true if player is allowed to use potions, otherwise false
  676. */
  677. public static boolean onPotionUse(int playerObjectId)
  678. {
  679. if (!isStarted())
  680. {
  681. return true;
  682. }
  683. if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_POTIONS_ALLOWED)
  684. {
  685. return false;
  686. }
  687. return true;
  688. }
  689. /**
  690. * Called on every escape use(thanks to nbd)
  691. * @param playerObjectId
  692. * @return boolean: true if player is not in tvt event, otherwise false
  693. */
  694. public static boolean onEscapeUse(int playerObjectId)
  695. {
  696. if (!isStarted())
  697. {
  698. return true;
  699. }
  700. if (isPlayerParticipant(playerObjectId))
  701. {
  702. return false;
  703. }
  704. return true;
  705. }
  706. /**
  707. * Called on every summon item use
  708. * @param playerObjectId
  709. * @return boolean: true if player is allowed to summon by item, otherwise false
  710. */
  711. public static boolean onItemSummon(int playerObjectId)
  712. {
  713. if (!isStarted())
  714. {
  715. return true;
  716. }
  717. if (isPlayerParticipant(playerObjectId) && !Config.TVT_EVENT_SUMMON_BY_ITEM_ALLOWED)
  718. {
  719. return false;
  720. }
  721. return true;
  722. }
  723. /**
  724. * Is called when a player is killed<br>
  725. * <br>
  726. * @param killerCharacter as L2Character<br>
  727. * @param killedPlayerInstance as L2PcInstance<br>
  728. */
  729. public static void onKill(L2Character killerCharacter, L2PcInstance killedPlayerInstance)
  730. {
  731. if ((killedPlayerInstance == null) || !isStarted())
  732. {
  733. return;
  734. }
  735. byte killedTeamId = getParticipantTeamId(killedPlayerInstance.getObjectId());
  736. if (killedTeamId == -1)
  737. {
  738. return;
  739. }
  740. new TvTEventTeleporter(killedPlayerInstance, _teams[killedTeamId].getCoordinates(), false, false);
  741. if (killerCharacter == null)
  742. {
  743. return;
  744. }
  745. L2PcInstance killerPlayerInstance = null;
  746. if ((killerCharacter instanceof L2PetInstance) || (killerCharacter instanceof L2ServitorInstance))
  747. {
  748. killerPlayerInstance = ((L2Summon) killerCharacter).getOwner();
  749. if (killerPlayerInstance == null)
  750. {
  751. return;
  752. }
  753. }
  754. else if (killerCharacter instanceof L2PcInstance)
  755. {
  756. killerPlayerInstance = (L2PcInstance) killerCharacter;
  757. }
  758. else
  759. {
  760. return;
  761. }
  762. byte killerTeamId = getParticipantTeamId(killerPlayerInstance.getObjectId());
  763. if ((killerTeamId != -1) && (killedTeamId != -1) && (killerTeamId != killedTeamId))
  764. {
  765. TvTEventTeam killerTeam = _teams[killerTeamId];
  766. killerTeam.increasePoints();
  767. CreatureSay cs = new CreatureSay(killerPlayerInstance.getObjectId(), Say2.TELL, killerPlayerInstance.getName(), "I have killed " + killedPlayerInstance.getName() + "!");
  768. for (L2PcInstance playerInstance : _teams[killerTeamId].getParticipatedPlayers().values())
  769. {
  770. if (playerInstance != null)
  771. {
  772. playerInstance.sendPacket(cs);
  773. }
  774. }
  775. fireTvtKillListeners(killerPlayerInstance, killedPlayerInstance, killerTeam);
  776. }
  777. }
  778. /**
  779. * Called on Appearing packet received (player finished teleporting)
  780. * @param playerInstance
  781. */
  782. public static void onTeleported(L2PcInstance playerInstance)
  783. {
  784. if (!isStarted() || (playerInstance == null) || !isPlayerParticipant(playerInstance.getObjectId()))
  785. {
  786. return;
  787. }
  788. if (playerInstance.isMageClass())
  789. {
  790. if ((Config.TVT_EVENT_MAGE_BUFFS != null) && !Config.TVT_EVENT_MAGE_BUFFS.isEmpty())
  791. {
  792. for (Entry<Integer, Integer> e : Config.TVT_EVENT_MAGE_BUFFS.entrySet())
  793. {
  794. Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
  795. if (skill != null)
  796. {
  797. skill.applyEffects(playerInstance, playerInstance);
  798. }
  799. }
  800. }
  801. }
  802. else
  803. {
  804. if ((Config.TVT_EVENT_FIGHTER_BUFFS != null) && !Config.TVT_EVENT_FIGHTER_BUFFS.isEmpty())
  805. {
  806. for (Entry<Integer, Integer> e : Config.TVT_EVENT_FIGHTER_BUFFS.entrySet())
  807. {
  808. Skill skill = SkillData.getInstance().getSkill(e.getKey(), e.getValue());
  809. if (skill != null)
  810. {
  811. skill.applyEffects(playerInstance, playerInstance);
  812. }
  813. }
  814. }
  815. }
  816. }
  817. /**
  818. * @param source
  819. * @param target
  820. * @param skill
  821. * @return true if player valid for skill
  822. */
  823. public static final boolean checkForTvTSkill(L2PcInstance source, L2PcInstance target, Skill skill)
  824. {
  825. if (!isStarted())
  826. {
  827. return true;
  828. }
  829. // TvT is started
  830. final int sourcePlayerId = source.getObjectId();
  831. final int targetPlayerId = target.getObjectId();
  832. final boolean isSourceParticipant = isPlayerParticipant(sourcePlayerId);
  833. final boolean isTargetParticipant = isPlayerParticipant(targetPlayerId);
  834. // both players not participating
  835. if (!isSourceParticipant && !isTargetParticipant)
  836. {
  837. return true;
  838. }
  839. // one player not participating
  840. if (!(isSourceParticipant && isTargetParticipant))
  841. {
  842. return false;
  843. }
  844. // players in the different teams ?
  845. if (getParticipantTeamId(sourcePlayerId) != getParticipantTeamId(targetPlayerId))
  846. {
  847. if (!skill.isBad())
  848. {
  849. return false;
  850. }
  851. }
  852. return true;
  853. }
  854. /**
  855. * Sets the TvTEvent state<br>
  856. * <br>
  857. * @param state as EventState<br>
  858. */
  859. private static void setState(EventState state)
  860. {
  861. synchronized (_state)
  862. {
  863. _state = state;
  864. }
  865. }
  866. /**
  867. * Is TvTEvent inactive?<br>
  868. * <br>
  869. * @return boolean: true if event is inactive(waiting for next event cycle), otherwise false<br>
  870. */
  871. public static boolean isInactive()
  872. {
  873. boolean isInactive;
  874. synchronized (_state)
  875. {
  876. isInactive = _state == EventState.INACTIVE;
  877. }
  878. return isInactive;
  879. }
  880. /**
  881. * Is TvTEvent in inactivating?<br>
  882. * <br>
  883. * @return boolean: true if event is in inactivating progress, otherwise false<br>
  884. */
  885. public static boolean isInactivating()
  886. {
  887. boolean isInactivating;
  888. synchronized (_state)
  889. {
  890. isInactivating = _state == EventState.INACTIVATING;
  891. }
  892. return isInactivating;
  893. }
  894. /**
  895. * Is TvTEvent in participation?<br>
  896. * <br>
  897. * @return boolean: true if event is in participation progress, otherwise false<br>
  898. */
  899. public static boolean isParticipating()
  900. {
  901. boolean isParticipating;
  902. synchronized (_state)
  903. {
  904. isParticipating = _state == EventState.PARTICIPATING;
  905. }
  906. return isParticipating;
  907. }
  908. /**
  909. * Is TvTEvent starting?<br>
  910. * <br>
  911. * @return boolean: true if event is starting up(setting up fighting spot, teleport players etc.), otherwise false<br>
  912. */
  913. public static boolean isStarting()
  914. {
  915. boolean isStarting;
  916. synchronized (_state)
  917. {
  918. isStarting = _state == EventState.STARTING;
  919. }
  920. return isStarting;
  921. }
  922. /**
  923. * Is TvTEvent started?<br>
  924. * <br>
  925. * @return boolean: true if event is started, otherwise false<br>
  926. */
  927. public static boolean isStarted()
  928. {
  929. boolean isStarted;
  930. synchronized (_state)
  931. {
  932. isStarted = _state == EventState.STARTED;
  933. }
  934. return isStarted;
  935. }
  936. /**
  937. * Is TvTEvent rewarding?<br>
  938. * <br>
  939. * @return boolean: true if event is currently rewarding, otherwise false<br>
  940. */
  941. public static boolean isRewarding()
  942. {
  943. boolean isRewarding;
  944. synchronized (_state)
  945. {
  946. isRewarding = _state == EventState.REWARDING;
  947. }
  948. return isRewarding;
  949. }
  950. /**
  951. * Returns the team id of a player, if player is not participant it returns -1
  952. * @param playerObjectId
  953. * @return byte: team name of the given playerName, if not in event -1
  954. */
  955. public static byte getParticipantTeamId(int playerObjectId)
  956. {
  957. return (byte) (_teams[0].containsPlayer(playerObjectId) ? 0 : (_teams[1].containsPlayer(playerObjectId) ? 1 : -1));
  958. }
  959. /**
  960. * Returns the team of a player, if player is not participant it returns null
  961. * @param playerObjectId
  962. * @return TvTEventTeam: team of the given playerObjectId, if not in event null
  963. */
  964. public static TvTEventTeam getParticipantTeam(int playerObjectId)
  965. {
  966. return (_teams[0].containsPlayer(playerObjectId) ? _teams[0] : (_teams[1].containsPlayer(playerObjectId) ? _teams[1] : null));
  967. }
  968. /**
  969. * Returns the enemy team of a player, if player is not participant it returns null
  970. * @param playerObjectId
  971. * @return TvTEventTeam: enemy team of the given playerObjectId, if not in event null
  972. */
  973. public static TvTEventTeam getParticipantEnemyTeam(int playerObjectId)
  974. {
  975. return (_teams[0].containsPlayer(playerObjectId) ? _teams[1] : (_teams[1].containsPlayer(playerObjectId) ? _teams[0] : null));
  976. }
  977. /**
  978. * Returns the team coordinates in which the player is in, if player is not in a team return null
  979. * @param playerObjectId
  980. * @return int[]: coordinates of teams, 2 elements, index 0 for team 1 and index 1 for team 2
  981. */
  982. public static int[] getParticipantTeamCoordinates(int playerObjectId)
  983. {
  984. return _teams[0].containsPlayer(playerObjectId) ? _teams[0].getCoordinates() : (_teams[1].containsPlayer(playerObjectId) ? _teams[1].getCoordinates() : null);
  985. }
  986. /**
  987. * Is given player participant of the event?
  988. * @param playerObjectId
  989. * @return boolean: true if player is participant, ohterwise false
  990. */
  991. public static boolean isPlayerParticipant(int playerObjectId)
  992. {
  993. if (!isParticipating() && !isStarting() && !isStarted())
  994. {
  995. return false;
  996. }
  997. return _teams[0].containsPlayer(playerObjectId) || _teams[1].containsPlayer(playerObjectId);
  998. }
  999. /**
  1000. * Returns participated player count<br>
  1001. * <br>
  1002. * @return int: amount of players registered in the event<br>
  1003. */
  1004. public static int getParticipatedPlayersCount()
  1005. {
  1006. if (!isParticipating() && !isStarting() && !isStarted())
  1007. {
  1008. return 0;
  1009. }
  1010. return _teams[0].getParticipatedPlayerCount() + _teams[1].getParticipatedPlayerCount();
  1011. }
  1012. /**
  1013. * Returns teams names<br>
  1014. * <br>
  1015. * @return String[]: names of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
  1016. */
  1017. public static String[] getTeamNames()
  1018. {
  1019. return new String[]
  1020. {
  1021. _teams[0].getName(),
  1022. _teams[1].getName()
  1023. };
  1024. }
  1025. /**
  1026. * Returns player count of both teams<br>
  1027. * <br>
  1028. * @return int[]: player count of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
  1029. */
  1030. public static int[] getTeamsPlayerCounts()
  1031. {
  1032. return new int[]
  1033. {
  1034. _teams[0].getParticipatedPlayerCount(),
  1035. _teams[1].getParticipatedPlayerCount()
  1036. };
  1037. }
  1038. /**
  1039. * Returns points count of both teams
  1040. * @return int[]: points of teams, 2 elements, index 0 for team 1 and index 1 for team 2<br>
  1041. */
  1042. public static int[] getTeamsPoints()
  1043. {
  1044. return new int[]
  1045. {
  1046. _teams[0].getPoints(),
  1047. _teams[1].getPoints()
  1048. };
  1049. }
  1050. public static int getTvTEventInstance()
  1051. {
  1052. return _TvTEventInstance;
  1053. }
  1054. // Listeners
  1055. /**
  1056. * Fires all the TvTListener.onKill() methods, if any
  1057. * @param killer
  1058. * @param victim
  1059. * @param killerTeam
  1060. */
  1061. private static void fireTvtKillListeners(L2PcInstance killer, L2PcInstance victim, TvTEventTeam killerTeam)
  1062. {
  1063. if (!tvtListeners.isEmpty() && (killer != null) && (victim != null) && (killerTeam != null))
  1064. {
  1065. TvtKillEvent event = new TvtKillEvent();
  1066. event.setKiller(killer);
  1067. event.setVictim(victim);
  1068. event.setKillerTeam(killerTeam);
  1069. for (TvTListener listener : tvtListeners)
  1070. {
  1071. listener.onKill(event);
  1072. }
  1073. }
  1074. }
  1075. /**
  1076. * Fires the appropriate TvtEventListeners, if any
  1077. * @param stage
  1078. */
  1079. private static void fireTvtEventListeners(EventStage stage)
  1080. {
  1081. if (!tvtListeners.isEmpty())
  1082. {
  1083. switch (stage)
  1084. {
  1085. case REGISTRATION_BEGIN:
  1086. {
  1087. for (TvTListener listener : tvtListeners)
  1088. {
  1089. listener.onRegistrationStart();
  1090. }
  1091. break;
  1092. }
  1093. case START:
  1094. {
  1095. for (TvTListener listener : tvtListeners)
  1096. {
  1097. listener.onBegin();
  1098. }
  1099. break;
  1100. }
  1101. case END:
  1102. {
  1103. for (TvTListener listener : tvtListeners)
  1104. {
  1105. listener.onEnd();
  1106. }
  1107. break;
  1108. }
  1109. }
  1110. }
  1111. }
  1112. /**
  1113. * Adds a TvT listener
  1114. * @param listener
  1115. */
  1116. public static void addTvTListener(TvTListener listener)
  1117. {
  1118. if (!tvtListeners.contains(listener))
  1119. {
  1120. tvtListeners.add(listener);
  1121. }
  1122. }
  1123. /**
  1124. * Removes a TvT listener
  1125. * @param listener
  1126. */
  1127. public static void removeTvtListener(TvTListener listener)
  1128. {
  1129. tvtListeners.remove(listener);
  1130. }
  1131. }