L2World.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. /*
  2. * Copyright (C) 2004-2014 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.model;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.Collection;
  23. import java.util.Comparator;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.concurrent.ConcurrentHashMap;
  27. import java.util.logging.Level;
  28. import java.util.logging.Logger;
  29. import com.l2jserver.Config;
  30. import com.l2jserver.gameserver.datatables.AdminTable;
  31. import com.l2jserver.gameserver.datatables.CharNameTable;
  32. import com.l2jserver.gameserver.model.actor.L2Playable;
  33. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  34. import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
  35. import com.l2jserver.gameserver.model.interfaces.IProcedure;
  36. import com.l2jserver.util.StringUtil;
  37. public final class L2World
  38. {
  39. private static final Logger _log = Logger.getLogger(L2World.class.getName());
  40. /** Gracia border Flying objects not allowed to the east of it. */
  41. public static final int GRACIA_MAX_X = -166168;
  42. public static final int GRACIA_MAX_Z = 6105;
  43. public static final int GRACIA_MIN_Z = -895;
  44. /** Biteshift, defines number of regions note, shifting by 15 will result in regions corresponding to map tiles shifting by 12 divides one tile to 8x8 regions. */
  45. public static final int SHIFT_BY = 12;
  46. private static final int TILE_SIZE = 32768;
  47. /** Map dimensions */
  48. public static final int TILE_X_MIN = 11;
  49. public static final int TILE_Y_MIN = 10;
  50. public static final int TILE_X_MAX = 26;
  51. public static final int TILE_Y_MAX = 26;
  52. public static final int TILE_ZERO_COORD_X = 20;
  53. public static final int TILE_ZERO_COORD_Y = 18;
  54. public static final int MAP_MIN_X = (TILE_X_MIN - TILE_ZERO_COORD_X) * TILE_SIZE;
  55. public static final int MAP_MIN_Y = (TILE_Y_MIN - TILE_ZERO_COORD_Y) * TILE_SIZE;
  56. public static final int MAP_MAX_X = ((TILE_X_MAX - TILE_ZERO_COORD_X) + 1) * TILE_SIZE;
  57. public static final int MAP_MAX_Y = ((TILE_Y_MAX - TILE_ZERO_COORD_Y) + 1) * TILE_SIZE;
  58. /** calculated offset used so top left region is 0,0 */
  59. public static final int OFFSET_X = Math.abs(MAP_MIN_X >> SHIFT_BY);
  60. public static final int OFFSET_Y = Math.abs(MAP_MIN_Y >> SHIFT_BY);
  61. /** number of regions */
  62. private static final int REGIONS_X = (MAP_MAX_X >> SHIFT_BY) + OFFSET_X;
  63. private static final int REGIONS_Y = (MAP_MAX_Y >> SHIFT_BY) + OFFSET_Y;
  64. /** Map containing all the players in game. */
  65. private final Map<Integer, L2PcInstance> _allPlayers = new ConcurrentHashMap<>();
  66. /** Map containing all visible objects. */
  67. private final Map<Integer, L2Object> _allObjects = new ConcurrentHashMap<>();
  68. /** Map used for debug. */
  69. private final Map<Integer, String> _allObjectsDebug = new ConcurrentHashMap<>();
  70. /** Map with the pets instances and their owner ID. */
  71. private final Map<Integer, L2PetInstance> _petsInstance = new ConcurrentHashMap<>();
  72. private L2WorldRegion[][] _worldRegions;
  73. /** Constructor of L2World. */
  74. protected L2World()
  75. {
  76. initRegions();
  77. }
  78. /**
  79. * Adds an object to the world.<br>
  80. * <B><U>Example of use</U>:</B>
  81. * <ul>
  82. * <li>Withdraw an item from the warehouse, create an item</li>
  83. * <li>Spawn a L2Character (PC, NPC, Pet)</li>
  84. * </ul>
  85. * @param object
  86. */
  87. public void storeObject(L2Object object)
  88. {
  89. if (_allObjects.containsKey(object.getObjectId()))
  90. {
  91. _log.log(Level.WARNING, getClass().getSimpleName() + ": Current object: " + object + " already exist in OID map!");
  92. _log.log(Level.WARNING, StringUtil.getTraceString(Thread.currentThread().getStackTrace()));
  93. _log.log(Level.WARNING, getClass().getSimpleName() + ": Previous object: " + _allObjects.get(object.getObjectId()) + " already exist in OID map!");
  94. _log.log(Level.WARNING, _allObjectsDebug.get(object.getObjectId()));
  95. _log.log(Level.WARNING, "---------------------- End ---------------------");
  96. return;
  97. }
  98. _allObjects.put(object.getObjectId(), object);
  99. _allObjectsDebug.put(object.getObjectId(), StringUtil.getTraceString(Thread.currentThread().getStackTrace()));
  100. }
  101. /**
  102. * Removes an object from the world.<br>
  103. * <B><U>Example of use</U>:</B>
  104. * <ul>
  105. * <li>Delete item from inventory, transfer Item from inventory to warehouse</li>
  106. * <li>Crystallize item</li>
  107. * <li>Remove NPC/PC/Pet from the world</li>
  108. * </ul>
  109. * @param object the object to remove
  110. */
  111. public void removeObject(L2Object object)
  112. {
  113. _allObjects.remove(object.getObjectId());
  114. _allObjectsDebug.remove(object.getObjectId());
  115. }
  116. public void removeObjects(List<L2Object> list)
  117. {
  118. for (L2Object o : list)
  119. {
  120. if (o != null)
  121. {
  122. _allObjects.remove(o.getObjectId());
  123. _allObjectsDebug.remove(o.getObjectId());
  124. }
  125. }
  126. }
  127. public void removeObjects(L2Object[] objects)
  128. {
  129. for (L2Object o : objects)
  130. {
  131. _allObjects.remove(o.getObjectId());
  132. _allObjectsDebug.remove(o.getObjectId());
  133. }
  134. }
  135. /**
  136. * <B><U> Example of use</U>:</B>
  137. * <ul>
  138. * <li>Client packets : Action, AttackRequest, RequestJoinParty, RequestJoinPledge...</li>
  139. * </ul>
  140. * @param oID Identifier of the L2Object
  141. * @return the L2Object object that belongs to an ID or null if no object found.
  142. */
  143. public L2Object findObject(int oID)
  144. {
  145. return _allObjects.get(oID);
  146. }
  147. public Collection<L2Object> getVisibleObjects()
  148. {
  149. return _allObjects.values();
  150. }
  151. /**
  152. * Get the count of all visible objects in world.
  153. * @return count off all L2World objects
  154. */
  155. public int getVisibleObjectsCount()
  156. {
  157. return _allObjects.size();
  158. }
  159. public List<L2PcInstance> getAllGMs()
  160. {
  161. return AdminTable.getInstance().getAllGms(true);
  162. }
  163. public Collection<L2PcInstance> getPlayers()
  164. {
  165. return _allPlayers.values();
  166. }
  167. /**
  168. * Gets all players sorted by the given comparator.
  169. * @param comparator the comparator
  170. * @return the players sorted by the comparator
  171. */
  172. public L2PcInstance[] getPlayersSortedBy(Comparator<L2PcInstance> comparator)
  173. {
  174. final L2PcInstance[] players = _allPlayers.values().toArray(new L2PcInstance[_allPlayers.values().size()]);
  175. Arrays.sort(players, comparator);
  176. return players;
  177. }
  178. public boolean forEachPlayer(IProcedure<L2PcInstance, Boolean> procedure)
  179. {
  180. for (L2PcInstance player : _allPlayers.values())
  181. {
  182. if (!procedure.execute(player))
  183. {
  184. return false;
  185. }
  186. }
  187. return true;
  188. }
  189. /**
  190. * Return how many players are online.
  191. * @return number of online players.
  192. */
  193. public int getAllPlayersCount()
  194. {
  195. return _allPlayers.size();
  196. }
  197. /**
  198. * <B>If you have access to player objectId use {@link #getPlayer(int playerObjId)}</B>
  199. * @param name Name of the player to get Instance
  200. * @return the player instance corresponding to the given name.
  201. */
  202. public L2PcInstance getPlayer(String name)
  203. {
  204. return getPlayer(CharNameTable.getInstance().getIdByName(name));
  205. }
  206. /**
  207. * @param playerObjId Object ID of the player to get Instance
  208. * @return the player instance corresponding to the given object ID.
  209. */
  210. public L2PcInstance getPlayer(int playerObjId)
  211. {
  212. return _allPlayers.get(playerObjId);
  213. }
  214. /**
  215. * @param ownerId ID of the owner
  216. * @return the pet instance from the given ownerId.
  217. */
  218. public L2PetInstance getPet(int ownerId)
  219. {
  220. return _petsInstance.get(ownerId);
  221. }
  222. /**
  223. * Add the given pet instance from the given ownerId.
  224. * @param ownerId ID of the owner
  225. * @param pet L2PetInstance of the pet
  226. * @return
  227. */
  228. public L2PetInstance addPet(int ownerId, L2PetInstance pet)
  229. {
  230. return _petsInstance.put(ownerId, pet);
  231. }
  232. /**
  233. * Remove the given pet instance.
  234. * @param ownerId ID of the owner
  235. */
  236. public void removePet(int ownerId)
  237. {
  238. _petsInstance.remove(ownerId);
  239. }
  240. /**
  241. * Remove the given pet instance.
  242. * @param pet the pet to remove
  243. */
  244. public void removePet(L2PetInstance pet)
  245. {
  246. _petsInstance.remove(pet.getOwner().getObjectId());
  247. }
  248. /**
  249. * Add a L2Object in the world. <B><U> Concept</U> :</B> L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in <B>_knownObjects</B> of other surrounding L2Characters <BR>
  250. * 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 <B><U> Actions</U> :</B> <li>Add the L2Object object in _allPlayers* of L2World</li> <li>Add the L2Object object in
  251. * _gmList** of GmListTable</li> <li>Add object in _knownObjects and _knownPlayer* of all surrounding L2WorldRegion L2Characters</li><BR>
  252. * <li>If object is a L2Character, add all surrounding L2Object in its _knownObjects and all surrounding L2PcInstance in its _knownPlayer</li><BR>
  253. * <I>* only if object is a L2PcInstance</I><BR>
  254. * <I>** only if object is a GM L2PcInstance</I> <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>
  255. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T ADD the object to _allObjects and _allPlayers* of L2World (need synchronisation)</B></FONT> <B><U> Example of use </U> :</B> <li>Drop an Item</li> <li>Spawn a L2Character</li> <li>Apply Death Penalty of a L2PcInstance</li>
  256. * @param object L2object to add in the world
  257. * @param newRegion L2WorldRegion in wich the object will be add (not used)
  258. */
  259. public void addVisibleObject(L2Object object, L2WorldRegion newRegion)
  260. {
  261. // TODO: this code should be obsoleted by protection in putObject func...
  262. if (object.isPlayer())
  263. {
  264. L2PcInstance player = object.getActingPlayer();
  265. if (!player.isTeleporting())
  266. {
  267. final L2PcInstance old = getPlayer(player.getObjectId());
  268. if (old != null)
  269. {
  270. _log.warning("Duplicate character!? Closing both characters (" + player.getName() + ")");
  271. player.logout();
  272. old.logout();
  273. return;
  274. }
  275. addPlayerToWorld(player);
  276. }
  277. }
  278. if (!newRegion.isActive())
  279. {
  280. return;
  281. }
  282. // Get all visible objects contained in the _visibleObjects of L2WorldRegions
  283. // in a circular area of 2000 units
  284. List<L2Object> visibles = getVisibleObjects(object, 2000);
  285. if (Config.DEBUG)
  286. {
  287. _log.finest("objects in range:" + visibles.size());
  288. }
  289. // tell the player about the surroundings
  290. // Go through the visible objects contained in the circular area
  291. for (L2Object visible : visibles)
  292. {
  293. if (visible == null)
  294. {
  295. continue;
  296. }
  297. // Add the object in L2ObjectHashSet(L2Object) _knownObjects of the visible L2Character according to conditions :
  298. // - L2Character is visible
  299. // - object is not already known
  300. // - object is in the watch distance
  301. // If L2Object is a L2PcInstance, add L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the visible L2Character
  302. visible.getKnownList().addKnownObject(object);
  303. // Add the visible L2Object in L2ObjectHashSet(L2Object) _knownObjects of the object according to conditions
  304. // If visible L2Object is a L2PcInstance, add visible L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the object
  305. object.getKnownList().addKnownObject(visible);
  306. }
  307. }
  308. /**
  309. * Adds the player to the world.
  310. * @param player the player to add
  311. */
  312. public void addPlayerToWorld(L2PcInstance player)
  313. {
  314. _allPlayers.put(player.getObjectId(), player);
  315. }
  316. /**
  317. * Remove the player from the world.
  318. * @param player the player to remove
  319. */
  320. public void removeFromAllPlayers(L2PcInstance player)
  321. {
  322. _allPlayers.remove(player.getObjectId());
  323. }
  324. /**
  325. * Remove a L2Object from the world. <B><U> Concept</U> :</B> L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in <B>_knownObjects</B> of other surrounding L2Characters <BR>
  326. * 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 <B><U> Actions</U> :</B> <li>Remove the L2Object object from _allPlayers* of L2World</li> <li>Remove the L2Object
  327. * object from _visibleObjects and _allPlayers* of L2WorldRegion</li> <li>Remove the L2Object object from _gmList** of GmListTable</li> <li>Remove object from _knownObjects and _knownPlayer* of all surrounding L2WorldRegion L2Characters</li><BR>
  328. * <li>If object is a L2Character, remove all L2Object from its _knownObjects and all L2PcInstance from its _knownPlayer</li> <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World</B></FONT> <I>* only if object is a L2PcInstance</I><BR>
  329. * <I>** only if object is a GM L2PcInstance</I> <B><U> Example of use </U> :</B> <li>Pickup an Item</li> <li>Decay a L2Character</li>
  330. * @param object L2object to remove from the world
  331. * @param oldRegion L2WorldRegion in which the object was before removing
  332. */
  333. public void removeVisibleObject(L2Object object, L2WorldRegion oldRegion)
  334. {
  335. if (object == null)
  336. {
  337. return;
  338. }
  339. if (oldRegion != null)
  340. {
  341. // Remove the object from the L2ObjectHashSet(L2Object) _visibleObjects of L2WorldRegion
  342. // If object is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _allPlayers of this L2WorldRegion
  343. oldRegion.removeVisibleObject(object);
  344. // Go through all surrounding L2WorldRegion L2Characters
  345. for (L2WorldRegion reg : oldRegion.getSurroundingRegions())
  346. {
  347. final Collection<L2Object> vObj = reg.getVisibleObjects().values();
  348. for (L2Object obj : vObj)
  349. {
  350. if (obj != null)
  351. {
  352. obj.getKnownList().removeKnownObject(object);
  353. }
  354. }
  355. }
  356. // If object is a L2Character :
  357. // Remove all L2Object from L2ObjectHashSet(L2Object) containing all L2Object detected by the L2Character
  358. // Remove all L2PcInstance from L2ObjectHashSet(L2PcInstance) containing all player ingame detected by the L2Character
  359. object.getKnownList().removeAllKnownObjects();
  360. // If selected L2Object is a L2PcIntance, remove it from L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
  361. if (object.isPlayer())
  362. {
  363. final L2PcInstance player = object.getActingPlayer();
  364. if (!player.isTeleporting())
  365. {
  366. removeFromAllPlayers(player);
  367. }
  368. }
  369. }
  370. }
  371. /**
  372. * Return all visible objects of the L2WorldRegion object's and of its surrounding L2WorldRegion. <B><U> Concept</U> :</B> All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  373. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object <B><U> Example of use </U> :</B> <li>Find Close Objects for L2Character</li><BR>
  374. * @param object L2object that determine the current L2WorldRegion
  375. * @return
  376. */
  377. public List<L2Object> getVisibleObjects(L2Object object)
  378. {
  379. L2WorldRegion reg = object.getWorldRegion();
  380. if (reg == null)
  381. {
  382. return null;
  383. }
  384. // Create an FastList in order to contain all visible L2Object
  385. List<L2Object> result = new ArrayList<>();
  386. // Go through the FastList of region
  387. for (L2WorldRegion regi : reg.getSurroundingRegions())
  388. {
  389. // Go through visible objects of the selected region
  390. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  391. for (L2Object _object : vObj)
  392. {
  393. if ((_object == null) || _object.equals(object))
  394. {
  395. continue; // skip our own character
  396. }
  397. else if (!_object.isVisible())
  398. {
  399. continue; // skip dying objects
  400. }
  401. result.add(_object);
  402. }
  403. }
  404. return result;
  405. }
  406. /**
  407. * Return all visible objects of the L2WorldRegions in the circular area (radius) centered on the object. <B><U> Concept</U> :</B> All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  408. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object <B><U> Example of use </U> :</B> <li>Define the aggrolist of monster</li> <li>Define visible objects of a L2Object</li> <li>Skill :
  409. * Confusion...</li><BR>
  410. * @param object L2object that determine the center of the circular area
  411. * @param radius Radius of the circular area
  412. * @return
  413. */
  414. public List<L2Object> getVisibleObjects(L2Object object, int radius)
  415. {
  416. if ((object == null) || !object.isVisible())
  417. {
  418. return new ArrayList<>();
  419. }
  420. final int sqRadius = radius * radius;
  421. // Create an FastList in order to contain all visible L2Object
  422. List<L2Object> result = new ArrayList<>();
  423. // Go through the FastList of region
  424. for (L2WorldRegion regi : object.getWorldRegion().getSurroundingRegions())
  425. {
  426. // Go through visible objects of the selected region
  427. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  428. for (L2Object _object : vObj)
  429. {
  430. if ((_object == null) || _object.equals(object))
  431. {
  432. continue; // skip our own character
  433. }
  434. if (sqRadius > object.calculateDistance(_object, false, true))
  435. {
  436. result.add(_object);
  437. }
  438. }
  439. }
  440. return result;
  441. }
  442. /**
  443. * Return all visible objects of the L2WorldRegions in the spheric area (radius) centered on the object. <B><U> Concept</U> :</B> All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  444. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object <B><U> Example of use </U> :</B> <li>Define the target list of a skill</li> <li>Define the target list of a polearme attack</li>
  445. * @param object L2object that determine the center of the circular area
  446. * @param radius Radius of the spheric area
  447. * @return
  448. */
  449. public List<L2Object> getVisibleObjects3D(L2Object object, int radius)
  450. {
  451. if ((object == null) || !object.isVisible())
  452. {
  453. return new ArrayList<>();
  454. }
  455. final int sqRadius = radius * radius;
  456. // Create an FastList in order to contain all visible L2Object
  457. List<L2Object> result = new ArrayList<>();
  458. // Go through visible object of the selected region
  459. for (L2WorldRegion regi : object.getWorldRegion().getSurroundingRegions())
  460. {
  461. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  462. for (L2Object _object : vObj)
  463. {
  464. if ((_object == null) || _object.equals(object))
  465. {
  466. continue; // skip our own character
  467. }
  468. if (sqRadius > object.calculateDistance(_object, true, true))
  469. {
  470. result.add(_object);
  471. }
  472. }
  473. }
  474. return result;
  475. }
  476. /**
  477. * <B><U> Concept</U> :</B> All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  478. * All surrounding L2WorldRegion are identified in <B>_surroundingRegions</B> of the selected L2WorldRegion in order to scan a large area around a L2Object <B><U> Example of use </U> :</B> <li>Find Close Objects for L2Character</li><BR>
  479. * @param object L2object that determine the current L2WorldRegion
  480. * @return all visible players of the L2WorldRegion object's and of its surrounding L2WorldRegion.
  481. */
  482. public List<L2Playable> getVisiblePlayable(L2Object object)
  483. {
  484. L2WorldRegion reg = object.getWorldRegion();
  485. if (reg == null)
  486. {
  487. return null;
  488. }
  489. // Create an FastList in order to contain all visible L2Object
  490. List<L2Playable> result = new ArrayList<>();
  491. // Go through the FastList of region
  492. for (L2WorldRegion regi : reg.getSurroundingRegions())
  493. {
  494. // Create an Iterator to go through the visible L2Object of the L2WorldRegion
  495. Map<Integer, L2Playable> _allpls = regi.getVisiblePlayable();
  496. Collection<L2Playable> _playables = _allpls.values();
  497. // Go through visible object of the selected region
  498. for (L2Playable _object : _playables)
  499. {
  500. if ((_object == null) || _object.equals(object))
  501. {
  502. continue; // skip our own character
  503. }
  504. if (!_object.isVisible())
  505. {
  506. continue; // skip dying objects
  507. }
  508. result.add(_object);
  509. }
  510. }
  511. return result;
  512. }
  513. /**
  514. * Calculate the current L2WorldRegions of the object according to its position (x,y). <B><U> Example of use </U> :</B> <li>Set position of a new L2Object (drop, spawn...)</li> <li>Update position of a L2Object after a movement</li><BR>
  515. * @param point position of the object
  516. * @return
  517. */
  518. public L2WorldRegion getRegion(Location point)
  519. {
  520. return _worldRegions[(point.getX() >> SHIFT_BY) + OFFSET_X][(point.getY() >> SHIFT_BY) + OFFSET_Y];
  521. }
  522. public L2WorldRegion getRegion(int x, int y)
  523. {
  524. return _worldRegions[(x >> SHIFT_BY) + OFFSET_X][(y >> SHIFT_BY) + OFFSET_Y];
  525. }
  526. /**
  527. * Returns the whole 2d array containing the world regions used by ZoneData.java to setup zones inside the world regions
  528. * @return
  529. */
  530. public L2WorldRegion[][] getWorldRegions()
  531. {
  532. return _worldRegions;
  533. }
  534. /**
  535. * Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B> <li>Init L2WorldRegions</li><BR>
  536. * @param x X position of the object
  537. * @param y Y position of the object
  538. * @return True if the L2WorldRegion is valid
  539. */
  540. private boolean validRegion(int x, int y)
  541. {
  542. return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
  543. }
  544. /**
  545. * Initialize the world regions.
  546. */
  547. private void initRegions()
  548. {
  549. _worldRegions = new L2WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];
  550. for (int i = 0; i <= REGIONS_X; i++)
  551. {
  552. for (int j = 0; j <= REGIONS_Y; j++)
  553. {
  554. _worldRegions[i][j] = new L2WorldRegion(i, j);
  555. }
  556. }
  557. for (int x = 0; x <= REGIONS_X; x++)
  558. {
  559. for (int y = 0; y <= REGIONS_Y; y++)
  560. {
  561. for (int a = -1; a <= 1; a++)
  562. {
  563. for (int b = -1; b <= 1; b++)
  564. {
  565. if (validRegion(x + a, y + b))
  566. {
  567. _worldRegions[x + a][y + b].addSurroundingRegion(_worldRegions[x][y]);
  568. }
  569. }
  570. }
  571. }
  572. }
  573. _log.info("L2World: (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
  574. }
  575. /**
  576. * Deleted all spawns in the world.
  577. */
  578. public void deleteVisibleNpcSpawns()
  579. {
  580. _log.info("Deleting all visible NPC's.");
  581. for (int i = 0; i <= REGIONS_X; i++)
  582. {
  583. for (int j = 0; j <= REGIONS_Y; j++)
  584. {
  585. _worldRegions[i][j].deleteVisibleNpcSpawns();
  586. }
  587. }
  588. _log.info("All visible NPC's deleted.");
  589. }
  590. /**
  591. * @return the current instance of L2World
  592. */
  593. public static L2World getInstance()
  594. {
  595. return SingletonHolder._instance;
  596. }
  597. private static class SingletonHolder
  598. {
  599. protected static final L2World _instance = new L2World();
  600. }
  601. }