Store fence objects in regions.
This commit is contained in:
@@ -17,12 +17,9 @@
|
||||
package org.l2jmobius.gameserver.data.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
@@ -44,7 +41,6 @@ public class FenceData implements IXmlReader
|
||||
|
||||
private static final int MAX_Z_DIFF = 100;
|
||||
|
||||
private final Map<WorldRegion, List<FenceInstance>> _regions = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, FenceInstance> _fences = new ConcurrentHashMap<>();
|
||||
|
||||
protected FenceData()
|
||||
@@ -103,18 +99,11 @@ public class FenceData implements IXmlReader
|
||||
private void addFence(FenceInstance fence)
|
||||
{
|
||||
_fences.put(fence.getObjectId(), fence);
|
||||
_regions.computeIfAbsent(World.getInstance().getRegion(fence), key -> new ArrayList<>()).add(fence);
|
||||
}
|
||||
|
||||
public void removeFence(FenceInstance fence)
|
||||
{
|
||||
_fences.remove(fence.getObjectId());
|
||||
|
||||
final List<FenceInstance> fencesInRegion = _regions.get(World.getInstance().getRegion(fence));
|
||||
if (fencesInRegion != null)
|
||||
{
|
||||
fencesInRegion.remove(fence);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, FenceInstance> getFences()
|
||||
@@ -129,18 +118,25 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId)
|
||||
{
|
||||
final Predicate<FenceInstance> filter = fence ->
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y);
|
||||
final List<FenceInstance> fences = region != null ? region.getFences() : null;
|
||||
if ((fences == null) || fences.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (FenceInstance fence : fences)
|
||||
{
|
||||
// Check if fence is geodata enabled.
|
||||
if (!fence.getState().isGeodataEnabled())
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if fence is within the instance we search for.
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@@ -149,41 +145,30 @@ public class FenceData implements IXmlReader
|
||||
final int yMax = fence.getYMax();
|
||||
if ((x < xMin) && (tx < xMin))
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
if ((x > xMax) && (tx > xMax))
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
if ((y < yMin) && (ty < yMin))
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
if ((y > yMax) && (ty > yMax))
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax))
|
||||
if ((x > xMin) && (tx > xMin) && (x < xMax) && (tx < xMax) && (y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax))
|
||||
{
|
||||
if ((y > yMin) && (ty > yMin) && (y < yMax) && (ty < yMax))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax))
|
||||
if ((crossLinePart(xMin, yMin, xMax, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMin, xMax, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMax, yMax, xMin, yMax, x, y, tx, ty, xMin, yMin, xMax, yMax) || crossLinePart(xMin, yMax, xMin, yMin, x, y, tx, ty, xMin, yMin, xMax, yMax)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
if ((z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return region == null ? false : _regions.getOrDefault(region, Collections.emptyList()).stream().anyMatch(filter);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean crossLinePart(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double xMin, double yMin, double xMax, double yMax)
|
||||
|
@@ -415,6 +415,15 @@ public abstract class WorldObject extends ListenersContainer implements IIdentif
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if this object is a fence.
|
||||
* @return {@code true} if object is Fence, {@code false} otherwise
|
||||
*/
|
||||
public boolean isFence()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if object Can be targeted
|
||||
*/
|
||||
|
@@ -25,6 +25,7 @@ import org.l2jmobius.commons.concurrent.ThreadPool;
|
||||
import org.l2jmobius.gameserver.model.actor.Attackable;
|
||||
import org.l2jmobius.gameserver.model.actor.Npc;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.DoorInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.FenceInstance;
|
||||
import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager;
|
||||
import org.l2jmobius.gameserver.util.UnboundArrayList;
|
||||
|
||||
@@ -34,6 +35,8 @@ public class WorldRegion
|
||||
private final UnboundArrayList<WorldObject> _visibleObjects = new UnboundArrayList<>();
|
||||
/** List containing doors in this world region. */
|
||||
private final List<DoorInstance> _doors = new ArrayList<>(1);
|
||||
/** List containing fences in this world region. */
|
||||
private final List<FenceInstance> _fences = new ArrayList<>(1);
|
||||
/** Array containing nearby regions forming this world region's effective area. */
|
||||
private WorldRegion[] _surroundingRegions;
|
||||
private final int _regionX;
|
||||
@@ -241,6 +244,13 @@ public class WorldRegion
|
||||
_surroundingRegions[i].addDoor((DoorInstance) object);
|
||||
}
|
||||
}
|
||||
else if (object.isFence())
|
||||
{
|
||||
for (int i = 0; i < _surroundingRegions.length; i++)
|
||||
{
|
||||
_surroundingRegions[i].addFence((FenceInstance) object);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is the first player to enter the region, activate self and neighbors.
|
||||
if (object.isPlayable() && !_active && !Config.GRIDS_ALWAYS_ON)
|
||||
@@ -271,7 +281,14 @@ public class WorldRegion
|
||||
{
|
||||
for (int i = 0; i < _surroundingRegions.length; i++)
|
||||
{
|
||||
removeDoor((DoorInstance) object);
|
||||
_surroundingRegions[i].removeDoor((DoorInstance) object);
|
||||
}
|
||||
}
|
||||
else if (object.isFence())
|
||||
{
|
||||
for (int i = 0; i < _surroundingRegions.length; i++)
|
||||
{
|
||||
_surroundingRegions[i].removeFence((FenceInstance) object);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,6 +321,24 @@ public class WorldRegion
|
||||
return _doors;
|
||||
}
|
||||
|
||||
public synchronized void addFence(FenceInstance fence)
|
||||
{
|
||||
if (!_fences.contains(fence))
|
||||
{
|
||||
_fences.add(fence);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void removeFence(FenceInstance fence)
|
||||
{
|
||||
_fences.remove(fence);
|
||||
}
|
||||
|
||||
public List<FenceInstance> getFences()
|
||||
{
|
||||
return _fences;
|
||||
}
|
||||
|
||||
public void setSurroundingRegions(WorldRegion[] regions)
|
||||
{
|
||||
_surroundingRegions = regions;
|
||||
|
@@ -160,4 +160,10 @@ public class FenceInstance extends WorldObject
|
||||
{
|
||||
return _yMax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFence()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user