L2Object.java 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  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;
  20. import java.util.Map;
  21. import java.util.concurrent.atomic.AtomicInteger;
  22. import javolution.util.FastMap;
  23. import com.l2jserver.gameserver.enums.InstanceType;
  24. import com.l2jserver.gameserver.enums.ShotType;
  25. import com.l2jserver.gameserver.handler.ActionHandler;
  26. import com.l2jserver.gameserver.handler.ActionShiftHandler;
  27. import com.l2jserver.gameserver.handler.IActionHandler;
  28. import com.l2jserver.gameserver.idfactory.IdFactory;
  29. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  30. import com.l2jserver.gameserver.model.actor.L2Character;
  31. import com.l2jserver.gameserver.model.actor.L2Npc;
  32. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  33. import com.l2jserver.gameserver.model.actor.knownlist.ObjectKnownList;
  34. import com.l2jserver.gameserver.model.actor.poly.ObjectPoly;
  35. import com.l2jserver.gameserver.model.entity.Instance;
  36. import com.l2jserver.gameserver.model.interfaces.IDecayable;
  37. import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
  38. import com.l2jserver.gameserver.model.interfaces.ILocational;
  39. import com.l2jserver.gameserver.model.interfaces.INamable;
  40. import com.l2jserver.gameserver.model.interfaces.IPositionable;
  41. import com.l2jserver.gameserver.model.interfaces.ISpawnable;
  42. import com.l2jserver.gameserver.model.interfaces.IUniqueId;
  43. import com.l2jserver.gameserver.model.zone.ZoneId;
  44. import com.l2jserver.gameserver.network.SystemMessageId;
  45. import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
  46. import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
  47. import com.l2jserver.gameserver.network.serverpackets.ExSendUIEvent;
  48. import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
  49. import com.l2jserver.gameserver.util.Util;
  50. /**
  51. * Base class for all interactive objects.
  52. */
  53. public abstract class L2Object implements IIdentifiable, INamable, ISpawnable, IUniqueId, IDecayable, IPositionable
  54. {
  55. /** Name */
  56. private String _name;
  57. /** Object ID */
  58. private int _objectId;
  59. /** World Region */
  60. private L2WorldRegion _worldRegion;
  61. /** Instance type */
  62. private InstanceType _instanceType = null;
  63. private volatile Map<String, Object> _scripts;
  64. /** X coordinate */
  65. private final AtomicInteger _x = new AtomicInteger(0);
  66. /** Y coordinate */
  67. private final AtomicInteger _y = new AtomicInteger(0);
  68. /** Z coordinate */
  69. private final AtomicInteger _z = new AtomicInteger(0);
  70. /** Orientation */
  71. private final AtomicInteger _heading = new AtomicInteger(0);
  72. /** Instance id of object. 0 - Global */
  73. private final AtomicInteger _instanceId = new AtomicInteger(0);
  74. private boolean _isVisible;
  75. private boolean _isInvisible;
  76. private ObjectKnownList _knownList;
  77. public L2Object(int objectId)
  78. {
  79. setInstanceType(InstanceType.L2Object);
  80. _objectId = objectId;
  81. initKnownList();
  82. }
  83. /**
  84. * Gets the instance type of object.
  85. * @return the instance type
  86. */
  87. public final InstanceType getInstanceType()
  88. {
  89. return _instanceType;
  90. }
  91. /**
  92. * Sets the instance type.
  93. * @param newInstanceType the instance type to set
  94. */
  95. protected final void setInstanceType(InstanceType newInstanceType)
  96. {
  97. _instanceType = newInstanceType;
  98. }
  99. /**
  100. * Verifies if object is of any given instance types.
  101. * @param instanceTypes the instance types to verify
  102. * @return {@code true} if object is of any given instance types, {@code false} otherwise
  103. */
  104. public final boolean isInstanceTypes(InstanceType... instanceTypes)
  105. {
  106. return _instanceType.isTypes(instanceTypes);
  107. }
  108. public final void onAction(L2PcInstance player)
  109. {
  110. onAction(player, true);
  111. }
  112. public void onAction(L2PcInstance player, boolean interact)
  113. {
  114. IActionHandler handler = ActionHandler.getInstance().getHandler(getInstanceType());
  115. if (handler != null)
  116. {
  117. handler.action(player, this, interact);
  118. }
  119. player.sendPacket(ActionFailed.STATIC_PACKET);
  120. }
  121. public void onActionShift(L2PcInstance player)
  122. {
  123. IActionHandler handler = ActionShiftHandler.getInstance().getHandler(getInstanceType());
  124. if (handler != null)
  125. {
  126. handler.action(player, this, true);
  127. }
  128. player.sendPacket(ActionFailed.STATIC_PACKET);
  129. }
  130. public void onForcedAttack(L2PcInstance player)
  131. {
  132. player.sendPacket(ActionFailed.STATIC_PACKET);
  133. }
  134. public void onSpawn()
  135. {
  136. }
  137. @Override
  138. public boolean decayMe()
  139. {
  140. assert getWorldRegion() != null;
  141. L2WorldRegion reg = getWorldRegion();
  142. synchronized (this)
  143. {
  144. _isVisible = false;
  145. setWorldRegion(null);
  146. }
  147. // this can synchronize on others instances, so it's out of
  148. // synchronized, to avoid deadlocks
  149. // Remove the L2Object from the world
  150. L2World.getInstance().removeVisibleObject(this, reg);
  151. L2World.getInstance().removeObject(this);
  152. return true;
  153. }
  154. public void refreshID()
  155. {
  156. L2World.getInstance().removeObject(this);
  157. IdFactory.getInstance().releaseId(getObjectId());
  158. _objectId = IdFactory.getInstance().getNextId();
  159. }
  160. @Override
  161. public final boolean spawnMe()
  162. {
  163. assert (getWorldRegion() == null) && (getLocation().getX() != 0) && (getLocation().getY() != 0) && (getLocation().getZ() != 0);
  164. synchronized (this)
  165. {
  166. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  167. _isVisible = true;
  168. setWorldRegion(L2World.getInstance().getRegion(getLocation()));
  169. // Add the L2Object spawn in the _allobjects of L2World
  170. L2World.getInstance().storeObject(this);
  171. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  172. getWorldRegion().addVisibleObject(this);
  173. }
  174. // this can synchronize on others instances, so it's out of synchronized, to avoid deadlocks
  175. // Add the L2Object spawn in the world as a visible object
  176. L2World.getInstance().addVisibleObject(this, getWorldRegion());
  177. onSpawn();
  178. return true;
  179. }
  180. public final void spawnMe(int x, int y, int z)
  181. {
  182. assert getWorldRegion() == null;
  183. synchronized (this)
  184. {
  185. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  186. _isVisible = true;
  187. if (x > L2World.MAP_MAX_X)
  188. {
  189. x = L2World.MAP_MAX_X - 5000;
  190. }
  191. if (x < L2World.MAP_MIN_X)
  192. {
  193. x = L2World.MAP_MIN_X + 5000;
  194. }
  195. if (y > L2World.MAP_MAX_Y)
  196. {
  197. y = L2World.MAP_MAX_Y - 5000;
  198. }
  199. if (y < L2World.MAP_MIN_Y)
  200. {
  201. y = L2World.MAP_MIN_Y + 5000;
  202. }
  203. setXYZ(x, y, z);
  204. setWorldRegion(L2World.getInstance().getRegion(getLocation()));
  205. // Add the L2Object spawn in the _allobjects of L2World
  206. }
  207. L2World.getInstance().storeObject(this);
  208. // these can synchronize on others instances, so they're out of
  209. // synchronized, to avoid deadlocks
  210. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  211. getWorldRegion().addVisibleObject(this);
  212. // Add the L2Object spawn in the world as a visible object
  213. L2World.getInstance().addVisibleObject(this, getWorldRegion());
  214. onSpawn();
  215. }
  216. /**
  217. * Verify if object can be attacked.
  218. * @return {@code true} if object can be attacked, {@code false} otherwise
  219. */
  220. public boolean canBeAttacked()
  221. {
  222. return false;
  223. }
  224. public abstract boolean isAutoAttackable(L2Character attacker);
  225. public final boolean isVisible()
  226. {
  227. return getWorldRegion() != null;
  228. }
  229. public final void setIsVisible(boolean value)
  230. {
  231. _isVisible = value;
  232. if (!_isVisible)
  233. {
  234. setWorldRegion(null);
  235. }
  236. }
  237. public void toggleVisible()
  238. {
  239. if (isVisible())
  240. {
  241. decayMe();
  242. }
  243. else
  244. {
  245. spawnMe();
  246. }
  247. }
  248. public ObjectKnownList getKnownList()
  249. {
  250. return _knownList;
  251. }
  252. public void initKnownList()
  253. {
  254. _knownList = new ObjectKnownList(this);
  255. }
  256. public final void setKnownList(ObjectKnownList value)
  257. {
  258. _knownList = value;
  259. }
  260. @Override
  261. public String getName()
  262. {
  263. return _name;
  264. }
  265. public void setName(String value)
  266. {
  267. _name = value;
  268. }
  269. @Override
  270. public final int getObjectId()
  271. {
  272. return _objectId;
  273. }
  274. public final ObjectPoly getPoly()
  275. {
  276. final ObjectPoly poly = getScript(ObjectPoly.class);
  277. return (poly == null) ? addScript(new ObjectPoly(this)) : poly;
  278. }
  279. public abstract void sendInfo(L2PcInstance activeChar);
  280. public void sendPacket(L2GameServerPacket mov)
  281. {
  282. }
  283. public void sendPacket(SystemMessageId id)
  284. {
  285. }
  286. public L2PcInstance getActingPlayer()
  287. {
  288. return null;
  289. }
  290. /**
  291. * Verify if object is instance of L2Attackable.
  292. * @return {@code true} if object is instance of L2Attackable, {@code false} otherwise
  293. */
  294. public boolean isAttackable()
  295. {
  296. return false;
  297. }
  298. /**
  299. * Verify if object is instance of L2Character.
  300. * @return {@code true} if object is instance of L2Character, {@code false} otherwise
  301. */
  302. public boolean isCharacter()
  303. {
  304. return false;
  305. }
  306. /**
  307. * Verify if object is instance of L2DoorInstance.
  308. * @return {@code true} if object is instance of L2DoorInstance, {@code false} otherwise
  309. */
  310. public boolean isDoor()
  311. {
  312. return false;
  313. }
  314. /**
  315. * Verify if object is instance of L2MonsterInstance.
  316. * @return {@code true} if object is instance of L2MonsterInstance, {@code false} otherwise
  317. */
  318. public boolean isMonster()
  319. {
  320. return false;
  321. }
  322. /**
  323. * Verify if object is instance of L2Npc.
  324. * @return {@code true} if object is instance of L2Npc, {@code false} otherwise
  325. */
  326. public boolean isNpc()
  327. {
  328. return false;
  329. }
  330. /**
  331. * Verify if object is instance of L2PetInstance.
  332. * @return {@code true} if object is instance of L2PetInstance, {@code false} otherwise
  333. */
  334. public boolean isPet()
  335. {
  336. return false;
  337. }
  338. /**
  339. * Verify if object is instance of L2PcInstance.
  340. * @return {@code true} if object is instance of L2PcInstance, {@code false} otherwise
  341. */
  342. public boolean isPlayer()
  343. {
  344. return false;
  345. }
  346. /**
  347. * Verify if object is instance of L2Playable.
  348. * @return {@code true} if object is instance of L2Playable, {@code false} otherwise
  349. */
  350. public boolean isPlayable()
  351. {
  352. return false;
  353. }
  354. /**
  355. * Verify if object is instance of L2ServitorInstance.
  356. * @return {@code true} if object is instance of L2ServitorInstance, {@code false} otherwise
  357. */
  358. public boolean isServitor()
  359. {
  360. return false;
  361. }
  362. /**
  363. * Verify if object is instance of L2Summon.
  364. * @return {@code true} if object is instance of L2Summon, {@code false} otherwise
  365. */
  366. public boolean isSummon()
  367. {
  368. return false;
  369. }
  370. /**
  371. * Verify if object is instance of L2TrapInstance.
  372. * @return {@code true} if object is instance of L2TrapInstance, {@code false} otherwise
  373. */
  374. public boolean isTrap()
  375. {
  376. return false;
  377. }
  378. /**
  379. * Verify if object is instance of L2ItemInstance.
  380. * @return {@code true} if object is instance of L2ItemInstance, {@code false} otherwise
  381. */
  382. public boolean isItem()
  383. {
  384. return false;
  385. }
  386. /**
  387. * @return {@code true} if object Npc Walker or Vehicle
  388. */
  389. public boolean isWalker()
  390. {
  391. return false;
  392. }
  393. /**
  394. * @return {@code true} if object Can be targeted
  395. */
  396. public boolean isTargetable()
  397. {
  398. return true;
  399. }
  400. /**
  401. * Check if the object is in the given zone Id.
  402. * @param zone the zone Id to check
  403. * @return {@code true} if the object is in that zone Id
  404. */
  405. public boolean isInsideZone(ZoneId zone)
  406. {
  407. return false;
  408. }
  409. /**
  410. * Check if current object has charged shot.
  411. * @param type of the shot to be checked.
  412. * @return {@code true} if the object has charged shot
  413. */
  414. public boolean isChargedShot(ShotType type)
  415. {
  416. return false;
  417. }
  418. /**
  419. * Charging shot into the current object.
  420. * @param type of the shot to be charged.
  421. * @param charged
  422. */
  423. public void setChargedShot(ShotType type, boolean charged)
  424. {
  425. }
  426. /**
  427. * Try to recharge a shot.
  428. * @param physical skill are using Soul shots.
  429. * @param magical skill are using Spirit shots.
  430. */
  431. public void rechargeShots(boolean physical, boolean magical)
  432. {
  433. }
  434. /**
  435. * @param <T>
  436. * @param script
  437. * @return
  438. */
  439. public final <T> T addScript(T script)
  440. {
  441. if (_scripts == null)
  442. {
  443. // Double-checked locking
  444. synchronized (this)
  445. {
  446. if (_scripts == null)
  447. {
  448. _scripts = new FastMap<String, Object>().shared();
  449. }
  450. }
  451. }
  452. _scripts.put(script.getClass().getName(), script);
  453. return script;
  454. }
  455. /**
  456. * @param <T>
  457. * @param script
  458. * @return
  459. */
  460. @SuppressWarnings("unchecked")
  461. public final <T> T removeScript(Class<T> script)
  462. {
  463. if (_scripts == null)
  464. {
  465. return null;
  466. }
  467. return (T) _scripts.remove(script.getName());
  468. }
  469. /**
  470. * @param <T>
  471. * @param script
  472. * @return
  473. */
  474. @SuppressWarnings("unchecked")
  475. public final <T> T getScript(Class<T> script)
  476. {
  477. if (_scripts == null)
  478. {
  479. return null;
  480. }
  481. return (T) _scripts.get(script.getName());
  482. }
  483. public void removeStatusListener(L2Character object)
  484. {
  485. }
  486. protected void badCoords()
  487. {
  488. if (isCharacter())
  489. {
  490. decayMe();
  491. }
  492. else if (isPlayer())
  493. {
  494. ((L2Character) this).teleToLocation(new Location(0, 0, 0), false);
  495. ((L2Character) this).sendMessage("Error with your coords, Please ask a GM for help!");
  496. }
  497. }
  498. public final void setXYZInvisible(int x, int y, int z)
  499. {
  500. assert getWorldRegion() == null;
  501. if (x > L2World.MAP_MAX_X)
  502. {
  503. x = L2World.MAP_MAX_X - 5000;
  504. }
  505. if (x < L2World.MAP_MIN_X)
  506. {
  507. x = L2World.MAP_MIN_X + 5000;
  508. }
  509. if (y > L2World.MAP_MAX_Y)
  510. {
  511. y = L2World.MAP_MAX_Y - 5000;
  512. }
  513. if (y < L2World.MAP_MIN_Y)
  514. {
  515. y = L2World.MAP_MIN_Y + 5000;
  516. }
  517. setXYZ(x, y, z);
  518. setIsVisible(false);
  519. }
  520. public final void setLocationInvisible(ILocational loc)
  521. {
  522. setXYZInvisible(loc.getX(), loc.getY(), loc.getZ());
  523. }
  524. public void updateWorldRegion()
  525. {
  526. if (!isVisible())
  527. {
  528. return;
  529. }
  530. L2WorldRegion newRegion = L2World.getInstance().getRegion(getLocation());
  531. if (newRegion != getWorldRegion())
  532. {
  533. getWorldRegion().removeVisibleObject(this);
  534. setWorldRegion(newRegion);
  535. // Add the L2Oject spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  536. getWorldRegion().addVisibleObject(this);
  537. }
  538. }
  539. public final L2WorldRegion getWorldRegion()
  540. {
  541. return _worldRegion;
  542. }
  543. public void setWorldRegion(L2WorldRegion value)
  544. {
  545. if ((getWorldRegion() != null) && isCharacter()) // confirm revalidation of old region's zones
  546. {
  547. if (value != null)
  548. {
  549. getWorldRegion().revalidateZones((L2Character) this); // at world region change
  550. }
  551. else
  552. {
  553. getWorldRegion().removeFromZones((L2Character) this); // at world region change
  554. }
  555. }
  556. _worldRegion = value;
  557. }
  558. /**
  559. * Gets the X coordinate.
  560. * @return the X coordinate
  561. */
  562. @Override
  563. public int getX()
  564. {
  565. return _x.get();
  566. }
  567. /**
  568. * Gets the Y coordinate.
  569. * @return the Y coordinate
  570. */
  571. @Override
  572. public int getY()
  573. {
  574. return _y.get();
  575. }
  576. /**
  577. * Gets the Z coordinate.
  578. * @return the Z coordinate
  579. */
  580. @Override
  581. public int getZ()
  582. {
  583. return _z.get();
  584. }
  585. /**
  586. * Gets the heading.
  587. * @return the heading
  588. */
  589. @Override
  590. public int getHeading()
  591. {
  592. return _heading.get();
  593. }
  594. /**
  595. * Gets the instance ID.
  596. * @return the instance ID
  597. */
  598. @Override
  599. public int getInstanceId()
  600. {
  601. return _instanceId.get();
  602. }
  603. /**
  604. * Gets the location object.
  605. * @return the location object
  606. */
  607. @Override
  608. public Location getLocation()
  609. {
  610. return new Location(getX(), getY(), getZ(), getHeading(), getInstanceId());
  611. }
  612. /**
  613. * Sets the X coordinate
  614. * @param newX the X coordinate
  615. */
  616. @Override
  617. public void setX(int newX)
  618. {
  619. _x.set(newX);
  620. }
  621. /**
  622. * Sets the Y coordinate
  623. * @param newY the Y coordinate
  624. */
  625. @Override
  626. public void setY(int newY)
  627. {
  628. _y.set(newY);
  629. }
  630. /**
  631. * Sets the Z coordinate
  632. * @param newZ the Z coordinate
  633. */
  634. @Override
  635. public void setZ(int newZ)
  636. {
  637. _z.set(newZ);
  638. }
  639. /**
  640. * Sets the x, y, z coordinate.
  641. * @param newX the X coordinate
  642. * @param newY the Y coordinate
  643. * @param newZ the Z coordinate
  644. */
  645. @Override
  646. public final void setXYZ(int newX, int newY, int newZ)
  647. {
  648. assert getWorldRegion() != null;
  649. setX(newX);
  650. setY(newY);
  651. setZ(newZ);
  652. try
  653. {
  654. if (L2World.getInstance().getRegion(getLocation()) != getWorldRegion())
  655. {
  656. updateWorldRegion();
  657. }
  658. }
  659. catch (Exception e)
  660. {
  661. badCoords();
  662. }
  663. }
  664. /**
  665. * Sets the x, y, z coordinate.
  666. * @param loc the location object
  667. */
  668. @Override
  669. public void setXYZ(ILocational loc)
  670. {
  671. setXYZ(loc.getX(), loc.getY(), loc.getZ());
  672. }
  673. /**
  674. * Sets heading of object.
  675. * @param newHeading the new heading
  676. */
  677. @Override
  678. public void setHeading(int newHeading)
  679. {
  680. _heading.set(newHeading);
  681. }
  682. /**
  683. * Sets the instance ID of object.<br>
  684. * 0 - Global<br>
  685. * TODO: Add listener here.
  686. * @param instanceId the ID of the instance
  687. */
  688. @Override
  689. public void setInstanceId(int instanceId)
  690. {
  691. if ((instanceId < 0) || (getInstanceId() == instanceId))
  692. {
  693. return;
  694. }
  695. Instance oldI = InstanceManager.getInstance().getInstance(getInstanceId());
  696. Instance newI = InstanceManager.getInstance().getInstance(instanceId);
  697. if (newI == null)
  698. {
  699. return;
  700. }
  701. if (isPlayer())
  702. {
  703. final L2PcInstance player = getActingPlayer();
  704. if ((getInstanceId() > 0) && (oldI != null))
  705. {
  706. oldI.removePlayer(getObjectId());
  707. if (oldI.isShowTimer())
  708. {
  709. sendInstanceUpdate(oldI, true);
  710. }
  711. }
  712. if (instanceId > 0)
  713. {
  714. newI.addPlayer(getObjectId());
  715. if (newI.isShowTimer())
  716. {
  717. sendInstanceUpdate(newI, false);
  718. }
  719. }
  720. if (player.hasSummon())
  721. {
  722. player.getSummon().setInstanceId(instanceId);
  723. }
  724. }
  725. else if (isNpc())
  726. {
  727. final L2Npc npc = (L2Npc) this;
  728. if ((getInstanceId() > 0) && (oldI != null))
  729. {
  730. oldI.removeNpc(npc);
  731. }
  732. if (instanceId > 0)
  733. {
  734. newI.addNpc(npc);
  735. }
  736. }
  737. _instanceId.set(instanceId);
  738. if (_isVisible && (_knownList != null))
  739. {
  740. // We don't want some ugly looking disappear/appear effects, so don't update
  741. // the knownlist here, but players usually enter instancezones through teleporting
  742. // and the teleport will do the revalidation for us.
  743. if (!isPlayer())
  744. {
  745. decayMe();
  746. spawnMe();
  747. }
  748. }
  749. }
  750. /**
  751. * Sets location of object.
  752. * @param loc the location object
  753. */
  754. @Override
  755. public void setLocation(Location loc)
  756. {
  757. _x.set(loc.getX());
  758. _y.set(loc.getY());
  759. _z.set(loc.getZ());
  760. _heading.set(loc.getHeading());
  761. _instanceId.set(loc.getInstanceId());
  762. }
  763. /**
  764. * Calculates distance between this L2Object and given x, y , z.
  765. * @param x the X coordinate
  766. * @param y the Y coordinate
  767. * @param z the Z coordinate
  768. * @param includeZAxis if {@code true} Z axis will be included
  769. * @param squared if {@code true} return will be squared
  770. * @return distance between object and given x, y, z.
  771. */
  772. public final double calculateDistance(int x, int y, int z, boolean includeZAxis, boolean squared)
  773. {
  774. final double distance = Math.pow(x - getX(), 2) + Math.pow(y - getY(), 2) + (includeZAxis ? Math.pow(z - getZ(), 2) : 0);
  775. return (squared) ? distance : Math.sqrt(distance);
  776. }
  777. /**
  778. * Calculates distance between this L2Object and given location.
  779. * @param loc the location object
  780. * @param includeZAxis if {@code true} Z axis will be included
  781. * @param squared if {@code true} return will be squared
  782. * @return distance between object and given location.
  783. */
  784. public final double calculateDistance(ILocational loc, boolean includeZAxis, boolean squared)
  785. {
  786. return calculateDistance(loc.getX(), loc.getY(), loc.getZ(), includeZAxis, squared);
  787. }
  788. /**
  789. * Calculates the angle in degrees from this object to the given object.<br>
  790. * The return value can be described as how much this object has to turn<br>
  791. * to have the given object directly in front of it.
  792. * @param target the object to which to calculate the angle
  793. * @return the angle this object has to turn to have the given object in front of it
  794. */
  795. public final double calculateDirectionTo(ILocational target)
  796. {
  797. int heading = Util.calculateHeadingFrom(this, target) - getHeading();
  798. if (heading < 0)
  799. {
  800. heading = 65535 + heading;
  801. }
  802. return Util.convertHeadingToDegree(heading);
  803. }
  804. /**
  805. * Sends an instance update for player.
  806. * @param instance the instance to update
  807. * @param hide if {@code true} hide the player
  808. */
  809. private final void sendInstanceUpdate(Instance instance, boolean hide)
  810. {
  811. final int startTime = (int) ((System.currentTimeMillis() - instance.getInstanceStartTime()) / 1000);
  812. final int endTime = (int) ((instance.getInstanceEndTime() - instance.getInstanceStartTime()) / 1000);
  813. if (instance.isTimerIncrease())
  814. {
  815. sendPacket(new ExSendUIEvent(getActingPlayer(), hide, true, startTime, endTime, instance.getTimerText()));
  816. }
  817. else
  818. {
  819. sendPacket(new ExSendUIEvent(getActingPlayer(), hide, false, endTime - startTime, 0, instance.getTimerText()));
  820. }
  821. }
  822. /**
  823. * @return {@code true} if this object is invisible, {@code false} otherwise.
  824. */
  825. public boolean isInvisible()
  826. {
  827. return _isInvisible;
  828. }
  829. /**
  830. * Sets this object as invisible or not
  831. * @param invis
  832. */
  833. public void setInvisible(boolean invis)
  834. {
  835. _isInvisible = invis;
  836. if (invis)
  837. {
  838. final DeleteObject deletePacket = new DeleteObject(this);
  839. for (L2Object obj : getKnownList().getKnownObjects().values())
  840. {
  841. if ((obj != null) && obj.isPlayer())
  842. {
  843. final L2PcInstance player = obj.getActingPlayer();
  844. if (!isVisibleFor(player))
  845. {
  846. obj.sendPacket(deletePacket);
  847. }
  848. }
  849. }
  850. }
  851. // Broadcast information regarding the object to those which are suppose to see.
  852. broadcastInfo();
  853. }
  854. /**
  855. * @param player
  856. * @return {@code true} if player can see an invisible object if it's invisible, {@code false} otherwise.
  857. */
  858. public boolean isVisibleFor(L2PcInstance player)
  859. {
  860. return !isInvisible() || player.canOverrideCond(PcCondOverride.SEE_ALL_PLAYERS);
  861. }
  862. /**
  863. * Broadcasts describing info to known players.
  864. */
  865. public void broadcastInfo()
  866. {
  867. for (L2Object obj : getKnownList().getKnownObjects().values())
  868. {
  869. if ((obj != null) && obj.isPlayer() && isVisibleFor(obj.getActingPlayer()))
  870. {
  871. sendInfo(obj.getActingPlayer());
  872. }
  873. }
  874. }
  875. @Override
  876. public boolean equals(Object obj)
  877. {
  878. return ((obj instanceof L2Object) && (((L2Object) obj).getObjectId() == getObjectId()));
  879. }
  880. @Override
  881. public String toString()
  882. {
  883. return (getClass().getSimpleName() + ":" + getName() + "[" + getObjectId() + "]");
  884. }
  885. }