L2Object.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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.ItemsOnGroundManager;
  19. import net.sf.l2j.gameserver.instancemanager.MercTicketManager;
  20. import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  21. import net.sf.l2j.gameserver.model.actor.knownlist.ObjectKnownList;
  22. import net.sf.l2j.gameserver.model.actor.poly.ObjectPoly;
  23. import net.sf.l2j.gameserver.model.actor.position.ObjectPosition;
  24. import net.sf.l2j.gameserver.model.quest.QuestState;
  25. import net.sf.l2j.gameserver.network.L2GameClient;
  26. import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
  27. import net.sf.l2j.gameserver.network.serverpackets.GetItem;
  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. // =========================================================
  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. public final int getY()
  95. {
  96. if (Config.ASSERT) assert getPosition().getWorldRegion() != null || _isVisible;
  97. return getPosition().getY();
  98. }
  99. public final int getZ()
  100. {
  101. if (Config.ASSERT) assert getPosition().getWorldRegion() != null || _isVisible;
  102. return getPosition().getZ();
  103. }
  104. // =========================================================
  105. // Method - Public
  106. /**
  107. * Remove a L2Object from the world.<BR><BR>
  108. *
  109. * <B><U> Actions</U> :</B><BR><BR>
  110. * <li>Remove the L2Object from the world</li><BR><BR>
  111. *
  112. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World </B></FONT><BR>
  113. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND Server->Client packets to players</B></FONT><BR><BR>
  114. *
  115. * <B><U> Assert </U> :</B><BR><BR>
  116. * <li> _worldRegion != null <I>(L2Object is visible at the beginning)</I></li><BR><BR>
  117. *
  118. * <B><U> Example of use </U> :</B><BR><BR>
  119. * <li> Delete NPC/PC or Unsummon</li><BR><BR>
  120. *
  121. */
  122. public final void decayMe()
  123. {
  124. if (Config.ASSERT) assert getPosition().getWorldRegion() != null;
  125. L2WorldRegion reg = getPosition().getWorldRegion();
  126. synchronized (this)
  127. {
  128. _isVisible = false;
  129. getPosition().setWorldRegion(null);
  130. }
  131. // this can synchronize on others instancies, so it's out of
  132. // synchronized, to avoid deadlocks
  133. // Remove the L2Object from the world
  134. L2World.getInstance().removeVisibleObject(this, reg);
  135. L2World.getInstance().removeObject(this);
  136. if (Config.SAVE_DROPPED_ITEM)
  137. ItemsOnGroundManager.getInstance().removeObject(this);
  138. }
  139. /**
  140. * Remove a L2ItemInstance from the world and send server->client GetItem packets.<BR><BR>
  141. *
  142. * <B><U> Actions</U> :</B><BR><BR>
  143. * <li>Send a Server->Client Packet GetItem to player that pick up and its _knowPlayers member </li>
  144. * <li>Remove the L2Object from the world</li><BR><BR>
  145. *
  146. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World </B></FONT><BR><BR>
  147. *
  148. * <B><U> Assert </U> :</B><BR><BR>
  149. * <li> this instanceof L2ItemInstance</li>
  150. * <li> _worldRegion != null <I>(L2Object is visible at the beginning)</I></li><BR><BR>
  151. *
  152. * <B><U> Example of use </U> :</B><BR><BR>
  153. * <li> Do Pickup Item : PCInstance and Pet</li><BR><BR>
  154. *
  155. * @param player Player that pick up the item
  156. *
  157. */
  158. public final void pickupMe(L2Character player) // NOTE: Should move this function into L2ItemInstance because it does not apply to L2Character
  159. {
  160. if (Config.ASSERT) assert this instanceof L2ItemInstance;
  161. if (Config.ASSERT) assert getPosition().getWorldRegion() != null;
  162. L2WorldRegion oldregion = getPosition().getWorldRegion();
  163. // Create a server->client GetItem packet to pick up the L2ItemInstance
  164. GetItem gi = new GetItem((L2ItemInstance)this, player.getObjectId());
  165. player.broadcastPacket(gi);
  166. synchronized (this)
  167. {
  168. _isVisible = false;
  169. getPosition().setWorldRegion(null);
  170. }
  171. // if this item is a mercenary ticket, remove the spawns!
  172. if (this instanceof L2ItemInstance)
  173. {
  174. int itemId = ((L2ItemInstance)this).getItemId();
  175. if (MercTicketManager.getInstance().getTicketCastleId(itemId) > 0)
  176. {
  177. MercTicketManager.getInstance().removeTicket((L2ItemInstance)this);
  178. ItemsOnGroundManager.getInstance().removeObject(this);
  179. }
  180. if (itemId == 57 || itemId == 6353)
  181. {
  182. QuestState qs = null;
  183. if (player instanceof L2Summon)
  184. {
  185. qs = ((L2Summon)player).getOwner().getQuestState("255_Tutorial");
  186. if (qs != null)
  187. qs.getQuest().notifyEvent("CE"+itemId+"",null,((L2Summon)player).getOwner());
  188. }
  189. else if (player instanceof L2PcInstance)
  190. {
  191. qs = ((L2PcInstance)player).getQuestState("255_Tutorial");
  192. if (qs != null)
  193. qs.getQuest().notifyEvent("CE"+itemId+"",null,(L2PcInstance)player);
  194. }
  195. }
  196. }
  197. // outside of synchronized to avoid deadlocks
  198. // Remove the L2ItemInstance from the world
  199. L2World.getInstance().removeVisibleObject(this, oldregion);
  200. }
  201. public void refreshID()
  202. {
  203. L2World.getInstance().removeObject(this);
  204. IdFactory.getInstance().releaseId(getObjectId());
  205. _objectId = IdFactory.getInstance().getNextId();
  206. }
  207. /**
  208. * Init the position of a L2Object spawn and add it in the world as a visible object.<BR><BR>
  209. *
  210. * <B><U> Actions</U> :</B><BR><BR>
  211. * <li>Set the x,y,z position of the L2Object spawn and update its _worldregion </li>
  212. * <li>Add the L2Object spawn in the _allobjects of L2World </li>
  213. * <li>Add the L2Object spawn to _visibleObjects of its L2WorldRegion</li>
  214. * <li>Add the L2Object spawn in the world as a <B>visible</B> object</li><BR><BR>
  215. *
  216. * <B><U> Assert </U> :</B><BR><BR>
  217. * <li> _worldRegion == null <I>(L2Object is invisible at the beginning)</I></li><BR><BR>
  218. *
  219. * <B><U> Example of use </U> :</B><BR><BR>
  220. * <li> Create Door</li>
  221. * <li> Spawn : Monster, Minion, CTs, Summon...</li><BR>
  222. *
  223. */
  224. public final void spawnMe()
  225. {
  226. if (Config.ASSERT) assert getPosition().getWorldRegion() == null && getPosition().getWorldPosition().getX() != 0 && getPosition().getWorldPosition().getY() != 0 && getPosition().getWorldPosition().getZ() != 0;
  227. synchronized (this)
  228. {
  229. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  230. _isVisible = true;
  231. getPosition().setWorldRegion(L2World.getInstance().getRegion(getPosition().getWorldPosition()));
  232. // Add the L2Object spawn in the _allobjects of L2World
  233. L2World.getInstance().storeObject(this);
  234. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  235. getPosition().getWorldRegion().addVisibleObject(this);
  236. }
  237. // this can synchronize on others instancies, so it's out of
  238. // synchronized, to avoid deadlocks
  239. // Add the L2Object spawn in the world as a visible object
  240. L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion(), null);
  241. onSpawn();
  242. }
  243. public final void spawnMe(int x, int y, int z)
  244. {
  245. if (Config.ASSERT) assert getPosition().getWorldRegion() == null;
  246. synchronized (this)
  247. {
  248. // Set the x,y,z position of the L2Object spawn and update its _worldregion
  249. _isVisible = true;
  250. if (x > L2World.MAP_MAX_X) x = L2World.MAP_MAX_X - 5000;
  251. if (x < L2World.MAP_MIN_X) x = L2World.MAP_MIN_X + 5000;
  252. if (y > L2World.MAP_MAX_Y) y = L2World.MAP_MAX_Y - 5000;
  253. if (y < L2World.MAP_MIN_Y) y = L2World.MAP_MIN_Y + 5000;
  254. getPosition().setWorldPosition(x, y ,z);
  255. getPosition().setWorldRegion(L2World.getInstance().getRegion(getPosition().getWorldPosition()));
  256. // Add the L2Object spawn in the _allobjects of L2World
  257. }
  258. L2World.getInstance().storeObject(this);
  259. // these can synchronize on others instancies, so they're out of
  260. // synchronized, to avoid deadlocks
  261. // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
  262. getPosition().getWorldRegion().addVisibleObject(this);
  263. // Add the L2Object spawn in the world as a visible object
  264. L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion(), null);
  265. onSpawn();
  266. }
  267. public void toggleVisible()
  268. {
  269. if (isVisible())
  270. decayMe();
  271. else
  272. spawnMe();
  273. }
  274. // =========================================================
  275. // Method - Private
  276. // =========================================================
  277. // Property - Public
  278. public boolean isAttackable()
  279. {
  280. return false;
  281. }
  282. public abstract boolean isAutoAttackable(L2Character attacker);
  283. public boolean isMarker()
  284. {
  285. return false;
  286. }
  287. /**
  288. * Return the visibilty state of the L2Object. <BR><BR>
  289. *
  290. * <B><U> Concept</U> :</B><BR><BR>
  291. * A L2Object is visble if <B>__IsVisible</B>=true and <B>_worldregion</B>!=null <BR><BR>
  292. */
  293. public final boolean isVisible()
  294. {
  295. //return getPosition().getWorldRegion() != null && _IsVisible;
  296. return getPosition().getWorldRegion() != null;
  297. }
  298. public final void setIsVisible(boolean value)
  299. {
  300. _isVisible = value;
  301. if (!_isVisible) getPosition().setWorldRegion(null);
  302. }
  303. public ObjectKnownList getKnownList()
  304. {
  305. if (_knownList == null) _knownList = new ObjectKnownList(this);
  306. return _knownList;
  307. }
  308. public final void setKnownList(ObjectKnownList value) { _knownList = value; }
  309. public final String getName()
  310. {
  311. return _name;
  312. }
  313. public final void setName(String value)
  314. {
  315. _name = value;
  316. }
  317. public final int getObjectId()
  318. {
  319. return _objectId;
  320. }
  321. public final ObjectPoly getPoly()
  322. {
  323. if (_poly == null) _poly = new ObjectPoly(this);
  324. return _poly;
  325. }
  326. public final ObjectPosition getPosition()
  327. {
  328. if (_position == null) _position = new ObjectPosition(this);
  329. return _position;
  330. }
  331. /**
  332. * returns reference to region this object is in
  333. */
  334. public L2WorldRegion getWorldRegion()
  335. {
  336. return getPosition().getWorldRegion();
  337. }
  338. @Override
  339. public String toString()
  340. {
  341. return "" + getObjectId();
  342. }
  343. }