L2WorldRegion related rework.

This commit is contained in:
MobiusDev 2018-09-04 21:31:49 +00:00
parent 484ec7823d
commit 0299a04d9b
16 changed files with 496 additions and 560 deletions

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -99,6 +99,7 @@ public final class L2World
/** Constructor of L2World. */
protected L2World()
{
// Initialize regions.
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
@ -107,6 +108,28 @@ public final class L2World
}
}
// Set surrounding regions.
for (int rx = 0; rx <= REGIONS_X; rx++)
{
for (int ry = 0; ry <= REGIONS_Y; ry++)
{
final List<L2WorldRegion> surroundingRegions = new ArrayList<>();
for (int sx = rx - 1; sx <= (rx + 1); sx++)
{
for (int sy = ry - 1; sy <= (ry + 1); sy++)
{
if (((sx >= 0) && (sx <= REGIONS_X) && (sy >= 0) && (sy <= REGIONS_Y)))
{
surroundingRegions.add(_worldRegions[sx][sy]);
}
}
}
L2WorldRegion[] regionArray = new L2WorldRegion[surroundingRegions.size()];
regionArray = surroundingRegions.toArray(regionArray);
_worldRegions[rx][ry].setSurroundingRegions(regionArray);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
@ -594,36 +617,23 @@ public final class L2World
return;
}
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
for (L2WorldRegion region : centerWorldRegion.getSurroundingRegions())
{
for (int y = regionY - 1; y <= (regionY + 1); y++)
for (L2Object visibleObject : region.getVisibleObjects().values())
{
if (validRegion(x, y))
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
continue;
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
disposeOutOfBoundsObject(object);
return;
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
@ -641,14 +651,14 @@ public final class L2World
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, result::add);
return result;
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, o ->
{
if (predicate.test(o))
@ -701,18 +711,6 @@ public final class L2World
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
if (object.isPlayer())

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@ -34,7 +33,9 @@ public final class L2WorldRegion
private static final Logger LOGGER = Logger.getLogger(L2WorldRegion.class.getName());
/** Map containing visible objects in this world region. */
private volatile Map<Integer, L2Object> _visibleObjects;
private volatile Map<Integer, L2Object> _visibleObjects = new ConcurrentHashMap<>();
/** Map containing nearby regions forming this world region's effective area. */
private L2WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private boolean _active = false;
@ -75,7 +76,7 @@ public final class L2WorldRegion
private void switchAI(boolean isOn)
{
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -218,16 +219,6 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
{
synchronized (object)
{
if (_visibleObjects == null)
{
_visibleObjects = new ConcurrentHashMap<>();
}
}
}
_visibleObjects.put(object.getObjectId(), object);
if (object.isPlayable())
@ -251,7 +242,7 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -268,28 +259,36 @@ public final class L2WorldRegion
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
return _visibleObjects;
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
for (L2WorldRegion worldRegion : _surroundingRegions)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
if (!p.test(worldRegion))
{
if (L2World.validRegion(x, y))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
return false;
}
}
return false;
}
}
return true;
}
public void setSurroundingRegions(L2WorldRegion[] regions)
{
_surroundingRegions = regions;
}
public L2WorldRegion[] getSurroundingRegions()
{
return _surroundingRegions;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
public int getRegionX()
{
return _regionX;
@ -300,11 +299,6 @@ public final class L2WorldRegion
return _regionY;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -99,6 +99,7 @@ public final class L2World
/** Constructor of L2World. */
protected L2World()
{
// Initialize regions.
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
@ -107,6 +108,28 @@ public final class L2World
}
}
// Set surrounding regions.
for (int rx = 0; rx <= REGIONS_X; rx++)
{
for (int ry = 0; ry <= REGIONS_Y; ry++)
{
final List<L2WorldRegion> surroundingRegions = new ArrayList<>();
for (int sx = rx - 1; sx <= (rx + 1); sx++)
{
for (int sy = ry - 1; sy <= (ry + 1); sy++)
{
if (((sx >= 0) && (sx <= REGIONS_X) && (sy >= 0) && (sy <= REGIONS_Y)))
{
surroundingRegions.add(_worldRegions[sx][sy]);
}
}
}
L2WorldRegion[] regionArray = new L2WorldRegion[surroundingRegions.size()];
regionArray = surroundingRegions.toArray(regionArray);
_worldRegions[rx][ry].setSurroundingRegions(regionArray);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
@ -594,36 +617,23 @@ public final class L2World
return;
}
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
for (L2WorldRegion region : centerWorldRegion.getSurroundingRegions())
{
for (int y = regionY - 1; y <= (regionY + 1); y++)
for (L2Object visibleObject : region.getVisibleObjects().values())
{
if (validRegion(x, y))
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
continue;
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
disposeOutOfBoundsObject(object);
return;
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
@ -641,14 +651,14 @@ public final class L2World
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, result::add);
return result;
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, o ->
{
if (predicate.test(o))
@ -701,18 +711,6 @@ public final class L2World
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
if (object.isPlayer())

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@ -34,7 +33,9 @@ public final class L2WorldRegion
private static final Logger LOGGER = Logger.getLogger(L2WorldRegion.class.getName());
/** Map containing visible objects in this world region. */
private volatile Map<Integer, L2Object> _visibleObjects;
private volatile Map<Integer, L2Object> _visibleObjects = new ConcurrentHashMap<>();
/** Map containing nearby regions forming this world region's effective area. */
private L2WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private boolean _active = false;
@ -75,7 +76,7 @@ public final class L2WorldRegion
private void switchAI(boolean isOn)
{
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -218,16 +219,6 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
{
synchronized (object)
{
if (_visibleObjects == null)
{
_visibleObjects = new ConcurrentHashMap<>();
}
}
}
_visibleObjects.put(object.getObjectId(), object);
if (object.isPlayable())
@ -251,7 +242,7 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -268,28 +259,36 @@ public final class L2WorldRegion
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
return _visibleObjects;
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
for (L2WorldRegion worldRegion : _surroundingRegions)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
if (!p.test(worldRegion))
{
if (L2World.validRegion(x, y))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
return false;
}
}
return false;
}
}
return true;
}
public void setSurroundingRegions(L2WorldRegion[] regions)
{
_surroundingRegions = regions;
}
public L2WorldRegion[] getSurroundingRegions()
{
return _surroundingRegions;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
public int getRegionX()
{
return _regionX;
@ -300,11 +299,6 @@ public final class L2WorldRegion
return _regionY;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -99,6 +99,7 @@ public final class L2World
/** Constructor of L2World. */
protected L2World()
{
// Initialize regions.
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
@ -107,6 +108,28 @@ public final class L2World
}
}
// Set surrounding regions.
for (int rx = 0; rx <= REGIONS_X; rx++)
{
for (int ry = 0; ry <= REGIONS_Y; ry++)
{
final List<L2WorldRegion> surroundingRegions = new ArrayList<>();
for (int sx = rx - 1; sx <= (rx + 1); sx++)
{
for (int sy = ry - 1; sy <= (ry + 1); sy++)
{
if (((sx >= 0) && (sx <= REGIONS_X) && (sy >= 0) && (sy <= REGIONS_Y)))
{
surroundingRegions.add(_worldRegions[sx][sy]);
}
}
}
L2WorldRegion[] regionArray = new L2WorldRegion[surroundingRegions.size()];
regionArray = surroundingRegions.toArray(regionArray);
_worldRegions[rx][ry].setSurroundingRegions(regionArray);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
@ -594,36 +617,23 @@ public final class L2World
return;
}
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
for (L2WorldRegion region : centerWorldRegion.getSurroundingRegions())
{
for (int y = regionY - 1; y <= (regionY + 1); y++)
for (L2Object visibleObject : region.getVisibleObjects().values())
{
if (validRegion(x, y))
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
continue;
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
disposeOutOfBoundsObject(object);
return;
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
@ -641,14 +651,14 @@ public final class L2World
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, result::add);
return result;
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, o ->
{
if (predicate.test(o))
@ -701,18 +711,6 @@ public final class L2World
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
if (object.isPlayer())

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@ -34,7 +33,9 @@ public final class L2WorldRegion
private static final Logger LOGGER = Logger.getLogger(L2WorldRegion.class.getName());
/** Map containing visible objects in this world region. */
private volatile Map<Integer, L2Object> _visibleObjects;
private volatile Map<Integer, L2Object> _visibleObjects = new ConcurrentHashMap<>();
/** Map containing nearby regions forming this world region's effective area. */
private L2WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private boolean _active = false;
@ -75,7 +76,7 @@ public final class L2WorldRegion
private void switchAI(boolean isOn)
{
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -218,16 +219,6 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
{
synchronized (object)
{
if (_visibleObjects == null)
{
_visibleObjects = new ConcurrentHashMap<>();
}
}
}
_visibleObjects.put(object.getObjectId(), object);
if (object.isPlayable())
@ -251,7 +242,7 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -268,28 +259,36 @@ public final class L2WorldRegion
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
return _visibleObjects;
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
for (L2WorldRegion worldRegion : _surroundingRegions)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
if (!p.test(worldRegion))
{
if (L2World.validRegion(x, y))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
return false;
}
}
return false;
}
}
return true;
}
public void setSurroundingRegions(L2WorldRegion[] regions)
{
_surroundingRegions = regions;
}
public L2WorldRegion[] getSurroundingRegions()
{
return _surroundingRegions;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
public int getRegionX()
{
return _regionX;
@ -300,11 +299,6 @@ public final class L2WorldRegion
return _regionY;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -99,6 +99,7 @@ public final class L2World
/** Constructor of L2World. */
protected L2World()
{
// Initialize regions.
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
@ -107,6 +108,28 @@ public final class L2World
}
}
// Set surrounding regions.
for (int rx = 0; rx <= REGIONS_X; rx++)
{
for (int ry = 0; ry <= REGIONS_Y; ry++)
{
final List<L2WorldRegion> surroundingRegions = new ArrayList<>();
for (int sx = rx - 1; sx <= (rx + 1); sx++)
{
for (int sy = ry - 1; sy <= (ry + 1); sy++)
{
if (((sx >= 0) && (sx <= REGIONS_X) && (sy >= 0) && (sy <= REGIONS_Y)))
{
surroundingRegions.add(_worldRegions[sx][sy]);
}
}
}
L2WorldRegion[] regionArray = new L2WorldRegion[surroundingRegions.size()];
regionArray = surroundingRegions.toArray(regionArray);
_worldRegions[rx][ry].setSurroundingRegions(regionArray);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
@ -594,36 +617,23 @@ public final class L2World
return;
}
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
for (L2WorldRegion region : centerWorldRegion.getSurroundingRegions())
{
for (int y = regionY - 1; y <= (regionY + 1); y++)
for (L2Object visibleObject : region.getVisibleObjects().values())
{
if (validRegion(x, y))
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
continue;
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
disposeOutOfBoundsObject(object);
return;
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
@ -641,14 +651,14 @@ public final class L2World
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, result::add);
return result;
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, o ->
{
if (predicate.test(o))
@ -701,18 +711,6 @@ public final class L2World
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
if (object.isPlayer())

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@ -34,7 +33,9 @@ public final class L2WorldRegion
private static final Logger LOGGER = Logger.getLogger(L2WorldRegion.class.getName());
/** Map containing visible objects in this world region. */
private volatile Map<Integer, L2Object> _visibleObjects;
private volatile Map<Integer, L2Object> _visibleObjects = new ConcurrentHashMap<>();
/** Map containing nearby regions forming this world region's effective area. */
private L2WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private boolean _active = false;
@ -75,7 +76,7 @@ public final class L2WorldRegion
private void switchAI(boolean isOn)
{
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -218,16 +219,6 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
{
synchronized (object)
{
if (_visibleObjects == null)
{
_visibleObjects = new ConcurrentHashMap<>();
}
}
}
_visibleObjects.put(object.getObjectId(), object);
if (object.isPlayable())
@ -251,7 +242,7 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -268,28 +259,36 @@ public final class L2WorldRegion
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
return _visibleObjects;
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
for (L2WorldRegion worldRegion : _surroundingRegions)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
if (!p.test(worldRegion))
{
if (L2World.validRegion(x, y))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
return false;
}
}
return false;
}
}
return true;
}
public void setSurroundingRegions(L2WorldRegion[] regions)
{
_surroundingRegions = regions;
}
public L2WorldRegion[] getSurroundingRegions()
{
return _surroundingRegions;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
public int getRegionX()
{
return _regionX;
@ -300,11 +299,6 @@ public final class L2WorldRegion
return _regionY;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -95,6 +95,7 @@ public final class L2World
/** Constructor of L2World. */
protected L2World()
{
// Initialize regions.
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
@ -103,6 +104,28 @@ public final class L2World
}
}
// Set surrounding regions.
for (int rx = 0; rx <= REGIONS_X; rx++)
{
for (int ry = 0; ry <= REGIONS_Y; ry++)
{
final List<L2WorldRegion> surroundingRegions = new ArrayList<>();
for (int sx = rx - 1; sx <= (rx + 1); sx++)
{
for (int sy = ry - 1; sy <= (ry + 1); sy++)
{
if (((sx >= 0) && (sx <= REGIONS_X) && (sy >= 0) && (sy <= REGIONS_Y)))
{
surroundingRegions.add(_worldRegions[sx][sy]);
}
}
}
L2WorldRegion[] regionArray = new L2WorldRegion[surroundingRegions.size()];
regionArray = surroundingRegions.toArray(regionArray);
_worldRegions[rx][ry].setSurroundingRegions(regionArray);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
@ -590,36 +613,23 @@ public final class L2World
return;
}
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
for (L2WorldRegion region : centerWorldRegion.getSurroundingRegions())
{
for (int y = regionY - 1; y <= (regionY + 1); y++)
for (L2Object visibleObject : region.getVisibleObjects().values())
{
if (validRegion(x, y))
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceId() != object.getInstanceId())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
continue;
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
if (visibleObject.getInstanceId() != object.getInstanceId())
{
disposeOutOfBoundsObject(object);
return;
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
@ -637,14 +647,14 @@ public final class L2World
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, result::add);
return result;
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, o ->
{
if (predicate.test(o))
@ -697,18 +707,6 @@ public final class L2World
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
if (object.isPlayer())

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@ -34,7 +33,9 @@ public final class L2WorldRegion
private static final Logger LOGGER = Logger.getLogger(L2WorldRegion.class.getName());
/** Map containing visible objects in this world region. */
private volatile Map<Integer, L2Object> _visibleObjects;
private volatile Map<Integer, L2Object> _visibleObjects = new ConcurrentHashMap<>();
/** Map containing nearby regions forming this world region's effective area. */
private L2WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private boolean _active = false;
@ -75,7 +76,7 @@ public final class L2WorldRegion
private void switchAI(boolean isOn)
{
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -218,16 +219,6 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
{
synchronized (object)
{
if (_visibleObjects == null)
{
_visibleObjects = new ConcurrentHashMap<>();
}
}
}
_visibleObjects.put(object.getObjectId(), object);
if (object.isPlayable())
@ -251,7 +242,7 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -268,28 +259,36 @@ public final class L2WorldRegion
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
return _visibleObjects;
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
for (L2WorldRegion worldRegion : _surroundingRegions)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
if (!p.test(worldRegion))
{
if (L2World.validRegion(x, y))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
return false;
}
}
return false;
}
}
return true;
}
public void setSurroundingRegions(L2WorldRegion[] regions)
{
_surroundingRegions = regions;
}
public L2WorldRegion[] getSurroundingRegions()
{
return _surroundingRegions;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
public int getRegionX()
{
return _regionX;
@ -300,11 +299,6 @@ public final class L2WorldRegion
return _regionY;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -99,6 +99,7 @@ public final class L2World
/** Constructor of L2World. */
protected L2World()
{
// Initialize regions.
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
@ -107,6 +108,28 @@ public final class L2World
}
}
// Set surrounding regions.
for (int rx = 0; rx <= REGIONS_X; rx++)
{
for (int ry = 0; ry <= REGIONS_Y; ry++)
{
final List<L2WorldRegion> surroundingRegions = new ArrayList<>();
for (int sx = rx - 1; sx <= (rx + 1); sx++)
{
for (int sy = ry - 1; sy <= (ry + 1); sy++)
{
if (((sx >= 0) && (sx <= REGIONS_X) && (sy >= 0) && (sy <= REGIONS_Y)))
{
surroundingRegions.add(_worldRegions[sx][sy]);
}
}
}
L2WorldRegion[] regionArray = new L2WorldRegion[surroundingRegions.size()];
regionArray = surroundingRegions.toArray(regionArray);
_worldRegions[rx][ry].setSurroundingRegions(regionArray);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
@ -594,36 +617,23 @@ public final class L2World
return;
}
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
for (L2WorldRegion region : centerWorldRegion.getSurroundingRegions())
{
for (int y = regionY - 1; y <= (regionY + 1); y++)
for (L2Object visibleObject : region.getVisibleObjects().values())
{
if (validRegion(x, y))
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
continue;
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
disposeOutOfBoundsObject(object);
return;
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
@ -641,14 +651,14 @@ public final class L2World
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, result::add);
return result;
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, o ->
{
if (predicate.test(o))
@ -701,18 +711,6 @@ public final class L2World
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
if (object.isPlayer())

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@ -34,7 +33,9 @@ public final class L2WorldRegion
private static final Logger LOGGER = Logger.getLogger(L2WorldRegion.class.getName());
/** Map containing visible objects in this world region. */
private volatile Map<Integer, L2Object> _visibleObjects;
private volatile Map<Integer, L2Object> _visibleObjects = new ConcurrentHashMap<>();
/** Map containing nearby regions forming this world region's effective area. */
private L2WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private boolean _active = false;
@ -75,7 +76,7 @@ public final class L2WorldRegion
private void switchAI(boolean isOn)
{
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -218,16 +219,6 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
{
synchronized (object)
{
if (_visibleObjects == null)
{
_visibleObjects = new ConcurrentHashMap<>();
}
}
}
_visibleObjects.put(object.getObjectId(), object);
if (object.isPlayable())
@ -251,7 +242,7 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -268,28 +259,36 @@ public final class L2WorldRegion
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
return _visibleObjects;
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
for (L2WorldRegion worldRegion : _surroundingRegions)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
if (!p.test(worldRegion))
{
if (L2World.validRegion(x, y))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
return false;
}
}
return false;
}
}
return true;
}
public void setSurroundingRegions(L2WorldRegion[] regions)
{
_surroundingRegions = regions;
}
public L2WorldRegion[] getSurroundingRegions()
{
return _surroundingRegions;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
public int getRegionX()
{
return _regionX;
@ -300,11 +299,6 @@ public final class L2WorldRegion
return _regionY;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -99,6 +99,7 @@ public final class L2World
/** Constructor of L2World. */
protected L2World()
{
// Initialize regions.
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
@ -107,6 +108,28 @@ public final class L2World
}
}
// Set surrounding regions.
for (int rx = 0; rx <= REGIONS_X; rx++)
{
for (int ry = 0; ry <= REGIONS_Y; ry++)
{
final List<L2WorldRegion> surroundingRegions = new ArrayList<>();
for (int sx = rx - 1; sx <= (rx + 1); sx++)
{
for (int sy = ry - 1; sy <= (ry + 1); sy++)
{
if (((sx >= 0) && (sx <= REGIONS_X) && (sy >= 0) && (sy <= REGIONS_Y)))
{
surroundingRegions.add(_worldRegions[sx][sy]);
}
}
}
L2WorldRegion[] regionArray = new L2WorldRegion[surroundingRegions.size()];
regionArray = surroundingRegions.toArray(regionArray);
_worldRegions[rx][ry].setSurroundingRegions(regionArray);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
@ -594,36 +617,23 @@ public final class L2World
return;
}
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
for (L2WorldRegion region : centerWorldRegion.getSurroundingRegions())
{
for (int y = regionY - 1; y <= (regionY + 1); y++)
for (L2Object visibleObject : region.getVisibleObjects().values())
{
if (validRegion(x, y))
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
continue;
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
disposeOutOfBoundsObject(object);
return;
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
@ -641,14 +651,14 @@ public final class L2World
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, result::add);
return result;
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, o ->
{
if (predicate.test(o))
@ -701,18 +711,6 @@ public final class L2World
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
if (object.isPlayer())

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@ -34,7 +33,9 @@ public final class L2WorldRegion
private static final Logger LOGGER = Logger.getLogger(L2WorldRegion.class.getName());
/** Map containing visible objects in this world region. */
private volatile Map<Integer, L2Object> _visibleObjects;
private volatile Map<Integer, L2Object> _visibleObjects = new ConcurrentHashMap<>();
/** Map containing nearby regions forming this world region's effective area. */
private L2WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private boolean _active = false;
@ -75,7 +76,7 @@ public final class L2WorldRegion
private void switchAI(boolean isOn)
{
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -218,16 +219,6 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
{
synchronized (object)
{
if (_visibleObjects == null)
{
_visibleObjects = new ConcurrentHashMap<>();
}
}
}
_visibleObjects.put(object.getObjectId(), object);
if (object.isPlayable())
@ -251,7 +242,7 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -268,28 +259,36 @@ public final class L2WorldRegion
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
return _visibleObjects;
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
for (L2WorldRegion worldRegion : _surroundingRegions)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
if (!p.test(worldRegion))
{
if (L2World.validRegion(x, y))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
return false;
}
}
return false;
}
}
return true;
}
public void setSurroundingRegions(L2WorldRegion[] regions)
{
_surroundingRegions = regions;
}
public L2WorldRegion[] getSurroundingRegions()
{
return _surroundingRegions;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
public int getRegionX()
{
return _regionX;
@ -300,11 +299,6 @@ public final class L2WorldRegion
return _regionY;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{

View File

@ -16,8 +16,8 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -99,6 +99,7 @@ public final class L2World
/** Constructor of L2World. */
protected L2World()
{
// Initialize regions.
for (int x = 0; x <= REGIONS_X; x++)
{
for (int y = 0; y <= REGIONS_Y; y++)
@ -107,6 +108,28 @@ public final class L2World
}
}
// Set surrounding regions.
for (int rx = 0; rx <= REGIONS_X; rx++)
{
for (int ry = 0; ry <= REGIONS_Y; ry++)
{
final List<L2WorldRegion> surroundingRegions = new ArrayList<>();
for (int sx = rx - 1; sx <= (rx + 1); sx++)
{
for (int sy = ry - 1; sy <= (ry + 1); sy++)
{
if (((sx >= 0) && (sx <= REGIONS_X) && (sy >= 0) && (sy <= REGIONS_Y)))
{
surroundingRegions.add(_worldRegions[sx][sy]);
}
}
}
L2WorldRegion[] regionArray = new L2WorldRegion[surroundingRegions.size()];
regionArray = surroundingRegions.toArray(regionArray);
_worldRegions[rx][ry].setSurroundingRegions(regionArray);
}
}
LOGGER.info(getClass().getSimpleName() + ": (" + REGIONS_X + " by " + REGIONS_Y + ") World Region Grid set up.");
}
@ -594,36 +617,23 @@ public final class L2World
return;
}
final int regionX = centerWorldRegion.getRegionX();
final int regionY = centerWorldRegion.getRegionY();
for (int x = regionX - 1; x <= (regionX + 1); x++)
for (L2WorldRegion region : centerWorldRegion.getSurroundingRegions())
{
for (int y = regionY - 1; y <= (regionY + 1); y++)
for (L2Object visibleObject : region.getVisibleObjects().values())
{
if (validRegion(x, y))
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
for (L2Object visibleObject : _worldRegions[x][y].getVisibleObjects().values())
{
if ((visibleObject == null) || (visibleObject == object) || !clazz.isInstance(visibleObject))
{
continue;
}
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
continue;
}
else if ((x == regionX) && (y == regionY)) // Precaution. Moved at invalid region?
if (visibleObject.getInstanceWorld() != object.getInstanceWorld())
{
disposeOutOfBoundsObject(object);
return;
continue;
}
if (visibleObject.calculateDistance(object, true, false) <= range)
{
c.accept(clazz.cast(visibleObject));
}
}
}
@ -641,14 +651,14 @@ public final class L2World
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, result::add);
return result;
}
public <T extends L2Object> List<T> getVisibleObjects(L2Object object, Class<T> clazz, int range, Predicate<T> predicate)
{
final List<T> result = new LinkedList<>();
final List<T> result = new ArrayList<>();
forEachVisibleObjectInRange(object, clazz, range, o ->
{
if (predicate.test(o))
@ -701,18 +711,6 @@ public final class L2World
return _worldRegions;
}
/**
* Check if the current L2WorldRegions of the object is valid according to its position (x,y). <B><U> Example of use </U> :</B>
* <li>Init L2WorldRegions</li><BR>
* @param x X position of the object
* @param y Y position of the object
* @return True if the L2WorldRegion is valid
*/
public static boolean validRegion(int x, int y)
{
return ((x >= 0) && (x <= REGIONS_X) && (y >= 0) && (y <= REGIONS_Y));
}
public synchronized void disposeOutOfBoundsObject(L2Object object)
{
if (object.isPlayer())

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.model;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
@ -34,7 +33,9 @@ public final class L2WorldRegion
private static final Logger LOGGER = Logger.getLogger(L2WorldRegion.class.getName());
/** Map containing visible objects in this world region. */
private volatile Map<Integer, L2Object> _visibleObjects;
private volatile Map<Integer, L2Object> _visibleObjects = new ConcurrentHashMap<>();
/** Map containing nearby regions forming this world region's effective area. */
private L2WorldRegion[] _surroundingRegions;
private final int _regionX;
private final int _regionY;
private boolean _active = false;
@ -75,7 +76,7 @@ public final class L2WorldRegion
private void switchAI(boolean isOn)
{
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -218,16 +219,6 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
{
synchronized (object)
{
if (_visibleObjects == null)
{
_visibleObjects = new ConcurrentHashMap<>();
}
}
}
_visibleObjects.put(object.getObjectId(), object);
if (object.isPlayable())
@ -251,7 +242,7 @@ public final class L2WorldRegion
return;
}
if (_visibleObjects == null)
if (_visibleObjects.isEmpty())
{
return;
}
@ -268,28 +259,36 @@ public final class L2WorldRegion
public Map<Integer, L2Object> getVisibleObjects()
{
return _visibleObjects != null ? _visibleObjects : Collections.emptyMap();
return _visibleObjects;
}
public boolean forEachSurroundingRegion(Predicate<L2WorldRegion> p)
{
for (int x = _regionX - 1; x <= (_regionX + 1); x++)
for (L2WorldRegion worldRegion : _surroundingRegions)
{
for (int y = _regionY - 1; y <= (_regionY + 1); y++)
if (!p.test(worldRegion))
{
if (L2World.validRegion(x, y))
{
final L2WorldRegion worldRegion = L2World.getInstance().getWorldRegions()[x][y];
if (!p.test(worldRegion))
{
return false;
}
}
return false;
}
}
return true;
}
public void setSurroundingRegions(L2WorldRegion[] regions)
{
_surroundingRegions = regions;
}
public L2WorldRegion[] getSurroundingRegions()
{
return _surroundingRegions;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
public int getRegionX()
{
return _regionX;
@ -300,11 +299,6 @@ public final class L2WorldRegion
return _regionY;
}
public boolean isSurroundingRegion(L2WorldRegion region)
{
return (region != null) && (_regionX >= (region.getRegionX() - 1)) && (_regionX <= (region.getRegionX() + 1)) && (_regionY >= (region.getRegionY() - 1)) && (_regionY <= (region.getRegionY() + 1));
}
@Override
public String toString()
{