Store fence objects in regions.
This commit is contained in:
parent
031006131b
commit
a8c77b8795
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -45,7 +42,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()
|
||||
@ -104,18 +100,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()
|
||||
@ -130,19 +119,26 @@ public class FenceData implements IXmlReader
|
||||
|
||||
public boolean checkIfFenceBetween(int x, int y, int z, int tx, int ty, int tz, Instance instance)
|
||||
{
|
||||
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.
|
||||
final int instanceId = (instance == null) ? 0 : instance.getId();
|
||||
if (fence.getInstanceId() != instanceId)
|
||||
{
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
final int xMin = fence.getXMin();
|
||||
@ -151,34 +147,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) && (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)) && (z > (fence.getZ() - MAX_Z_DIFF)) && (z < (fence.getZ() + MAX_Z_DIFF)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
final WorldRegion region = World.getInstance().getRegion(x, y); // Should never be null.
|
||||
return (region != null) && _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)
|
||||
|
@ -412,6 +412,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;
|
||||
}
|
||||
|
||||
public void setTargetable(boolean targetable)
|
||||
{
|
||||
if (_isTargetable != targetable)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user