L2Object.java 12 KB

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