Package l2p.gameserver.model

Source Code of l2p.gameserver.model.Reflection

package l2p.gameserver.model;

import l2p.common.ThreadPoolManager;
import l2p.gameserver.idfactory.IdFactory;
import l2p.gameserver.instancemanager.InstancedZoneManager.InstancedZone;
import l2p.gameserver.instancemanager.InstancedZoneManager.SpawnInfo;
import l2p.gameserver.model.instances.L2DoorInstance;
import l2p.gameserver.model.instances.L2MonsterInstance;
import l2p.gameserver.model.instances.L2ReflectionBossInstance;
import l2p.gameserver.serverpackets.SystemMessage;
import l2p.gameserver.tables.NpcTable;
import l2p.gameserver.tables.ReflectionTable;
import l2p.gameserver.tables.TerritoryTable;
import l2p.util.GArray;
import l2p.util.Location;
import l2p.util.Rnd;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.ReentrantLock;

public class Reflection extends L2Object
{
  protected long _id = Integer.MAX_VALUE;
  private InstancedZone _instance = null;
  private int _instancedZoneId = 0;
  private Location _coreLoc; // место, к которому кидает при использовании SoE/unstuck, иначе выбрасывает в основной мир
  private Location _returnLoc; // если не прописано core, но прописан return, то телепортит туда, одновременно перемещая в основной мир
  private Location _teleportLoc; // точка входа
  private GArray<L2Spawn> _spawns = new GArray<L2Spawn>();
  private GArray<L2DoorInstance> _doors = new GArray<L2DoorInstance>();
  protected GArray<Long> _objects = new GArray<Long>();
  protected final ReentrantLock _objects_lock = new ReentrantLock(), _CollapseTimer_lock = new ReentrantLock();
  protected int _playerCount = 0;
  private Timer _collapseTimer;
  private Timer _collapse1minTimer;
  private TimerTask _collapseTimerTask;
  private TimerTask _collapse1minTimerTask;
  private L2Party _party;
  private L2CommandChannel _commandChannel;
  private boolean _isCollapseStarted;
  private int _geoIndex = 0;
  private String _name = "";
  private boolean _notCollapseWithoutPlayers = false;

  public int getGeoIndex()
  {
    return _geoIndex;
  }

  public void setGeoIndex(int id)
  {
    _geoIndex = id;
  }

  public int getInstancedZoneId()
  {
    return _instancedZoneId;
  }

  public void setInstancedZoneId(int id)
  {
    _instancedZoneId = id;
  }

  /**
   * Использовать только для статичных отражений с id <= 0.
   */
  public Reflection(long id)
  {
    super(IdFactory.getInstance().getNextId());
    _id = id;
    ReflectionTable.getInstance().addReflection(this);
  }

  /**
   * Создает отражение и регистрирует его в индексе. Вызывать только из конструктора отражения.
   *
   * @param name
   */
  public Reflection(String name)
  {
    super(IdFactory.getInstance().getNextId());
    _name = name;
    ReflectionTable.getInstance().addReflection(this);
  }

  /**
   * Создает отражение и регистрирует его в индексе. Сохраняет информацию о инстансе.
   */
  public Reflection(InstancedZone iz)
  {
    super(IdFactory.getInstance().getNextId());
    _instance = iz;
    _name = iz.getName();
    ReflectionTable.getInstance().addReflection(this);
  }

  public void addSpawn(L2Spawn spawn)
  {
    if(spawn != null)
    {
      _spawns.add(spawn);
    }
  }

  public void addDoor(L2DoorInstance door)
  {
    _doors.add(door);
  }

  public void setParty(L2Party party)
  {
    _party = party;
  }

  public L2Party getParty()
  {
    return _party;
  }

  public void setCommandChannel(L2CommandChannel commandChannel)
  {
    _commandChannel = commandChannel;
  }

  public void setNotCollapseWithoutPlayers(boolean value)
  {
    _notCollapseWithoutPlayers = value;
  }

  /**
   * Время в мс
   *
   * @param time
   */
  public void startCollapseTimer(long time)
  {
    if(_id <= 0)
    {
      new Exception("Basic reflection " + _id + " could not be collapsed!").printStackTrace();
      return;
    }
    _CollapseTimer_lock.lock();
    if(_collapseTimerTask != null)
    {
      _collapseTimerTask.cancel();
      _collapseTimerTask = null;
    }
    if(_collapse1minTimerTask != null)
    {
      _collapse1minTimerTask.cancel();
      _collapse1minTimerTask = null;
    }
    if(_collapseTimer != null)
    {
      _collapseTimer.cancel();
      _collapseTimer = null;
    }
    if(_collapse1minTimer != null)
    {
      _collapse1minTimer.cancel();
      _collapse1minTimer = null;
    }
    _collapseTimer = new Timer();
    _collapseTimerTask = new TimerTask()
    {
      @Override
      public void run()
      {
        collapse();
      }
    };
    _collapse1minTimer = new Timer();
    _collapse1minTimerTask = new TimerTask()
    {
      @Override
      public void run()
      {
        minuteBeforeCollapse();
      }
    };
    if(time > 60 * 1000L)
    {
      _collapse1minTimer.schedule(_collapse1minTimerTask, time - 60 * 1000L);
    }
    _collapseTimer.schedule(_collapseTimerTask, time);
    _CollapseTimer_lock.unlock();
  }

  public void stopCollapseTimer()
  {
    _CollapseTimer_lock.lock();
    if(_collapseTimerTask != null)
    {
      _collapseTimerTask.cancel();
    }
    _collapseTimerTask = null;
    if(_collapse1minTimerTask != null)
    {
      _collapse1minTimerTask.cancel();
    }
    _collapse1minTimerTask = null;
    if(_collapseTimer != null)
    {
      _collapseTimer.cancel();
    }
    if(_collapse1minTimer != null)
    {
      _collapse1minTimer.cancel();
    }
    _collapseTimer = null;
    _collapse1minTimer = null;
    _CollapseTimer_lock.unlock();
  }

  public void minuteBeforeCollapse()
  {
    if(_isCollapseStarted)
    {
      return;
    }
    _objects_lock.lock();
    for(Long storedId : _objects)
    {
      L2Object o = L2ObjectsStorage.get(storedId);
      if(o != null && o.isPlayer())
      {
        ((L2Player) o).sendPacket(new SystemMessage(SystemMessage.THIS_DUNGEON_WILL_EXPIRE_IN_S1_MINUTES).addNumber(1));
      }
    }
    _objects_lock.unlock();
  }

  public void collapse()
  {
    if(_id <= 0)
    {
      new Exception("Basic reflection " + _id + " could not be collapsed!").printStackTrace();
      return;
    }
    _CollapseTimer_lock.lock();
    if(_isCollapseStarted)
    {
      _CollapseTimer_lock.unlock();
      return;
    }
    _isCollapseStarted = true;
    _CollapseTimer_lock.unlock();
    try
    {
      stopCollapseTimer();
      for(L2Spawn s : _spawns)
      {
        if(s != null)
        {
          s.despawnAll();
        }
      }
      for(L2DoorInstance d : _doors)
      {
        d.deleteMe();
      }
      GArray<L2Player> teleport_list = new GArray<L2Player>();
      GArray<L2Object> delete_list = new GArray<L2Object>();
      _objects_lock.lock();
      for(Long storedId : _objects)
      {
        L2Object o = L2ObjectsStorage.get(storedId);
        if(o != null)
        {
          if(o.isPlayer())
          {
            teleport_list.add((L2Player) o);
          }
          else if(!o.isSummon() && !o.isPet())
          {
            delete_list.add(o);
          }
        }
      }
      _objects_lock.unlock();
      for(L2Player player : teleport_list)
      {
        if(player.getParty() != null)
        {
          if(equals(player.getParty().getReflection()))
          {
            player.getParty().setReflection(null);
          }
          if(player.getParty().getCommandChannel() != null && equals(player.getParty().getCommandChannel().getReflection()))
          {
            player.getParty().getCommandChannel().setReflection(null);
          }
        }
        if(equals(player.getReflection()))
        {
          if(getReturnLoc() != null)
          {
            player.teleToLocation(getReturnLoc(), 0);
          }
          else
          {
            player.setReflection(0);
          }
        }
      }
      if(_commandChannel != null)
      {
        _commandChannel.setReflection(null);
      }
      if(getParty() != null)
      {
        getParty().setReflection(null);
      }
      setParty(null);
      for(L2Object o : delete_list)
      {
        o.deleteMe();
      }
      _doors = null;
      _objects = null;
      _commandChannel = null;
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    finally
    {
      L2ObjectsStorage.remove(getId());
      IdFactory.getInstance().releaseId(getObjectId());
    }
  }

  public long getId()
  {
    return _id;
  }

  public void setId(long newId)
  {
    _id = newId;
  }

  public void addObject(L2Object o)
  {
    if(_isCollapseStarted)
    {
      return;
    }
    _objects_lock.lock();
    _objects.add(o.getStoredId());
    if(o.isPlayer())
    {
      _playerCount++;
    }
    _objects_lock.unlock();
  }

  public void removeObject(L2Object o)
  {
    if(_isCollapseStarted)
    {
      return;
    }
    _objects_lock.lock();
    _objects.remove(o.getStoredId());
    _objects_lock.unlock();
    if(o.isPlayer())
    {
      _playerCount--;
    }
    if(_playerCount <= 0 && _id > 0 && !_notCollapseWithoutPlayers)
    {
      collapse();
    }
  }

  public void setCoreLoc(Location l)
  {
    _coreLoc = l;
  }

  public Location getCoreLoc()
  {
    return _coreLoc;
  }

  public void setReturnLoc(Location l)
  {
    _returnLoc = l;
  }

  public Location getReturnLoc()
  {
    return _returnLoc;
  }

  public void setTeleportLoc(Location l)
  {
    _teleportLoc = l;
  }

  public Location getTeleportLoc()
  {
    return _teleportLoc;
  }

  public GArray<L2Spawn> getSpawns()
  {
    return _spawns;
  }

  public GArray<L2Player> getPlayers()
  {
    GArray<L2Player> result = new GArray<L2Player>();
    _objects_lock.lock();
    if(_objects != null)
    {
      for(Long storedId : _objects)
      {
        L2Object o = L2ObjectsStorage.get(storedId);
        if(o != null && o.isPlayer())
        {
          result.add((L2Player) o);
        }
      }
    }
    _objects_lock.unlock();
    return result;
  }

  public GArray<L2MonsterInstance> getMonsters()
  {
    GArray<L2MonsterInstance> result = new GArray<L2MonsterInstance>();
    _objects_lock.lock();
    if(_objects != null)
    {
      for(Long storedId : _objects)
      {
        L2Object o = L2ObjectsStorage.get(storedId);
        if(o != null && o.isMonster())
        {
          result.add((L2MonsterInstance) o);
        }
      }
    }
    _objects_lock.unlock();
    return result;
  }

  public GArray<L2DoorInstance> getDoors()
  {
    return _doors;
  }

  @Override
  protected void finalize()
  {
    collapse();
  }

  public boolean canChampions()
  {
    return _id <= 0;
  }

  public boolean isAutolootForced()
  {
    return false;
  }

  public boolean isCollapseStarted()
  {
    return _isCollapseStarted;
  }

  public int getPlayerCount()
  {
    return _playerCount;
  }

  @Override
  public String getName()
  {
    return _name;
  }

  public InstancedZone getInstancedZone()
  {
    return _instance;
  }

  @Override
  public boolean isAutoAttackable(L2Character attacker)
  {
    return false; // XXX: для совместимости с суперклассом
  }

  public void FillSpawns(GArray<SpawnInfo> si)
  {
    if(si == null)
    {
      return;
    }
    for(SpawnInfo s : si)
    {
      L2Spawn c;
      GArray<int[]> points = TerritoryTable.getInstance().getLocation(s.getLocationId()).getCoords();
      switch(s.getType())
      {
        case 0: // точечный спаун, в каждой указанной точке
          for(int[] point : points)
          {
            c = s.getSpawn().clone();
            addSpawn(c);
            c.setReflection(getId());
            c.setRespawnDelay(s.getSpawn().getRespawnDelay(), s.getSpawn().getRespawnDelayRandom());
            c.setLocation(0);
            c.setLoc(new Location(point));
            if(!NpcTable.getTemplate(c.getNpcId()).isInstanceOf(L2ReflectionBossInstance.class))
            {
              c.startRespawn();
            }
            c.doSpawn(true);
            if(s.getSpawn().getNativeRespawnDelay() == 0)
            {
              c.stopRespawn();
            }
          }
          break;
        case 1: // один точечный спаун в рандомной точке
          c = s.getSpawn().clone();
          addSpawn(c);
          c.setReflection(getId());
          c.setRespawnDelay(s.getSpawn().getRespawnDelay(), s.getSpawn().getRespawnDelayRandom());
          c.setLocation(0);
          c.setLoc(new Location(points.get(Rnd.get(points.size()))));
          if(!NpcTable.getTemplate(c.getNpcId()).isInstanceOf(L2ReflectionBossInstance.class))
          {
            c.startRespawn();
          }
          c.doSpawn(true);
          if(s.getSpawn().getNativeRespawnDelay() == 0)
          {
            c.stopRespawn();
          }
          break;
        case 2: // локационный спаун
          c = s.getSpawn().clone();
          addSpawn(c);
          c.setReflection(getId());
          c.setRespawnDelay(s.getSpawn().getRespawnDelay(), s.getSpawn().getRespawnDelayRandom());
          if(!NpcTable.getTemplate(c.getNpcId()).isInstanceOf(L2ReflectionBossInstance.class))
          {
            c.startRespawn();
          }
          for(int j = 0; j < c.getAmount(); j++)
          {
            c.doSpawn(true);
          }
          if(s.getSpawn().getNativeRespawnDelay() == 0)
          {
            c.stopRespawn();
          }
      }
    }
  }

  public void FillDoors(GArray<L2DoorInstance> doors)
  {
    if(doors == null)
    {
      return;
    }
    for(L2DoorInstance d : doors)
    {
      L2DoorInstance door = d.clone();
      door.setReflection(this);
      addDoor(door);
      door.spawnMe();
      if(d.isOpen())
      {
        door.openMe();
      }
      door.setIsInvul(d.isInvul());
    }
  }

  /**
   * Открывает дверь в отражении
   */
  public void openDoor(int doorId)
  {
    for(L2DoorInstance door : getDoors())
    {
      if(door.getDoorId() == doorId)
      {
        door.openMe();
      }
    }
  }

  /**
   * Закрывает дверь в отражении
   */
  public void closeDoor(int doorId)
  {
    for(L2DoorInstance door : getDoors())
    {
      if(door.getDoorId() == doorId)
      {
        door.closeMe();
      }
    }
  }

  /**
   * Удаляет все спауны из рефлекшена и запускает коллапс-таймер. Время указывается в минутах.
   */
  public void clearReflection(int collapseTime, boolean message)
  {
    if(getId() <= 0)
    {
      return;
    }
    ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
    {
      @Override
      public void run()
      {
        for(L2Spawn s : getSpawns())
        {
          s.despawnAll();
          s.stopRespawn();
        }
      }
    }, 1000);
    startCollapseTimer(collapseTime * 60 * 1000L);
    if(message)
    {
      for(L2Player pl : getPlayers())
      {
        if(pl != null)
        {
          pl.sendPacket(new SystemMessage(SystemMessage.THIS_INSTANCE_ZONE_WILL_BE_TERMINATED_IN_S1_MINUTES_YOU_WILL_BE_FORCED_OUT_OF_THE_DANGEON_THEN_TIME_EXPIRES).addNumber(collapseTime));
        }
      }
    }
  }
}
TOP

Related Classes of l2p.gameserver.model.Reflection

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.