L2World.java 25 KB

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