CursedWeapon.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. /*
  2. * Copyright (C) 2004-2013 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;
  20. import java.sql.Connection;
  21. import java.sql.PreparedStatement;
  22. import java.sql.SQLException;
  23. import java.util.concurrent.ScheduledFuture;
  24. import java.util.logging.Level;
  25. import java.util.logging.Logger;
  26. import com.l2jserver.Config;
  27. import com.l2jserver.L2DatabaseFactory;
  28. import com.l2jserver.gameserver.ThreadPoolManager;
  29. import com.l2jserver.gameserver.datatables.SkillTable;
  30. import com.l2jserver.gameserver.datatables.SkillTable.FrequentSkill;
  31. import com.l2jserver.gameserver.datatables.TransformData;
  32. import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager;
  33. import com.l2jserver.gameserver.model.L2Party.messageType;
  34. import com.l2jserver.gameserver.model.actor.L2Attackable;
  35. import com.l2jserver.gameserver.model.actor.L2Character;
  36. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  37. import com.l2jserver.gameserver.model.interfaces.INamable;
  38. import com.l2jserver.gameserver.model.items.L2Item;
  39. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  40. import com.l2jserver.gameserver.model.skills.L2Skill;
  41. import com.l2jserver.gameserver.network.SystemMessageId;
  42. import com.l2jserver.gameserver.network.serverpackets.Earthquake;
  43. import com.l2jserver.gameserver.network.serverpackets.ExRedSky;
  44. import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
  45. import com.l2jserver.gameserver.network.serverpackets.ItemList;
  46. import com.l2jserver.gameserver.network.serverpackets.SocialAction;
  47. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  48. import com.l2jserver.gameserver.network.serverpackets.UserInfo;
  49. import com.l2jserver.gameserver.util.Broadcast;
  50. import com.l2jserver.gameserver.util.Point3D;
  51. import com.l2jserver.util.Rnd;
  52. public class CursedWeapon implements INamable
  53. {
  54. private static final Logger _log = Logger.getLogger(CursedWeapon.class.getName());
  55. // _name is the name of the cursed weapon associated with its ID.
  56. private final String _name;
  57. // _itemId is the Item ID of the cursed weapon.
  58. private final int _itemId;
  59. // _skillId is the skills ID.
  60. private final int _skillId;
  61. private final int _skillMaxLevel;
  62. private int _dropRate;
  63. private int _duration;
  64. private int _durationLost;
  65. private int _disapearChance;
  66. private int _stageKills;
  67. // this should be false unless if the cursed weapon is dropped, in that case it would be true.
  68. private boolean _isDropped = false;
  69. // this sets the cursed weapon status to true only if a player has the cursed weapon, otherwise this should be false.
  70. private boolean _isActivated = false;
  71. private ScheduledFuture<?> _removeTask;
  72. private int _nbKills = 0;
  73. private long _endTime = 0;
  74. private int _playerId = 0;
  75. protected L2PcInstance _player = null;
  76. private L2ItemInstance _item = null;
  77. private int _playerKarma = 0;
  78. private int _playerPkKills = 0;
  79. protected int transformationId = 0;
  80. public CursedWeapon(int itemId, int skillId, String name)
  81. {
  82. _name = name;
  83. _itemId = itemId;
  84. _skillId = skillId;
  85. _skillMaxLevel = SkillTable.getInstance().getMaxLevel(_skillId);
  86. }
  87. public void endOfLife()
  88. {
  89. if (_isActivated)
  90. {
  91. if ((_player != null) && _player.isOnline())
  92. {
  93. // Remove from player
  94. _log.info(_name + " being removed online.");
  95. _player.abortAttack();
  96. _player.setKarma(_playerKarma);
  97. _player.setPkKills(_playerPkKills);
  98. _player.setCursedWeaponEquippedId(0);
  99. removeSkill();
  100. // Remove
  101. _player.getInventory().unEquipItemInBodySlot(L2Item.SLOT_LR_HAND);
  102. _player.storeMe();
  103. // Destroy
  104. L2ItemInstance removedItem = _player.getInventory().destroyItemByItemId("", _itemId, 1, _player, null);
  105. if (!Config.FORCE_INVENTORY_UPDATE)
  106. {
  107. InventoryUpdate iu = new InventoryUpdate();
  108. if (removedItem.getCount() == 0)
  109. {
  110. iu.addRemovedItem(removedItem);
  111. }
  112. else
  113. {
  114. iu.addModifiedItem(removedItem);
  115. }
  116. _player.sendPacket(iu);
  117. }
  118. else
  119. {
  120. _player.sendPacket(new ItemList(_player, true));
  121. }
  122. _player.broadcastUserInfo();
  123. }
  124. else
  125. {
  126. // Remove from Db
  127. _log.info(_name + " being removed offline.");
  128. try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  129. PreparedStatement del = con.prepareStatement("DELETE FROM items WHERE owner_id=? AND item_id=?");
  130. PreparedStatement ps = con.prepareStatement("UPDATE characters SET karma=?, pkkills=? WHERE charId=?"))
  131. {
  132. // Delete the item
  133. del.setInt(1, _playerId);
  134. del.setInt(2, _itemId);
  135. if (del.executeUpdate() != 1)
  136. {
  137. _log.warning("Error while deleting itemId " + _itemId + " from userId " + _playerId);
  138. }
  139. // Restore the karma
  140. ps.setInt(1, _playerKarma);
  141. ps.setInt(2, _playerPkKills);
  142. ps.setInt(3, _playerId);
  143. if (ps.executeUpdate() != 1)
  144. {
  145. _log.warning("Error while updating karma & pkkills for userId " + _playerId);
  146. }
  147. }
  148. catch (Exception e)
  149. {
  150. _log.log(Level.WARNING, "Could not delete : " + e.getMessage(), e);
  151. }
  152. }
  153. }
  154. else
  155. {
  156. // either this cursed weapon is in the inventory of someone who has another cursed weapon equipped,
  157. // OR this cursed weapon is on the ground.
  158. if ((_player != null) && (_player.getInventory().getItemByItemId(_itemId) != null))
  159. {
  160. // Destroy
  161. L2ItemInstance removedItem = _player.getInventory().destroyItemByItemId("", _itemId, 1, _player, null);
  162. if (!Config.FORCE_INVENTORY_UPDATE)
  163. {
  164. InventoryUpdate iu = new InventoryUpdate();
  165. if (removedItem.getCount() == 0)
  166. {
  167. iu.addRemovedItem(removedItem);
  168. }
  169. else
  170. {
  171. iu.addModifiedItem(removedItem);
  172. }
  173. _player.sendPacket(iu);
  174. }
  175. else
  176. {
  177. _player.sendPacket(new ItemList(_player, true));
  178. }
  179. _player.broadcastUserInfo();
  180. }
  181. // is dropped on the ground
  182. else if (_item != null)
  183. {
  184. _item.decayMe();
  185. L2World.getInstance().removeObject(_item);
  186. _log.info(_name + " item has been removed from World.");
  187. }
  188. }
  189. // Delete infos from table if any
  190. CursedWeaponsManager.removeFromDb(_itemId);
  191. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_DISAPPEARED);
  192. sm.addItemName(_itemId);
  193. CursedWeaponsManager.announce(sm);
  194. // Reset state
  195. cancelTask();
  196. _isActivated = false;
  197. _isDropped = false;
  198. _endTime = 0;
  199. _player = null;
  200. _playerId = 0;
  201. _playerKarma = 0;
  202. _playerPkKills = 0;
  203. _item = null;
  204. _nbKills = 0;
  205. }
  206. private void cancelTask()
  207. {
  208. if (_removeTask != null)
  209. {
  210. _removeTask.cancel(true);
  211. _removeTask = null;
  212. }
  213. }
  214. private class RemoveTask implements Runnable
  215. {
  216. protected RemoveTask()
  217. {
  218. }
  219. @Override
  220. public void run()
  221. {
  222. if (System.currentTimeMillis() >= getEndTime())
  223. {
  224. endOfLife();
  225. }
  226. }
  227. }
  228. private void dropIt(L2Attackable attackable, L2PcInstance player)
  229. {
  230. dropIt(attackable, player, null, true);
  231. }
  232. private void dropIt(L2Attackable attackable, L2PcInstance player, L2Character killer, boolean fromMonster)
  233. {
  234. _isActivated = false;
  235. if (fromMonster)
  236. {
  237. _item = attackable.dropItem(player, _itemId, 1);
  238. _item.setDropTime(0); // Prevent item from being removed by ItemsAutoDestroy
  239. // RedSky and Earthquake
  240. ExRedSky packet = new ExRedSky(10);
  241. Earthquake eq = new Earthquake(player.getX(), player.getY(), player.getZ(), 14, 3);
  242. Broadcast.toAllOnlinePlayers(packet);
  243. Broadcast.toAllOnlinePlayers(eq);
  244. }
  245. else
  246. {
  247. _item = _player.getInventory().getItemByItemId(_itemId);
  248. _player.dropItem("DieDrop", _item, killer, true);
  249. _player.setKarma(_playerKarma);
  250. _player.setPkKills(_playerPkKills);
  251. _player.setCursedWeaponEquippedId(0);
  252. removeSkill();
  253. _player.abortAttack();
  254. // L2ItemInstance item = _player.getInventory().getItemByItemId(_itemId);
  255. // _player.getInventory().dropItem("DieDrop", item, _player, null);
  256. // _player.getInventory().getItemByItemId(_itemId).dropMe(_player, _player.getX(), _player.getY(), _player.getZ());
  257. }
  258. _isDropped = true;
  259. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S2_WAS_DROPPED_IN_THE_S1_REGION);
  260. if (player != null)
  261. {
  262. sm.addZoneName(player.getX(), player.getY(), player.getZ()); // Region Name
  263. }
  264. else if (_player != null)
  265. {
  266. sm.addZoneName(_player.getX(), _player.getY(), _player.getZ()); // Region Name
  267. }
  268. else
  269. {
  270. sm.addZoneName(killer.getX(), killer.getY(), killer.getZ()); // Region Name
  271. }
  272. sm.addItemName(_itemId);
  273. CursedWeaponsManager.announce(sm); // in the Hot Spring region
  274. }
  275. public void cursedOnLogin()
  276. {
  277. doTransform();
  278. giveSkill();
  279. SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.S2_OWNER_HAS_LOGGED_INTO_THE_S1_REGION);
  280. msg.addZoneName(_player.getX(), _player.getY(), _player.getZ());
  281. msg.addItemName(_player.getCursedWeaponEquippedId());
  282. CursedWeaponsManager.announce(msg);
  283. CursedWeapon cw = CursedWeaponsManager.getInstance().getCursedWeapon(_player.getCursedWeaponEquippedId());
  284. SystemMessage msg2 = SystemMessage.getSystemMessage(SystemMessageId.S2_MINUTE_OF_USAGE_TIME_ARE_LEFT_FOR_S1);
  285. int timeLeft = (int) (cw.getTimeLeft() / 60000);
  286. msg2.addItemName(_player.getCursedWeaponEquippedId());
  287. msg2.addNumber(timeLeft);
  288. _player.sendPacket(msg2);
  289. }
  290. /**
  291. * Yesod:<br>
  292. * Rebind the passive skill belonging to the CursedWeapon. Invoke this method if the weapon owner switches to a subclass.
  293. */
  294. public void giveSkill()
  295. {
  296. int level = 1 + (_nbKills / _stageKills);
  297. if (level > _skillMaxLevel)
  298. {
  299. level = _skillMaxLevel;
  300. }
  301. final L2Skill skill = SkillTable.getInstance().getInfo(_skillId, level);
  302. _player.addSkill(skill, false);
  303. // Void Burst, Void Flow
  304. _player.addSkill(FrequentSkill.VOID_BURST.getSkill(), false);
  305. _player.addTransformSkill(FrequentSkill.VOID_BURST.getId());
  306. _player.addSkill(FrequentSkill.VOID_FLOW.getSkill(), false);
  307. _player.addTransformSkill(FrequentSkill.VOID_FLOW.getId());
  308. _player.sendSkillList();
  309. }
  310. public void doTransform()
  311. {
  312. if (_itemId == 8689)
  313. {
  314. transformationId = 302;
  315. }
  316. else if (_itemId == 8190)
  317. {
  318. transformationId = 301;
  319. }
  320. if (_player.isTransformed() || _player.isInStance())
  321. {
  322. _player.stopTransformation(true);
  323. ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
  324. {
  325. @Override
  326. public void run()
  327. {
  328. TransformData.getInstance().transformPlayer(transformationId, _player);
  329. }
  330. }, 500);
  331. }
  332. else
  333. {
  334. TransformData.getInstance().transformPlayer(transformationId, _player);
  335. }
  336. }
  337. public void removeSkill()
  338. {
  339. _player.removeSkill(_skillId);
  340. _player.removeSkill(SkillTable.FrequentSkill.VOID_BURST.getSkill().getId());
  341. _player.removeSkill(SkillTable.FrequentSkill.VOID_FLOW.getSkill().getId());
  342. _player.untransform();
  343. _player.sendSkillList();
  344. }
  345. public void reActivate()
  346. {
  347. _isActivated = true;
  348. if ((_endTime - System.currentTimeMillis()) <= 0)
  349. {
  350. endOfLife();
  351. }
  352. else
  353. {
  354. _removeTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new RemoveTask(), _durationLost * 12000L, _durationLost * 12000L);
  355. }
  356. }
  357. public boolean checkDrop(L2Attackable attackable, L2PcInstance player)
  358. {
  359. if (Rnd.get(100000) < _dropRate)
  360. {
  361. // Drop the item
  362. dropIt(attackable, player);
  363. // Start the Life Task
  364. _endTime = System.currentTimeMillis() + (_duration * 60000L);
  365. _removeTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new RemoveTask(), _durationLost * 12000L, _durationLost * 12000L);
  366. return true;
  367. }
  368. return false;
  369. }
  370. public void activate(L2PcInstance player, L2ItemInstance item)
  371. {
  372. // If the player is mounted, attempt to unmount first.
  373. // Only allow picking up the cursed weapon if unmounting is successful.
  374. if (player.isMounted() && !player.dismount())
  375. {
  376. // TODO: Verify the following system message, may still be custom.
  377. player.sendPacket(SystemMessageId.FAILED_TO_PICKUP_S1);
  378. player.dropItem("InvDrop", item, null, true);
  379. return;
  380. }
  381. _isActivated = true;
  382. // Player holding it data
  383. _player = player;
  384. _playerId = _player.getObjectId();
  385. _playerKarma = _player.getKarma();
  386. _playerPkKills = _player.getPkKills();
  387. saveData();
  388. // Change player stats
  389. _player.setCursedWeaponEquippedId(_itemId);
  390. _player.setKarma(9999999);
  391. _player.setPkKills(0);
  392. if (_player.isInParty())
  393. {
  394. _player.getParty().removePartyMember(_player, messageType.Expelled);
  395. }
  396. // Disable All Skills
  397. // Do Transform
  398. doTransform();
  399. // Add skill
  400. giveSkill();
  401. // Equip with the weapon
  402. _item = item;
  403. // L2ItemInstance[] items =
  404. _player.getInventory().equipItem(_item);
  405. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_EQUIPPED);
  406. sm.addItemName(_item);
  407. _player.sendPacket(sm);
  408. // Fully heal player
  409. _player.setCurrentHpMp(_player.getMaxHp(), _player.getMaxMp());
  410. _player.setCurrentCp(_player.getMaxCp());
  411. // Refresh inventory
  412. if (!Config.FORCE_INVENTORY_UPDATE)
  413. {
  414. InventoryUpdate iu = new InventoryUpdate();
  415. iu.addItem(_item);
  416. // iu.addItems(Arrays.asList(items));
  417. _player.sendPacket(iu);
  418. }
  419. else
  420. {
  421. _player.sendPacket(new ItemList(_player, false));
  422. }
  423. // Refresh player stats
  424. _player.broadcastUserInfo();
  425. SocialAction atk = new SocialAction(_player.getObjectId(), 17);
  426. _player.broadcastPacket(atk);
  427. sm = SystemMessage.getSystemMessage(SystemMessageId.THE_OWNER_OF_S2_HAS_APPEARED_IN_THE_S1_REGION);
  428. sm.addZoneName(_player.getX(), _player.getY(), _player.getZ()); // Region Name
  429. sm.addItemName(_item);
  430. CursedWeaponsManager.announce(sm);
  431. }
  432. public void saveData()
  433. {
  434. if (Config.DEBUG)
  435. {
  436. _log.info("CursedWeapon: Saving data to disk.");
  437. }
  438. try (Connection con = L2DatabaseFactory.getInstance().getConnection();
  439. PreparedStatement del = con.prepareStatement("DELETE FROM cursed_weapons WHERE itemId = ?");
  440. PreparedStatement ps = con.prepareStatement("INSERT INTO cursed_weapons (itemId, charId, playerKarma, playerPkKills, nbKills, endTime) VALUES (?, ?, ?, ?, ?, ?)"))
  441. {
  442. // Delete previous datas
  443. del.setInt(1, _itemId);
  444. del.executeUpdate();
  445. if (_isActivated)
  446. {
  447. ps.setInt(1, _itemId);
  448. ps.setInt(2, _playerId);
  449. ps.setInt(3, _playerKarma);
  450. ps.setInt(4, _playerPkKills);
  451. ps.setInt(5, _nbKills);
  452. ps.setLong(6, _endTime);
  453. ps.executeUpdate();
  454. }
  455. }
  456. catch (SQLException e)
  457. {
  458. _log.log(Level.SEVERE, "CursedWeapon: Failed to save data.", e);
  459. }
  460. }
  461. public void dropIt(L2Character killer)
  462. {
  463. if (Rnd.get(100) <= _disapearChance)
  464. {
  465. // Remove it
  466. endOfLife();
  467. }
  468. else
  469. {
  470. // Unequip & Drop
  471. dropIt(null, null, killer, false);
  472. // Reset player stats
  473. _player.setKarma(_playerKarma);
  474. _player.setPkKills(_playerPkKills);
  475. _player.setCursedWeaponEquippedId(0);
  476. removeSkill();
  477. _player.abortAttack();
  478. _player.broadcastUserInfo();
  479. }
  480. }
  481. public void increaseKills()
  482. {
  483. _nbKills++;
  484. if ((_player != null) && _player.isOnline())
  485. {
  486. _player.setPkKills(_nbKills);
  487. _player.sendPacket(new UserInfo(_player));
  488. if (((_nbKills % _stageKills) == 0) && (_nbKills <= (_stageKills * (_skillMaxLevel - 1))))
  489. {
  490. giveSkill();
  491. }
  492. }
  493. // Reduce time-to-live
  494. _endTime -= _durationLost * 60000L;
  495. saveData();
  496. }
  497. public void setDisapearChance(int disapearChance)
  498. {
  499. _disapearChance = disapearChance;
  500. }
  501. public void setDropRate(int dropRate)
  502. {
  503. _dropRate = dropRate;
  504. }
  505. public void setDuration(int duration)
  506. {
  507. _duration = duration;
  508. }
  509. public void setDurationLost(int durationLost)
  510. {
  511. _durationLost = durationLost;
  512. }
  513. public void setStageKills(int stageKills)
  514. {
  515. _stageKills = stageKills;
  516. }
  517. public void setNbKills(int nbKills)
  518. {
  519. _nbKills = nbKills;
  520. }
  521. public void setPlayerId(int playerId)
  522. {
  523. _playerId = playerId;
  524. }
  525. public void setPlayerKarma(int playerKarma)
  526. {
  527. _playerKarma = playerKarma;
  528. }
  529. public void setPlayerPkKills(int playerPkKills)
  530. {
  531. _playerPkKills = playerPkKills;
  532. }
  533. public void setActivated(boolean isActivated)
  534. {
  535. _isActivated = isActivated;
  536. }
  537. public void setDropped(boolean isDropped)
  538. {
  539. _isDropped = isDropped;
  540. }
  541. public void setEndTime(long endTime)
  542. {
  543. _endTime = endTime;
  544. }
  545. public void setPlayer(L2PcInstance player)
  546. {
  547. _player = player;
  548. }
  549. public void setItem(L2ItemInstance item)
  550. {
  551. _item = item;
  552. }
  553. public boolean isActivated()
  554. {
  555. return _isActivated;
  556. }
  557. public boolean isDropped()
  558. {
  559. return _isDropped;
  560. }
  561. public long getEndTime()
  562. {
  563. return _endTime;
  564. }
  565. @Override
  566. public String getName()
  567. {
  568. return _name;
  569. }
  570. public int getItemId()
  571. {
  572. return _itemId;
  573. }
  574. public int getSkillId()
  575. {
  576. return _skillId;
  577. }
  578. public int getPlayerId()
  579. {
  580. return _playerId;
  581. }
  582. public L2PcInstance getPlayer()
  583. {
  584. return _player;
  585. }
  586. public int getPlayerKarma()
  587. {
  588. return _playerKarma;
  589. }
  590. public int getPlayerPkKills()
  591. {
  592. return _playerPkKills;
  593. }
  594. public int getNbKills()
  595. {
  596. return _nbKills;
  597. }
  598. public int getStageKills()
  599. {
  600. return _stageKills;
  601. }
  602. public boolean isActive()
  603. {
  604. return _isActivated || _isDropped;
  605. }
  606. public int getLevel()
  607. {
  608. if (_nbKills > (_stageKills * _skillMaxLevel))
  609. {
  610. return _skillMaxLevel;
  611. }
  612. return (_nbKills / _stageKills);
  613. }
  614. public long getTimeLeft()
  615. {
  616. return _endTime - System.currentTimeMillis();
  617. }
  618. public void goTo(L2PcInstance player)
  619. {
  620. if (player == null)
  621. {
  622. return;
  623. }
  624. if (_isActivated && (_player != null))
  625. {
  626. // Go to player holding the weapon
  627. player.teleToLocation(_player.getLocation(), true);
  628. }
  629. else if (_isDropped && (_item != null))
  630. {
  631. // Go to item on the ground
  632. player.teleToLocation(_item.getLocation(), true);
  633. }
  634. else
  635. {
  636. player.sendMessage(_name + " isn't in the World.");
  637. }
  638. }
  639. public Point3D getWorldPosition()
  640. {
  641. if (_isActivated && (_player != null))
  642. {
  643. return _player.getWorldPosition();
  644. }
  645. if (_isDropped && (_item != null))
  646. {
  647. return _item.getWorldPosition();
  648. }
  649. return null;
  650. }
  651. public long getDuration()
  652. {
  653. return _duration;
  654. }
  655. }