Package l2p.gameserver.model

Source Code of l2p.gameserver.model.L2WorldRegion

package l2p.gameserver.model;

import java.util.concurrent.locks.ReentrantLock;

import l2p.Config;
import l2p.gameserver.ai.DefaultAI;
import l2p.gameserver.model.instances.L2NpcInstance;
import l2p.gameserver.serverpackets.DeleteObject;
import l2p.gameserver.serverpackets.L2GameServerPacket;
import l2p.gameserver.tables.SpawnTable;
import l2p.gameserver.tables.TerritoryTable;
import l2p.util.GArray;
import l2p.util.Location;

public final class L2WorldRegion
{
  private L2Object[] _objects = null;
  private GArray<L2Territory> territories = null;
  private int tileX, tileY, tileZ, _objectsSize = 0, _playersSize = 0;
  private boolean _spawned = false;
  private boolean _small = false;
  private final ReentrantLock objects_lock = new ReentrantLock();
  private final ReentrantLock spawn_lock = new ReentrantLock();
  private final ReentrantLock territories_lock = new ReentrantLock();

  public L2WorldRegion(int pTileX, int pTileY, int pTileZ, boolean small)
  {
    tileX = pTileX;
    tileY = pTileY;
    tileZ = pTileZ;
    _small = small;
  }

  private void spawn()
  {
    if(!_spawned && Config.DELAYED_SPAWN)
    {
      spawn_lock.lock();
      try
      {
        if(_spawned)
        {
          return;
        }
        _spawned = true;
        for(L2Spawn spawn : SpawnTable.getInstance().getSpawnTable())
        {
          Location loc;
          if(spawn.getLocx() == 0)
          {
            if(spawn.getLocation() <= 0)
            {
              continue;
            }
            L2Territory terr = TerritoryTable.getInstance().getLocation(spawn.getLocation());
            if(terr == null)
            {
              continue;
            }
            loc = terr.getCenter();
          }
          else
          {
            loc = spawn.getLoc();
          }
          int x = loc.x / L2World.DIV_BY + L2World.OFFSET_X;
          int y = loc.y / L2World.DIV_BY + L2World.OFFSET_Y;
          if(L2World.validRegion(x, y, 0, false))
          {
            int z = 0;
            if(L2World.getRegions()[x][y].length > 1)
            {
              z = loc.z / L2World.DIV_BY_FOR_Z + L2World.OFFSET_Z;
              if(!L2World.validRegion(x, y, z, false))
              {
                continue;
              }
            }
            if(x == tileX && y == tileY && z == tileZ)
            {
              spawn.init();
            }
          }
        }
      }
      catch(Exception e)
      {
        e.printStackTrace();
      }
      finally
      {
        spawn_lock.unlock();
      }
    }
  }

  public void addToPlayers(L2Object object, L2Character dropper)
  {
    if(_objects == null)
    {
      _objectsSize = 0;
      _playersSize = 0;
      return;
    }
    L2Player player = null;
    if(object.isPlayer())
    {
      player = (L2Player) object;
    }
    // Если object - игрок, показать ему все видимые обьекты в регионе
    if(player != null)
    {
      GArray<L2GameServerPacket> result = new GArray<L2GameServerPacket>(_objectsSize);
      for(L2Object obj : getObjectsList(new GArray<L2Object>(_objectsSize), object.getObjectId(), object.getReflection()))
      {
        if(obj == null)
        {
          continue;
        }
        // Если это фэйк обсервера - не показывать.
        if(obj.inObserverMode() && !obj.isInOlympiadMode() && (obj.getCurrentRegion() == null || !obj.getCurrentRegion().equals(this)))
        {
          continue;
        }
        result.addAll(player.addVisibleObject(obj, dropper));
      }
      player.sendPackets(result);
    }
    // Показать обьект всем игрокам в регионе
    for(L2Player pl : getPlayersList(new GArray<L2Player>(_playersSize), object.getObjectId(), object.getReflection()))
    {
      pl.sendPackets(pl.addVisibleObject(object, dropper));
    }
  }

  public void removeFromPlayers(L2Object object, boolean move)
  {
    if(_objects == null)
    {
      _objectsSize = 0;
      _playersSize = 0;
      return;
    }
    L2Player player = null;
    if(object.isPlayer())
    {
      player = (L2Player) object;
    }
    // Если object - игрок, убрать у него все видимые обьекты в регионе
    if(player != null)
    {
      GArray<L2GameServerPacket> result = new GArray<L2GameServerPacket>(_objectsSize);
      for(L2Object obj : getObjectsList(new GArray<L2Object>(_objectsSize), object.getObjectId(), object.getReflection()))
      {
        L2GameServerPacket p = player.removeVisibleObject(obj, null, move);
        if(p != null)
        {
          result.add(p);
        }
      }
      player.sendPackets(result);
    }
    DeleteObject p = new DeleteObject(object);
    // Убрать обьект у всех игроков в регионе
    for(L2Player pl : getPlayersList(new GArray<L2Player>(_playersSize), object.getObjectId(), object.getReflection()))
    {
      L2GameServerPacket d = pl.removeVisibleObject(object, p, move);
      if(d != null)
      {
        pl.sendPacket(d);
      }
    }
  }

  public L2Object[] getObjects()
  {
    objects_lock.lock();
    try
    {
      if(_objects == null)
      {
        _objects = new L2Object[50];
        _objectsSize = 0;
        _playersSize = 0;
      }
      return _objects;
    }
    finally
    {
      objects_lock.unlock();
    }
  }

  public void addObject(L2Object obj)
  {
    if(obj == null)
    {
      return;
    }
    objects_lock.lock();
    try
    {
      if(_objects == null)
      {
        _objects = new L2Object[50];
        _objectsSize = 0;
      }
      else if(_objectsSize >= _objects.length)
      {
        L2Object[] temp = new L2Object[_objects.length * 2];
        System.arraycopy(_objects, 0, temp, 0, _objectsSize);
        _objects = temp;
      }
      _objects[_objectsSize] = obj;
      _objectsSize++;
      if(obj.isPlayer())
      {
        _playersSize++;
        for(L2WorldRegion neighbor : getNeighbors())
        {
          neighbor.spawn();
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    if(obj.isNpc() && obj.getAI() instanceof DefaultAI && obj.getAI().isGlobalAI() && !obj.getAI().isActive())
    {
      obj.getAI().startAITask();
    }
  }

  public void removeObject(L2Object obj, boolean move)
  {
    if(obj == null)
    {
      return;
    }
    objects_lock.lock();
    try
    {
      if(_objects == null)
      {
        _objectsSize = 0;
        _playersSize = 0;
        return;
      }
      if(_objectsSize > 1)
      {
        int k = -1;
        for(int i = 0; i < _objectsSize; i++)
        {
          if(_objects[i] == obj)
          {
            k = i;
            break;
          }
        }
        if(k > -1)
        {
          _objects[k] = _objects[_objectsSize - 1];
          _objects[_objectsSize - 1] = null;
          _objectsSize--;
        }
      }
      else if(_objectsSize == 1 && _objects[0] == obj)
      {
        _objects[0] = null;
        _objects = null;
        _objectsSize = 0;
        _playersSize = 0;
      }
      if(obj.isPlayer())
      {
        _playersSize--;
        if(_playersSize <= 0)
        {
          _playersSize = 0;
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    if(!move && obj.isNpc() && obj.getAI() instanceof DefaultAI && !obj.getAI().isGlobalAI())
    {
      obj.getAI().stopAITask();
    }
  }

  public GArray<L2Object> getObjectsList(GArray<L2Object> result, int exclude, Reflection reflection)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj != null && obj.getObjectId() != exclude && (reflection.getId() == -1 || obj.getReflection() == reflection))
        {
          result.add(obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2Object> getObjectsList(GArray<L2Object> result, int exclude, Reflection reflection, int x, int y, int z, long sqrad, int height)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj == null || obj.getObjectId() == exclude || reflection.getId() != -1 && obj.getReflection() != reflection)
        {
          continue;
        }
        if(Math.abs(obj.getZ() - z) > height)
        {
          continue;
        }
        long dx = obj.getX() - x;
        dx *= dx;
        if(dx > sqrad)
        {
          continue;
        }
        long dy = obj.getY() - y;
        dy *= dy;
        if(dx + dy < sqrad)
        {
          result.add(obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2Character> getCharactersList(GArray<L2Character> result, int exclude, long reflection)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj != null && obj.isCharacter() && obj.getObjectId() != exclude && (reflection == -1 || obj.getReflection().getId() == reflection))
        {
          result.add((L2Character) obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2Character> getCharactersList(GArray<L2Character> result, int exclude, long reflection, int x, int y, int z, long sqrad, int height)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj == null || !obj.isCharacter() || obj.getObjectId() == exclude || reflection != -1 && obj.getReflection().getId() != reflection)
        {
          continue;
        }
        if(Math.abs(obj.getZ() - z) > height)
        {
          continue;
        }
        long dx = obj.getX() - x;
        dx *= dx;
        if(dx > sqrad)
        {
          continue;
        }
        long dy = obj.getY() - y;
        dy *= dy;
        if(dx + dy < sqrad)
        {
          result.add((L2Character) obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2NpcInstance> getNpcsList(GArray<L2NpcInstance> result, int exclude, long reflection)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj != null && obj.isNpc() && obj.getObjectId() != exclude && (reflection == -1 || obj.getReflection().getId() == reflection))
        {
          result.add((L2NpcInstance) obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2NpcInstance> getNpcsList(GArray<L2NpcInstance> result, int exclude, long reflection, int x, int y, int z, long sqrad, int height)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj == null || !obj.isNpc() || obj.getObjectId() == exclude || reflection != -1 && obj.getReflection().getId() != reflection)
        {
          continue;
        }
        if(Math.abs(obj.getZ() - z) > height)
        {
          continue;
        }
        long dx = obj.getX() - x;
        dx *= dx;
        if(dx > sqrad)
        {
          continue;
        }
        long dy = obj.getY() - y;
        dy *= dy;
        if(dx + dy < sqrad)
        {
          result.add((L2NpcInstance) obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2Player> getPlayersList(GArray<L2Player> result, int exclude, Reflection reflection)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj != null && obj.isPlayer() && obj.getObjectId() != exclude && (reflection.getId() == -1 || obj.getReflection() == reflection))
        {
          result.add((L2Player) obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2Player> getPlayersList(GArray<L2Player> result, int exclude, Reflection reflection, int x, int y, int z, long sqrad, int height)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj == null || !obj.isPlayer() || obj.getObjectId() == exclude || reflection.getId() != -1 && obj.getReflection().getId() != reflection.getId())
        {
          continue;
        }
        if(Math.abs(obj.getZ() - z) > height)
        {
          continue;
        }
        long dx = obj.getX() - x;
        dx *= dx;
        if(dx > sqrad)
        {
          continue;
        }
        long dy = obj.getY() - y;
        dy *= dy;
        if(dx + dy < sqrad)
        {
          result.add((L2Player) obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2Playable> getPlayablesList(GArray<L2Playable> result, int exclude, Reflection reflection)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj != null && obj.isPlayable() && obj.getObjectId() != exclude && (reflection.getId() == -1 || obj.getReflection() == reflection))
        {
          result.add((L2Playable) obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  public GArray<L2Playable> getPlayablesList(GArray<L2Playable> result, int exclude, Reflection reflection, int x, int y, int z, long sqrad, int height)
  {
    objects_lock.lock();
    try
    {
      if(_objects == null || _objectsSize == 0)
      {
        return result;
      }
      for(int i = 0; i < _objectsSize; i++)
      {
        L2Object obj = _objects[i];
        if(obj == null || !obj.isPlayable() || obj.getObjectId() == exclude || reflection.getId() != -1 && obj.getReflection().getId() != reflection.getId())
        {
          continue;
        }
        if(Math.abs(obj.getZ() - z) > height)
        {
          continue;
        }
        long dx = obj.getX() - x;
        dx *= dx;
        if(dx > sqrad)
        {
          continue;
        }
        long dy = obj.getY() - y;
        dy *= dy;
        if(dx + dy < sqrad)
        {
          result.add((L2Playable) obj);
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    return result;
  }

  /**
   * Удаляет весь видимый спаун из региона.
   */
  public void deleteVisibleNpcSpawns()
  {
    GArray<L2NpcInstance> toRemove = new GArray<L2NpcInstance>(_objectsSize);
    objects_lock.lock();
    try
    {
      if(_objects != null)
      {
        for(int i = 0; i < _objectsSize; i++)
        {
          L2Object obj = _objects[i];
          if(obj != null && obj.isNpc())
          {
            toRemove.add((L2NpcInstance) obj);
          }
        }
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      objects_lock.unlock();
    }
    for(L2NpcInstance npc : toRemove)
    {
      L2Spawn spawn = npc.getSpawn();
      if(spawn != null)
      {
        npc.deleteMe();
        spawn.stopRespawn();
      }
    }
  }

  /**
   * Показывает игроку все видимые обьекты в регионе
   */
  public void showObjectsToPlayer(L2Player player)
  {
    if(player != null && _objects != null)
    {
      GArray<L2GameServerPacket> result = new GArray<L2GameServerPacket>(_objectsSize);
      for(L2Object obj : getObjectsList(new GArray<L2Object>(_objectsSize), player.getObjectId(), player.getReflection()))
      {
        result.addAll(player.addVisibleObject(obj, null));
      }
      player.sendPackets(result);
    }
  }

  /**
   * Убирает у игрока все видимые обьекты в регионе
   */
  public void removeObjectsFromPlayer(L2Player player)
  {
    if(player != null && _objects != null)
    {
      GArray<L2GameServerPacket> result = new GArray<L2GameServerPacket>(_objectsSize);
      for(L2Object obj : getObjectsList(new GArray<L2Object>(_objectsSize), player.getObjectId(), player.getReflection()))
      {
        L2GameServerPacket p = player.removeVisibleObject(obj, null, true);
        if(p != null)
        {
          result.add(p);
        }
      }
      player.sendPackets(result);
    }
  }

  /**
   * Убирает обьект у всех игроков в регионе
   */
  public void removePlayerFromOtherPlayers(L2Object object)
  {
    if(object != null && _objects != null)
    {
      DeleteObject p = new DeleteObject(object);
      for(L2Player pl : getPlayersList(new GArray<L2Player>(_playersSize), object.getObjectId(), object.getReflection()))
      {
        L2GameServerPacket d = pl.removeVisibleObject(object, p, true);
        if(d != null)
        {
          pl.sendPacket(d);
        }
      }
    }
  }

  /**
   * Возвращает true если текущий и примыкающий к нему регионы пусты (в них нет игроков)
   */
  public boolean areNeighborsEmpty()
  {
    if(!isEmpty())
    {
      return false;
    }
    for(L2WorldRegion neighbor : getNeighbors())
    {
      if(neighbor != null && !neighbor.isEmpty())
      {
        return false;
      }
    }
    return true;
  }

  /**
   * Выдает массив регионов, примыкающих к текущему, плюс текущий регион (куб 3х3х3) На входе - координаты региона (уже преобразованные)
   */
  public GArray<L2WorldRegion> getNeighbors()
  {
    return L2World.getNeighbors(tileX, tileY, tileZ, _small);
  }

  public int getObjectsSize()
  {
    return _objectsSize;
  }

  public int getPlayersSize()
  {
    return _playersSize;
  }

  public boolean isEmpty()
  {
    return _playersSize <= 0;
  }

  public boolean isNull()
  {
    return _objectsSize <= 0;
  }

  public void addTerritory(L2Territory territory)
  {
    territories_lock.lock();
    try
    {
      if(territories == null)
      {
        territories = new GArray<L2Territory>(5);
      }
      if(!territories.contains(territory))
      {
        territories.add(territory);
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      territories_lock.unlock();
    }
  }

  public void removeTerritory(L2Territory territory)
  {
    territories_lock.lock();
    try
    {
      if(territories == null)
      {
        return;
      }
      territories.remove(territory);
      if(territories.isEmpty())
      {
        territories = null;
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      territories_lock.unlock();
    }
  }

  public GArray<L2Territory> getTerritories(int x, int y, int z)
  {
    territories_lock.lock();
    try
    {
      if(territories == null)
      {
        return null;
      }
      GArray<L2Territory> result = new GArray<L2Territory>(territories.size());
      for(L2Territory terr : territories)
      {
        if(terr != null && terr.isInside(x, y, z))
        {
          result.add(terr);
        }
      }
      return result.isEmpty() ? null : result;
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      territories_lock.unlock();
    }
    return null;
  }

  public String getName()
  {
    return "(" + tileX + ", " + tileY + ", " + tileZ + ")";
  }
}
TOP

Related Classes of l2p.gameserver.model.L2WorldRegion

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.