/** * */ package net.sf.l2j.gameserver.util; import java.util.Collection; import java.util.Iterator; import java.util.Map; import javolution.util.FastList; import javolution.util.FastMap; import javolution.util.FastSet; import net.sf.l2j.gameserver.model.L2Character; import net.sf.l2j.gameserver.model.L2Object; import net.sf.l2j.gameserver.model.L2PcInstance; import net.sf.l2j.gameserver.model.L2World; import net.sf.l2j.gameserver.model.L2WorldRegion; import net.sf.l2j.util.Point3D; /** * @author Layane * */ public class PcKnownList extends NpcKnownList { protected Map _knownCharacters; protected Map _knownOthers; public PcKnownList(L2PcInstance owner) { super(owner); } public void add(L2Object object) { if (object instanceof L2PcInstance) { addPlayer((L2PcInstance)object); } else if (object instanceof L2Character) { addCharacter((L2Character)object); } else { addOtherObject(object); } } public final void addCharacter(L2Character cha) { if (cha == null) return; if (_knownCharacters == null) _knownCharacters = new FastMap().setShared(true); _knownCharacters.put(cha,cha); } public final void addOtherObject(L2Object object) { if (object == null) return; if (_knownOthers == null) _knownOthers = new FastMap().setShared(true); _knownOthers.put(object,object); } public void remove(L2Object object) { if (object instanceof L2PcInstance) { removePlayer((L2PcInstance)object); } else if (object instanceof L2Character) { removeCharacter((L2Character)object); } else { removeOtherObject(object); } } public final void removeCharacter(L2Character cha) { if (cha == null || _knownCharacters == null) return; _knownCharacters.remove(cha); } public final void removeOtherObject(L2Object object) { if (object == null || _knownOthers == null) return; _knownOthers.remove(object); } public boolean knownsObject(L2Object object) { if (object == null) return false; if (_knownCharacters != null && _knownCharacters.containsKey(object)) return true; if (_knownCharacters != null && _knownPlayers.containsKey(object)) return true; if (_knownCharacters != null && _knownPlayers.containsKey(object)) return true; return false; } public final boolean knowsCharacter(L2Character cha) { if (cha == null || _knownCharacters == null) return false; return _knownCharacters.containsKey(cha); } public final boolean knowsOtherObject(L2Object object) { if (object == null || _knownOthers == null) return false; return _knownOthers.containsKey(object); } public Collection getKnownObjects() { if (_knownPlayers == null && _knownCharacters == null) return null; FastList result = new FastList(); if (_knownCharacters != null) result.addAll(_knownCharacters.values()); if (_knownPlayers != null) result.addAll(_knownPlayers.values()); if (_knownOthers != null) result.addAll(_knownOthers.values()); return result; } public final Collection getKnownCharacters() { if (_knownCharacters == null) return null; return _knownCharacters.values(); } public void clear() { if (_knownPlayers != null) _knownPlayers.clear(); if (_knownCharacters != null) _knownCharacters.clear(); } public void update() { Point3D myPosition; synchronized (this) { //Temporal check to minimize fallout mob problem and limbo fall bugs if ((System.currentTimeMillis() - _lastUpdate) < MINIMUN_UPDATE_TIME) return; //Coordinate check to evaluate the position myPosition = _owner.getWorldPosition(); if (myPosition.distanceSquaredTo(_lastUpdatePosition) <= MINIMUM_UPDATE_DISTANCE_SQUARED) return; _lastUpdate = System.currentTimeMillis(); _lastUpdatePosition.setTo(myPosition); } //Find close objects L2World world = L2World.getInstance(); int x = myPosition.getX(); int y = myPosition.getY(); //Minimized regions to iterate FastSet adjZones = new FastSet(); adjZones.add(_owner.getCurrentWorldRegion()); adjZones.add(world.getRegion(x - _vision, y + _vision)); adjZones.add(world.getRegion(x - _vision, y)); adjZones.add(world.getRegion(x - _vision, y - _vision)); adjZones.add(world.getRegion(x, y - _vision)); adjZones.add(world.getRegion(x + _vision, y + _vision)); adjZones.add(world.getRegion(x, y + _vision)); adjZones.add(world.getRegion(x + _vision, y - _vision)); adjZones.add(world.getRegion(x + _vision, y)); for (L2WorldRegion region : adjZones) { L2Object object; for (Iterator it = region.iterateVisibleObjects();it.hasNext();) { object = it.next(); if (myPosition.distanceSquaredTo(object.getWorldPosition()) <= _vision) { _owner.addKnownObject(object, null); } } } } public void forgetKnownObjects() { for (L2PcInstance player : _knownPlayers.values()) { // Remove all invisible object from _knownObjects is invisible if (!player.isVisible()) _owner.removeKnownObject(player); else if (_owner.getDistanceToForgetObject(player) > MINIMUM_UPDATE_DISTANCE_SQUARED) _owner.removeKnownObject(player); } for (L2Character cha : _knownCharacters.values()) { if (!cha.isVisible()) _owner.removeKnownObject(cha); if (_owner.getDistanceToForgetObject(cha) > MINIMUM_UPDATE_DISTANCE_SQUARED) _owner.removeKnownObject(cha); } } }