L2World.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  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 gnu.trove.TIntObjectHashMap;
  17. import gnu.trove.TObjectProcedure;
  18. import java.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.concurrent.locks.Lock;
  23. import java.util.concurrent.locks.ReentrantReadWriteLock;
  24. import java.util.logging.Logger;
  25. import javolution.util.FastList;
  26. import com.l2jserver.Config;
  27. import com.l2jserver.gameserver.GmListTable;
  28. import com.l2jserver.gameserver.datatables.CharNameTable;
  29. import com.l2jserver.gameserver.model.actor.L2Playable;
  30. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  31. import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
  32. import com.l2jserver.gameserver.util.Point3D;
  33. import com.l2jserver.util.StringUtil;
  34. /**
  35. * This class ...
  36. *
  37. * @version $Revision: 1.21.2.5.2.7 $ $Date: 2005/03/27 15:29:32 $
  38. */
  39. public final class L2World
  40. {
  41. private static Logger _log = Logger.getLogger(L2World.class.getName());
  42. /**
  43. * Gracia border
  44. * Flying objects not allowed to the east of it.
  45. */
  46. public static final int GRACIA_MAX_X = -166168;
  47. public static final int GRACIA_MAX_Z = 6105;
  48. public static final int GRACIA_MIN_Z = -895;
  49. /*
  50. * biteshift, defines number of regions
  51. * note, shifting by 15 will result in regions corresponding to map tiles
  52. * shifting by 12 divides one tile to 8x8 regions
  53. */
  54. public static final int SHIFT_BY = 12;
  55. private static final int TILE_SIZE = 32768;
  56. /** Map dimensions */
  57. public static final int MAP_MIN_X = (Config.WORLD_X_MIN - 20) * TILE_SIZE;
  58. public static final int MAP_MAX_X = (Config.WORLD_X_MAX - 19) * TILE_SIZE;
  59. public static final int MAP_MIN_Y = (Config.WORLD_Y_MIN - 18) * TILE_SIZE;
  60. public static final int MAP_MAX_Y = (Config.WORLD_Y_MAX - 17) * TILE_SIZE;
  61. /** calculated offset used so top left region is 0,0 */
  62. public static final int OFFSET_X = Math.abs(MAP_MIN_X >> SHIFT_BY);
  63. public static final int OFFSET_Y = Math.abs(MAP_MIN_Y >> SHIFT_BY);
  64. /** number of regions */
  65. private static final int REGIONS_X = (MAP_MAX_X >> SHIFT_BY) + OFFSET_X;
  66. private static final int REGIONS_Y = (MAP_MAX_Y >> SHIFT_BY) + OFFSET_Y;
  67. //private FastMap<String, L2PcInstance> _allGms;
  68. /** HashMap(Integer Player id, L2PcInstance) containing all the players in game */
  69. private TIntObjectHashMap<L2PcInstance> _allPlayers;
  70. private final Lock _apRL;
  71. private final Lock _apWL;
  72. /** L2ObjectHashMap(L2Object) containing all visible objects */
  73. private TIntObjectHashMap<L2Object> _allObjects;
  74. private final Lock _aoRL;
  75. private final Lock _aoWL;
  76. /** List with the pets instances and their owner id */
  77. private TIntObjectHashMap<L2PetInstance> _petsInstance;
  78. private final Lock _piRL;
  79. private final Lock _piWL;
  80. private L2WorldRegion[][] _worldRegions;
  81. /**
  82. * Constructor of L2World.<BR><BR>
  83. */
  84. private L2World()
  85. {
  86. ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  87. _apRL = lock.readLock();
  88. _apWL = lock.writeLock();
  89. _allPlayers = new TIntObjectHashMap<L2PcInstance>();
  90. lock = new ReentrantReadWriteLock();
  91. _aoRL = lock.readLock();
  92. _aoWL = lock.writeLock();
  93. _allObjects = new TIntObjectHashMap<L2Object>();
  94. lock = new ReentrantReadWriteLock();
  95. _piRL = lock.readLock();
  96. _piWL = lock.writeLock();
  97. _petsInstance = new TIntObjectHashMap<L2PetInstance>();
  98. initRegions();
  99. }
  100. /**
  101. * Return the current instance of L2World.<BR><BR>
  102. */
  103. public static L2World getInstance()
  104. {
  105. return SingletonHolder._instance;
  106. }
  107. /**
  108. * Add L2Object object in _allObjects.<BR><BR>
  109. *
  110. * <B><U> Example of use </U> :</B><BR><BR>
  111. * <li> Withdraw an item from the warehouse, create an item</li>
  112. * <li> Spawn a L2Character (PC, NPC, Pet)</li><BR>
  113. */
  114. public void storeObject(L2Object object)
  115. {
  116. _aoWL.lock();
  117. try
  118. {
  119. _aoRL.lock();
  120. try
  121. {
  122. assert !_allObjects.containsKey(object.getObjectId());
  123. if (_allObjects.containsKey(object.getObjectId()))
  124. {
  125. if (Config.DEBUG)
  126. {
  127. _log.warning("[L2World] object: " + object + " already exist in OID map!");
  128. _log.info(StringUtil.getTraceString(Thread.currentThread().getStackTrace()));
  129. return;
  130. }
  131. }
  132. }
  133. finally
  134. {
  135. _aoRL.unlock();
  136. }
  137. _allObjects.put(object.getObjectId(), object);
  138. }
  139. finally
  140. {
  141. _aoWL.unlock();
  142. }
  143. }
  144. public long timeStoreObject(L2Object object)
  145. {
  146. _aoWL.lock();
  147. try
  148. {
  149. long time = System.nanoTime();
  150. _allObjects.put(object.getObjectId(), object);
  151. time = System.nanoTime() - time;
  152. return time;
  153. }
  154. finally
  155. {
  156. _aoWL.unlock();
  157. }
  158. }
  159. /**
  160. * Remove L2Object object from _allObjects of L2World.<BR><BR>
  161. *
  162. * <B><U> Example of use </U> :</B><BR><BR>
  163. * <li> Delete item from inventory, tranfer Item from inventory to warehouse</li>
  164. * <li> Crystallize item</li>
  165. * <li> Remove NPC/PC/Pet from the world</li><BR>
  166. *
  167. * @param object L2Object to remove from _allObjects of L2World
  168. *
  169. */
  170. public void removeObject(L2Object object)
  171. {
  172. _aoWL.lock();
  173. try
  174. {
  175. _allObjects.remove(object.getObjectId()); // suggestion by whatev
  176. //IdFactory.getInstance().releaseId(object.getObjectId());
  177. }
  178. finally
  179. {
  180. _aoWL.unlock();
  181. }
  182. }
  183. public void removeObjects(List<L2Object> list)
  184. {
  185. _aoWL.lock();
  186. try
  187. {
  188. for (L2Object o : list)
  189. {
  190. if (o != null)
  191. _allObjects.remove(o.getObjectId()); // suggestion by whatev
  192. }
  193. //IdFactory.getInstance().releaseId(object.getObjectId());
  194. }
  195. finally
  196. {
  197. _aoWL.unlock();
  198. }
  199. }
  200. public void removeObjects(L2Object[] objects)
  201. {
  202. _aoWL.lock();
  203. try
  204. {
  205. for (L2Object o : objects)
  206. _allObjects.remove(o.getObjectId()); // suggestion by whatev
  207. //IdFactory.getInstance().releaseId(object.getObjectId());
  208. }
  209. finally
  210. {
  211. _aoWL.unlock();
  212. }
  213. }
  214. public long timeRemoveObject(L2Object object)
  215. {
  216. _aoWL.lock();
  217. try
  218. {
  219. long time = System.nanoTime();
  220. _allObjects.remove(object.getObjectId());
  221. time = System.nanoTime() - time;
  222. return time;
  223. }
  224. finally
  225. {
  226. _aoWL.unlock();
  227. }
  228. }
  229. /**
  230. * Return the L2Object object that belongs to an ID or null if no object found.<BR><BR>
  231. *
  232. * <B><U> Example of use </U> :</B><BR><BR>
  233. * <li> Client packets : Action, AttackRequest, RequestJoinParty, RequestJoinPledge...</li><BR>
  234. *
  235. * @param oID Identifier of the L2Object
  236. */
  237. public L2Object findObject(int oID)
  238. {
  239. _aoRL.lock();
  240. try
  241. {
  242. return _allObjects.get(oID);
  243. }
  244. finally
  245. {
  246. _aoRL.unlock();
  247. }
  248. }
  249. public long timeFindObject(int objectID)
  250. {
  251. _aoRL.lock();
  252. try
  253. {
  254. long time = System.nanoTime();
  255. _allObjects.get(objectID);
  256. time = System.nanoTime() - time;
  257. return time;
  258. }
  259. finally
  260. {
  261. _aoRL.unlock();
  262. }
  263. }
  264. /**
  265. * Added by Tempy - 08 Aug 05
  266. * Allows easy retrevial of all visible objects in world.
  267. *
  268. * -- do not use that fucntion, its unsafe!
  269. *
  270. * @deprecated
  271. */
  272. @Deprecated
  273. public final TIntObjectHashMap<L2Object> getAllVisibleObjects()
  274. {
  275. _aoRL.lock();
  276. try
  277. {
  278. return _allObjects;
  279. }
  280. finally
  281. {
  282. _aoRL.unlock();
  283. }
  284. }
  285. public final L2Object[] getAllVisibleObjectsArray()
  286. {
  287. _aoRL.lock();
  288. try
  289. {
  290. return _allObjects.getValues(new L2Object[_allObjects.size()]);
  291. }
  292. finally
  293. {
  294. _aoRL.unlock();
  295. }
  296. }
  297. public final boolean forEachObject(final TObjectProcedure<L2Object> proc)
  298. {
  299. _aoRL.lock();
  300. try
  301. {
  302. return _allObjects.forEachValue(proc);
  303. }
  304. finally
  305. {
  306. _aoRL.unlock();
  307. }
  308. }
  309. /**
  310. * Get the count of all visible objects in world.<br><br>
  311. *
  312. * @return count off all L2World objects
  313. */
  314. public final int getAllVisibleObjectsCount()
  315. {
  316. return _allObjects.size();
  317. }
  318. /**
  319. * Return a table containing all GMs.<BR><BR>
  320. *
  321. */
  322. public FastList<L2PcInstance> getAllGMs()
  323. {
  324. return GmListTable.getInstance().getAllGms(true);
  325. }
  326. public TIntObjectHashMap<L2PcInstance> getAllPlayers()
  327. {
  328. _apRL.lock();
  329. try
  330. {
  331. return _allPlayers;
  332. }
  333. finally
  334. {
  335. _apRL.unlock();
  336. }
  337. }
  338. public final L2PcInstance[] getAllPlayersArray()
  339. {
  340. _apRL.lock();
  341. try
  342. {
  343. return _allPlayers.getValues(new L2PcInstance[_allPlayers.size()]);
  344. }
  345. finally
  346. {
  347. _apRL.unlock();
  348. }
  349. }
  350. public final boolean forEachPlayer(final TObjectProcedure<L2PcInstance> proc)
  351. {
  352. _apRL.lock();
  353. try
  354. {
  355. return _allPlayers.forEachValue(proc);
  356. }
  357. finally
  358. {
  359. _apRL.unlock();
  360. }
  361. }
  362. /**
  363. * Return how many players are online.<BR><BR>
  364. *
  365. * @return number of online players.
  366. */
  367. public int getAllPlayersCount()
  368. {
  369. return _allPlayers.size();
  370. }
  371. /**
  372. * Return the player instance corresponding to the given name.<BR><BR>
  373. * <B>If you have access to player objectId use {@link #getPlayer(int playerObjId)}</B>
  374. * <BR>
  375. * @param name Name of the player to get Instance
  376. */
  377. public L2PcInstance getPlayer(String name)
  378. {
  379. return getPlayer(CharNameTable.getInstance().getIdByName(name));
  380. }
  381. /**
  382. * Return the player instance corresponding to the given object ID.<BR><BR>
  383. *
  384. * @param playerObjId Object ID of the player to get Instance
  385. */
  386. public L2PcInstance getPlayer(int playerObjId)
  387. {
  388. _apRL.lock();
  389. try
  390. {
  391. return _allPlayers.get(playerObjId);
  392. }
  393. finally
  394. {
  395. _apRL.unlock();
  396. }
  397. }
  398. /**
  399. * Return the pet instance from the given ownerId.<BR><BR>
  400. *
  401. * @param ownerId ID of the owner
  402. */
  403. public L2PetInstance getPet(int ownerId)
  404. {
  405. _piRL.lock();
  406. try
  407. {
  408. return _petsInstance.get(ownerId);
  409. }
  410. finally
  411. {
  412. _piRL.unlock();
  413. }
  414. }
  415. /**
  416. * Add the given pet instance from the given ownerId.<BR><BR>
  417. *
  418. * @param ownerId ID of the owner
  419. * @param pet L2PetInstance of the pet
  420. */
  421. public L2PetInstance addPet(int ownerId, L2PetInstance pet)
  422. {
  423. _piWL.lock();
  424. try
  425. {
  426. return _petsInstance.put(ownerId, pet);
  427. }
  428. finally
  429. {
  430. _piWL.unlock();
  431. }
  432. }
  433. /**
  434. * Remove the given pet instance.<BR><BR>
  435. *
  436. * @param ownerId ID of the owner
  437. */
  438. public void removePet(int ownerId)
  439. {
  440. _piWL.lock();
  441. try
  442. {
  443. _petsInstance.remove(ownerId);
  444. }
  445. finally
  446. {
  447. _piWL.unlock();
  448. }
  449. }
  450. /**
  451. * Remove the given pet instance.<BR><BR>
  452. *
  453. * @param pet the pet to remove
  454. */
  455. public void removePet(L2PetInstance pet)
  456. {
  457. _piWL.lock();
  458. try
  459. {
  460. _petsInstance.remove(pet.getOwner().getObjectId());
  461. }
  462. finally
  463. {
  464. _piWL.unlock();
  465. }
  466. }
  467. /**
  468. * Add a L2Object in the world.<BR><BR>
  469. *
  470. * <B><U> Concept</U> :</B><BR><BR>
  471. * L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in <B>_knownObjects</B> of other surrounding L2Characters <BR>
  472. * L2PcInstance are identified in <B>_allPlayers</B> of L2World, in <B>_allPlayers</B> of his current L2WorldRegion and in <B>_knownPlayer</B> of other surrounding L2Characters <BR><BR>
  473. *
  474. * <B><U> Actions</U> :</B><BR><BR>
  475. * <li>Add the L2Object object in _allPlayers* of L2World </li>
  476. * <li>Add the L2Object object in _gmList** of GmListTable </li>
  477. * <li>Add object in _knownObjects and _knownPlayer* of all surrounding L2WorldRegion L2Characters </li><BR>
  478. *
  479. * <li>If object is a L2Character, add all surrounding L2Object in its _knownObjects and all surrounding L2PcInstance in its _knownPlayer </li><BR>
  480. *
  481. * <I>* only if object is a L2PcInstance</I><BR>
  482. * <I>** only if object is a GM L2PcInstance</I><BR><BR>
  483. *
  484. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T ADD the object in _visibleObjects and _allPlayers* of L2WorldRegion (need synchronisation)</B></FONT><BR>
  485. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T ADD the object to _allObjects and _allPlayers* of L2World (need synchronisation)</B></FONT><BR><BR>
  486. *
  487. * <B><U> Example of use </U> :</B><BR><BR>
  488. * <li> Drop an Item </li>
  489. * <li> Spawn a L2Character</li>
  490. * <li> Apply Death Penalty of a L2PcInstance </li><BR><BR>
  491. *
  492. * @param object L2object to add in the world
  493. * @param newregion L2WorldRegion in wich the object will be add (not used)
  494. * @param dropper L2Character who has dropped the object (if necessary)
  495. *
  496. */
  497. public void addVisibleObject(L2Object object, L2WorldRegion newRegion)
  498. {
  499. // If selected L2Object is a L2PcIntance, add it in L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
  500. // XXX TODO: this code should be obsoleted by protection in putObject func...
  501. if (object instanceof L2PcInstance)
  502. {
  503. L2PcInstance player = (L2PcInstance) object;
  504. if (!player.isTeleporting())
  505. {
  506. L2PcInstance tmp = getPlayer(player.getObjectId());
  507. if (tmp != null)
  508. {
  509. _log.warning("Duplicate character!? Closing both characters (" + player.getName() + ")");
  510. player.logout();
  511. tmp.logout();
  512. return;
  513. }
  514. addToAllPlayers(player);
  515. }
  516. }
  517. if (!newRegion.isActive())
  518. return;
  519. // Get all visible objects contained in the _visibleObjects of L2WorldRegions
  520. // in a circular area of 2000 units
  521. List<L2Object> visibles = getVisibleObjects(object, 2000);
  522. if (Config.DEBUG)
  523. _log.finest("objects in range:" + visibles.size());
  524. // tell the player about the surroundings
  525. // Go through the visible objects contained in the circular area
  526. for (L2Object visible : visibles)
  527. {
  528. if (visible == null)
  529. continue;
  530. // Add the object in L2ObjectHashSet(L2Object) _knownObjects of the visible L2Character according to conditions :
  531. // - L2Character is visible
  532. // - object is not already known
  533. // - object is in the watch distance
  534. // If L2Object is a L2PcInstance, add L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the visible L2Character
  535. visible.getKnownList().addKnownObject(object);
  536. // Add the visible L2Object in L2ObjectHashSet(L2Object) _knownObjects of the object according to conditions
  537. // If visible L2Object is a L2PcInstance, add visible L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the object
  538. object.getKnownList().addKnownObject(visible);
  539. }
  540. }
  541. /**
  542. * Add the L2PcInstance to _allPlayers of L2World.<BR><BR>
  543. *
  544. */
  545. public void addToAllPlayers(L2PcInstance cha)
  546. {
  547. _apWL.lock();
  548. try
  549. {
  550. _allPlayers.put(cha.getObjectId(), cha);
  551. }
  552. finally
  553. {
  554. _apWL.unlock();
  555. }
  556. }
  557. /**
  558. * Remove the L2PcInstance from _allPlayers of L2World.<BR><BR>
  559. *
  560. * <B><U> Example of use </U> :</B><BR><BR>
  561. * <li> Remove a player fom the visible objects </li><BR>
  562. *
  563. */
  564. public void removeFromAllPlayers(L2PcInstance cha)
  565. {
  566. _apWL.lock();
  567. try
  568. {
  569. _allPlayers.remove(cha.getObjectId());
  570. }
  571. finally
  572. {
  573. _apWL.unlock();
  574. }
  575. }
  576. /**
  577. * Remove a L2Object from the world.<BR><BR>
  578. *
  579. * <B><U> Concept</U> :</B><BR><BR>
  580. * L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in <B>_knownObjects</B> of other surrounding L2Characters <BR>
  581. * L2PcInstance are identified in <B>_allPlayers</B> of L2World, in <B>_allPlayers</B> of his current L2WorldRegion and in <B>_knownPlayer</B> of other surrounding L2Characters <BR><BR>
  582. *
  583. * <B><U> Actions</U> :</B><BR><BR>
  584. * <li>Remove the L2Object object from _allPlayers* of L2World </li>
  585. * <li>Remove the L2Object object from _visibleObjects and _allPlayers* of L2WorldRegion </li>
  586. * <li>Remove the L2Object object from _gmList** of GmListTable </li>
  587. * <li>Remove object from _knownObjects and _knownPlayer* of all surrounding L2WorldRegion L2Characters </li><BR>
  588. *
  589. * <li>If object is a L2Character, remove all L2Object from its _knownObjects and all L2PcInstance from its _knownPlayer </li><BR><BR>
  590. *
  591. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World</B></FONT><BR><BR>
  592. *
  593. * <I>* only if object is a L2PcInstance</I><BR>
  594. * <I>** only if object is a GM L2PcInstance</I><BR><BR>
  595. *
  596. * <B><U> Example of use </U> :</B><BR><BR>
  597. * <li> Pickup an Item </li>
  598. * <li> Decay a L2Character</li><BR><BR>
  599. *
  600. * @param object L2object to remove from the world
  601. * @param oldregion L2WorldRegion in wich the object was before removing
  602. *
  603. */
  604. public void removeVisibleObject(L2Object object, L2WorldRegion oldRegion)
  605. {
  606. if (object == null)
  607. return;
  608. //removeObject(object);
  609. if (oldRegion != null)
  610. {
  611. // Remove the object from the L2ObjectHashSet(L2Object) _visibleObjects of L2WorldRegion
  612. // If object is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _allPlayers of this L2WorldRegion
  613. oldRegion.removeVisibleObject(object);
  614. // Go through all surrounding L2WorldRegion L2Characters
  615. for (L2WorldRegion reg : oldRegion.getSurroundingRegions())
  616. {
  617. //synchronized (KnownListUpdateTaskManager.getInstance().getSync())
  618. {
  619. Collection<L2Object> vObj = reg.getVisibleObjects().values();
  620. //synchronized (reg.getVisibleObjects())
  621. {
  622. for (L2Object obj : vObj)
  623. {
  624. if (obj != null)
  625. {
  626. obj.getKnownList().removeKnownObject(object);
  627. object.getKnownList().removeKnownObject(obj);
  628. }
  629. }
  630. }
  631. }
  632. }
  633. // If object is a L2Character :
  634. // Remove all L2Object from L2ObjectHashSet(L2Object) containing all L2Object detected by the L2Character
  635. // Remove all L2PcInstance from L2ObjectHashSet(L2PcInstance) containing all player ingame detected by the L2Character
  636. object.getKnownList().removeAllKnownObjects();
  637. // If selected L2Object is a L2PcIntance, remove it from L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
  638. if (object instanceof L2PcInstance)
  639. {
  640. if (!((L2PcInstance) object).isTeleporting())
  641. removeFromAllPlayers((L2PcInstance) object);
  642. // If selected L2Object is a GM L2PcInstance, remove it from Set(L2PcInstance) _gmList of GmListTable
  643. //if (((L2PcInstance)object).isGM())
  644. //GmListTable.getInstance().deleteGm((L2PcInstance)object);
  645. }
  646. }
  647. }
  648. /**
  649. * Return all visible objects of the L2WorldRegion object's and of its surrounding L2WorldRegion.<BR><BR>
  650. *
  651. * <B><U> Concept</U> :</B><BR><BR>
  652. * All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  653. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR><BR>
  654. *
  655. * <B><U> Example of use </U> :</B><BR><BR>
  656. * <li> Find Close Objects for L2Character </li><BR>
  657. *
  658. * @param object L2object that determine the current L2WorldRegion
  659. *
  660. */
  661. public List<L2Object> getVisibleObjects(L2Object object)
  662. {
  663. L2WorldRegion reg = object.getWorldRegion();
  664. if (reg == null)
  665. return null;
  666. // Create an FastList in order to contain all visible L2Object
  667. List<L2Object> result = new ArrayList<L2Object>();
  668. // Go through the FastList of region
  669. for (L2WorldRegion regi : reg.getSurroundingRegions())
  670. {
  671. // Go through visible objects of the selected region
  672. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  673. //synchronized (regi.getVisibleObjects())
  674. {
  675. for (L2Object _object : vObj)
  676. {
  677. if (_object == null || _object.equals(object))
  678. continue; // skip our own character
  679. if (!_object.isVisible())
  680. continue; // skip dying objects
  681. result.add(_object);
  682. }
  683. }
  684. }
  685. return result;
  686. }
  687. /**
  688. * Return all visible objects of the L2WorldRegions in the circular area (radius) centered on the object.<BR><BR>
  689. *
  690. * <B><U> Concept</U> :</B><BR><BR>
  691. * All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  692. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR><BR>
  693. *
  694. * <B><U> Example of use </U> :</B><BR><BR>
  695. * <li> Define the aggrolist of monster </li>
  696. * <li> Define visible objects of a L2Object </li>
  697. * <li> Skill : Confusion... </li><BR>
  698. *
  699. * @param object L2object that determine the center of the circular area
  700. * @param radius Radius of the circular area
  701. *
  702. */
  703. public List<L2Object> getVisibleObjects(L2Object object, int radius)
  704. {
  705. if (object == null || !object.isVisible())
  706. return new ArrayList<L2Object>();
  707. int x = object.getX();
  708. int y = object.getY();
  709. int sqRadius = radius * radius;
  710. // Create an FastList in order to contain all visible L2Object
  711. List<L2Object> result = new ArrayList<L2Object>();
  712. // Go through the FastList of region
  713. for (L2WorldRegion regi : object.getWorldRegion().getSurroundingRegions())
  714. {
  715. // Go through visible objects of the selected region
  716. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  717. //synchronized (regi.getVisibleObjects())
  718. {
  719. for (L2Object _object : vObj)
  720. {
  721. if (_object == null || _object.equals(object))
  722. continue; // skip our own character
  723. int x1 = _object.getX();
  724. int y1 = _object.getY();
  725. double dx = x1 - x;
  726. double dy = y1 - y;
  727. if (dx * dx + dy * dy < sqRadius)
  728. result.add(_object);
  729. }
  730. }
  731. }
  732. return result;
  733. }
  734. /**
  735. * Return all visible objects of the L2WorldRegions in the spheric area (radius) centered on the object.<BR><BR>
  736. *
  737. * <B><U> Concept</U> :</B><BR><BR>
  738. * All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  739. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR><BR>
  740. *
  741. * <B><U> Example of use </U> :</B><BR><BR>
  742. * <li> Define the target list of a skill </li>
  743. * <li> Define the target list of a polearme attack </li><BR><BR>
  744. *
  745. * @param object L2object that determine the center of the circular area
  746. * @param radius Radius of the spheric area
  747. *
  748. */
  749. public List<L2Object> getVisibleObjects3D(L2Object object, int radius)
  750. {
  751. if (object == null || !object.isVisible())
  752. return new ArrayList<L2Object>();
  753. int x = object.getX();
  754. int y = object.getY();
  755. int z = object.getZ();
  756. int sqRadius = radius * radius;
  757. // Create an FastList in order to contain all visible L2Object
  758. List<L2Object> result = new ArrayList<L2Object>();
  759. // Go through visible object of the selected region
  760. for (L2WorldRegion regi : object.getWorldRegion().getSurroundingRegions())
  761. {
  762. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  763. //synchronized (regi.getVisibleObjects())
  764. {
  765. for (L2Object _object : vObj)
  766. {
  767. if (_object == null || _object.equals(object))
  768. continue; // skip our own character
  769. int x1 = _object.getX();
  770. int y1 = _object.getY();
  771. int z1 = _object.getZ();
  772. long dx = x1 - x;
  773. long dy = y1 - y;
  774. long dz = z1 - z;
  775. if (dx * dx + dy * dy + dz * dz < sqRadius)
  776. result.add(_object);
  777. }
  778. }
  779. }
  780. return result;
  781. }
  782. /**
  783. * Return all visible players of the L2WorldRegion object's and of its surrounding L2WorldRegion.<BR><BR>
  784. *
  785. * <B><U> Concept</U> :</B><BR><BR>
  786. * All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  787. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR><BR>
  788. *
  789. * <B><U> Example of use </U> :</B><BR><BR>
  790. * <li> Find Close Objects for L2Character </li><BR>
  791. *
  792. * @param object L2object that determine the current L2WorldRegion
  793. *
  794. */
  795. public List<L2Playable> getVisiblePlayable(L2Object object)
  796. {
  797. L2WorldRegion reg = object.getWorldRegion();
  798. if (reg == null)
  799. return null;
  800. // Create an FastList in order to contain all visible L2Object
  801. List<L2Playable> result = new ArrayList<L2Playable>();
  802. // Go through the FastList of region
  803. for (L2WorldRegion regi : reg.getSurroundingRegions())
  804. {
  805. // Create an Iterator to go through the visible L2Object of the L2WorldRegion
  806. Map<Integer, L2Playable> _allpls = regi.getVisiblePlayable();
  807. Collection<L2Playable> _playables = _allpls.values();
  808. // Go through visible object of the selected region
  809. //synchronized (_allpls)
  810. {
  811. for (L2Playable _object : _playables)
  812. {
  813. if (_object == null || _object.equals(object))
  814. continue; // skip our own character
  815. if (!_object.isVisible()) // GM invisible is different than this...
  816. continue; // skip dying objects
  817. result.add(_object);
  818. }
  819. }
  820. }
  821. return result;
  822. }
  823. /**
  824. * Calculate the current L2WorldRegions of the object according to its position (x,y).<BR><BR>
  825. *
  826. * <B><U> Example of use </U> :</B><BR><BR>
  827. * <li> Set position of a new L2Object (drop, spawn...) </li>
  828. * <li> Update position of a L2Object after a mouvement </li><BR>
  829. *
  830. * @param Point3D point position of the object
  831. */
  832. public L2WorldRegion getRegion(Point3D point)
  833. {
  834. return _worldRegions[(point.getX() >> SHIFT_BY) + OFFSET_X][(point.getY() >> SHIFT_BY) + OFFSET_Y];
  835. }
  836. public L2WorldRegion getRegion(int x, int y)
  837. {
  838. return _worldRegions[(x >> SHIFT_BY) + OFFSET_X][(y >> SHIFT_BY) + OFFSET_Y];
  839. }
  840. /**
  841. * Returns the whole 2d array containing the world regions
  842. * used by ZoneData.java to setup zones inside the world regions
  843. * @return
  844. */
  845. public L2WorldRegion[][] getAllWorldRegions()
  846. {
  847. return _worldRegions;
  848. }
  849. /**
  850. * Check if the current L2WorldRegions of the object is valid according to its position (x,y).<BR><BR>
  851. *
  852. * <B><U> Example of use </U> :</B><BR><BR>
  853. * <li> Init L2WorldRegions </li><BR>
  854. *
  855. * @param x X position of the object
  856. * @param y Y position of the object
  857. *
  858. * @return True if the L2WorldRegion is valid
  859. */
  860. private boolean validRegion(int x, int y)
  861. {
  862. return (x >= 0 && x <= REGIONS_X && y >= 0 && y <= REGIONS_Y);
  863. }
  864. /**
  865. * Init each L2WorldRegion and their surrounding table.<BR><BR>
  866. *
  867. * <B><U> Concept</U> :</B><BR><BR>
  868. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object<BR><BR>
  869. *
  870. * <B><U> Example of use </U> :</B><BR><BR>
  871. * <li> Constructor of L2World </li><BR>
  872. *
  873. */
  874. private void initRegions()
  875. {
  876. _worldRegions = new L2WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];
  877. for (int i = 0; i <= REGIONS_X; i++)
  878. {
  879. for (int j = 0; j <= REGIONS_Y; j++)
  880. {
  881. _worldRegions[i][j] = new L2WorldRegion(i, j);
  882. }
  883. }
  884. for (int x = 0; x <= REGIONS_X; x++)
  885. {
  886. for (int y = 0; y <= REGIONS_Y; y++)
  887. {
  888. for (int a = -1; a <= 1; a++)
  889. {
  890. for (int b = -1; b <= 1; b++)
  891. {
  892. if (validRegion(x + a, y + b))
  893. {
  894. _worldRegions[x + a][y + b].addSurroundingRegion(_worldRegions[x][y]);
  895. }
  896. }
  897. }
  898. }
  899. }
  900. _log.info("L2World: (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
  901. }
  902. /**
  903. * Deleted all spawns in the world.
  904. */
  905. public void deleteVisibleNpcSpawns()
  906. {
  907. _log.info("Deleting all visible NPC's.");
  908. for (int i = 0; i <= REGIONS_X; i++)
  909. {
  910. for (int j = 0; j <= REGIONS_Y; j++)
  911. {
  912. _worldRegions[i][j].deleteVisibleNpcSpawns();
  913. }
  914. }
  915. _log.info("All visible NPC's deleted.");
  916. }
  917. @SuppressWarnings("synthetic-access")
  918. private static class SingletonHolder
  919. {
  920. protected static final L2World _instance = new L2World();
  921. }
  922. }