L2Object.java 14 KB

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