L2World.java 25 KB

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