L2Object.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package com.l2jserver.gameserver.model;
  16. import com.l2jserver.Config;
  17. import com.l2jserver.gameserver.idfactory.IdFactory;
  18. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  19. import com.l2jserver.gameserver.instancemanager.ItemsOnGroundManager;
  20. import com.l2jserver.gameserver.model.actor.L2Character;
  21. import com.l2jserver.gameserver.model.actor.L2Npc;
  22. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  23. import com.l2jserver.gameserver.model.actor.knownlist.ObjectKnownList;
  24. import com.l2jserver.gameserver.model.actor.poly.ObjectPoly;
  25. import com.l2jserver.gameserver.model.actor.position.ObjectPosition;
  26. import com.l2jserver.gameserver.network.L2GameClient;
  27. import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
  28. import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
  29. /**
  30. * Mother class of all objects in the world wich ones is it possible
  31. * to interact (PC, NPC, Item...)<BR><BR>
  32. *
  33. * L2Object :<BR><BR>
  34. * <li>L2Character</li>
  35. * <li>L2ItemInstance</li>
  36. * <li>L2Potion</li>
  37. *
  38. */
  39. public abstract class L2Object
  40. {
  41. // =========================================================
  42. // Data Field
  43. private boolean _isVisible; // Object visibility
  44. private ObjectKnownList _knownList;
  45. private String _name;
  46. private int _objectId; // Object identifier
  47. private ObjectPoly _poly;
  48. private ObjectPosition _position;
  49. private int _instanceId = 0;
  50. // =========================================================
  51. // Constructor
  52. public L2Object(int objectId)
  53. {
  54. _objectId = objectId;
  55. initKnownList();
  56. initPosition();
  57. }
  58. // =========================================================
  59. // Event - Public
  60. public final void onAction(L2PcInstance player)
  61. {
  62. onAction(player, true);
  63. }
  64. public void onAction(L2PcInstance player, boolean interact)
  65. {
  66. player.sendPacket(ActionFailed.STATIC_PACKET);
  67. }
  68. @Deprecated
  69. public void onActionShift(L2GameClient client)
  70. {
  71. client.getActiveChar().sendPacket(ActionFailed.STATIC_PACKET);
  72. }
  73. public void onActionShift(L2PcInstance player)
  74. {
  75. player.sendPacket(ActionFailed.STATIC_PACKET);
  76. }
  77. public void onForcedAttack(L2PcInstance player)
  78. {
  79. player.sendPacket(ActionFailed.STATIC_PACKET);
  80. }
  81. /**
  82. * Do Nothing.<BR><BR>
  83. *
  84. * <B><U> Overridden in </U> :</B><BR><BR>
  85. * <li> L2GuardInstance : Set the home location of its L2GuardInstance </li>
  86. * <li> L2Attackable : Reset the Spoiled flag </li><BR><BR>
  87. *
  88. */
  89. public void onSpawn()
  90. {
  91. }
  92. // =========================================================
  93. // Position - Should remove to fully move to L2ObjectPosition
  94. public final void setXYZ(int x, int y, int z)
  95. {
  96. getPosition().setXYZ(x, y, z);
  97. }
  98. public final void setXYZInvisible(int x, int y, int z)
  99. {
  100. getPosition().setXYZInvisible(x, y, z);
  101. }
  102. public final int getX()
  103. {
  104. if (Config.ASSERT) assert getPosition().getWorldRegion() != null || _isVisible;
  105. return getPosition().getX();
  106. }
  107. /**
  108. * @return The id of the instance zone the object is in - id 0 is global
  109. * since everything like dropped items, mobs, players can be in a instanciated area, it must be in l2object
  110. */
  111. public int getInstanceId()
  112. {
  113. return _instanceId;
  114. }
  115. /**
  116. * @param instanceId The id of the instance zone the object is in - id 0 is global
  117. */
  118. public void setInstanceId(int instanceId)
  119. {
  120. if (_instanceId == instanceId)
  121. return;
  122. if (this instanceof L2PcInstance)
  123. {
  124. if (_instanceId > 0)
  125. InstanceManager.getInstance().getInstance(_instanceId).removePlayer(getObjectId());
  126. if (instanceId > 0)
  127. InstanceManager.getInstance().getInstance(instanceId).addPlayer(getObjectId());
  128. if (((L2PcInstance)this).getPet() != null)
  129. ((L2PcInstance)this).getPet().setInstanceId(instanceId);
  130. }
  131. else if (this instanceof L2Npc)
  132. {
  133. if (_instanceId > 0)
  134. InstanceManager.getInstance().getInstance(_instanceId).removeNpc(((L2Npc)this));
  135. if (instanceId > 0)
  136. InstanceManager.getInstance().getInstance(instanceId).addNpc(((L2Npc)this));
  137. }
  138. _instanceId = instanceId;
  139. // If we change it for visible objects, me must clear & revalidate knownlists
  140. if (_isVisible && _knownList != null)
  141. {
  142. if (this instanceof L2PcInstance)
  143. {
  144. // We don't want some ugly looking disappear/appear effects, so don't update
  145. // the knownlist here, but players usually enter instancezones through teleporting
  146. // and the teleport will do the revalidation for us.
  147. }
  148. else
  149. {
  150. decayMe();
  151. spawnMe();
  152. }
  153. }
  154. }
  155. public final int getY()
  156. {
  157. if (Config.ASSERT) assert getPosition().getWorldRegion() != null || _isVisible;
  158. return getPosition().getY();
  159. }
  160. public final int getZ()
  161. {
  162. if (Config.ASSERT) assert getPosition().getWorldRegion() != null || _isVisible;
  163. return getPosition().getZ();
  164. }
  165. // =========================================================
  166. // Method - Public
  167. /**
  168. * Remove a L2Object from the world.<BR><BR>
  169. *
  170. * <B><U> Actions</U> :</B><BR><BR>
  171. * <li>Remove the L2Object from the world</li><BR><BR>
  172. *
  173. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World </B></FONT><BR>
  174. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND Server->Client packets to players</B></FONT><BR><BR>
  175. *
  176. * <B><U> Assert </U> :</B><BR><BR>
  177. * <li> _worldRegion != null <I>(L2Object is visible at the beginning)</I></li><BR><BR>
  178. *
  179. * <B><U> Example of use </U> :</B><BR><BR>
  180. * <li> Delete NPC/PC or Unsummon</li><BR><BR>
  181. *
  182. */
  183. public final void decayMe()
  184. {
  185. if (Config.ASSERT) assert getPosition().getWorldRegion() != null;
  186. L2WorldRegion reg = getPosition().getWorldRegion();
  187. synchronized (this)
  188. {
  189. _isVisible = false;
  190. getPosition().setWorldRegion(null);
  191. }
  192. // this can synchronize on others instancies, so it's out of
  193. // synchronized, to avoid deadlocks
  194. // Remove the L2Object from the world
  195. L2World.getInstance().removeVisibleObject(this, reg);
  196. L2World.getInstance().removeObject(this);
  197. if (Config.SAVE_DROPPED_ITEM)
  198. ItemsOnGroundManager.getInstance().removeObject(this);
  199. }
  200. public void refreshID()
  201. {
  202. L2World.getInstance().removeObject(this);
  203. IdFactory.getInstance().releaseId(getObjectId());
  204. _objectId = IdFactory.getInstance().getNextId();
  205. }
  206. /**
  207. * Init the position of a L2Object spawn and add it in the world as a visible object.<BR><BR>
  208. *
  209. * <B><U> Actions</U> :</B><BR><BR>
  210. * <li>Set the x,y,z position of the L2Object spawn and update its _worldregion </li>
  211. * <li>Add the L2Object spawn in the _allobjects of L2World </li>
  212. * <li>Add the L2Object spawn to _visibleObjects of its L2WorldRegion</li>
  213. * <li>Add the L2Object spawn in the world as a <B>visible</B> object</li><BR><BR>
  214. *
  215. * <B><U> Assert </U> :</B><BR><BR>
  216. * <li> _worldRegion == null <I>(L2Object is invisible at the beginning)</I></li><BR><BR>
  217. *
  218. * <B><U> Example of use </U> :</B><BR><BR>
  219. * <li> Create Door</li>
  220. * <li> Spawn : Monster, Minion, CTs, Summon...</li><BR>
  221. *
  222. */
  223. public final void spawnMe()
  224. {
  225. if (Config.ASSERT) assert getPosition().getWorldRegion() == null && getPosition().getWorldPosition().getX() != 0 && getPosition().getWorldPosition().getY() != 0 && getPosition().getWorldPosition().getZ() != 0;
  226. synchronized (this)
  227. {
  228. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  229. _isVisible = true;
  230. getPosition().setWorldRegion(L2World.getInstance().getRegion(getPosition().getWorldPosition()));
  231. // Add the L2Object spawn in the _allobjects of L2World
  232. L2World.getInstance().storeObject(this);
  233. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  234. getPosition().getWorldRegion().addVisibleObject(this);
  235. }
  236. // this can synchronize on others instancies, so it's out of
  237. // synchronized, to avoid deadlocks
  238. // Add the L2Object spawn in the world as a visible object
  239. L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion());
  240. onSpawn();
  241. }
  242. public final void spawnMe(int x, int y, int z)
  243. {
  244. if (Config.ASSERT) assert getPosition().getWorldRegion() == null;
  245. synchronized (this)
  246. {
  247. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  248. _isVisible = true;
  249. if (x > L2World.MAP_MAX_X) x = L2World.MAP_MAX_X - 5000;
  250. if (x < L2World.MAP_MIN_X) x = L2World.MAP_MIN_X + 5000;
  251. if (y > L2World.MAP_MAX_Y) y = L2World.MAP_MAX_Y - 5000;
  252. if (y < L2World.MAP_MIN_Y) y = L2World.MAP_MIN_Y + 5000;
  253. getPosition().setWorldPosition(x, y ,z);
  254. getPosition().setWorldRegion(L2World.getInstance().getRegion(getPosition().getWorldPosition()));
  255. // Add the L2Object spawn in the _allobjects of L2World
  256. }
  257. L2World.getInstance().storeObject(this);
  258. // these can synchronize on others instancies, so they're out of
  259. // synchronized, to avoid deadlocks
  260. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  261. getPosition().getWorldRegion().addVisibleObject(this);
  262. // Add the L2Object spawn in the world as a visible object
  263. L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion());
  264. onSpawn();
  265. }
  266. public void toggleVisible()
  267. {
  268. if (isVisible())
  269. decayMe();
  270. else
  271. spawnMe();
  272. }
  273. // =========================================================
  274. // Method - Private
  275. // =========================================================
  276. // Property - Public
  277. public boolean isAttackable()
  278. {
  279. return false;
  280. }
  281. public abstract boolean isAutoAttackable(L2Character attacker);
  282. public boolean isMarker()
  283. {
  284. return false;
  285. }
  286. /**
  287. * Return the visibilty state of the L2Object. <BR><BR>
  288. *
  289. * <B><U> Concept</U> :</B><BR><BR>
  290. * A L2Object is visble if <B>__IsVisible</B>=true and <B>_worldregion</B>!=null <BR><BR>
  291. */
  292. public final boolean isVisible()
  293. {
  294. //return getPosition().getWorldRegion() != null && _IsVisible;
  295. return getPosition().getWorldRegion() != null;
  296. }
  297. public final void setIsVisible(boolean value)
  298. {
  299. _isVisible = value;
  300. if (!_isVisible) getPosition().setWorldRegion(null);
  301. }
  302. public ObjectKnownList getKnownList()
  303. {
  304. return _knownList;
  305. }
  306. /**
  307. * Initializes the KnownList of the L2Object,
  308. * is overwritten in classes that require a different knownlist Type.
  309. *
  310. * Removes the need for instanceof checks.
  311. */
  312. public void initKnownList()
  313. {
  314. _knownList = new ObjectKnownList(this);
  315. }
  316. public final void setKnownList(ObjectKnownList value)
  317. {
  318. _knownList = value;
  319. }
  320. public final String getName()
  321. {
  322. return _name;
  323. }
  324. public final void setName(String value)
  325. {
  326. _name = value;
  327. }
  328. public final int getObjectId()
  329. {
  330. return _objectId;
  331. }
  332. public final ObjectPoly getPoly()
  333. {
  334. if (_poly == null) _poly = new ObjectPoly(this);
  335. return _poly;
  336. }
  337. public ObjectPosition getPosition()
  338. {
  339. return _position;
  340. }
  341. /**
  342. * Initializes the Position class of the L2Object,
  343. * is overwritten in classes that require a different position Type.
  344. *
  345. * Removes the need for instanceof checks.
  346. */
  347. public void initPosition()
  348. {
  349. _position = new ObjectPosition(this);
  350. }
  351. public final void setObjectPosition(ObjectPosition value)
  352. {
  353. _position = value;
  354. }
  355. /**
  356. * returns reference to region this object is in
  357. */
  358. public L2WorldRegion getWorldRegion()
  359. {
  360. return getPosition().getWorldRegion();
  361. }
  362. public L2PcInstance getActingPlayer()
  363. {
  364. return null;
  365. }
  366. /**
  367. * Sends the Server->Client info packet for the object.<br><br>
  368. * Is Overridden in:
  369. * <li>L2AirShipInstance</li>
  370. * <li>L2BoatInstance</li>
  371. * <li>L2DoorInstance</li>
  372. * <li>L2PcInstance</li>
  373. * <li>L2StaticObjectInstance</li>
  374. * <li>L2Decoy</li>
  375. * <li>L2Npc</li>
  376. * <li>L2Summon</li>
  377. * <li>L2Trap</li>
  378. * <li>L2ItemInstance</li>
  379. */
  380. public void sendInfo(L2PcInstance activeChar)
  381. {
  382. }
  383. @Override
  384. public String toString()
  385. {
  386. return "" + getObjectId();
  387. }
  388. /**
  389. * Not Implemented.<BR><BR>
  390. *
  391. * <B><U> Overridden in </U> :</B><BR><BR>
  392. * <li> L2PcInstance</li><BR><BR>
  393. */
  394. public void sendPacket(L2GameServerPacket mov)
  395. {
  396. // default implementation
  397. }
  398. }