L2World.java 29 KB

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