Package com.l2jfrozen.gameserver.model

Source Code of com.l2jfrozen.gameserver.model.L2WorldRegion$NeighborsTask

/*
* 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.Iterator;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Logger;

import javolution.util.FastList;

import com.l2jfrozen.Config;
import com.l2jfrozen.gameserver.ai.L2AttackableAI;
import com.l2jfrozen.gameserver.ai.L2FortSiegeGuardAI;
import com.l2jfrozen.gameserver.ai.L2SiegeGuardAI;
import com.l2jfrozen.gameserver.datatables.sql.SpawnTable;
import com.l2jfrozen.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance;
import com.l2jfrozen.gameserver.model.spawn.L2Spawn;
import com.l2jfrozen.gameserver.model.zone.L2ZoneManager;
import com.l2jfrozen.gameserver.model.zone.L2ZoneType;
import com.l2jfrozen.gameserver.model.zone.type.L2PeaceZone;
import com.l2jfrozen.gameserver.thread.ThreadPoolManager;
import com.l2jfrozen.util.object.L2ObjectSet;

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

  /**
   * L2ObjectHashSet(L2PlayableInstance) containing L2PlayableInstance of all player & summon in game in this
   * L2WorldRegion
   */
  private L2ObjectSet<L2PlayableInstance> _allPlayable;

  /** L2ObjectHashSet(L2Object) containing L2Object visible in this L2WorldRegion */
  private L2ObjectSet<L2Object> _visibleObjects;

  private FastList<L2WorldRegion> _surroundingRegions;
  private int _tileX, _tileY;
  private Boolean _active = false;
  private ScheduledFuture<?> _neighborsTask = null;

  private L2ZoneManager _zoneManager;

  public L2WorldRegion(int pTileX, int pTileY)
  {
    _allPlayable = L2ObjectSet.createL2PlayerSet(); //new L2ObjectHashSet<L2PcInstance>();
    _visibleObjects = L2ObjectSet.createL2ObjectSet(); // new L2ObjectHashSet<L2Object>();
    _surroundingRegions = new FastList<L2WorldRegion>();
    //_surroundingRegions.add(this); //done in L2World.initRegions()

    _tileX = pTileX;
    _tileY = pTileY;

    // default a newly initialized region to inactive, unless always on is specified
    if(Config.GRIDS_ALWAYS_ON)
    {
      _active = true;
    }
    else
    {
      _active = false;
    }
  }

  public void addZone(L2ZoneType zone)
  {
    if(_zoneManager == null)
    {
      _zoneManager = new L2ZoneManager();
    }
    _zoneManager.registerNewZone(zone);
  }

  public void removeZone(L2ZoneType zone)
  {
    if(_zoneManager == null)
      return;

    _zoneManager.unregisterZone(zone);
  }

  public void revalidateZones(L2Character character)
  {
    if(_zoneManager == null)
      return;

    if(_zoneManager != null)
    {
      _zoneManager.revalidateZones(character);
    }
  }

  public void removeFromZones(L2Character character)
  {
    if(_zoneManager == null)
      return;

    if(_zoneManager != null)
    {
      _zoneManager.removeCharacter(character);
    }
  }

  public void onDeath(L2Character character)
  {
    if(_zoneManager == null)
      return;

    if(_zoneManager != null)
    {
      _zoneManager.onDeath(character);
    }
  }

  public void onRevive(L2Character character)
  {
    if(_zoneManager == null)
      return;

    if(_zoneManager != null)
    {
      _zoneManager.onRevive(character);
    }
  }

  /** Task of AI notification */
  public class NeighborsTask implements Runnable
  {
    private boolean _isActivating;

    public NeighborsTask(boolean isActivating)
    {
      _isActivating = isActivating;
    }

    @Override
    public void run()
    {
      if(_isActivating)
      {
        // for each neighbor, if it's not active, activate.
        for(L2WorldRegion neighbor : getSurroundingRegions())
        {
          neighbor.setActive(true);
        }
      }
      else
      {
        if(areNeighborsEmpty())
        {
          setActive(false);
        }

        // check and deactivate
        for(L2WorldRegion neighbor : getSurroundingRegions())
          if(neighbor.areNeighborsEmpty())
          {
            neighbor.setActive(false);
          }
      }
    }
  }

  private void switchAI(Boolean isOn)
  {
    int c = 0;

    if(!isOn)
    {
      for(L2Object o : _visibleObjects)
      {
        if(o instanceof L2Attackable)
        {
          c++;
          L2Attackable mob = (L2Attackable) o;

          // Set target to null and cancel Attack or Cast
          mob.setTarget(null);

          // Stop movement
          mob.stopMove(null);

          // Stop all active skills effects in progress on the L2Character
          mob.stopAllEffects();

          mob.clearAggroList();
          mob.getKnownList().removeAllKnownObjects();

          if(mob.getAI()!=null){
           
            mob.getAI().setIntention(com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE);

            // stop the ai tasks
            if(mob.getAI() instanceof L2AttackableAI)
              ((L2AttackableAI) mob.getAI()).stopAITask();
            else if(mob.getAI() instanceof L2FortSiegeGuardAI)
              ((L2FortSiegeGuardAI) mob.getAI()).stopAITask();
            else if(mob.getAI() instanceof L2SiegeGuardAI)
              ((L2SiegeGuardAI) mob.getAI()).stopAITask();

          }
         
          // Stop HP/MP/CP Regeneration task
          // try this: allow regen, but only until mob is 100% full...then stop
          // it until the grid is made active.
          //mob.getStatus().stopHpMpRegeneration();
        }
      }
      _log.fine(c + " mobs were turned off");
    }
    else
    {
      for(L2Object o : _visibleObjects)
      {
        if(o instanceof L2Attackable)
        {
          c++;
          // Start HP/MP/CP Regeneration task
          ((L2Attackable) o).getStatus().startHpMpRegeneration();

          // start the ai
          //((L2AttackableAI) mob.getAI()).startAITask();
        }
        else if(o instanceof L2NpcInstance)
        {
          // Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it
          // L2Monsterinstance/L2Attackable socials are handled by AI (TODO: check the instances)
          ((L2NpcInstance) o).startRandomAnimationTimer();
        }
      }
      _log.fine(c + " mobs were turned on");
    }

  }

  public Boolean isActive()
  {
    return _active;
  }

  // check if all 9 neighbors (including self) are inactive or active but with no players.
  // returns true if the above condition is met.
  public Boolean areNeighborsEmpty()
  {
    // if this region is occupied, return false.
    if(isActive() && _allPlayable.size() > 0)
      return false;

    // if any one of the neighbors is occupied, return false
    for(L2WorldRegion neighbor : _surroundingRegions)
      if(neighbor.isActive() && neighbor._allPlayable.size() > 0)
        return false;

    // in all other cases, return true.
    return true;
  }

  /**
   * this function turns this region's AI and geodata on or off
   *
   * @param value
   */
  public void setActive(boolean value)
  {
    if(_active == value)
      return;

    _active = value;

    // turn the AI on or off to match the region's activation.
    switchAI(value);

    // TODO
    // turn the geodata on or off to match the region's activation.
    if(value)
    {
      _log.fine("Starting Grid " + _tileX + "," + _tileY);
    }
    else
    {
      _log.fine("Stoping Grid " + _tileX + "," + _tileY);
    }
  }

  /**
   * Immediately sets self as active and starts a timer to set neighbors as active this timer is to avoid turning on
   * neighbors in the case when a person just teleported into a region and then teleported out immediately...there is
   * no reason to activate all the neighbors in that case.
   */
  private void startActivation()
  {
    // first set self to active and do self-tasks...
    setActive(true);

    // if the timer to deactivate neighbors is running, cancel it.
    if(_neighborsTask != null)
    {
      _neighborsTask.cancel(true);
      _neighborsTask = null;
    }

    // then, set a timer to activate the neighbors
    _neighborsTask = ThreadPoolManager.getInstance().scheduleGeneral(new NeighborsTask(true), 1000 * Config.GRID_NEIGHBOR_TURNON_TIME);
  }

  /**
   * starts a timer to set neighbors (including self) as inactive this timer is to avoid turning off neighbors in the
   * case when a person just moved out of a region that he may very soon return to. There is no reason to turn self &
   * neighbors off in that case.
   */
  private void startDeactivation()
  {
    // if the timer to activate neighbors is running, cancel it.
    if(_neighborsTask != null)
    {
      _neighborsTask.cancel(true);
      _neighborsTask = null;
    }

    // start a timer to "suggest" a deactivate to self and neighbors.
    // suggest means: first check if a neighbor has L2PcInstances in it.  If not, deactivate.
    _neighborsTask = ThreadPoolManager.getInstance().scheduleGeneral(new NeighborsTask(false), 1000 * Config.GRID_NEIGHBOR_TURNOFF_TIME);
  }

  /**
   * Add the L2Object in the L2ObjectHashSet(L2Object) _visibleObjects containing L2Object visible in this
   * L2WorldRegion <BR>
   * If L2Object is a L2PcInstance, Add the L2PcInstance in the L2ObjectHashSet(L2PcInstance) _allPlayable containing
   * L2PcInstance of all player in game in this L2WorldRegion <BR>
   * Assert : object.getCurrentWorldRegion() == this
   * @param object
   */
  public void addVisibleObject(L2Object object)
  {
    if(Config.ASSERT)
    {
      assert object.getWorldRegion() == this;
    }

    if(object == null)
      return;

    _visibleObjects.put(object);

    if(object instanceof L2PlayableInstance)
    {
      _allPlayable.put((L2PlayableInstance) object);

      // if this is the first player to enter the region, activate self & neighbors
      if(_allPlayable.size() == 1 && !Config.GRIDS_ALWAYS_ON)
      {
        startActivation();
      }
    }
  }

  /**
   * Remove the L2Object from the L2ObjectHashSet(L2Object) _visibleObjects in this L2WorldRegion <BR>
   * <BR>
   * If L2Object is a L2PcInstance, remove it from the L2ObjectHashSet(L2PcInstance) _allPlayable of this
   * L2WorldRegion <BR>
   * Assert : object.getCurrentWorldRegion() == this || object.getCurrentWorldRegion() == null
   * @param object
   */
  public void removeVisibleObject(L2Object object)
  {
    if(Config.ASSERT)
    {
      assert object.getWorldRegion() == this || object.getWorldRegion() == null;
    }

    if(object == null)
      return;

    _visibleObjects.remove(object);

    if(object instanceof L2PlayableInstance)
    {
      _allPlayable.remove((L2PlayableInstance) object);

      if(_allPlayable.size() == 0 && !Config.GRIDS_ALWAYS_ON)
      {
        startDeactivation();
      }
    }
  }

  public void addSurroundingRegion(L2WorldRegion region)
  {
    _surroundingRegions.add(region);
  }

  /**
   * @return the list _surroundingRegions containing all L2WorldRegion around the current L2WorldRegion
   */
  public FastList<L2WorldRegion> getSurroundingRegions()
  {
    //change to return L2WorldRegion[] ?
    //this should not change after initialization, so maybe changes are not necessary

    return _surroundingRegions;
  }

  public Iterator<L2PlayableInstance> iterateAllPlayers()
  {
    return _allPlayable.iterator();
  }

  public L2ObjectSet<L2Object> getVisibleObjects()
  {
    return _visibleObjects;
  }

  public String getName()
  {
    return "(" + _tileX + ", " + _tileY + ")";
  }

  /**
   * Deleted all spawns in the world.
   */
  public synchronized void deleteVisibleNpcSpawns()
  {
    _log.fine("Deleting all visible NPC's in Region: " + getName());
    for(L2Object obj : _visibleObjects)
    {
      if(obj instanceof L2NpcInstance)
      {
        L2NpcInstance target = (L2NpcInstance) obj;
        target.deleteMe();
        L2Spawn spawn = target.getSpawn();

        if(spawn != null)
        {
          spawn.stopRespawn();
          SpawnTable.getInstance().deleteSpawn(spawn, false);
        }

        _log.finest("Removed NPC " + target.getObjectId());

        target = null;
        spawn = null;
      }
    }if(Config.DEBUG){
    _log.info("All visible NPC's deleted in Region: " + getName());}
  }

  /**
   * @param skill
   * @param x
   * @param y
   * @param z
   * @return
   */
  public boolean checkEffectRangeInsidePeaceZone(L2Skill skill, final int x, final int y, final int z)
    {
        if (_zoneManager != null)
        {
            final int range = skill.getEffectRange();
            final int up = y + range;
            final int down = y - range;
            final int left = x + range;
            final int right = x - range;
           
            for (L2ZoneType e : _zoneManager.getZones())
            {
              if (e instanceof L2PeaceZone)
              {
                if (e.isInsideZone(x, up, z))
                  return false;
                       
                if (e.isInsideZone(x, down, z))
                  return false;
                         
                if (e.isInsideZone(left, y, z))
                  return false;
               
                if (e.isInsideZone(right, y, z))
                  return false;
                       
                if (e.isInsideZone(x, y, z))
                  return false;
              }
            }
            return true;
        }
        return true;
    }
}
TOP

Related Classes of com.l2jfrozen.gameserver.model.L2WorldRegion$NeighborsTask

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.