L2Object.java 12 KB

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