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 javax.xml.parsers.DocumentBuilderFactory;
|
||||
@@ -33,7 +30,6 @@ import org.w3c.dom.Node;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.enums.FenceState;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.World;
|
||||
import org.l2jmobius.gameserver.model.WorldRegion;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.FenceInstance;
|
||||
@@ -47,7 +43,6 @@ public class FenceData
|
||||
|
||||
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()
|
||||
@@ -126,21 +121,12 @@ public class FenceData
|
||||
|
||||
private void addFence(FenceInstance fence)
|
||||
{
|
||||
final Location point = new Location(fence.getX(), fence.getY(), fence.getZ());
|
||||
_fences.put(fence.getObjectId(), fence);
|
||||
_regions.computeIfAbsent(World.getInstance().getRegion(point), key -> new ArrayList<>()).add(fence);
|
||||
}
|
||||
|
||||
public void removeFence(FenceInstance fence)
|
||||
{
|
||||
_fences.remove(fence.getObjectId());
|
||||
|
||||
final Location point = new Location(fence.getX(), fence.getY(), fence.getZ());
|
||||
final List<FenceInstance> fencesInRegion = _regions.get(World.getInstance().getRegion(point));
|
||||
if (fencesInRegion != null)
|
||||
{
|
||||
fencesInRegion.remove(fence);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, FenceInstance> getFences()
|
||||
@@ -155,12 +141,19 @@ public class FenceData
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@@ -169,40 +162,30 @@ public class FenceData
|
||||
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;
|
||||
};
|
||||
|
||||
return _regions.getOrDefault(World.getInstance().getRegion(new Location(x, y, z)), 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)
|
||||
|
@@ -460,6 +460,11 @@ public abstract class WorldObject
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFence()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isBoat()
|
||||
{
|
||||
return false;
|
||||
|
@@ -31,6 +31,7 @@ import org.l2jmobius.gameserver.data.sql.SpawnTable;
|
||||
import org.l2jmobius.gameserver.model.actor.Attackable;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.DoorInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.FenceInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.NpcInstance;
|
||||
import org.l2jmobius.gameserver.model.spawn.Spawn;
|
||||
import org.l2jmobius.gameserver.model.zone.ZoneManager;
|
||||
@@ -45,6 +46,7 @@ public class WorldRegion
|
||||
|
||||
private final UnboundArrayList<WorldObject> _visibleObjects = new UnboundArrayList<>();
|
||||
private final List<DoorInstance> _doors = new ArrayList<>(1);
|
||||
private final List<FenceInstance> _fences = new ArrayList<>(1);
|
||||
private WorldRegion[] _surroundingRegions;
|
||||
private final int _regionX;
|
||||
private final int _regionY;
|
||||
@@ -241,7 +243,7 @@ public class WorldRegion
|
||||
|
||||
_active = value;
|
||||
|
||||
// turn the AI on or off to match the region's activation.
|
||||
// Turn the AI on or off to match the region's activation.
|
||||
switchAI(value);
|
||||
}
|
||||
|
||||
@@ -305,8 +307,7 @@ public class WorldRegion
|
||||
|
||||
/**
|
||||
* Add the WorldObject in the WorldObjectHashSet(WorldObject) _visibleObjects containing WorldObject visible in this WorldRegion<br>
|
||||
* If WorldObject is a PlayerInstance, Add the PlayerInstance in the WorldObjectHashSet(PlayerInstance) _allPlayable containing PlayerInstance of all player in game in this WorldRegion<br>
|
||||
* Assert : object.getCurrentWorldRegion() == this
|
||||
* If WorldObject is a PlayerInstance, Add the PlayerInstance in the WorldObjectHashSet(PlayerInstance) _allPlayable containing PlayerInstance of all player in game in this WorldRegion
|
||||
* @param object
|
||||
*/
|
||||
public void addVisibleObject(WorldObject object)
|
||||
@@ -325,6 +326,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)
|
||||
@@ -334,9 +342,7 @@ public class WorldRegion
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the WorldObject from the WorldObjectHashSet(WorldObject) _visibleObjects in this WorldRegion<br>
|
||||
* If WorldObject is a PlayerInstance, remove it from the WorldObjectHashSet(PlayerInstance) _allPlayable of this WorldRegion<br>
|
||||
* Assert : object.getCurrentWorldRegion() == this || object.getCurrentWorldRegion() == null
|
||||
* Remove the WorldObject from the WorldObjectHashSet(WorldObject) _visibleObjects in this WorldRegion. If WorldObject is a PlayerInstance, remove it from the WorldObjectHashSet(PlayerInstance) _allPlayable of this WorldRegion
|
||||
* @param object
|
||||
*/
|
||||
public void removeVisibleObject(WorldObject object)
|
||||
@@ -357,7 +363,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,6 +427,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 String getName()
|
||||
{
|
||||
return "(" + _regionX + ", " + _regionY + ")";
|
||||
|
@@ -153,4 +153,10 @@ public class FenceInstance extends WorldObject
|
||||
{
|
||||
return _yMax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFence()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user