L2Object.java 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. /*
  2. * Copyright (C) 2004-2015 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.model;
  20. import java.util.Map;
  21. import java.util.concurrent.ConcurrentHashMap;
  22. import java.util.concurrent.atomic.AtomicInteger;
  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.handler.IActionShiftHandler;
  29. import com.l2jserver.gameserver.idfactory.IdFactory;
  30. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  31. import com.l2jserver.gameserver.model.actor.L2Character;
  32. import com.l2jserver.gameserver.model.actor.L2Npc;
  33. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  34. import com.l2jserver.gameserver.model.actor.knownlist.ObjectKnownList;
  35. import com.l2jserver.gameserver.model.actor.poly.ObjectPoly;
  36. import com.l2jserver.gameserver.model.entity.Instance;
  37. import com.l2jserver.gameserver.model.events.ListenersContainer;
  38. import com.l2jserver.gameserver.model.interfaces.IDecayable;
  39. import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
  40. import com.l2jserver.gameserver.model.interfaces.ILocational;
  41. import com.l2jserver.gameserver.model.interfaces.INamable;
  42. import com.l2jserver.gameserver.model.interfaces.IPositionable;
  43. import com.l2jserver.gameserver.model.interfaces.ISpawnable;
  44. import com.l2jserver.gameserver.model.interfaces.IUniqueId;
  45. import com.l2jserver.gameserver.model.zone.ZoneId;
  46. import com.l2jserver.gameserver.network.SystemMessageId;
  47. import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
  48. import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
  49. import com.l2jserver.gameserver.network.serverpackets.ExSendUIEvent;
  50. import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
  51. import com.l2jserver.gameserver.util.Util;
  52. /**
  53. * Base class for all interactive objects.
  54. */
  55. public abstract class L2Object extends ListenersContainer implements IIdentifiable, INamable, ISpawnable, IUniqueId, IDecayable, IPositionable
  56. {
  57. /** Name */
  58. private String _name;
  59. /** Object ID */
  60. private int _objectId;
  61. /** World Region */
  62. private L2WorldRegion _worldRegion;
  63. /** Instance type */
  64. private InstanceType _instanceType = null;
  65. private volatile Map<String, Object> _scripts;
  66. /** X coordinate */
  67. private final AtomicInteger _x = new AtomicInteger(0);
  68. /** Y coordinate */
  69. private final AtomicInteger _y = new AtomicInteger(0);
  70. /** Z coordinate */
  71. private final AtomicInteger _z = new AtomicInteger(0);
  72. /** Orientation */
  73. private final AtomicInteger _heading = new AtomicInteger(0);
  74. /** Instance id of object. 0 - Global */
  75. private final AtomicInteger _instanceId = new AtomicInteger(0);
  76. private boolean _isVisible;
  77. private boolean _isInvisible;
  78. private ObjectKnownList _knownList;
  79. public L2Object(int objectId)
  80. {
  81. setInstanceType(InstanceType.L2Object);
  82. _objectId = objectId;
  83. initKnownList();
  84. }
  85. /**
  86. * Gets the instance type of object.
  87. * @return the instance type
  88. */
  89. public final InstanceType getInstanceType()
  90. {
  91. return _instanceType;
  92. }
  93. /**
  94. * Sets the instance type.
  95. * @param newInstanceType the instance type to set
  96. */
  97. protected final void setInstanceType(InstanceType newInstanceType)
  98. {
  99. _instanceType = newInstanceType;
  100. }
  101. /**
  102. * Verifies if object is of any given instance types.
  103. * @param instanceTypes the instance types to verify
  104. * @return {@code true} if object is of any given instance types, {@code false} otherwise
  105. */
  106. public final boolean isInstanceTypes(InstanceType... instanceTypes)
  107. {
  108. return _instanceType.isTypes(instanceTypes);
  109. }
  110. public final void onAction(L2PcInstance player)
  111. {
  112. onAction(player, true);
  113. }
  114. public void onAction(L2PcInstance player, boolean interact)
  115. {
  116. IActionHandler handler = ActionHandler.getInstance().getHandler(getInstanceType());
  117. if (handler != null)
  118. {
  119. handler.action(player, this, interact);
  120. }
  121. player.sendPacket(ActionFailed.STATIC_PACKET);
  122. }
  123. public void onActionShift(L2PcInstance player)
  124. {
  125. IActionShiftHandler handler = ActionShiftHandler.getInstance().getHandler(getInstanceType());
  126. if (handler != null)
  127. {
  128. handler.action(player, this, true);
  129. }
  130. player.sendPacket(ActionFailed.STATIC_PACKET);
  131. }
  132. public void onForcedAttack(L2PcInstance player)
  133. {
  134. player.sendPacket(ActionFailed.STATIC_PACKET);
  135. }
  136. public void onSpawn()
  137. {
  138. }
  139. @Override
  140. public boolean decayMe()
  141. {
  142. assert getWorldRegion() != null;
  143. L2WorldRegion reg = getWorldRegion();
  144. synchronized (this)
  145. {
  146. _isVisible = false;
  147. setWorldRegion(null);
  148. }
  149. // this can synchronize on others instances, so it's out of
  150. // synchronized, to avoid deadlocks
  151. // Remove the L2Object from the world
  152. L2World.getInstance().removeVisibleObject(this, reg);
  153. L2World.getInstance().removeObject(this);
  154. return true;
  155. }
  156. public void refreshID()
  157. {
  158. L2World.getInstance().removeObject(this);
  159. IdFactory.getInstance().releaseId(getObjectId());
  160. _objectId = IdFactory.getInstance().getNextId();
  161. }
  162. @Override
  163. public final boolean spawnMe()
  164. {
  165. assert (getWorldRegion() == null) && (getLocation().getX() != 0) && (getLocation().getY() != 0) && (getLocation().getZ() != 0);
  166. synchronized (this)
  167. {
  168. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  169. _isVisible = true;
  170. setWorldRegion(L2World.getInstance().getRegion(getLocation()));
  171. // Add the L2Object spawn in the _allobjects of L2World
  172. L2World.getInstance().storeObject(this);
  173. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  174. getWorldRegion().addVisibleObject(this);
  175. }
  176. // this can synchronize on others instances, so it's out of synchronized, to avoid deadlocks
  177. // Add the L2Object spawn in the world as a visible object
  178. L2World.getInstance().addVisibleObject(this, getWorldRegion());
  179. onSpawn();
  180. return true;
  181. }
  182. public final void spawnMe(int x, int y, int z)
  183. {
  184. assert getWorldRegion() == null;
  185. synchronized (this)
  186. {
  187. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  188. _isVisible = true;
  189. if (x > L2World.MAP_MAX_X)
  190. {
  191. x = L2World.MAP_MAX_X - 5000;
  192. }
  193. if (x < L2World.MAP_MIN_X)
  194. {
  195. x = L2World.MAP_MIN_X + 5000;
  196. }
  197. if (y > L2World.MAP_MAX_Y)
  198. {
  199. y = L2World.MAP_MAX_Y - 5000;
  200. }
  201. if (y < L2World.MAP_MIN_Y)
  202. {
  203. y = L2World.MAP_MIN_Y + 5000;
  204. }
  205. setXYZ(x, y, z);
  206. setWorldRegion(L2World.getInstance().getRegion(getLocation()));
  207. // Add the L2Object spawn in the _allobjects of L2World
  208. }
  209. L2World.getInstance().storeObject(this);
  210. // these can synchronize on others instances, so they're out of
  211. // synchronized, to avoid deadlocks
  212. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  213. getWorldRegion().addVisibleObject(this);
  214. // Add the L2Object spawn in the world as a visible object
  215. L2World.getInstance().addVisibleObject(this, getWorldRegion());
  216. onSpawn();
  217. }
  218. /**
  219. * Verify if object can be attacked.
  220. * @return {@code true} if object can be attacked, {@code false} otherwise
  221. */
  222. public boolean canBeAttacked()
  223. {
  224. return false;
  225. }
  226. public abstract boolean isAutoAttackable(L2Character attacker);
  227. public final boolean isVisible()
  228. {
  229. return getWorldRegion() != null;
  230. }
  231. public final void setIsVisible(boolean value)
  232. {
  233. _isVisible = value;
  234. if (!_isVisible)
  235. {
  236. setWorldRegion(null);
  237. }
  238. }
  239. public void toggleVisible()
  240. {
  241. if (isVisible())
  242. {
  243. decayMe();
  244. }
  245. else
  246. {
  247. spawnMe();
  248. }
  249. }
  250. public ObjectKnownList getKnownList()
  251. {
  252. return _knownList;
  253. }
  254. public void initKnownList()
  255. {
  256. _knownList = new ObjectKnownList(this);
  257. }
  258. public final void setKnownList(ObjectKnownList value)
  259. {
  260. _knownList = value;
  261. }
  262. @Override
  263. public String getName()
  264. {
  265. return _name;
  266. }
  267. public void setName(String value)
  268. {
  269. _name = value;
  270. }
  271. @Override
  272. public final int getObjectId()
  273. {
  274. return _objectId;
  275. }
  276. public final ObjectPoly getPoly()
  277. {
  278. final ObjectPoly poly = getScript(ObjectPoly.class);
  279. return (poly == null) ? addScript(new ObjectPoly(this)) : poly;
  280. }
  281. public abstract void sendInfo(L2PcInstance activeChar);
  282. public void sendPacket(L2GameServerPacket mov)
  283. {
  284. }
  285. public void sendPacket(SystemMessageId id)
  286. {
  287. }
  288. public L2PcInstance getActingPlayer()
  289. {
  290. return null;
  291. }
  292. /**
  293. * Verify if object is instance of L2Attackable.
  294. * @return {@code true} if object is instance of L2Attackable, {@code false} otherwise
  295. */
  296. public boolean isAttackable()
  297. {
  298. return false;
  299. }
  300. /**
  301. * Verify if object is instance of L2Character.
  302. * @return {@code true} if object is instance of L2Character, {@code false} otherwise
  303. */
  304. public boolean isCharacter()
  305. {
  306. return false;
  307. }
  308. /**
  309. * Verify if object is instance of L2DoorInstance.
  310. * @return {@code true} if object is instance of L2DoorInstance, {@code false} otherwise
  311. */
  312. public boolean isDoor()
  313. {
  314. return false;
  315. }
  316. /**
  317. * Verify if object is instance of L2MonsterInstance.
  318. * @return {@code true} if object is instance of L2MonsterInstance, {@code false} otherwise
  319. */
  320. public boolean isMonster()
  321. {
  322. return false;
  323. }
  324. /**
  325. * Verify if object is instance of L2Npc.
  326. * @return {@code true} if object is instance of L2Npc, {@code false} otherwise
  327. */
  328. public boolean isNpc()
  329. {
  330. return false;
  331. }
  332. /**
  333. * Verify if object is instance of L2PetInstance.
  334. * @return {@code true} if object is instance of L2PetInstance, {@code false} otherwise
  335. */
  336. public boolean isPet()
  337. {
  338. return false;
  339. }
  340. /**
  341. * Verify if object is instance of L2PcInstance.
  342. * @return {@code true} if object is instance of L2PcInstance, {@code false} otherwise
  343. */
  344. public boolean isPlayer()
  345. {
  346. return false;
  347. }
  348. /**
  349. * Verify if object is instance of L2Playable.
  350. * @return {@code true} if object is instance of L2Playable, {@code false} otherwise
  351. */
  352. public boolean isPlayable()
  353. {
  354. return false;
  355. }
  356. /**
  357. * Verify if object is instance of L2ServitorInstance.
  358. * @return {@code true} if object is instance of L2ServitorInstance, {@code false} otherwise
  359. */
  360. public boolean isServitor()
  361. {
  362. return false;
  363. }
  364. /**
  365. * Verify if object is instance of L2Summon.
  366. * @return {@code true} if object is instance of L2Summon, {@code false} otherwise
  367. */
  368. public boolean isSummon()
  369. {
  370. return false;
  371. }
  372. /**
  373. * Verify if object is instance of L2TrapInstance.
  374. * @return {@code true} if object is instance of L2TrapInstance, {@code false} otherwise
  375. */
  376. public boolean isTrap()
  377. {
  378. return false;
  379. }
  380. /**
  381. * Verify if object is instance of L2ItemInstance.
  382. * @return {@code true} if object is instance of L2ItemInstance, {@code false} otherwise
  383. */
  384. public boolean isItem()
  385. {
  386. return false;
  387. }
  388. /**
  389. * Verifies if the object is a walker NPC.
  390. * @return {@code true} if object is a walker NPC, {@code false} otherwise
  391. */
  392. public boolean isWalker()
  393. {
  394. return false;
  395. }
  396. /**
  397. * Verifies if this object is a vehicle.
  398. * @return {@code true} if object is Vehicle, {@code false} otherwise
  399. */
  400. public boolean isVehicle()
  401. {
  402. return false;
  403. }
  404. /**
  405. * @return {@code true} if object Can be targeted
  406. */
  407. public boolean isTargetable()
  408. {
  409. return true;
  410. }
  411. /**
  412. * Check if the object is in the given zone Id.
  413. * @param zone the zone Id to check
  414. * @return {@code true} if the object is in that zone Id
  415. */
  416. public boolean isInsideZone(ZoneId zone)
  417. {
  418. return false;
  419. }
  420. /**
  421. * Check if current object has charged shot.
  422. * @param type of the shot to be checked.
  423. * @return {@code true} if the object has charged shot
  424. */
  425. public boolean isChargedShot(ShotType type)
  426. {
  427. return false;
  428. }
  429. /**
  430. * Charging shot into the current object.
  431. * @param type of the shot to be charged.
  432. * @param charged
  433. */
  434. public void setChargedShot(ShotType type, boolean charged)
  435. {
  436. }
  437. /**
  438. * Try to recharge a shot.
  439. * @param physical skill are using Soul shots.
  440. * @param magical skill are using Spirit shots.
  441. */
  442. public void rechargeShots(boolean physical, boolean magical)
  443. {
  444. }
  445. /**
  446. * @param <T>
  447. * @param script
  448. * @return
  449. */
  450. public final <T> T addScript(T script)
  451. {
  452. if (_scripts == null)
  453. {
  454. synchronized (this)
  455. {
  456. if (_scripts == null)
  457. {
  458. _scripts = new ConcurrentHashMap<>();
  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. }