L2World.java 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. /*
  2. * Copyright (C) 2004-2013 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.Collection;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.logging.Level;
  25. import java.util.logging.Logger;
  26. import com.l2jserver.Config;
  27. import com.l2jserver.gameserver.datatables.AdminTable;
  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.L2TIntObjectHashMap;
  33. import com.l2jserver.gameserver.util.Point3D;
  34. import com.l2jserver.util.StringUtil;
  35. import gnu.trove.procedure.TObjectProcedure;
  36. /**
  37. * This class ...
  38. * @version $Revision: 1.21.2.5.2.7 $ $Date: 2005/03/27 15:29:32 $
  39. */
  40. public final class L2World
  41. {
  42. private static Logger _log = Logger.getLogger(L2World.class.getName());
  43. /**
  44. * Gracia border 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 note, shifting by 15 will result in regions corresponding to map tiles shifting by 12 divides one tile to 8x8 regions
  51. */
  52. public static final int SHIFT_BY = 12;
  53. private static final int TILE_SIZE = 32768;
  54. /** Map dimensions */
  55. public static final int MAP_MIN_X = (Config.WORLD_X_MIN - 20) * TILE_SIZE;
  56. public static final int MAP_MAX_X = (Config.WORLD_X_MAX - 19) * TILE_SIZE;
  57. public static final int MAP_MIN_Y = (Config.WORLD_Y_MIN - 18) * TILE_SIZE;
  58. public static final int MAP_MAX_Y = (Config.WORLD_Y_MAX - 17) * TILE_SIZE;
  59. /** calculated offset used so top left region is 0,0 */
  60. public static final int OFFSET_X = Math.abs(MAP_MIN_X >> SHIFT_BY);
  61. public static final int OFFSET_Y = Math.abs(MAP_MIN_Y >> SHIFT_BY);
  62. /** number of regions */
  63. private static final int REGIONS_X = (MAP_MAX_X >> SHIFT_BY) + OFFSET_X;
  64. private static final int REGIONS_Y = (MAP_MAX_Y >> SHIFT_BY) + OFFSET_Y;
  65. // private FastMap<String, L2PcInstance> _allGms;
  66. /** HashMap(Integer Player id, L2PcInstance) containing all the players in game */
  67. private final L2TIntObjectHashMap<L2PcInstance> _allPlayers;
  68. /** L2ObjectHashMap(L2Object) containing all visible objects */
  69. private final L2TIntObjectHashMap<L2Object> _allObjects;
  70. private final L2TIntObjectHashMap<String> _allObjectsDebug;
  71. /** List with the pets instances and their owner id */
  72. private final L2TIntObjectHashMap<L2PetInstance> _petsInstance;
  73. private L2WorldRegion[][] _worldRegions;
  74. /**
  75. * Constructor of L2World.
  76. */
  77. protected L2World()
  78. {
  79. _allPlayers = new L2TIntObjectHashMap<>();
  80. _allObjects = new L2TIntObjectHashMap<>();
  81. _allObjectsDebug = new L2TIntObjectHashMap<>();
  82. _petsInstance = new L2TIntObjectHashMap<>();
  83. initRegions();
  84. }
  85. /**
  86. * @return the current instance of L2World.
  87. */
  88. public static L2World getInstance()
  89. {
  90. return SingletonHolder._instance;
  91. }
  92. /**
  93. * Add L2Object object in _allObjects. <B><U> Example of use </U> :</B> <li>Withdraw an item from the warehouse, create an item</li> <li>Spawn a L2Character (PC, NPC, Pet)</li><BR>
  94. * @param object
  95. */
  96. public void storeObject(L2Object object)
  97. {
  98. if (_allObjects.containsKey(object.getObjectId()))
  99. {
  100. _log.log(Level.WARNING, getClass().getSimpleName() + ": Current object: " + object + " already exist in OID map!");
  101. _log.log(Level.WARNING, StringUtil.getTraceString(Thread.currentThread().getStackTrace()));
  102. _log.log(Level.WARNING, getClass().getSimpleName() + ": Previous object: " + _allObjects.get(object.getObjectId()) + " already exist in OID map!");
  103. _log.log(Level.WARNING, _allObjectsDebug.get(object.getObjectId()));
  104. _log.log(Level.WARNING, "---------------------- End ---------------------");
  105. return;
  106. }
  107. _allObjects.put(object.getObjectId(), object);
  108. _allObjectsDebug.put(object.getObjectId(), StringUtil.getTraceString(Thread.currentThread().getStackTrace()));
  109. }
  110. /**
  111. * Remove L2Object object from _allObjects of L2World. <B><U> Example of use </U> :</B> <li>Delete item from inventory, tranfer Item from inventory to warehouse</li> <li>Crystallize item</li> <li>Remove NPC/PC/Pet from the world</li><BR>
  112. * @param object L2Object to remove from _allObjects of L2World
  113. */
  114. public void removeObject(L2Object object)
  115. {
  116. _allObjects.remove(object.getObjectId());
  117. _allObjectsDebug.remove(object.getObjectId());
  118. }
  119. public void removeObjects(List<L2Object> list)
  120. {
  121. for (L2Object o : list)
  122. {
  123. if (o != null)
  124. {
  125. _allObjects.remove(o.getObjectId());
  126. _allObjectsDebug.remove(o.getObjectId());
  127. }
  128. }
  129. }
  130. public void removeObjects(L2Object[] objects)
  131. {
  132. for (L2Object o : objects)
  133. {
  134. _allObjects.remove(o.getObjectId());
  135. _allObjectsDebug.remove(o.getObjectId());
  136. }
  137. }
  138. /**
  139. * <B><U> Example of use </U> :</B> <li>Client packets : Action, AttackRequest, RequestJoinParty, RequestJoinPledge...</li>
  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 final L2Object[] getAllVisibleObjectsArray()
  148. {
  149. return _allObjects.values(new L2Object[0]);
  150. }
  151. public final boolean forEachObject(final TObjectProcedure<L2Object> proc)
  152. {
  153. return _allObjects.forEachValue(proc);
  154. }
  155. /**
  156. * Get the count of all visible objects in world.
  157. * @return count off all L2World objects
  158. */
  159. public final int getAllVisibleObjectsCount()
  160. {
  161. return _allObjects.size();
  162. }
  163. /**
  164. * @return a table containing all GMs.
  165. */
  166. public List<L2PcInstance> getAllGMs()
  167. {
  168. return AdminTable.getInstance().getAllGms(true);
  169. }
  170. public L2TIntObjectHashMap<L2PcInstance> getAllPlayers()
  171. {
  172. return _allPlayers;
  173. }
  174. public final L2PcInstance[] getAllPlayersArray()
  175. {
  176. return _allPlayers.values(new L2PcInstance[0]);
  177. }
  178. public final boolean forEachPlayer(final TObjectProcedure<L2PcInstance> proc)
  179. {
  180. return _allPlayers.forEachValue(proc);
  181. }
  182. /**
  183. * Return how many players are online.
  184. * @return number of online players.
  185. */
  186. public int getAllPlayersCount()
  187. {
  188. return _allPlayers.size();
  189. }
  190. /**
  191. * <B>If you have access to player objectId use {@link #getPlayer(int playerObjId)}</B>
  192. * @param name Name of the player to get Instance
  193. * @return the player instance corresponding to the given name.
  194. */
  195. public L2PcInstance getPlayer(String name)
  196. {
  197. return getPlayer(CharNameTable.getInstance().getIdByName(name));
  198. }
  199. /**
  200. * @param playerObjId Object ID of the player to get Instance
  201. * @return the player instance corresponding to the given object ID.
  202. */
  203. public L2PcInstance getPlayer(int playerObjId)
  204. {
  205. return _allPlayers.get(playerObjId);
  206. }
  207. /**
  208. * @param ownerId ID of the owner
  209. * @return the pet instance from the given ownerId.
  210. */
  211. public L2PetInstance getPet(int ownerId)
  212. {
  213. return _petsInstance.get(ownerId);
  214. }
  215. /**
  216. * Add the given pet instance from the given ownerId.
  217. * @param ownerId ID of the owner
  218. * @param pet L2PetInstance of the pet
  219. * @return
  220. */
  221. public L2PetInstance addPet(int ownerId, L2PetInstance pet)
  222. {
  223. return _petsInstance.put(ownerId, pet);
  224. }
  225. /**
  226. * Remove the given pet instance.
  227. * @param ownerId ID of the owner
  228. */
  229. public void removePet(int ownerId)
  230. {
  231. _petsInstance.remove(ownerId);
  232. }
  233. /**
  234. * Remove the given pet instance.
  235. * @param pet the pet to remove
  236. */
  237. public void removePet(L2PetInstance pet)
  238. {
  239. _petsInstance.remove(pet.getOwner().getObjectId());
  240. }
  241. /**
  242. * 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>
  243. * 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
  244. * _gmList** of GmListTable</li> <li>Add object in _knownObjects and _knownPlayer* of all surrounding L2WorldRegion L2Characters</li><BR>
  245. * <li>If object is a L2Character, add all surrounding L2Object in its _knownObjects and all surrounding L2PcInstance in its _knownPlayer</li><BR>
  246. * <I>* only if object is a L2PcInstance</I><BR>
  247. * <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>
  248. * <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>
  249. * @param object L2object to add in the world
  250. * @param newRegion L2WorldRegion in wich the object will be add (not used)
  251. */
  252. public void addVisibleObject(L2Object object, L2WorldRegion newRegion)
  253. {
  254. // If selected L2Object is a L2PcIntance, add it in L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
  255. // XXX TODO: this code should be obsoleted by protection in putObject func...
  256. if (object.isPlayer())
  257. {
  258. L2PcInstance player = object.getActingPlayer();
  259. if (!player.isTeleporting())
  260. {
  261. L2PcInstance tmp = getPlayer(player.getObjectId());
  262. if (tmp != null)
  263. {
  264. _log.warning("Duplicate character!? Closing both characters (" + player.getName() + ")");
  265. player.logout();
  266. tmp.logout();
  267. return;
  268. }
  269. addToAllPlayers(player);
  270. }
  271. }
  272. if (!newRegion.isActive())
  273. {
  274. return;
  275. }
  276. // Get all visible objects contained in the _visibleObjects of L2WorldRegions
  277. // in a circular area of 2000 units
  278. List<L2Object> visibles = getVisibleObjects(object, 2000);
  279. if (Config.DEBUG)
  280. {
  281. _log.finest("objects in range:" + visibles.size());
  282. }
  283. // tell the player about the surroundings
  284. // Go through the visible objects contained in the circular area
  285. for (L2Object visible : visibles)
  286. {
  287. if (visible == null)
  288. {
  289. continue;
  290. }
  291. // Add the object in L2ObjectHashSet(L2Object) _knownObjects of the visible L2Character according to conditions :
  292. // - L2Character is visible
  293. // - object is not already known
  294. // - object is in the watch distance
  295. // If L2Object is a L2PcInstance, add L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the visible L2Character
  296. visible.getKnownList().addKnownObject(object);
  297. // Add the visible L2Object in L2ObjectHashSet(L2Object) _knownObjects of the object according to conditions
  298. // If visible L2Object is a L2PcInstance, add visible L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the object
  299. object.getKnownList().addKnownObject(visible);
  300. }
  301. }
  302. /**
  303. * Add the L2PcInstance to _allPlayers of L2World.
  304. * @param cha
  305. */
  306. public void addToAllPlayers(L2PcInstance cha)
  307. {
  308. _allPlayers.put(cha.getObjectId(), cha);
  309. }
  310. /**
  311. * Remove the L2PcInstance from _allPlayers of L2World. <B><U> Example of use </U> :</B> <li>Remove a player from the visible objects</li><BR>
  312. * @param cha
  313. */
  314. public void removeFromAllPlayers(L2PcInstance cha)
  315. {
  316. _allPlayers.remove(cha.getObjectId());
  317. }
  318. /**
  319. * 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>
  320. * 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
  321. * 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>
  322. * <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>
  323. * <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>
  324. * @param object L2object to remove from the world
  325. * @param oldRegion L2WorldRegion in which the object was before removing
  326. */
  327. public void removeVisibleObject(L2Object object, L2WorldRegion oldRegion)
  328. {
  329. if (object == null)
  330. {
  331. return;
  332. }
  333. if (oldRegion != null)
  334. {
  335. // Remove the object from the L2ObjectHashSet(L2Object) _visibleObjects of L2WorldRegion
  336. // If object is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _allPlayers of this L2WorldRegion
  337. oldRegion.removeVisibleObject(object);
  338. // Go through all surrounding L2WorldRegion L2Characters
  339. for (L2WorldRegion reg : oldRegion.getSurroundingRegions())
  340. {
  341. final Collection<L2Object> vObj = reg.getVisibleObjects().values();
  342. for (L2Object obj : vObj)
  343. {
  344. if (obj != null)
  345. {
  346. obj.getKnownList().removeKnownObject(object);
  347. }
  348. }
  349. }
  350. // If object is a L2Character :
  351. // Remove all L2Object from L2ObjectHashSet(L2Object) containing all L2Object detected by the L2Character
  352. // Remove all L2PcInstance from L2ObjectHashSet(L2PcInstance) containing all player ingame detected by the L2Character
  353. object.getKnownList().removeAllKnownObjects();
  354. // If selected L2Object is a L2PcIntance, remove it from L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
  355. if (object.isPlayer())
  356. {
  357. final L2PcInstance player = object.getActingPlayer();
  358. if (!player.isTeleporting())
  359. {
  360. removeFromAllPlayers(player);
  361. }
  362. }
  363. }
  364. }
  365. /**
  366. * 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>
  367. * 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>
  368. * @param object L2object that determine the current L2WorldRegion
  369. * @return
  370. */
  371. public List<L2Object> getVisibleObjects(L2Object object)
  372. {
  373. L2WorldRegion reg = object.getWorldRegion();
  374. if (reg == null)
  375. {
  376. return null;
  377. }
  378. // Create an FastList in order to contain all visible L2Object
  379. List<L2Object> result = new ArrayList<>();
  380. // Go through the FastList of region
  381. for (L2WorldRegion regi : reg.getSurroundingRegions())
  382. {
  383. // Go through visible objects of the selected region
  384. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  385. for (L2Object _object : vObj)
  386. {
  387. if ((_object == null) || _object.equals(object))
  388. {
  389. continue; // skip our own character
  390. }
  391. else if (!_object.isVisible())
  392. {
  393. continue; // skip dying objects
  394. }
  395. result.add(_object);
  396. }
  397. }
  398. return result;
  399. }
  400. /**
  401. * 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>
  402. * 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 :
  403. * Confusion...</li><BR>
  404. * @param object L2object that determine the center of the circular area
  405. * @param radius Radius of the circular area
  406. * @return
  407. */
  408. public List<L2Object> getVisibleObjects(L2Object object, int radius)
  409. {
  410. if ((object == null) || !object.isVisible())
  411. {
  412. return new ArrayList<>();
  413. }
  414. int x = object.getX();
  415. int y = object.getY();
  416. int sqRadius = radius * radius;
  417. // Create an FastList in order to contain all visible L2Object
  418. List<L2Object> result = new ArrayList<>();
  419. // Go through the FastList of region
  420. for (L2WorldRegion regi : object.getWorldRegion().getSurroundingRegions())
  421. {
  422. // Go through visible objects of the selected region
  423. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  424. for (L2Object _object : vObj)
  425. {
  426. if ((_object == null) || _object.equals(object))
  427. {
  428. continue; // skip our own character
  429. }
  430. int x1 = _object.getX();
  431. int y1 = _object.getY();
  432. double dx = x1 - x;
  433. double dy = y1 - y;
  434. if (((dx * dx) + (dy * dy)) < sqRadius)
  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. int x = object.getX();
  456. int y = object.getY();
  457. int z = object.getZ();
  458. int sqRadius = radius * radius;
  459. // Create an FastList in order to contain all visible L2Object
  460. List<L2Object> result = new ArrayList<>();
  461. // Go through visible object of the selected region
  462. for (L2WorldRegion regi : object.getWorldRegion().getSurroundingRegions())
  463. {
  464. Collection<L2Object> vObj = regi.getVisibleObjects().values();
  465. for (L2Object _object : vObj)
  466. {
  467. if ((_object == null) || _object.equals(object))
  468. {
  469. continue; // skip our own character
  470. }
  471. int x1 = _object.getX();
  472. int y1 = _object.getY();
  473. int z1 = _object.getZ();
  474. long dx = x1 - x;
  475. long dy = y1 - y;
  476. long dz = z1 - z;
  477. if (((dx * dx) + (dy * dy) + (dz * dz)) < sqRadius)
  478. {
  479. result.add(_object);
  480. }
  481. }
  482. }
  483. return result;
  484. }
  485. /**
  486. * <B><U> Concept</U> :</B> All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
  487. * 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>
  488. * @param object L2object that determine the current L2WorldRegion
  489. * @return all visible players of the L2WorldRegion object's and of its surrounding L2WorldRegion.
  490. */
  491. public List<L2Playable> getVisiblePlayable(L2Object object)
  492. {
  493. L2WorldRegion reg = object.getWorldRegion();
  494. if (reg == null)
  495. {
  496. return null;
  497. }
  498. // Create an FastList in order to contain all visible L2Object
  499. List<L2Playable> result = new ArrayList<>();
  500. // Go through the FastList of region
  501. for (L2WorldRegion regi : reg.getSurroundingRegions())
  502. {
  503. // Create an Iterator to go through the visible L2Object of the L2WorldRegion
  504. Map<Integer, L2Playable> _allpls = regi.getVisiblePlayable();
  505. Collection<L2Playable> _playables = _allpls.values();
  506. // Go through visible object of the selected region
  507. for (L2Playable _object : _playables)
  508. {
  509. if ((_object == null) || _object.equals(object))
  510. {
  511. continue; // skip our own character
  512. }
  513. if (!_object.isVisible())
  514. {
  515. continue; // skip dying objects
  516. }
  517. result.add(_object);
  518. }
  519. }
  520. return result;
  521. }
  522. /**
  523. * 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>
  524. * @param point position of the object
  525. * @return
  526. */
  527. public L2WorldRegion getRegion(Point3D point)
  528. {
  529. return _worldRegions[(point.getX() >> SHIFT_BY) + OFFSET_X][(point.getY() >> SHIFT_BY) + OFFSET_Y];
  530. }
  531. public L2WorldRegion getRegion(int x, int y)
  532. {
  533. return _worldRegions[(x >> SHIFT_BY) + OFFSET_X][(y >> SHIFT_BY) + OFFSET_Y];
  534. }
  535. /**
  536. * Returns the whole 2d array containing the world regions used by ZoneData.java to setup zones inside the world regions
  537. * @return
  538. */
  539. public L2WorldRegion[][] getAllWorldRegions()
  540. {
  541. return _worldRegions;
  542. }
  543. /**
  544. * 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>
  545. * @param x X position of the object
  546. * @param y Y position of the object
  547. * @return True if the L2WorldRegion is valid
  548. */
  549. private boolean validRegion(int x, int y)
  550. {
  551. return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
  552. }
  553. /**
  554. * Init each L2WorldRegion and their surrounding table. <B><U> Concept</U> :</B> 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>Constructor of L2World</li>
  555. * <BR>
  556. */
  557. private void initRegions()
  558. {
  559. _worldRegions = new L2WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];
  560. for (int i = 0; i <= REGIONS_X; i++)
  561. {
  562. for (int j = 0; j <= REGIONS_Y; j++)
  563. {
  564. _worldRegions[i][j] = new L2WorldRegion(i, j);
  565. }
  566. }
  567. for (int x = 0; x <= REGIONS_X; x++)
  568. {
  569. for (int y = 0; y <= REGIONS_Y; y++)
  570. {
  571. for (int a = -1; a <= 1; a++)
  572. {
  573. for (int b = -1; b <= 1; b++)
  574. {
  575. if (validRegion(x + a, y + b))
  576. {
  577. _worldRegions[x + a][y + b].addSurroundingRegion(_worldRegions[x][y]);
  578. }
  579. }
  580. }
  581. }
  582. }
  583. _log.info("L2World: (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
  584. }
  585. /**
  586. * Deleted all spawns in the world.
  587. */
  588. public void deleteVisibleNpcSpawns()
  589. {
  590. _log.info("Deleting all visible NPC's.");
  591. for (int i = 0; i <= REGIONS_X; i++)
  592. {
  593. for (int j = 0; j <= REGIONS_Y; j++)
  594. {
  595. _worldRegions[i][j].deleteVisibleNpcSpawns();
  596. }
  597. }
  598. _log.info("All visible NPC's deleted.");
  599. }
  600. private static class SingletonHolder
  601. {
  602. protected static final L2World _instance = new L2World();
  603. }
  604. }