DimensionalRift.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /*
  2. * Copyright (C) 2004-2015 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.ArrayList;
  21. import java.util.List;
  22. import java.util.Timer;
  23. import java.util.TimerTask;
  24. import java.util.concurrent.CopyOnWriteArrayList;
  25. import java.util.concurrent.Future;
  26. import com.l2jserver.Config;
  27. import com.l2jserver.gameserver.ThreadPoolManager;
  28. import com.l2jserver.gameserver.instancemanager.DimensionalRiftManager;
  29. import com.l2jserver.gameserver.instancemanager.QuestManager;
  30. import com.l2jserver.gameserver.model.L2Party;
  31. import com.l2jserver.gameserver.model.Location;
  32. import com.l2jserver.gameserver.model.actor.L2Npc;
  33. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  34. import com.l2jserver.gameserver.model.quest.Quest;
  35. import com.l2jserver.gameserver.model.quest.QuestState;
  36. import com.l2jserver.gameserver.network.serverpackets.Earthquake;
  37. import com.l2jserver.util.Rnd;
  38. /**
  39. * Thanks to L2Fortress and balancer.ru - kombat
  40. */
  41. public class DimensionalRift
  42. {
  43. protected byte _type;
  44. protected L2Party _party;
  45. protected List<Byte> _completedRooms = new ArrayList<>();
  46. private static final long seconds_5 = 5000L;
  47. // private static final int MILLISECONDS_IN_MINUTE = 60000;
  48. protected byte jumps_current = 0;
  49. private Timer teleporterTimer;
  50. private TimerTask teleporterTimerTask;
  51. private Timer spawnTimer;
  52. private TimerTask spawnTimerTask;
  53. private Future<?> earthQuakeTask;
  54. protected byte _choosenRoom = -1;
  55. private boolean _hasJumped = false;
  56. protected List<L2PcInstance> _deadPlayers = new CopyOnWriteArrayList<>();
  57. protected List<L2PcInstance> _revivedInWaitingRoom = new CopyOnWriteArrayList<>();
  58. private boolean isBossRoom = false;
  59. public DimensionalRift(L2Party party, byte type, byte room)
  60. {
  61. DimensionalRiftManager.getInstance().getRoom(type, room).setPartyInside(true);
  62. _type = type;
  63. _party = party;
  64. _choosenRoom = room;
  65. Location coords = getRoomCoord(room);
  66. party.setDimensionalRift(this);
  67. for (L2PcInstance p : party.getMembers())
  68. {
  69. final Quest riftQuest = QuestManager.getInstance().getQuest(635);
  70. if (riftQuest != null)
  71. {
  72. QuestState qs = p.getQuestState(riftQuest.getName());
  73. if (qs == null)
  74. {
  75. qs = riftQuest.newQuestState(p);
  76. }
  77. if (!qs.isStarted())
  78. {
  79. qs.startQuest();
  80. }
  81. }
  82. p.teleToLocation(coords);
  83. }
  84. createSpawnTimer(_choosenRoom);
  85. createTeleporterTimer(true);
  86. }
  87. public byte getType()
  88. {
  89. return _type;
  90. }
  91. public byte getCurrentRoom()
  92. {
  93. return _choosenRoom;
  94. }
  95. protected void createTeleporterTimer(final boolean reasonTP)
  96. {
  97. if (_party == null)
  98. {
  99. return;
  100. }
  101. if (teleporterTimerTask != null)
  102. {
  103. teleporterTimerTask.cancel();
  104. teleporterTimerTask = null;
  105. }
  106. if (teleporterTimer != null)
  107. {
  108. teleporterTimer.cancel();
  109. teleporterTimer = null;
  110. }
  111. if (earthQuakeTask != null)
  112. {
  113. earthQuakeTask.cancel(false);
  114. earthQuakeTask = null;
  115. }
  116. teleporterTimer = new Timer();
  117. teleporterTimerTask = new TimerTask()
  118. {
  119. @Override
  120. public void run()
  121. {
  122. if (_choosenRoom > -1)
  123. {
  124. DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).unspawn().setPartyInside(false);
  125. }
  126. if (reasonTP && (jumps_current < getMaxJumps()) && (_party.getMemberCount() > _deadPlayers.size()))
  127. {
  128. jumps_current++;
  129. _completedRooms.add(_choosenRoom);
  130. _choosenRoom = -1;
  131. for (L2PcInstance p : _party.getMembers())
  132. {
  133. if (!_revivedInWaitingRoom.contains(p))
  134. {
  135. teleportToNextRoom(p);
  136. }
  137. }
  138. createTeleporterTimer(true);
  139. createSpawnTimer(_choosenRoom);
  140. }
  141. else
  142. {
  143. for (L2PcInstance p : _party.getMembers())
  144. {
  145. if (!_revivedInWaitingRoom.contains(p))
  146. {
  147. teleportToWaitingRoom(p);
  148. }
  149. }
  150. killRift();
  151. cancel();
  152. }
  153. }
  154. };
  155. if (reasonTP)
  156. {
  157. long jumpTime = calcTimeToNextJump();
  158. teleporterTimer.schedule(teleporterTimerTask, jumpTime); // Teleporter task, 8-10 minutes
  159. earthQuakeTask = ThreadPoolManager.getInstance().scheduleGeneral(() ->
  160. {
  161. for (L2PcInstance p : _party.getMembers())
  162. {
  163. if (!_revivedInWaitingRoom.contains(p))
  164. {
  165. p.sendPacket(new Earthquake(p.getX(), p.getY(), p.getZ(), 65, 9));
  166. }
  167. }
  168. }, jumpTime - 7000);
  169. }
  170. else
  171. {
  172. teleporterTimer.schedule(teleporterTimerTask, seconds_5); // incorrect party member invited.
  173. }
  174. }
  175. public void createSpawnTimer(final byte room)
  176. {
  177. if (spawnTimerTask != null)
  178. {
  179. spawnTimerTask.cancel();
  180. spawnTimerTask = null;
  181. }
  182. if (spawnTimer != null)
  183. {
  184. spawnTimer.cancel();
  185. spawnTimer = null;
  186. }
  187. spawnTimer = new Timer();
  188. spawnTimerTask = new TimerTask()
  189. {
  190. @Override
  191. public void run()
  192. {
  193. DimensionalRiftManager.getInstance().getRoom(_type, room).spawn();
  194. }
  195. };
  196. spawnTimer.schedule(spawnTimerTask, Config.RIFT_SPAWN_DELAY);
  197. }
  198. public void partyMemberInvited()
  199. {
  200. createTeleporterTimer(false);
  201. }
  202. public void partyMemberExited(L2PcInstance player)
  203. {
  204. if (_deadPlayers.contains(player))
  205. {
  206. _deadPlayers.remove(player);
  207. }
  208. if (_revivedInWaitingRoom.contains(player))
  209. {
  210. _revivedInWaitingRoom.remove(player);
  211. }
  212. if ((_party.getMemberCount() < Config.RIFT_MIN_PARTY_SIZE) || (_party.getMemberCount() == 1))
  213. {
  214. for (L2PcInstance p : _party.getMembers())
  215. {
  216. teleportToWaitingRoom(p);
  217. }
  218. killRift();
  219. }
  220. }
  221. public void manualTeleport(L2PcInstance player, L2Npc npc)
  222. {
  223. if (!player.isInParty() || !player.getParty().isInDimensionalRift())
  224. {
  225. return;
  226. }
  227. if (player.getObjectId() != player.getParty().getLeaderObjectId())
  228. {
  229. DimensionalRiftManager.getInstance().showHtmlFile(player, "data/html/seven_signs/rift/NotPartyLeader.htm", npc);
  230. return;
  231. }
  232. if (_hasJumped)
  233. {
  234. DimensionalRiftManager.getInstance().showHtmlFile(player, "data/html/seven_signs/rift/AlreadyTeleported.htm", npc);
  235. return;
  236. }
  237. _hasJumped = true;
  238. DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).unspawn().setPartyInside(false);
  239. _completedRooms.add(_choosenRoom);
  240. _choosenRoom = -1;
  241. for (L2PcInstance p : _party.getMembers())
  242. {
  243. teleportToNextRoom(p);
  244. }
  245. DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).setPartyInside(true);
  246. createSpawnTimer(_choosenRoom);
  247. createTeleporterTimer(true);
  248. }
  249. public void manualExitRift(L2PcInstance player, L2Npc npc)
  250. {
  251. if (!player.isInParty() || !player.getParty().isInDimensionalRift())
  252. {
  253. return;
  254. }
  255. if (player.getObjectId() != player.getParty().getLeaderObjectId())
  256. {
  257. DimensionalRiftManager.getInstance().showHtmlFile(player, "data/html/seven_signs/rift/NotPartyLeader.htm", npc);
  258. return;
  259. }
  260. for (L2PcInstance p : player.getParty().getMembers())
  261. {
  262. teleportToWaitingRoom(p);
  263. }
  264. killRift();
  265. }
  266. protected void teleportToNextRoom(L2PcInstance player)
  267. {
  268. if (_choosenRoom == -1)
  269. {
  270. List<Byte> emptyRooms;
  271. do
  272. {
  273. emptyRooms = DimensionalRiftManager.getInstance().getFreeRooms(_type);
  274. // Do not tp in the same room a second time
  275. emptyRooms.removeAll(_completedRooms);
  276. // If no room left, find any empty
  277. if (emptyRooms.isEmpty())
  278. {
  279. emptyRooms = DimensionalRiftManager.getInstance().getFreeRooms(_type);
  280. }
  281. _choosenRoom = emptyRooms.get(Rnd.get(1, emptyRooms.size()) - 1);
  282. }
  283. while (DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).isPartyInside());
  284. }
  285. DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).setPartyInside(true);
  286. checkBossRoom(_choosenRoom);
  287. player.teleToLocation(getRoomCoord(_choosenRoom));
  288. }
  289. protected void teleportToWaitingRoom(L2PcInstance player)
  290. {
  291. DimensionalRiftManager.getInstance().teleportToWaitingRoom(player);
  292. final Quest riftQuest = QuestManager.getInstance().getQuest(635);
  293. if (riftQuest != null)
  294. {
  295. final QuestState qs = player.getQuestState(riftQuest.getName());
  296. if ((qs != null) && qs.isCond(1))
  297. {
  298. qs.exitQuest(true, true);
  299. }
  300. }
  301. }
  302. public void killRift()
  303. {
  304. _completedRooms.clear();
  305. if (_party != null)
  306. {
  307. _party.setDimensionalRift(null);
  308. }
  309. _party = null;
  310. _revivedInWaitingRoom = null;
  311. _deadPlayers = null;
  312. if (earthQuakeTask != null)
  313. {
  314. earthQuakeTask.cancel(false);
  315. earthQuakeTask = null;
  316. }
  317. DimensionalRiftManager.getInstance().getRoom(_type, _choosenRoom).unspawn().setPartyInside(false);
  318. DimensionalRiftManager.getInstance().killRift(this);
  319. }
  320. public Timer getTeleportTimer()
  321. {
  322. return teleporterTimer;
  323. }
  324. public TimerTask getTeleportTimerTask()
  325. {
  326. return teleporterTimerTask;
  327. }
  328. public Timer getSpawnTimer()
  329. {
  330. return spawnTimer;
  331. }
  332. public TimerTask getSpawnTimerTask()
  333. {
  334. return spawnTimerTask;
  335. }
  336. public void setTeleportTimer(Timer t)
  337. {
  338. teleporterTimer = t;
  339. }
  340. public void setTeleportTimerTask(TimerTask tt)
  341. {
  342. teleporterTimerTask = tt;
  343. }
  344. public void setSpawnTimer(Timer t)
  345. {
  346. spawnTimer = t;
  347. }
  348. public void setSpawnTimerTask(TimerTask st)
  349. {
  350. spawnTimerTask = st;
  351. }
  352. private long calcTimeToNextJump()
  353. {
  354. int time = Rnd.get(Config.RIFT_AUTO_JUMPS_TIME_MIN, Config.RIFT_AUTO_JUMPS_TIME_MAX) * 1000;
  355. if (isBossRoom)
  356. {
  357. return (long) (time * Config.RIFT_BOSS_ROOM_TIME_MUTIPLY);
  358. }
  359. return time;
  360. }
  361. public void memberDead(L2PcInstance player)
  362. {
  363. if (!_deadPlayers.contains(player))
  364. {
  365. _deadPlayers.add(player);
  366. }
  367. }
  368. public void memberRessurected(L2PcInstance player)
  369. {
  370. if (_deadPlayers.contains(player))
  371. {
  372. _deadPlayers.remove(player);
  373. }
  374. }
  375. public void usedTeleport(L2PcInstance player)
  376. {
  377. if (!_revivedInWaitingRoom.contains(player))
  378. {
  379. _revivedInWaitingRoom.add(player);
  380. }
  381. if (!_deadPlayers.contains(player))
  382. {
  383. _deadPlayers.add(player);
  384. }
  385. if ((_party.getMemberCount() - _revivedInWaitingRoom.size()) < Config.RIFT_MIN_PARTY_SIZE)
  386. {
  387. // int pcm = _party.getMemberCount();
  388. // int rev = revivedInWaitingRoom.size();
  389. // int min = Config.RIFT_MIN_PARTY_SIZE;
  390. for (L2PcInstance p : _party.getMembers())
  391. {
  392. if ((p != null) && !_revivedInWaitingRoom.contains(p))
  393. {
  394. teleportToWaitingRoom(p);
  395. }
  396. }
  397. killRift();
  398. }
  399. }
  400. public List<L2PcInstance> getDeadMemberList()
  401. {
  402. return _deadPlayers;
  403. }
  404. public List<L2PcInstance> getRevivedAtWaitingRoom()
  405. {
  406. return _revivedInWaitingRoom;
  407. }
  408. public void checkBossRoom(byte room)
  409. {
  410. isBossRoom = DimensionalRiftManager.getInstance().getRoom(_type, room).isBossRoom();
  411. }
  412. public Location getRoomCoord(byte room)
  413. {
  414. return DimensionalRiftManager.getInstance().getRoom(_type, room).getTeleportCoorinates();
  415. }
  416. public byte getMaxJumps()
  417. {
  418. if ((Config.RIFT_MAX_JUMPS <= 8) && (Config.RIFT_MAX_JUMPS >= 1))
  419. {
  420. return (byte) Config.RIFT_MAX_JUMPS;
  421. }
  422. return 4;
  423. }
  424. }