L2Object.java 24 KB

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