rendered paste body/**
*
*/
package net.sf.l2j.gameserver.util;
import java.util.Collection;
import java.util.Iterator;
import javolution.util.FastMap;
import javolution.util.FastSet;
import net.sf.l2j.gameserver.model.L2PcInstance;
import net.sf.l2j.gameserver.model.L2Character;
import net.sf.l2j.gameserver.model.L2Object;
import net.sf.l2j.gameserver.model.L2World;
import net.sf.l2j.gameserver.model.L2WorldRegion;
import net.sf.l2j.util.Point3D;
import net.sf.l2j.Config;
/**
* @author Layane
* @version: $
*
* MRU Alg,Zone check,Distance check
*/
public class NpcKnownList
{
private static final int MINIMUM_UPDATE_DISTANCE_SQUARED = Config.MINIMUM_UPDATE_DISTANCE * Config.MINIMUM_UPDATE_DISTANCE;
protected FastMap<L2PcInstance,L2PcInstance> _knownPlayers;
protected Point3D _lastUpdatePosition;
protected L2Character _owner;
public NpcKnownList(L2Character owner)
{
_lastUpdatePosition = new Point3D(owner.getWorldPosition());
_owner = owner;
}
public void add(L2Object object)
{
if (object instanceof L2PcInstance)
{
addPlayer((L2PcInstance)object);
}
}
public synchronized final void addPlayer(L2PcInstance player)
{
if (player == null)
return;
if (_knownPlayers == null)
_knownPlayers = new FastMap<L2PcInstance,L2PcInstance>().setShared(true);
_knownPlayers.put(player,player);
}
public void remove(L2Object object)
{
if (object instanceof L2PcInstance)
{
removePlayer((L2PcInstance)object);
}
}
public final void removePlayer(L2PcInstance player)
{
if (player == null || _knownPlayers == null)
return;
_knownPlayers.remove(player);
}
public final boolean knowsPlayer(L2PcInstance player)
{
if (player == null || _knownPlayers == null)
return false;
return _knownPlayers.containsKey(player);
}
public final Collection<L2PcInstance> getKnownPlayers()
{
if (_knownPlayers == null)
return null;
return _knownPlayers.values();
}
public Collection getKnownObjects()
{
if (_knownPlayers == null)
return null;
return _knownPlayers.values();
}
public void clear()
{
if (_knownPlayers != null)
_knownPlayers.clear();
}
public void update()
{
Point3D myPosition;
synchronized (this)
{
myPosition = _owner.getWorldPosition();
if (myPosition.distanceSquaredTo(_lastUpdatePosition) <= MINIMUM_UPDATE_DISTANCE_SQUARED)
return;
_lastUpdatePosition.setTo(myPosition);
}
//Forget distant objects
for (L2PcInstance player : _knownPlayers.values())
{
if (_owner.getDistanceToForgetObject(player) > MINIMUM_UPDATE_DISTANCE_SQUARED)
{
player.removeKnownObject(_owner);
_owner.removeKnownObject(player);
}
}
//Find close objects
L2World world = L2World.getInstance();
int vision = _owner.getDistanceToWatchObject(null);
int x = myPosition.getX();
int y = myPosition.getY();
FastSet<L2WorldRegion> adjZones = new FastSet<L2WorldRegion>();
adjZones.add(_owner.getCurrentWorldRegion());
adjZones.add(world.getRegion(x - vision, y + vision));
adjZones.add(world.getRegion(x - vision, y - vision));
adjZones.add(world.getRegion(x + vision, y + vision));
adjZones.add(world.getRegion(x + vision, y - vision));
adjZones.add(world.getRegion(x, y - vision));
adjZones.add(world.getRegion(x, y + vision));
adjZones.add(world.getRegion(x - vision, y));
adjZones.add(world.getRegion(x + vision, y));
Iterator<L2PcInstance> it;
L2PcInstance player;
for (L2WorldRegion region : adjZones)
{
it = region.iterateAllPlayers();
while(it.hasNext())
{
player = it.next();
if (myPosition.distanceSquaredTo(player.getWorldPosition()) <= vision)
{
player.addKnownObject(_owner, null);
_owner.addKnownObject(player, null);
}
}
}
}
}