L2Object.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. /*
  2. * Copyright (C) 2004-2013 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.model;
  20. import java.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.ExSendUIEvent;
  47. import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
  48. /**
  49. * Base class for all interactive objects.
  50. * @author unknown
  51. */
  52. public abstract class L2Object implements IIdentifiable, INamable, ISpawnable, IUniqueId, IDecayable, IPositionable
  53. {
  54. private boolean _isVisible;
  55. private ObjectKnownList _knownList;
  56. private String _name;
  57. private int _objectId;
  58. private L2WorldRegion _worldRegion;
  59. private InstanceType _instanceType = null;
  60. private volatile Map<String, Object> _scripts;
  61. private final AtomicInteger _x = new AtomicInteger(0);
  62. private final AtomicInteger _y = new AtomicInteger(0);
  63. private final AtomicInteger _z = new AtomicInteger(0);
  64. private final AtomicInteger _heading = new AtomicInteger(0);
  65. private final AtomicInteger _instanceId = new AtomicInteger(0);
  66. public L2Object(int objectId)
  67. {
  68. setInstanceType(InstanceType.L2Object);
  69. _objectId = objectId;
  70. initKnownList();
  71. }
  72. protected final void setInstanceType(InstanceType i)
  73. {
  74. _instanceType = i;
  75. }
  76. public final InstanceType getInstanceType()
  77. {
  78. return _instanceType;
  79. }
  80. public final boolean isInstanceType(InstanceType i)
  81. {
  82. return _instanceType.isType(i);
  83. }
  84. public final boolean isInstanceTypes(InstanceType... i)
  85. {
  86. return _instanceType.isTypes(i);
  87. }
  88. public final void onAction(L2PcInstance player)
  89. {
  90. onAction(player, true);
  91. }
  92. public void onAction(L2PcInstance player, boolean interact)
  93. {
  94. IActionHandler handler = ActionHandler.getInstance().getHandler(getInstanceType());
  95. if (handler != null)
  96. {
  97. handler.action(player, this, interact);
  98. }
  99. player.sendPacket(ActionFailed.STATIC_PACKET);
  100. }
  101. public void onActionShift(L2PcInstance player)
  102. {
  103. IActionHandler handler = ActionShiftHandler.getInstance().getHandler(getInstanceType());
  104. if (handler != null)
  105. {
  106. handler.action(player, this, true);
  107. }
  108. player.sendPacket(ActionFailed.STATIC_PACKET);
  109. }
  110. public void onForcedAttack(L2PcInstance player)
  111. {
  112. player.sendPacket(ActionFailed.STATIC_PACKET);
  113. }
  114. public void onSpawn()
  115. {
  116. }
  117. /**
  118. * UnAfraid: TODO: Add listener here.
  119. * @param instanceId The id of the instance zone the object is in - id 0 is global
  120. */
  121. @Override
  122. public void setInstanceId(int instanceId)
  123. {
  124. if ((instanceId < 0) || (getInstanceId() == instanceId))
  125. {
  126. return;
  127. }
  128. Instance oldI = InstanceManager.getInstance().getInstance(getInstanceId());
  129. Instance newI = InstanceManager.getInstance().getInstance(instanceId);
  130. if (newI == null)
  131. {
  132. return;
  133. }
  134. if (isPlayer())
  135. {
  136. final L2PcInstance player = getActingPlayer();
  137. if ((getInstanceId() > 0) && (oldI != null))
  138. {
  139. oldI.removePlayer(getObjectId());
  140. if (oldI.isShowTimer())
  141. {
  142. sendInstanceUpdate(oldI, true);
  143. }
  144. }
  145. if (instanceId > 0)
  146. {
  147. newI.addPlayer(getObjectId());
  148. if (newI.isShowTimer())
  149. {
  150. sendInstanceUpdate(newI, false);
  151. }
  152. }
  153. if (player.hasSummon())
  154. {
  155. player.getSummon().setInstanceId(instanceId);
  156. }
  157. }
  158. else if (isNpc())
  159. {
  160. final L2Npc npc = (L2Npc) this;
  161. if ((getInstanceId() > 0) && (oldI != null))
  162. {
  163. oldI.removeNpc(npc);
  164. }
  165. if (instanceId > 0)
  166. {
  167. newI.addNpc(npc);
  168. }
  169. }
  170. _instanceId.set(instanceId);
  171. if (_isVisible && (_knownList != null))
  172. {
  173. // We don't want some ugly looking disappear/appear effects, so don't update
  174. // the knownlist here, but players usually enter instancezones through teleporting
  175. // and the teleport will do the revalidation for us.
  176. if (!isPlayer())
  177. {
  178. decayMe();
  179. spawnMe();
  180. }
  181. }
  182. }
  183. private final void sendInstanceUpdate(Instance instance, boolean hide)
  184. {
  185. final int startTime = (int) ((System.currentTimeMillis() - instance.getInstanceStartTime()) / 1000);
  186. final int endTime = (int) ((instance.getInstanceEndTime() - instance.getInstanceStartTime()) / 1000);
  187. if (instance.isTimerIncrease())
  188. {
  189. sendPacket(new ExSendUIEvent(getActingPlayer(), hide, true, startTime, endTime, instance.getTimerText()));
  190. }
  191. else
  192. {
  193. sendPacket(new ExSendUIEvent(getActingPlayer(), hide, false, endTime - startTime, 0, instance.getTimerText()));
  194. }
  195. }
  196. @Override
  197. public boolean decayMe()
  198. {
  199. assert getWorldRegion() != null;
  200. L2WorldRegion reg = getWorldRegion();
  201. synchronized (this)
  202. {
  203. _isVisible = false;
  204. setWorldRegion(null);
  205. }
  206. // this can synchronize on others instances, so it's out of
  207. // synchronized, to avoid deadlocks
  208. // Remove the L2Object from the world
  209. L2World.getInstance().removeVisibleObject(this, reg);
  210. L2World.getInstance().removeObject(this);
  211. return true;
  212. }
  213. public void refreshID()
  214. {
  215. L2World.getInstance().removeObject(this);
  216. IdFactory.getInstance().releaseId(getObjectId());
  217. _objectId = IdFactory.getInstance().getNextId();
  218. }
  219. @Override
  220. public final boolean spawnMe()
  221. {
  222. assert (getWorldRegion() == null) && (getLocation().getX() != 0) && (getLocation().getY() != 0) && (getLocation().getZ() != 0);
  223. synchronized (this)
  224. {
  225. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  226. _isVisible = true;
  227. setWorldRegion(L2World.getInstance().getRegion(getLocation()));
  228. // Add the L2Object spawn in the _allobjects of L2World
  229. L2World.getInstance().storeObject(this);
  230. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  231. getWorldRegion().addVisibleObject(this);
  232. }
  233. // this can synchronize on others instances, so it's out of synchronized, to avoid deadlocks
  234. // Add the L2Object spawn in the world as a visible object
  235. L2World.getInstance().addVisibleObject(this, getWorldRegion());
  236. onSpawn();
  237. return true;
  238. }
  239. public final void spawnMe(int x, int y, int z)
  240. {
  241. assert getWorldRegion() == null;
  242. synchronized (this)
  243. {
  244. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  245. _isVisible = true;
  246. if (x > L2World.MAP_MAX_X)
  247. {
  248. x = L2World.MAP_MAX_X - 5000;
  249. }
  250. if (x < L2World.MAP_MIN_X)
  251. {
  252. x = L2World.MAP_MIN_X + 5000;
  253. }
  254. if (y > L2World.MAP_MAX_Y)
  255. {
  256. y = L2World.MAP_MAX_Y - 5000;
  257. }
  258. if (y < L2World.MAP_MIN_Y)
  259. {
  260. y = L2World.MAP_MIN_Y + 5000;
  261. }
  262. setXYZ(x, y, z);
  263. setWorldRegion(L2World.getInstance().getRegion(getLocation()));
  264. // Add the L2Object spawn in the _allobjects of L2World
  265. }
  266. L2World.getInstance().storeObject(this);
  267. // these can synchronize on others instances, so they're out of
  268. // synchronized, to avoid deadlocks
  269. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  270. getWorldRegion().addVisibleObject(this);
  271. // Add the L2Object spawn in the world as a visible object
  272. L2World.getInstance().addVisibleObject(this, getWorldRegion());
  273. onSpawn();
  274. }
  275. public boolean isAttackable()
  276. {
  277. return false;
  278. }
  279. public abstract boolean isAutoAttackable(L2Character attacker);
  280. public final boolean isVisible()
  281. {
  282. return getWorldRegion() != null;
  283. }
  284. public final void setIsVisible(boolean value)
  285. {
  286. _isVisible = value;
  287. if (!_isVisible)
  288. {
  289. setWorldRegion(null);
  290. }
  291. }
  292. public void toggleVisible()
  293. {
  294. if (isVisible())
  295. {
  296. decayMe();
  297. }
  298. else
  299. {
  300. spawnMe();
  301. }
  302. }
  303. public ObjectKnownList getKnownList()
  304. {
  305. return _knownList;
  306. }
  307. public void initKnownList()
  308. {
  309. _knownList = new ObjectKnownList(this);
  310. }
  311. public final void setKnownList(ObjectKnownList value)
  312. {
  313. _knownList = value;
  314. }
  315. @Override
  316. public final String getName()
  317. {
  318. return _name;
  319. }
  320. public void setName(String value)
  321. {
  322. _name = value;
  323. }
  324. @Override
  325. public final int getObjectId()
  326. {
  327. return _objectId;
  328. }
  329. public final ObjectPoly getPoly()
  330. {
  331. final ObjectPoly poly = getScript(ObjectPoly.class);
  332. return (poly == null) ? addScript(new ObjectPoly(this)) : poly;
  333. }
  334. public abstract void sendInfo(L2PcInstance activeChar);
  335. public void sendPacket(L2GameServerPacket mov)
  336. {
  337. }
  338. public void sendPacket(SystemMessageId id)
  339. {
  340. }
  341. public L2PcInstance getActingPlayer()
  342. {
  343. return null;
  344. }
  345. /**
  346. * @return {@code true} if object is instance of L2PcInstance
  347. */
  348. public boolean isPlayer()
  349. {
  350. return false;
  351. }
  352. /**
  353. * @return {@code true} if object is instance of L2Playable
  354. */
  355. public boolean isPlayable()
  356. {
  357. return false;
  358. }
  359. /**
  360. * @return {@code true} if object is instance of L2Summon
  361. */
  362. public boolean isSummon()
  363. {
  364. return false;
  365. }
  366. /**
  367. * @return {@code true} if object is instance of L2PetInstance
  368. */
  369. public boolean isPet()
  370. {
  371. return false;
  372. }
  373. /**
  374. * @return {@code true} if object is instance of L2ServitorInstance
  375. */
  376. public boolean isServitor()
  377. {
  378. return false;
  379. }
  380. /**
  381. * @return {@code true} if object is instance of L2Attackable
  382. */
  383. public boolean isCharacter()
  384. {
  385. return false;
  386. }
  387. /**
  388. * @return {@code true} if object is instance of L2DoorInstance
  389. */
  390. public boolean isDoor()
  391. {
  392. return false;
  393. }
  394. /**
  395. * @return {@code true} if object is instance of L2Npc
  396. */
  397. public boolean isNpc()
  398. {
  399. return false;
  400. }
  401. /**
  402. * @return {@code true} if object is instance of L2Attackable
  403. */
  404. public boolean isL2Attackable()
  405. {
  406. return false;
  407. }
  408. /**
  409. * @return {@code true} if object is instance of L2MonsterInstance
  410. */
  411. public boolean isMonster()
  412. {
  413. return false;
  414. }
  415. /**
  416. * @return {@code true} if object is instance of L2TrapInstance
  417. */
  418. public boolean isTrap()
  419. {
  420. return false;
  421. }
  422. /**
  423. * @return {@code true} if object is instance of L2ItemInstance
  424. */
  425. public boolean isItem()
  426. {
  427. return false;
  428. }
  429. /**
  430. * @return {@code true} if object Npc Walker or Vehicle
  431. */
  432. public boolean isWalker()
  433. {
  434. return false;
  435. }
  436. /**
  437. * @return {@code true} if object Can be targeted
  438. */
  439. public boolean isTargetable()
  440. {
  441. return true;
  442. }
  443. /**
  444. * Check if the object is in the given zone Id.
  445. * @param zone the zone Id to check
  446. * @return {@code true} if the object is in that zone Id
  447. */
  448. public boolean isInsideZone(ZoneId zone)
  449. {
  450. return false;
  451. }
  452. /**
  453. * Check if current object has charged shot.
  454. * @param type of the shot to be checked.
  455. * @return {@code true} if the object has charged shot
  456. */
  457. public boolean isChargedShot(ShotType type)
  458. {
  459. return false;
  460. }
  461. /**
  462. * Charging shot into the current object.
  463. * @param type of the shot to be charged.
  464. * @param charged
  465. */
  466. public void setChargedShot(ShotType type, boolean charged)
  467. {
  468. }
  469. /**
  470. * Try to recharge a shot.
  471. * @param physical skill are using Soul shots.
  472. * @param magical skill are using Spirit shots.
  473. */
  474. public void rechargeShots(boolean physical, boolean magical)
  475. {
  476. }
  477. /**
  478. * @param <T>
  479. * @param script
  480. * @return
  481. */
  482. public final <T> T addScript(T script)
  483. {
  484. if (_scripts == null)
  485. {
  486. // Double-checked locking
  487. synchronized (this)
  488. {
  489. if (_scripts == null)
  490. {
  491. _scripts = new FastMap<String, Object>().shared();
  492. }
  493. }
  494. }
  495. _scripts.put(script.getClass().getName(), script);
  496. return script;
  497. }
  498. /**
  499. * @param <T>
  500. * @param script
  501. * @return
  502. */
  503. @SuppressWarnings("unchecked")
  504. public final <T> T removeScript(Class<T> script)
  505. {
  506. if (_scripts == null)
  507. {
  508. return null;
  509. }
  510. return (T) _scripts.remove(script.getName());
  511. }
  512. /**
  513. * @param <T>
  514. * @param script
  515. * @return
  516. */
  517. @SuppressWarnings("unchecked")
  518. public final <T> T getScript(Class<T> script)
  519. {
  520. if (_scripts == null)
  521. {
  522. return null;
  523. }
  524. return (T) _scripts.get(script.getName());
  525. }
  526. public void removeStatusListener(L2Character object)
  527. {
  528. }
  529. @Override
  530. public final void setXYZ(int x, int y, int z)
  531. {
  532. assert getWorldRegion() != null;
  533. setX(x);
  534. setY(y);
  535. setZ(z);
  536. try
  537. {
  538. if (L2World.getInstance().getRegion(getLocation()) != getWorldRegion())
  539. {
  540. updateWorldRegion();
  541. }
  542. }
  543. catch (Exception e)
  544. {
  545. badCoords();
  546. }
  547. }
  548. protected void badCoords()
  549. {
  550. if (isCharacter())
  551. {
  552. this.decayMe();
  553. }
  554. else if (isPlayer())
  555. {
  556. ((L2Character) this).teleToLocation(new Location(0, 0, 0), false);
  557. ((L2Character) this).sendMessage("Error with your coords, Please ask a GM for help!");
  558. }
  559. }
  560. public final void setXYZInvisible(int x, int y, int z)
  561. {
  562. assert getWorldRegion() == null;
  563. if (x > L2World.MAP_MAX_X)
  564. {
  565. x = L2World.MAP_MAX_X - 5000;
  566. }
  567. if (x < L2World.MAP_MIN_X)
  568. {
  569. x = L2World.MAP_MIN_X + 5000;
  570. }
  571. if (y > L2World.MAP_MAX_Y)
  572. {
  573. y = L2World.MAP_MAX_Y - 5000;
  574. }
  575. if (y < L2World.MAP_MIN_Y)
  576. {
  577. y = L2World.MAP_MIN_Y + 5000;
  578. }
  579. setXYZ(x, y, z);
  580. this.setIsVisible(false);
  581. }
  582. public final void setLocationInvisible(ILocational loc)
  583. {
  584. setXYZInvisible(loc.getX(), loc.getY(), loc.getZ());
  585. }
  586. public void updateWorldRegion()
  587. {
  588. if (!this.isVisible())
  589. {
  590. return;
  591. }
  592. L2WorldRegion newRegion = L2World.getInstance().getRegion(getLocation());
  593. if (newRegion != getWorldRegion())
  594. {
  595. getWorldRegion().removeVisibleObject(this);
  596. setWorldRegion(newRegion);
  597. // Add the L2Oject spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  598. getWorldRegion().addVisibleObject(this);
  599. }
  600. }
  601. public final L2WorldRegion getWorldRegion()
  602. {
  603. return _worldRegion;
  604. }
  605. public void setWorldRegion(L2WorldRegion value)
  606. {
  607. if ((getWorldRegion() != null) && isCharacter()) // confirm revalidation of old region's zones
  608. {
  609. if (value != null)
  610. {
  611. getWorldRegion().revalidateZones((L2Character) this); // at world region change
  612. }
  613. else
  614. {
  615. getWorldRegion().removeFromZones((L2Character) this); // at world region change
  616. }
  617. }
  618. _worldRegion = value;
  619. }
  620. /**
  621. * Calculates distance between this L2Object and given x, y , z.
  622. * @param x - X coordinate.
  623. * @param y - Y coordinate.
  624. * @param z - Z coordinate.
  625. * @param includeZAxis - If set to true, Z coordinate will be included.
  626. * @param squared - If set to true, distance returned will be squared.
  627. * @return {@code double} - Distance between object and given x, y , z.
  628. */
  629. public double calculateDistance(int x, int y, int z, boolean includeZAxis, boolean squared)
  630. {
  631. final double distance = Math.pow(x - getX(), 2) + Math.pow(y - getY(), 2) + (includeZAxis ? Math.pow(z - getZ(), 2) : 0);
  632. return (squared) ? distance : Math.sqrt(distance);
  633. }
  634. /**
  635. * Calculates distance between this L2Object and given location.
  636. * @param loc - Location on map.
  637. * @param includeZAxis - If set to true, Z coordinate will be included.
  638. * @param squared - If set to true, distance returned will be squared.
  639. * @return {@code double} - Distance between object and given location.
  640. */
  641. public double calculateDistance(ILocational loc, boolean includeZAxis, boolean squared)
  642. {
  643. return calculateDistance(loc.getLocation(this).getX(), loc.getLocation(this).getY(), loc.getLocation(this).getZ(), includeZAxis, squared);
  644. }
  645. @Override
  646. public int getX()
  647. {
  648. return _x.get();
  649. }
  650. @Override
  651. public int getY()
  652. {
  653. return _y.get();
  654. }
  655. @Override
  656. public int getZ()
  657. {
  658. return _z.get();
  659. }
  660. @Override
  661. public int getHeading()
  662. {
  663. return _heading.get();
  664. }
  665. @Override
  666. public int getInstanceId()
  667. {
  668. return _instanceId.get();
  669. }
  670. @Override
  671. public Location getLocation()
  672. {
  673. return new Location(getX(), getY(), getZ(), getHeading(), getInstanceId());
  674. }
  675. @Override
  676. public Location getLocation(L2Object obj)
  677. {
  678. return getLocation();
  679. }
  680. @Override
  681. public void setX(int x)
  682. {
  683. _x.set(x);
  684. }
  685. @Override
  686. public void setY(int y)
  687. {
  688. _y.set(y);
  689. }
  690. @Override
  691. public void setZ(int z)
  692. {
  693. _z.set(z);
  694. }
  695. public void setXYZ(ILocational loc)
  696. {
  697. _x.set(loc.getX());
  698. _y.set(loc.getY());
  699. _z.set(loc.getZ());
  700. }
  701. @Override
  702. public void setHeading(int heading)
  703. {
  704. _heading.set(heading);
  705. }
  706. @Override
  707. public void setLocation(Location loc)
  708. {
  709. _x.set(loc.getX());
  710. _y.set(loc.getY());
  711. _z.set(loc.getZ());
  712. _heading.set(loc.getHeading());
  713. _instanceId.set(loc.getInstanceId());
  714. }
  715. @Override
  716. public boolean equals(Object obj)
  717. {
  718. return ((obj instanceof L2Object) && (((L2Object) obj).getObjectId() == getObjectId()));
  719. }
  720. @Override
  721. public String toString()
  722. {
  723. return (getClass().getSimpleName() + ":" + getName() + "[" + getObjectId() + "]");
  724. }
  725. }