L2Object.java 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  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. * @return {@code true} if object Npc Walker or Vehicle
  389. */
  390. public boolean isWalker()
  391. {
  392. return false;
  393. }
  394. /**
  395. * @return {@code true} if object Can be targeted
  396. */
  397. public boolean isTargetable()
  398. {
  399. return true;
  400. }
  401. /**
  402. * Check if the object is in the given zone Id.
  403. * @param zone the zone Id to check
  404. * @return {@code true} if the object is in that zone Id
  405. */
  406. public boolean isInsideZone(ZoneId zone)
  407. {
  408. return false;
  409. }
  410. /**
  411. * Check if current object has charged shot.
  412. * @param type of the shot to be checked.
  413. * @return {@code true} if the object has charged shot
  414. */
  415. public boolean isChargedShot(ShotType type)
  416. {
  417. return false;
  418. }
  419. /**
  420. * Charging shot into the current object.
  421. * @param type of the shot to be charged.
  422. * @param charged
  423. */
  424. public void setChargedShot(ShotType type, boolean charged)
  425. {
  426. }
  427. /**
  428. * Try to recharge a shot.
  429. * @param physical skill are using Soul shots.
  430. * @param magical skill are using Spirit shots.
  431. */
  432. public void rechargeShots(boolean physical, boolean magical)
  433. {
  434. }
  435. /**
  436. * @param <T>
  437. * @param script
  438. * @return
  439. */
  440. public final <T> T addScript(T script)
  441. {
  442. if (_scripts == null)
  443. {
  444. // Double-checked locking
  445. synchronized (this)
  446. {
  447. if (_scripts == null)
  448. {
  449. _scripts = new FastMap<String, Object>().shared();
  450. }
  451. }
  452. }
  453. _scripts.put(script.getClass().getName(), script);
  454. return script;
  455. }
  456. /**
  457. * @param <T>
  458. * @param script
  459. * @return
  460. */
  461. @SuppressWarnings("unchecked")
  462. public final <T> T removeScript(Class<T> script)
  463. {
  464. if (_scripts == null)
  465. {
  466. return null;
  467. }
  468. return (T) _scripts.remove(script.getName());
  469. }
  470. /**
  471. * @param <T>
  472. * @param script
  473. * @return
  474. */
  475. @SuppressWarnings("unchecked")
  476. public final <T> T getScript(Class<T> script)
  477. {
  478. if (_scripts == null)
  479. {
  480. return null;
  481. }
  482. return (T) _scripts.get(script.getName());
  483. }
  484. public void removeStatusListener(L2Character object)
  485. {
  486. }
  487. protected void badCoords()
  488. {
  489. if (isCharacter())
  490. {
  491. decayMe();
  492. }
  493. else if (isPlayer())
  494. {
  495. ((L2Character) this).teleToLocation(new Location(0, 0, 0), false);
  496. ((L2Character) this).sendMessage("Error with your coords, Please ask a GM for help!");
  497. }
  498. }
  499. public final void setXYZInvisible(int x, int y, int z)
  500. {
  501. assert getWorldRegion() == null;
  502. if (x > L2World.MAP_MAX_X)
  503. {
  504. x = L2World.MAP_MAX_X - 5000;
  505. }
  506. if (x < L2World.MAP_MIN_X)
  507. {
  508. x = L2World.MAP_MIN_X + 5000;
  509. }
  510. if (y > L2World.MAP_MAX_Y)
  511. {
  512. y = L2World.MAP_MAX_Y - 5000;
  513. }
  514. if (y < L2World.MAP_MIN_Y)
  515. {
  516. y = L2World.MAP_MIN_Y + 5000;
  517. }
  518. setXYZ(x, y, z);
  519. setIsVisible(false);
  520. }
  521. public final void setLocationInvisible(ILocational loc)
  522. {
  523. setXYZInvisible(loc.getX(), loc.getY(), loc.getZ());
  524. }
  525. public void updateWorldRegion()
  526. {
  527. if (!isVisible())
  528. {
  529. return;
  530. }
  531. L2WorldRegion newRegion = L2World.getInstance().getRegion(getLocation());
  532. if (newRegion != getWorldRegion())
  533. {
  534. getWorldRegion().removeVisibleObject(this);
  535. setWorldRegion(newRegion);
  536. // Add the L2Oject spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  537. getWorldRegion().addVisibleObject(this);
  538. }
  539. }
  540. public final L2WorldRegion getWorldRegion()
  541. {
  542. return _worldRegion;
  543. }
  544. public void setWorldRegion(L2WorldRegion value)
  545. {
  546. if ((getWorldRegion() != null) && isCharacter()) // confirm revalidation of old region's zones
  547. {
  548. if (value != null)
  549. {
  550. getWorldRegion().revalidateZones((L2Character) this); // at world region change
  551. }
  552. else
  553. {
  554. getWorldRegion().removeFromZones((L2Character) this); // at world region change
  555. }
  556. }
  557. _worldRegion = value;
  558. }
  559. /**
  560. * Gets the X coordinate.
  561. * @return the X coordinate
  562. */
  563. @Override
  564. public int getX()
  565. {
  566. return _x.get();
  567. }
  568. /**
  569. * Gets the Y coordinate.
  570. * @return the Y coordinate
  571. */
  572. @Override
  573. public int getY()
  574. {
  575. return _y.get();
  576. }
  577. /**
  578. * Gets the Z coordinate.
  579. * @return the Z coordinate
  580. */
  581. @Override
  582. public int getZ()
  583. {
  584. return _z.get();
  585. }
  586. /**
  587. * Gets the heading.
  588. * @return the heading
  589. */
  590. @Override
  591. public int getHeading()
  592. {
  593. return _heading.get();
  594. }
  595. /**
  596. * Gets the instance ID.
  597. * @return the instance ID
  598. */
  599. @Override
  600. public int getInstanceId()
  601. {
  602. return _instanceId.get();
  603. }
  604. /**
  605. * Gets the location object.
  606. * @return the location object
  607. */
  608. @Override
  609. public Location getLocation()
  610. {
  611. return new Location(getX(), getY(), getZ(), getHeading(), getInstanceId());
  612. }
  613. /**
  614. * Sets the X coordinate
  615. * @param newX the X coordinate
  616. */
  617. @Override
  618. public void setX(int newX)
  619. {
  620. _x.set(newX);
  621. }
  622. /**
  623. * Sets the Y coordinate
  624. * @param newY the Y coordinate
  625. */
  626. @Override
  627. public void setY(int newY)
  628. {
  629. _y.set(newY);
  630. }
  631. /**
  632. * Sets the Z coordinate
  633. * @param newZ the Z coordinate
  634. */
  635. @Override
  636. public void setZ(int newZ)
  637. {
  638. _z.set(newZ);
  639. }
  640. /**
  641. * Sets the x, y, z coordinate.
  642. * @param newX the X coordinate
  643. * @param newY the Y coordinate
  644. * @param newZ the Z coordinate
  645. */
  646. @Override
  647. public final void setXYZ(int newX, int newY, int newZ)
  648. {
  649. assert getWorldRegion() != null;
  650. setX(newX);
  651. setY(newY);
  652. setZ(newZ);
  653. try
  654. {
  655. if (L2World.getInstance().getRegion(getLocation()) != getWorldRegion())
  656. {
  657. updateWorldRegion();
  658. }
  659. }
  660. catch (Exception e)
  661. {
  662. badCoords();
  663. }
  664. }
  665. /**
  666. * Sets the x, y, z coordinate.
  667. * @param loc the location object
  668. */
  669. @Override
  670. public void setXYZ(ILocational loc)
  671. {
  672. setXYZ(loc.getX(), loc.getY(), loc.getZ());
  673. }
  674. /**
  675. * Sets heading of object.
  676. * @param newHeading the new heading
  677. */
  678. @Override
  679. public void setHeading(int newHeading)
  680. {
  681. _heading.set(newHeading);
  682. }
  683. /**
  684. * Sets the instance ID of object.<br>
  685. * 0 - Global<br>
  686. * TODO: Add listener here.
  687. * @param instanceId the ID of the instance
  688. */
  689. @Override
  690. public void setInstanceId(int instanceId)
  691. {
  692. if ((instanceId < 0) || (getInstanceId() == instanceId))
  693. {
  694. return;
  695. }
  696. Instance oldI = InstanceManager.getInstance().getInstance(getInstanceId());
  697. Instance newI = InstanceManager.getInstance().getInstance(instanceId);
  698. if (newI == null)
  699. {
  700. return;
  701. }
  702. if (isPlayer())
  703. {
  704. final L2PcInstance player = getActingPlayer();
  705. if ((getInstanceId() > 0) && (oldI != null))
  706. {
  707. oldI.removePlayer(getObjectId());
  708. if (oldI.isShowTimer())
  709. {
  710. sendInstanceUpdate(oldI, true);
  711. }
  712. }
  713. if (instanceId > 0)
  714. {
  715. newI.addPlayer(getObjectId());
  716. if (newI.isShowTimer())
  717. {
  718. sendInstanceUpdate(newI, false);
  719. }
  720. }
  721. if (player.hasSummon())
  722. {
  723. player.getSummon().setInstanceId(instanceId);
  724. }
  725. }
  726. else if (isNpc())
  727. {
  728. final L2Npc npc = (L2Npc) this;
  729. if ((getInstanceId() > 0) && (oldI != null))
  730. {
  731. oldI.removeNpc(npc);
  732. }
  733. if (instanceId > 0)
  734. {
  735. newI.addNpc(npc);
  736. }
  737. }
  738. _instanceId.set(instanceId);
  739. if (_isVisible && (_knownList != null))
  740. {
  741. // We don't want some ugly looking disappear/appear effects, so don't update
  742. // the knownlist here, but players usually enter instancezones through teleporting
  743. // and the teleport will do the revalidation for us.
  744. if (!isPlayer())
  745. {
  746. decayMe();
  747. spawnMe();
  748. }
  749. }
  750. }
  751. /**
  752. * Sets location of object.
  753. * @param loc the location object
  754. */
  755. @Override
  756. public void setLocation(Location loc)
  757. {
  758. _x.set(loc.getX());
  759. _y.set(loc.getY());
  760. _z.set(loc.getZ());
  761. _heading.set(loc.getHeading());
  762. _instanceId.set(loc.getInstanceId());
  763. }
  764. /**
  765. * Calculates distance between this L2Object and given x, y , z.
  766. * @param x the X coordinate
  767. * @param y the Y coordinate
  768. * @param z the Z coordinate
  769. * @param includeZAxis if {@code true} Z axis will be included
  770. * @param squared if {@code true} return will be squared
  771. * @return distance between object and given x, y, z.
  772. */
  773. public final double calculateDistance(int x, int y, int z, boolean includeZAxis, boolean squared)
  774. {
  775. final double distance = Math.pow(x - getX(), 2) + Math.pow(y - getY(), 2) + (includeZAxis ? Math.pow(z - getZ(), 2) : 0);
  776. return (squared) ? distance : Math.sqrt(distance);
  777. }
  778. /**
  779. * Calculates distance between this L2Object and given location.
  780. * @param loc the location object
  781. * @param includeZAxis if {@code true} Z axis will be included
  782. * @param squared if {@code true} return will be squared
  783. * @return distance between object and given location.
  784. */
  785. public final double calculateDistance(ILocational loc, boolean includeZAxis, boolean squared)
  786. {
  787. return calculateDistance(loc.getX(), loc.getY(), loc.getZ(), includeZAxis, squared);
  788. }
  789. /**
  790. * Calculates the angle in degrees from this object to the given object.<br>
  791. * The return value can be described as how much this object has to turn<br>
  792. * to have the given object directly in front of it.
  793. * @param target the object to which to calculate the angle
  794. * @return the angle this object has to turn to have the given object in front of it
  795. */
  796. public final double calculateDirectionTo(ILocational target)
  797. {
  798. int heading = Util.calculateHeadingFrom(this, target) - getHeading();
  799. if (heading < 0)
  800. {
  801. heading = 65535 + heading;
  802. }
  803. return Util.convertHeadingToDegree(heading);
  804. }
  805. /**
  806. * Sends an instance update for player.
  807. * @param instance the instance to update
  808. * @param hide if {@code true} hide the player
  809. */
  810. private final void sendInstanceUpdate(Instance instance, boolean hide)
  811. {
  812. final int startTime = (int) ((System.currentTimeMillis() - instance.getInstanceStartTime()) / 1000);
  813. final int endTime = (int) ((instance.getInstanceEndTime() - instance.getInstanceStartTime()) / 1000);
  814. if (instance.isTimerIncrease())
  815. {
  816. sendPacket(new ExSendUIEvent(getActingPlayer(), hide, true, startTime, endTime, instance.getTimerText()));
  817. }
  818. else
  819. {
  820. sendPacket(new ExSendUIEvent(getActingPlayer(), hide, false, endTime - startTime, 0, instance.getTimerText()));
  821. }
  822. }
  823. /**
  824. * @return {@code true} if this object is invisible, {@code false} otherwise.
  825. */
  826. public boolean isInvisible()
  827. {
  828. return _isInvisible;
  829. }
  830. /**
  831. * Sets this object as invisible or not
  832. * @param invis
  833. */
  834. public void setInvisible(boolean invis)
  835. {
  836. _isInvisible = invis;
  837. if (invis)
  838. {
  839. final DeleteObject deletePacket = new DeleteObject(this);
  840. for (L2Object obj : getKnownList().getKnownObjects().values())
  841. {
  842. if ((obj != null) && obj.isPlayer())
  843. {
  844. final L2PcInstance player = obj.getActingPlayer();
  845. if (!isVisibleFor(player))
  846. {
  847. obj.sendPacket(deletePacket);
  848. }
  849. }
  850. }
  851. }
  852. // Broadcast information regarding the object to those which are suppose to see.
  853. broadcastInfo();
  854. }
  855. /**
  856. * @param player
  857. * @return {@code true} if player can see an invisible object if it's invisible, {@code false} otherwise.
  858. */
  859. public boolean isVisibleFor(L2PcInstance player)
  860. {
  861. return !isInvisible() || player.canOverrideCond(PcCondOverride.SEE_ALL_PLAYERS);
  862. }
  863. /**
  864. * Broadcasts describing info to known players.
  865. */
  866. public void broadcastInfo()
  867. {
  868. for (L2Object obj : getKnownList().getKnownObjects().values())
  869. {
  870. if ((obj != null) && obj.isPlayer() && isVisibleFor(obj.getActingPlayer()))
  871. {
  872. sendInfo(obj.getActingPlayer());
  873. }
  874. }
  875. }
  876. @Override
  877. public boolean equals(Object obj)
  878. {
  879. return ((obj instanceof L2Object) && (((L2Object) obj).getObjectId() == getObjectId()));
  880. }
  881. @Override
  882. public String toString()
  883. {
  884. return (getClass().getSimpleName() + ":" + getName() + "[" + getObjectId() + "]");
  885. }
  886. }