L2World.java 27 KB

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