Package com.l2jfrozen.gameserver.model

Source Code of com.l2jfrozen.gameserver.model.L2World

/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package com.l2jfrozen.gameserver.model;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javolution.util.FastList;
import javolution.util.FastMap;

import com.l2jfrozen.Config;
import com.l2jfrozen.gameserver.datatables.GmListTable;
import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2PetInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance;
import com.l2jfrozen.util.Point3D;
import com.l2jfrozen.util.object.L2ObjectMap;
import com.l2jfrozen.util.object.L2ObjectSet;

/**
* This class ...
*
* @version $Revision: 1.21.2.5.2.7 $ $Date: 2005/03/27 15:29:32 $
*/
public final class L2World
{
 
  /** The _log. */
  private static Logger _log = Logger.getLogger(L2World.class.getName());

  /*
   * biteshift, defines number of regions
   * note, shifting by 15 will result in regions corresponding to map tiles
   * shifting by 12 divides one tile to 8x8 regions
   */
  /** The Constant SHIFT_BY. */
  public static final int SHIFT_BY = 12;

  /** Map dimensions. */
  public static final int MAP_MIN_X = Config.WORLD_SIZE_MIN_X; //-131072
 
  /** The Constant MAP_MAX_X. */
  public static final int MAP_MAX_X = Config.WORLD_SIZE_MAX_X; //228608
 
  /** The Constant MAP_MIN_Y. */
  public static final int MAP_MIN_Y = Config.WORLD_SIZE_MIN_Y; //-262144
 
  /** The Constant MAP_MAX_Y. */
  public static final int MAP_MAX_Y = Config.WORLD_SIZE_MAX_Y; //262144
 
  /** calculated offset used so top left region is 0,0. */
  public static final int OFFSET_X = Math.abs(MAP_MIN_X >> SHIFT_BY);
 
  /** The Constant OFFSET_Y. */
  public static final int OFFSET_Y = Math.abs(MAP_MIN_Y >> SHIFT_BY);

  /** number of regions. */
  private static final int REGIONS_X = (MAP_MAX_X >> SHIFT_BY) + OFFSET_X;
 
  /** The Constant REGIONS_Y. */
  private static final int REGIONS_Y = (MAP_MAX_Y >> SHIFT_BY) + OFFSET_Y;

  //public static final int WORLD_SIZE_X = L2World.MAP_MAX_X - L2World.MAP_MIN_X + 1 >> 15;
  //public static final int WORLD_SIZE_Y = L2World.MAP_MAX_Y - L2World.MAP_MIN_Y + 1 >> 15;

  //private FastMap<String, L2PcInstance> _allGms;

  /** HashMap(String Player name, L2PcInstance) containing all the players in game. */
  private static Map<String, L2PcInstance> _allPlayers = new FastMap<String, L2PcInstance>().shared();

  /** L2ObjectHashMap(L2Object) containing all visible objects. */
  private static L2ObjectMap<L2Object> _allObjects;

  /** List with the pets instances and their owner id. */
  private FastMap<Integer, L2PetInstance> _petsInstance;

  /** The _instance. */
  private static L2World _instance = null;

  /** The _world regions. */
  private L2WorldRegion[][] _worldRegions;

  /**
   * Constructor of L2World.<BR>
   * <BR>
   */
  private L2World()
  {
    //_allGms = new FastMap<String, L2PcInstance>();
    //_allPlayers = new FastMap<String, L2PcInstance>().shared();

    _petsInstance = new FastMap<Integer, L2PetInstance>().shared();
    _allObjects = L2ObjectMap.createL2ObjectMap();

    initRegions();
  }

  /**
   * Gets the single instance of L2World.
   *
   * @return the current instance of L2World.
   */
  public static L2World getInstance()
  {
    if(_instance == null){
      _instance = new L2World();
    }
    return _instance;
  }

  /**
   * Add L2Object object in _allObjects.<BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Withdraw an item from the warehouse, create an item</li> <li>Spawn a L2Character (PC, NPC, Pet)</li><BR>
   *
   * @param object the object
   */
  public void storeObject(L2Object object)
  {
    if(_allObjects.get(object.getObjectId()) != null)
    {
      if(Config.DEBUG)
      {
        _log.warning("[L2World] objectId " + object.getObjectId() + " already exist in OID map!");
      }

      return;
    }

    _allObjects.put(object);
  }

  /**
   * Time store object.
   *
   * @param object the object
   * @return the long
   */
  public long timeStoreObject(L2Object object)
  {
    long time = System.currentTimeMillis();
    _allObjects.put(object);
    time -= System.currentTimeMillis();

    return time;
  }

  /**
   * Remove L2Object object from _allObjects of L2World.<BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Delete item from inventory, tranfer Item from inventory to warehouse</li> <li>Crystallize item</li> <li>
   * Remove NPC/PC/Pet from the world</li><BR>
   *
   * @param object L2Object to remove from _allObjects of L2World
   */
  public void removeObject(L2Object object)
  {
    _allObjects.remove(object); // suggestion by whatev
    //IdFactory.getInstance().releaseId(object.getObjectId());
  }

  /**
   * Removes the objects.
   *
   * @param list the list
   */
  public void removeObjects(List<L2Object> list)
  {
    for(L2Object o : list)
    {
      _allObjects.remove(o); // suggestion by whatev
      //IdFactory.getInstance().releaseId(object.getObjectId());
    }
  }

  /**
   * Removes the objects.
   *
   * @param objects the objects
   */
  public void removeObjects(L2Object[] objects)
  {
    for(L2Object o : objects)
    {
      _allObjects.remove(o); // suggestion by whatev
      //IdFactory.getInstance().releaseId(object.getObjectId());
    }
  }

  /**
   * Time remove object.
   *
   * @param object the object
   * @return the long
   */
  public long timeRemoveObject(L2Object object)
  {
    long time = System.currentTimeMillis();
    _allObjects.remove(object);
    time -= System.currentTimeMillis();

    return time;
  }

  /**
   * Return the L2Object object that belongs to an ID or null if no object found.<BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Client packets : Action, AttackRequest, RequestJoinParty, RequestJoinPledge...</li><BR>
   *
   * @param oID Identifier of the L2Object
   * @return the l2 object
   */
  public L2Object findObject(int oID)
  {
    return _allObjects.get(oID);
  }

  /**
   * Time find object.
   *
   * @param objectID the object id
   * @return the long
   */
  public long timeFindObject(int objectID)
  {
    long time = System.currentTimeMillis();
    _allObjects.get(objectID);
    time -= System.currentTimeMillis();

    return time;
  }

  /**
   * Added by Tempy - 08 Aug 05 Allows easy retrevial of all visible objects in world. -- do not use that fucntion,
   * its unsafe!
   *
   * @return the all visible objects
   */
  public final L2ObjectMap<L2Object> getAllVisibleObjects()
  {
    return _allObjects;
  }

  /**
   * Get the count of all visible objects in world.<br>
   * <br>
   *
   * @return count off all L2World objects
   */
  public final int getAllVisibleObjectsCount()
  {
    return _allObjects.size();
  }

  /**
   * Return a table containing all GMs.<BR>
   * <BR>
   *
   * @return the all g ms
   */
  public FastList<L2PcInstance> getAllGMs()
  {
    return GmListTable.getInstance().getAllGms(true);
  }

  /**
   * Return a collection containing all players in game.<BR>
   * <BR>
   * <FONT COLOR=#FF0000><B> <U>Caution</U> : Read-only, please! </B></FONT><BR>
   * <BR>
   *
   * @return the all players
   */
  public Collection<L2PcInstance> getAllPlayers()
  {
    return _allPlayers.values();
  }

  /**
   * Return how many players are online.<BR>
   * <BR>
   *
   * @return number of online players.
   */
  public static Integer getAllPlayersCount()
  {
    return _allPlayers.size();
  }

  /**
   * Return the player instance corresponding to the given name.
   * @param name Name of the player to get Instance
   * @return the player
   */
  public L2PcInstance getPlayer(String name)
  {
    return _allPlayers.get(name.toLowerCase());
  }
 
  /**
   * Gets the player.
   *
   * @param playerObjId the player obj id
   * @return the player
   */
  public L2PcInstance getPlayer(int playerObjId)
  {
    for(L2PcInstance actual:_allPlayers.values())
    {
      if(actual.getObjectId() == playerObjId)
      {
        return actual;
      }
    }
    return null;
  }

  /**
   * Return a collection containing all pets in game.<BR>
   * <BR>
   * <FONT COLOR=#FF0000><B> <U>Caution</U> : Read-only, please! </B></FONT><BR>
   * <BR>
   *
   * @return the all pets
   */
  public Collection<L2PetInstance> getAllPets()
  {
    return _petsInstance.values();
  }

  /**
   * Return the pet instance from the given ownerId.<BR>
   * <BR>
   *
   * @param ownerId ID of the owner
   * @return the pet
   */
  public L2PetInstance getPet(int ownerId)
  {
    return _petsInstance.get(new Integer(ownerId));
  }

  /**
   * Add the given pet instance from the given ownerId.<BR>
   * <BR>
   *
   * @param ownerId ID of the owner
   * @param pet L2PetInstance of the pet
   * @return the l2 pet instance
   */
  public L2PetInstance addPet(int ownerId, L2PetInstance pet)
  {
    return _petsInstance.put(new Integer(ownerId), pet);
  }

  /**
   * Remove the given pet instance.<BR>
   * <BR>
   *
   * @param ownerId ID of the owner
   */
  public void removePet(int ownerId)
  {
    _petsInstance.remove(new Integer(ownerId));
  }

  /**
   * Remove the given pet instance.<BR>
   * <BR>
   *
   * @param pet the pet to remove
   */
  public void removePet(L2PetInstance pet)
  {
    _petsInstance.values().remove(pet);
  }

  /**
   * Add a L2Object in the world.<BR>
   * <BR>
   * <B><U> Concept</U> :</B><BR>
   * <BR>
   * L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in
   * <B>_knownObjects</B> of other surrounding L2Characters <BR>
   * 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>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Add the L2Object object in _allPlayers* of L2World</li> <li>Add the L2Object object in _gmList** of
   * GmListTable</li> <li>Add object in _knownObjects and _knownPlayer* of all surrounding L2WorldRegion L2Characters</li>
   * <BR>
   * <li>If object is a L2Character, add all surrounding L2Object in its _knownObjects and all surrounding
   * L2PcInstance in its _knownPlayer</li><BR>
   * <I>* only if object is a L2PcInstance</I><BR>
   * <I>** only if object is a GM L2PcInstance</I><BR>
   * <BR>
   * <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>
   * <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>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Drop an Item</li> <li>Spawn a L2Character</li> <li>Apply Death Penalty of a L2PcInstance</li><BR>
   * <BR>
   *
   * @param object L2object to add in the world
   * @param newRegion the new region
   * @param dropper L2Character who has dropped the object (if necessary)
   */
  public void addVisibleObject(L2Object object, L2WorldRegion newRegion, L2Character dropper)
  {
    // If selected L2Object is a L2PcIntance, add it in L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
    //
    if(object instanceof L2PcInstance)
    {
      L2PcInstance player = (L2PcInstance) object;
      L2PcInstance tmp =_allPlayers.get(player.getName().toLowerCase());
      if(tmp != null && tmp != player) //just kick the player previous instance
      {
        tmp.store(); // Store character and items
        tmp.logout();
       
        if(tmp.getClient() != null)
        {
          tmp.getClient().setActiveChar(null); // prevent deleteMe from being called a second time on disconnection
        }
       
        tmp = null;
        /*
        if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && tmp.isOffline())
        {
          _log.warning("Offline: Duplicate character!? Closing offline character (" + tmp.getName() + ")");
         
          tmp.store(); // Store character and items
          tmp.logout();
         
          if(tmp.getClient() != null)
          {
            tmp.getClient().setActiveChar(null); // prevent deleteMe from being called a second time on disconnection
          }
         
          tmp = null;
        }
        else
        {
          _log.warning("EnterWorld: Duplicate character!? Closing both characters (" + player.getName() + ")");
          L2GameClient client = player.getClient();
         
          player.store(); // Store character
          player.deleteMe();
          client.setActiveChar(null); // prevent deleteMe from being called a second time on disconnection
          client = tmp.getClient();
         
         
          tmp.store(); // Store character and items
          tmp.deleteMe();
         
          if(client != null)
          {
            client.setActiveChar(null); // prevent deleteMe from being called a second time on disconnection
          }

          tmp = null;
         
          return;
        }
        */
      }
     
     if (!newRegion.isActive())
        return;
      // Get all visible objects contained in the _visibleObjects of L2WorldRegions
      // in a circular area of 2000 units
      List<L2Object> visibles = getVisibleObjects(object, 2000);
      if (Config.DEBUG)
        _log.finest("objects in range:" + visibles.size());
     
      // tell the player about the surroundings
      // Go through the visible objects contained in the circular area
      for (L2Object visible : visibles)
      {
        if (visible == null)
          continue;
       
        // Add the object in L2ObjectHashSet(L2Object) _knownObjects of the visible L2Character according to conditions :
        //   - L2Character is visible
        //   - object is not already known
        //   - object is in the watch distance
        // If L2Object is a L2PcInstance, add L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the visible L2Character
        visible.getKnownList().addKnownObject(object);
       
        // Add the visible L2Object in L2ObjectHashSet(L2Object) _knownObjects of the object according to conditions
        // If visible L2Object is a L2PcInstance, add visible L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the object
        object.getKnownList().addKnownObject(visible);
      }

     
      if(!player.isTeleporting())
      {
        //L2PcInstance tmp = _allPlayers.get(player.getName().toLowerCase());
        if(tmp != null)
        {
          _log.warning("Teleporting: Duplicate character!? Closing both characters (" + player.getName() + ")");
          player.closeNetConnection();
          tmp.closeNetConnection();
          return;
        }
       
      }

      synchronized(_allPlayers){
        _allPlayers.put(player.getName().toLowerCase(), player);

      }
     
      player = null;
    }

    // Get all visible objects contained in the _visibleObjects of L2WorldRegions
    // in a circular area of 2000 units
    FastList<L2Object> visibles = getVisibleObjects(object, 2000);
    if(Config.DEBUG)
    {
      _log.finest("objects in range:" + visibles.size());
    }

    // tell the player about the surroundings
    // Go through the visible objects contained in the circular area
    for(L2Object visible : visibles)
    {
      // Add the object in L2ObjectHashSet(L2Object) _knownObjects of the visible L2Character according to conditions :
      //   - L2Character is visible
      //   - object is not already known
      //   - object is in the watch distance
      // If L2Object is a L2PcInstance, add L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the visible L2Character
      visible.getKnownList().addKnownObject(object, dropper);

      // Add the visible L2Object in L2ObjectHashSet(L2Object) _knownObjects of the object according to conditions
      // If visible L2Object is a L2PcInstance, add visible L2Object in L2ObjectHashSet(L2PcInstance) _knownPlayer of the object
      object.getKnownList().addKnownObject(visible, dropper);
    }

    visibles = null;
  }

  /**
   * Add the L2PcInstance to _allPlayers of L2World.
   * @param cha the cha
   */
  public void addToAllPlayers(L2PcInstance cha)
  {
    _allPlayers.put(cha.getName().toLowerCase(), cha);
  }

  /**
   * Remove the L2PcInstance from _allPlayers of L2World.<BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Remove a player fom the visible objects</li><BR>
   *
   * @param cha the cha
   */
  public void removeFromAllPlayers(L2PcInstance cha)
  {
    if(cha != null && !cha.isTeleporting())
    {
      if(Config.DEBUG)
      {
        _log.info("Removed player: "+cha.getName().toLowerCase());
        }
      _allPlayers.remove(cha.getName().toLowerCase());
    }
  }
 

  /**
   * Remove a L2Object from the world.<BR>
   * <BR>
   * <B><U> Concept</U> :</B><BR>
   * <BR>
   * L2Object (including L2PcInstance) are identified in <B>_visibleObjects</B> of his current L2WorldRegion and in
   * <B>_knownObjects</B> of other surrounding L2Characters <BR>
   * 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>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Remove the L2Object object from _allPlayers* of L2World</li> <li>Remove the L2Object object from
   * _visibleObjects and _allPlayers* of L2WorldRegion</li> <li>Remove the L2Object object from _gmList** of
   * GmListTable</li> <li>Remove object from _knownObjects and _knownPlayer* of all surrounding L2WorldRegion
   * L2Characters</li><BR>
   * <li>If object is a L2Character, remove all L2Object from its _knownObjects and all L2PcInstance from its
   * _knownPlayer</li><BR>
   * <BR>
   * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of
   * L2World</B></FONT><BR>
   * <BR>
   * <I>* only if object is a L2PcInstance</I><BR>
   * <I>** only if object is a GM L2PcInstance</I><BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Pickup an Item</li> <li>Decay a L2Character</li><BR>
   * <BR>
   *
   * @param object L2object to remove from the world
   * @param oldRegion the old region
   */
  public void removeVisibleObject(L2Object object, L2WorldRegion oldRegion)
  {
    if(object == null)
      return;

    //removeObject(object);

    if(oldRegion != null)
    {
      // Remove the object from the L2ObjectHashSet(L2Object) _visibleObjects of L2WorldRegion
      // If object is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _allPlayers of this L2WorldRegion
      oldRegion.removeVisibleObject(object);

      // Go through all surrounding L2WorldRegion L2Characters
      for(L2WorldRegion reg : oldRegion.getSurroundingRegions())
      {
        for(L2Object obj : reg.getVisibleObjects())
        {
          // Remove the L2Object from the L2ObjectHashSet(L2Object) _knownObjects of the surrounding L2WorldRegion L2Characters
          // If object is a L2PcInstance, remove the L2Object from the L2ObjectHashSet(L2PcInstance) _knownPlayer of the surrounding L2WorldRegion L2Characters
          // If object is targeted by one of the surrounding L2WorldRegion L2Characters, cancel ATTACK and cast
          if(obj != null && obj.getKnownList() != null)
          {
            obj.getKnownList().removeKnownObject(object);
          }

          // Remove surrounding L2WorldRegion L2Characters from the L2ObjectHashSet(L2Object) _KnownObjects of object
          // If surrounding L2WorldRegion L2Characters is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _knownPlayer of object
          //
          if(object.getKnownList() != null)
          {
            object.getKnownList().removeKnownObject(obj);
          }
        }
      }

      // If object is a L2Character :
      // Remove all L2Object from L2ObjectHashSet(L2Object) containing all L2Object detected by the L2Character
      // Remove all L2PcInstance from L2ObjectHashSet(L2PcInstance) containing all player ingame detected by the L2Character
      object.getKnownList().removeAllKnownObjects();

      // If selected L2Object is a L2PcIntance, remove it from L2ObjectHashSet(L2PcInstance) _allPlayers of L2World
      if(object instanceof L2PcInstance)
      {
        if(!((L2PcInstance) object).isTeleporting())
        {
          removeFromAllPlayers((L2PcInstance) object);
        }

        // If selected L2Object is a GM L2PcInstance, remove it from Set(L2PcInstance) _gmList of GmListTable
        //if (((L2PcInstance)object).isGM())
        //GmListTable.getInstance().deleteGm((L2PcInstance)object);
      }

    }
  }

  /**
   * Return all visible objects of the L2WorldRegion object's and of its surrounding L2WorldRegion.<BR>
   * <BR>
   * <B><U> Concept</U> :</B><BR>
   * <BR>
   * All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
   * 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>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Find Close Objects for L2Character</li><BR>
   *
   * @param object L2object that determine the current L2WorldRegion
   * @return the visible objects
   */
  public FastList<L2Object> getVisibleObjects(L2Object object)
  {
    if(object == null)
      return null;
   
    final L2WorldRegion reg = object.getWorldRegion();

    if(reg == null)
      return null;

    // Create an FastList in order to contain all visible L2Object
    FastList<L2Object> result = new FastList<L2Object>();

    // Create a FastList containing all regions around the current region
    FastList<L2WorldRegion> regions = reg.getSurroundingRegions();

    // Go through the FastList of region
    for(int i = 0; regions!=null && i < regions.size(); i++)
    {
      // Go through visible objects of the selected region
      L2ObjectSet<L2Object> actual_objectSet = null;
      if(regions.get(i)!=null)
        actual_objectSet = regions.get(i).getVisibleObjects();
     
      if(actual_objectSet!=null && actual_objectSet.size()>0)
        for(L2Object _object :actual_objectSet)
        {
          if(_object == null)
          {
            continue;
          }
 
          if(_object.equals(object))
          {
            continue; // skip our own character
          }
 
          if(!_object.isVisible())
          {
            continue; // skip dying objects
          }
 
          result.add(_object);
        }
    }

    regions = null;

    return result;
  }

  /**
   * Return all visible objects of the L2WorldRegions in the circular area (radius) centered on the object.<BR>
   * <BR>
   * <B><U> Concept</U> :</B><BR>
   * <BR>
   * All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
   * 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>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Define the aggrolist of monster</li> <li>Define visible objects of a L2Object</li> <li>Skill : Confusion...</li>
   * <BR>
   *
   * @param object L2object that determine the center of the circular area
   * @param radius Radius of the circular area
   * @return the visible objects
   */
  public FastList<L2Object> getVisibleObjects(final L2Object object, int radius)
  {
    if(object == null || !object.isVisible())
      return new FastList<L2Object>();

    final L2WorldRegion region = object.getWorldRegion();
   
    if(region == null)
      return new FastList<L2Object>();
   
    int x = object.getX();
    int y = object.getY();
    int sqRadius = radius * radius;

    // Create an FastList in order to contain all visible L2Object
    FastList<L2Object> result = new FastList<L2Object>();

    // Create an FastList containing all regions around the current region
    FastList<L2WorldRegion> regions = region.getSurroundingRegions();

    // Go through the FastList of region
    for(int i = 0;regions!=null && i < regions.size(); i++)
    {
      // Go through visible objects of the selected region
      for(L2Object _object : regions.get(i).getVisibleObjects())
      {
        if(_object == null)
        {
          continue;
        }

        if(_object.equals(object))
        {
          continue; // skip our own character
        }

        int x1 = _object.getX();
        int y1 = _object.getY();

        double dx = x1 - x;
        //if (dx > radius || -dx > radius)
        //  continue;
        double dy = y1 - y;
        //if (dy > radius || -dy > radius)
        //  continue;

        // If the visible object is inside the circular area
        // add the object to the FastList result
        if(dx * dx + dy * dy < sqRadius)
        {
          result.add(_object);
        }
      }
    }

    regions = null;

    return result;
  }

  /**
   * Return all visible objects of the L2WorldRegions in the spheric area (radius) centered on the object.<BR>
   * <BR>
   * <B><U> Concept</U> :</B><BR>
   * <BR>
   * All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
   * 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>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Define the target list of a skill</li> <li>Define the target list of a polearme attack</li><BR>
   * <BR>
   *
   * @param object L2object that determine the center of the circular area
   * @param radius Radius of the spheric area
   * @return the visible objects3 d
   */
  public FastList<L2Object> getVisibleObjects3D(L2Object object, int radius)
  {
    if(object == null || !object.isVisible())
      return new FastList<L2Object>();

    int x = object.getX();
    int y = object.getY();
    int z = object.getZ();
    int sqRadius = radius * radius;

    // Create an FastList in order to contain all visible L2Object
    FastList<L2Object> result = new FastList<L2Object>();

    // Create an FastList containing all regions around the current region
    FastList<L2WorldRegion> regions = object.getWorldRegion().getSurroundingRegions();

    // Go through visible object of the selected region
    for(int i = 0; i < regions.size(); i++)
    {
      for(L2Object _object : regions.get(i).getVisibleObjects())
      {
        if(_object == null)
        {
          continue;
        }

        if(_object.equals(object))
        {
          continue; // skip our own character
        }

        int x1 = _object.getX();
        int y1 = _object.getY();
        int z1 = _object.getZ();

        long dx = x1 - x;
        //if (dx > radius || -dx > radius)
        //  continue;
        long dy = y1 - y;
        //if (dy > radius || -dy > radius)
        //  continue;
        long dz = z1 - z;

        if(dx * dx + dy * dy + dz * dz < sqRadius)
        {
          result.add(_object);
        }
      }
    }

    regions = null;

    return result;
  }

  /**
   * Return all visible players of the L2WorldRegion object's and of its surrounding L2WorldRegion.<BR>
   * <BR>
   * <B><U> Concept</U> :</B><BR>
   * <BR>
   * All visible object are identified in <B>_visibleObjects</B> of their current L2WorldRegion <BR>
   * 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>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Find Close Objects for L2Character</li><BR>
   *
   * @param object L2object that determine the current L2WorldRegion
   * @return the visible playable
   */
  public FastList<L2PlayableInstance> getVisiblePlayable(L2Object object)
  {
    L2WorldRegion reg = object.getWorldRegion();

    if(reg == null)
      return null;

    // Create an FastList in order to contain all visible L2Object
    FastList<L2PlayableInstance> result = new FastList<L2PlayableInstance>();

    // Create a FastList containing all regions around the current region
    FastList<L2WorldRegion> regions = reg.getSurroundingRegions();

    // Go through the FastList of region
    for(int i = 0; i < regions.size(); i++)
    {
      // Create an Iterator to go through the visible L2Object of the L2WorldRegion
      Iterator<L2PlayableInstance> playables = regions.get(i).iterateAllPlayers();

      // Go through visible object of the selected region
      while(playables.hasNext())
      {
        L2PlayableInstance _object = playables.next();

        if(_object == null)
        {
          continue;
        }

        if(_object.equals(object))
        {
          continue; // skip our own character
        }

        if(!_object.isVisible())
        {
          continue; // skip dying objects
        }

        result.add(_object);

        _object = null;
      }

      playables = null;
    }

    reg = null;
    regions = null;

    return result;
  }

  /**
   * Calculate the current L2WorldRegions of the object according to its position (x,y).<BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Set position of a new L2Object (drop, spawn...)</li> <li>Update position of a L2Object after a mouvement</li><BR>
   *
   * @param point the point
   * @return the region
   */
  public L2WorldRegion getRegion(Point3D point)
  {
    return _worldRegions[(point.getX() >> SHIFT_BY) + OFFSET_X][(point.getY() >> SHIFT_BY) + OFFSET_Y];
  }

  /**
   * Gets the region.
   *
   * @param x the x
   * @param y the y
   * @return the region
   */
  public L2WorldRegion getRegion(int x, int y)
  {
    return _worldRegions[(x >> SHIFT_BY) + OFFSET_X][(y >> SHIFT_BY) + OFFSET_Y];
  }

  /**
   * Returns the whole 2d array containing the world regions used by ZoneData.java to setup zones inside the world
   * regions
   *
   * @return the all world regions
   */
  public L2WorldRegion[][] getAllWorldRegions()
  {
    return _worldRegions;
  }

  /**
   * Check if the current L2WorldRegions of the object is valid according to its position (x,y).<BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Init L2WorldRegions</li><BR>
   *
   * @param x X position of the object
   * @param y Y position of the object
   * @return True if the L2WorldRegion is valid
   */
  private boolean validRegion(int x, int y)
  {
    return x >= 0 && x <= REGIONS_X && y >= 0 && y <= REGIONS_Y;
  }

  /**
   * Init each L2WorldRegion and their surrounding table.<BR>
   * <BR>
   * <B><U> Concept</U> :</B><BR>
   * <BR>
   * 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>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>Constructor of L2World</li><BR>
   */
  private void initRegions()
  {
    _log.config("L2World: Setting up World Regions");

    _worldRegions = new L2WorldRegion[REGIONS_X + 1][REGIONS_Y + 1];

    for(int i = 0; i <= REGIONS_X; i++)
    {
      for(int j = 0; j <= REGIONS_Y; j++)
      {
        _worldRegions[i][j] = new L2WorldRegion(i, j);
      }
    }

    for(int x = 0; x <= REGIONS_X; x++)
    {
      for(int y = 0; y <= REGIONS_Y; y++)
      {
        for(int a = -1; a <= 1; a++)
        {
          for(int b = -1; b <= 1; b++)
          {
            if(validRegion(x + a, y + b))
            {
              _worldRegions[x + a][y + b].addSurroundingRegion(_worldRegions[x][y]);
            }
          }
        }
      }
    }

    _log.config("L2World: ("+ REGIONS_X + "x" + REGIONS_Y +") World Region Grid set up.");

  }

  /**
   * Deleted all spawns in the world.
   */
  public synchronized void deleteVisibleNpcSpawns()
  {
    _log.info("Deleting all visible NPC's.");

    for(int i = 0; i <= REGIONS_X; i++)
    {
      for(int j = 0; j <= REGIONS_Y; j++)
      {
        _worldRegions[i][j].deleteVisibleNpcSpawns();
      }
    }
    _log.info("All visible NPC's deleted.");
  }
 
  /**
   * Gets the account players.
   *
   * @param account_name the account_name
   * @return the account players
   */
  public FastList<L2PcInstance> getAccountPlayers(String account_name){
   
    FastList<L2PcInstance> players_for_account = new FastList<L2PcInstance>();
    for(L2PcInstance actual:_allPlayers.values())
    {
      if(actual.getAccountName().equals(account_name))
        players_for_account.add(actual);
    }
    return players_for_account;
  }
}
TOP

Related Classes of com.l2jfrozen.gameserver.model.L2World

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.