forked from MagicBane/Server
Project cleanup pre merge.
This commit is contained in:
+322
-332
@@ -21,364 +21,354 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class Regions {
|
||||
|
||||
public class Regions {
|
||||
public static HashMap<Integer, Regions> FurnitureRegionMap = new HashMap<>();
|
||||
public final boolean stairs;
|
||||
public final boolean exit;
|
||||
public int room;
|
||||
public boolean outside;
|
||||
public int level;
|
||||
public Vector3fImmutable lowLerp;
|
||||
public Vector3fImmutable highLerp;
|
||||
public Vector3f center;
|
||||
public float regionDistanceSquared;
|
||||
|
||||
public int room;
|
||||
public boolean outside;
|
||||
public int level;
|
||||
public final boolean stairs;
|
||||
public final boolean exit;
|
||||
public static HashMap<Integer,Regions> FurnitureRegionMap = new HashMap<>();
|
||||
public Vector3fImmutable lowLerp;
|
||||
public Vector3fImmutable highLerp;
|
||||
public Vector3f center;
|
||||
public float regionDistanceSquared;
|
||||
|
||||
public ArrayList<Vector3f> regionPoints;
|
||||
|
||||
public int parentBuildingID;
|
||||
public ArrayList<Vector3f> regionPoints;
|
||||
|
||||
public int parentBuildingID;
|
||||
|
||||
|
||||
public Regions(ArrayList<Vector3f> regionPoints, int level, int room, boolean outside, boolean exit,boolean stairs, Vector3f center, int parentBuildingID) {
|
||||
super();
|
||||
|
||||
public Regions(ArrayList<Vector3f> regionPoints, int level, int room, boolean outside, boolean exit, boolean stairs, Vector3f center, int parentBuildingID) {
|
||||
super();
|
||||
|
||||
this.level = level;
|
||||
this.room = room;
|
||||
|
||||
this.outside = (outside);
|
||||
this.regionPoints = regionPoints;
|
||||
this.exit = exit;
|
||||
this.stairs = stairs;
|
||||
this.center = center;
|
||||
this.parentBuildingID = parentBuildingID;
|
||||
//order regionpoints clockwise starting from top left, and ending bottom left.
|
||||
|
||||
ArrayList<Vector3f> top = new ArrayList<>();
|
||||
ArrayList<Vector3f> bottom = new ArrayList<>();
|
||||
|
||||
for (Vector3f point : this.regionPoints){
|
||||
if (point.y > center.y)
|
||||
top.add(point);
|
||||
else if (point.y < center.y)
|
||||
bottom.add(point);
|
||||
}
|
||||
|
||||
|
||||
if (top.size() == 2 && bottom.size() == 2){
|
||||
Vector3f topLeft = Vector3f.min(top.get(0), top.get(1));
|
||||
Vector3f topRight = Vector3f.max(top.get(0), top.get(1));
|
||||
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
Vector3f bottomLeft = Vector3f.min(bottom.get(0), bottom.get(1));
|
||||
Vector3f bottomRight = Vector3f.max(bottom.get(0), bottom.get(1));
|
||||
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
|
||||
} else if (top.size() == 2 && bottom.size() == 1){
|
||||
Vector3f topLeft = Vector3f.min(top.get(0), top.get(1));
|
||||
Vector3f topRight = Vector3f.max(top.get(0), top.get(1));
|
||||
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
Vector3f topCopy = topRight.subtract2D(topLeft);
|
||||
topCopy.normalize();
|
||||
|
||||
float topMagnitude = topRight.subtract2D(topLeft).length();
|
||||
|
||||
topCopy.multLocal(topMagnitude);
|
||||
|
||||
Vector3f bottomLeft = null;
|
||||
Vector3f bottomRight = null;
|
||||
if (bottom.get(0).distance2D(topLeft) <= bottom.get(0).distance2D(topRight))
|
||||
bottomLeft = bottom.get(0);
|
||||
else if (bottom.get(0).distance2D(topRight) <= bottom.get(0).distance2D(topLeft))
|
||||
bottomRight = bottom.get(0);
|
||||
//find bottom right point
|
||||
|
||||
if (bottomLeft != null){
|
||||
bottomRight = bottomLeft.add(topCopy);
|
||||
}else if (bottomRight != null){
|
||||
bottomLeft = bottomRight.subtract(topCopy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
|
||||
}else if (bottom.size() == 2 && top.size() == 1){
|
||||
Vector3f topLeft = Vector3f.min(bottom.get(0), bottom.get(1));
|
||||
Vector3f topRight = Vector3f.max(bottom.get(0), bottom.get(1));
|
||||
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
Vector3f topCopy = topRight.subtract2D(topLeft);
|
||||
topCopy.normalize();
|
||||
|
||||
float topMagnitude = topRight.subtract2D(topLeft).length();
|
||||
|
||||
topCopy.multLocal(topMagnitude);
|
||||
|
||||
Vector3f bottomLeft = null;
|
||||
Vector3f bottomRight = null;
|
||||
if (top.get(0).distance2D(topLeft) < top.get(0).distance2D(topRight))
|
||||
bottomLeft = bottom.get(0);
|
||||
else if (top.get(0).distance2D(topRight) < top.get(0).distance2D(topLeft))
|
||||
bottomRight = bottom.get(0);
|
||||
//find bottom right point
|
||||
|
||||
if (bottomLeft != null){
|
||||
bottomRight = bottomLeft.add(topCopy);
|
||||
}else if (bottomRight != null){
|
||||
bottomLeft = bottomRight.subtract(topCopy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
}
|
||||
|
||||
if (this.lowLerp == null)
|
||||
this.lowLerp = new Vector3fImmutable(this.regionPoints.get(0));
|
||||
|
||||
if (this.highLerp == null){
|
||||
this.highLerp = new Vector3fImmutable(this.regionPoints.get(2));
|
||||
}
|
||||
|
||||
this.regionDistanceSquared = this.lowLerp.distanceSquared2D(this.highLerp);
|
||||
}
|
||||
|
||||
public int getRoom() {
|
||||
return room;
|
||||
}
|
||||
this.outside = (outside);
|
||||
this.regionPoints = regionPoints;
|
||||
this.exit = exit;
|
||||
this.stairs = stairs;
|
||||
this.center = center;
|
||||
this.parentBuildingID = parentBuildingID;
|
||||
//order regionpoints clockwise starting from top left, and ending bottom left.
|
||||
|
||||
|
||||
ArrayList<Vector3f> top = new ArrayList<>();
|
||||
ArrayList<Vector3f> bottom = new ArrayList<>();
|
||||
|
||||
for (Vector3f point : this.regionPoints) {
|
||||
if (point.y > center.y)
|
||||
top.add(point);
|
||||
else if (point.y < center.y)
|
||||
bottom.add(point);
|
||||
}
|
||||
|
||||
|
||||
public boolean isOutside() {
|
||||
return outside;
|
||||
}
|
||||
if (top.size() == 2 && bottom.size() == 2) {
|
||||
Vector3f topLeft = Vector3f.min(top.get(0), top.get(1));
|
||||
Vector3f topRight = Vector3f.max(top.get(0), top.get(1));
|
||||
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
Vector3f bottomLeft = Vector3f.min(bottom.get(0), bottom.get(1));
|
||||
Vector3f bottomRight = Vector3f.max(bottom.get(0), bottom.get(1));
|
||||
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
|
||||
} else if (top.size() == 2 && bottom.size() == 1) {
|
||||
Vector3f topLeft = Vector3f.min(top.get(0), top.get(1));
|
||||
Vector3f topRight = Vector3f.max(top.get(0), top.get(1));
|
||||
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
Vector3f topCopy = topRight.subtract2D(topLeft);
|
||||
topCopy.normalize();
|
||||
|
||||
float topMagnitude = topRight.subtract2D(topLeft).length();
|
||||
|
||||
topCopy.multLocal(topMagnitude);
|
||||
|
||||
Vector3f bottomLeft = null;
|
||||
Vector3f bottomRight = null;
|
||||
if (bottom.get(0).distance2D(topLeft) <= bottom.get(0).distance2D(topRight))
|
||||
bottomLeft = bottom.get(0);
|
||||
else if (bottom.get(0).distance2D(topRight) <= bottom.get(0).distance2D(topLeft))
|
||||
bottomRight = bottom.get(0);
|
||||
//find bottom right point
|
||||
|
||||
if (bottomLeft != null) {
|
||||
bottomRight = bottomLeft.add(topCopy);
|
||||
} else if (bottomRight != null) {
|
||||
bottomLeft = bottomRight.subtract(topCopy);
|
||||
}
|
||||
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public boolean collides(Vector3fImmutable collisionPoint){
|
||||
|
||||
//test if inside triangle // Regions either have 3 or 4 points
|
||||
if (this.regionPoints.size() == 3){
|
||||
float regionArea = FastMath.area(regionPoints.get(0).x, regionPoints.get(0).z, regionPoints.get(1).x, regionPoints.get(1).z, regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
float collisionArea1 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(0).x, regionPoints.get(0).z,regionPoints.get(1).x, regionPoints.get(1).z);
|
||||
float collisionArea2 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(1).x, regionPoints.get(1).z,regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
float collisionArea3 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(0).x, regionPoints.get(0).z,regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
|
||||
if ((collisionArea1 + collisionArea2 + collisionArea3) == regionArea)
|
||||
return true;
|
||||
|
||||
}else{
|
||||
|
||||
int i;
|
||||
int j;
|
||||
for (i = 0, j = this.regionPoints.size() - 1; i < this.regionPoints.size(); j = i++) {
|
||||
if ((regionPoints.get(i).z > collisionPoint.z) != (regionPoints.get(j).z > collisionPoint.z) &&
|
||||
(collisionPoint.x < (regionPoints.get(j).x - regionPoints.get(i).x) * (collisionPoint.z - regionPoints.get(i).z) / (regionPoints.get(j).z-regionPoints.get(i).z) + regionPoints.get(i).x)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPointInPolygon( Vector3fImmutable point)
|
||||
{
|
||||
boolean inside = false;
|
||||
for (int i = 0, j = regionPoints.size()-1; i < regionPoints.size(); j = i++)
|
||||
{
|
||||
if (((regionPoints.get(i).z > point.z) != (regionPoints.get(j).z > point.z)) &&
|
||||
(point.x < (regionPoints.get(j).x - regionPoints.get(i).x) * (point.z - regionPoints.get(i).z) / (regionPoints.get(j).z - regionPoints.get(i).z) + regionPoints.get(i).x))
|
||||
inside = !inside;
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
||||
public static boolean CanEnterRegion(AbstractWorldObject worldObject, Regions toEnter){
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
if (worldObject.region == null)
|
||||
if (toEnter.level == 0 || toEnter.room == -1 || toEnter.exit)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
|
||||
if (worldObject.region.equals(toEnter))
|
||||
return true;
|
||||
} else if (bottom.size() == 2 && top.size() == 1) {
|
||||
Vector3f topLeft = Vector3f.min(bottom.get(0), bottom.get(1));
|
||||
Vector3f topRight = Vector3f.max(bottom.get(0), bottom.get(1));
|
||||
|
||||
if (worldObject.region.level == toEnter.level)
|
||||
return true;
|
||||
Vector3f topCenter = topLeft.lerp(topRight, .5f);
|
||||
|
||||
//next region is stairs, if they are on the same level as stairs or 1 up, world object can enter.
|
||||
if (toEnter.stairs)
|
||||
if (worldObject.region.level == toEnter.level || toEnter.level - 1 == worldObject.region.level)
|
||||
return true;
|
||||
if (worldObject.region.stairs) {
|
||||
Vector3f topCopy = topRight.subtract2D(topLeft);
|
||||
topCopy.normalize();
|
||||
|
||||
boolean movingUp = false;
|
||||
float topMagnitude = topRight.subtract2D(topLeft).length();
|
||||
|
||||
boolean movingDown = false;
|
||||
float yLerp = worldObject.region.lerpY(worldObject);
|
||||
topCopy.multLocal(topMagnitude);
|
||||
|
||||
if (yLerp == (worldObject.region.highLerp.y))
|
||||
movingUp = true;
|
||||
else if (yLerp == (worldObject.region.lowLerp.y))
|
||||
movingDown = true;
|
||||
//Stairs are always considered on the bottom floor.
|
||||
Vector3f bottomLeft = null;
|
||||
Vector3f bottomRight = null;
|
||||
if (top.get(0).distance2D(topLeft) < top.get(0).distance2D(topRight))
|
||||
bottomLeft = bottom.get(0);
|
||||
else if (top.get(0).distance2D(topRight) < top.get(0).distance2D(topLeft))
|
||||
bottomRight = bottom.get(0);
|
||||
//find bottom right point
|
||||
|
||||
if (bottomLeft != null) {
|
||||
bottomRight = bottomLeft.add(topCopy);
|
||||
} else if (bottomRight != null) {
|
||||
bottomLeft = bottomRight.subtract(topCopy);
|
||||
}
|
||||
|
||||
|
||||
if (movingUp) {
|
||||
if (toEnter.level == worldObject.region.level + 1)
|
||||
return true;
|
||||
} else if (movingDown)
|
||||
if (toEnter.level == worldObject.region.level)
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public float lerpY (AbstractWorldObject lerper){
|
||||
|
||||
Vector3fImmutable lengthVector = this.highLerp.subtract2D(this.lowLerp);
|
||||
Vector3fImmutable characterVector = lerper.getLoc().subtract2D(this.lowLerp);
|
||||
float lengthVectorMagnitude = lengthVector.magnitude();
|
||||
float characterVectorMagnitude = characterVector.magnitude();
|
||||
float percentDistance = characterVectorMagnitude/lengthVectorMagnitude;
|
||||
float interpolatedY = this.lowLerp.interpolate(this.highLerp, percentDistance).y;
|
||||
|
||||
if (interpolatedY > this.highLerp.y)
|
||||
interpolatedY = this.highLerp.y;
|
||||
else if (interpolatedY < this.lowLerp.y)
|
||||
interpolatedY = this.lowLerp.y;
|
||||
return interpolatedY;
|
||||
}
|
||||
Vector3f bottomCenter = bottomLeft.lerp(bottomRight, .5f);
|
||||
|
||||
this.lowLerp = new Vector3fImmutable(bottomCenter);
|
||||
this.highLerp = new Vector3fImmutable(topCenter);
|
||||
}
|
||||
|
||||
if (this.lowLerp == null)
|
||||
this.lowLerp = new Vector3fImmutable(this.regionPoints.get(0));
|
||||
|
||||
if (this.highLerp == null) {
|
||||
this.highLerp = new Vector3fImmutable(this.regionPoints.get(2));
|
||||
}
|
||||
|
||||
this.regionDistanceSquared = this.lowLerp.distanceSquared2D(this.highLerp);
|
||||
}
|
||||
|
||||
public static boolean CanEnterRegion(AbstractWorldObject worldObject, Regions toEnter) {
|
||||
|
||||
if (worldObject.region == null)
|
||||
if (toEnter.level == 0 || toEnter.room == -1 || toEnter.exit)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (worldObject.region.equals(toEnter))
|
||||
return true;
|
||||
|
||||
if (worldObject.region.level == toEnter.level)
|
||||
return true;
|
||||
|
||||
//next region is stairs, if they are on the same level as stairs or 1 up, world object can enter.
|
||||
if (toEnter.stairs)
|
||||
if (worldObject.region.level == toEnter.level || toEnter.level - 1 == worldObject.region.level)
|
||||
return true;
|
||||
if (worldObject.region.stairs) {
|
||||
|
||||
boolean movingUp = false;
|
||||
|
||||
boolean movingDown = false;
|
||||
float yLerp = worldObject.region.lerpY(worldObject);
|
||||
|
||||
if (yLerp == (worldObject.region.highLerp.y))
|
||||
movingUp = true;
|
||||
else if (yLerp == (worldObject.region.lowLerp.y))
|
||||
movingDown = true;
|
||||
//Stairs are always considered on the bottom floor.
|
||||
|
||||
|
||||
public boolean isStairs() {
|
||||
return stairs;
|
||||
}
|
||||
if (movingUp) {
|
||||
if (toEnter.level == worldObject.region.level + 1)
|
||||
return true;
|
||||
} else if (movingDown)
|
||||
if (toEnter.level == worldObject.region.level)
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static float GetMagnitudeOfRegionSlope(Regions region) {
|
||||
Vector3fImmutable lengthVector = region.highLerp.subtract2D(region.lowLerp);
|
||||
return lengthVector.magnitude();
|
||||
}
|
||||
|
||||
public static float GetMagnitudeOfPlayerOnRegionSlope(Regions region, PlayerCharacter player) {
|
||||
Vector3fImmutable characterVector = player.getLoc().subtract2D(region.lowLerp);
|
||||
return characterVector.magnitude();
|
||||
}
|
||||
|
||||
public static float SlopeLerpPercent(PlayerCharacter player, Regions region) {
|
||||
|
||||
float lengthVectorMagnitude = Regions.GetMagnitudeOfRegionSlope(region);
|
||||
float characterVectorMagnitude = Regions.GetMagnitudeOfPlayerOnRegionSlope(region, player);
|
||||
float percentDistance = characterVectorMagnitude / lengthVectorMagnitude * 2;
|
||||
return percentDistance;
|
||||
}
|
||||
|
||||
public static boolean CanEnterFromOutsideBuilding(Building building, Regions region) {
|
||||
if (!region.outside)
|
||||
return false;
|
||||
if (region.lowLerp.y - building.getLoc().y > 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean CanEnterNextLevel(Regions fromRegion, Regions toRegion, AbstractWorldObject worldObject) {
|
||||
|
||||
if (fromRegion == null)
|
||||
return false;
|
||||
|
||||
if (toRegion == null)
|
||||
return false;
|
||||
|
||||
// regions are the same, no need to go any further.
|
||||
if (fromRegion.equals(toRegion))
|
||||
return true;
|
||||
|
||||
//cant move up a level without stairs.
|
||||
if (!fromRegion.stairs)
|
||||
return false;
|
||||
|
||||
boolean movingUp = false;
|
||||
|
||||
Vector3fImmutable closestPoint = Vector3fImmutable.ClosestPointOnLine(fromRegion.lowLerp, fromRegion.highLerp, worldObject.getLoc());
|
||||
|
||||
//Closest point of a region higher than current region will always return highlerp.
|
||||
if (closestPoint.equals(fromRegion.highLerp))
|
||||
movingUp = true;
|
||||
//Stairs are always considered on the bottom floor.
|
||||
|
||||
if (movingUp) {
|
||||
if (toRegion.level != fromRegion.level + 1)
|
||||
return false;
|
||||
} else if (toRegion.level != fromRegion.level)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean IsGroundLevel(Regions region, Building building) {
|
||||
|
||||
if (region.lowLerp.y - building.getLoc().y > 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Building GetBuildingForRegion(Regions region) {
|
||||
return BuildingManager.getBuildingFromCache(region.parentBuildingID);
|
||||
}
|
||||
|
||||
public static Regions GetRegionForTeleport(Vector3fImmutable location) {
|
||||
Regions region = null;
|
||||
|
||||
|
||||
public boolean isExit() {
|
||||
return exit;
|
||||
}
|
||||
//Find building
|
||||
for (AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(location, MBServerStatics.STRUCTURE_LOAD_RANGE, MBServerStatics.MASK_BUILDING)) {
|
||||
Building building = (Building) awo;
|
||||
if (!Bounds.collide(location, building.getBounds()))
|
||||
continue;
|
||||
|
||||
public static float GetMagnitudeOfRegionSlope(Regions region){
|
||||
Vector3fImmutable lengthVector = region.highLerp.subtract2D(region.lowLerp);
|
||||
return lengthVector.magnitude();
|
||||
}
|
||||
//find regions that intersect x and z, check if object can enter.
|
||||
for (Regions toEnter : building.getBounds().getRegions()) {
|
||||
if (toEnter.isPointInPolygon(location)) {
|
||||
|
||||
public static float GetMagnitudeOfPlayerOnRegionSlope(Regions region, PlayerCharacter player){
|
||||
Vector3fImmutable characterVector = player.getLoc().subtract2D(region.lowLerp);
|
||||
return characterVector.magnitude();
|
||||
}
|
||||
if (region == null)
|
||||
region = toEnter;
|
||||
else // we're using a low level to high level tree structure, database not always in order low to high.
|
||||
//check for highest level index.
|
||||
if (region != null && toEnter.highLerp.y > region.highLerp.y)
|
||||
region = toEnter;
|
||||
|
||||
public static float SlopeLerpPercent(PlayerCharacter player, Regions region){
|
||||
|
||||
float lengthVectorMagnitude = Regions.GetMagnitudeOfRegionSlope(region);
|
||||
float characterVectorMagnitude = Regions.GetMagnitudeOfPlayerOnRegionSlope(region, player);
|
||||
float percentDistance = characterVectorMagnitude/lengthVectorMagnitude * 2;
|
||||
return percentDistance;
|
||||
}
|
||||
|
||||
public static boolean CanEnterFromOutsideBuilding(Building building,Regions region){
|
||||
if (!region.outside)
|
||||
return false;
|
||||
if (region.lowLerp.y - building.getLoc().y > 1 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean CanEnterNextLevel(Regions fromRegion,Regions toRegion, AbstractWorldObject worldObject){
|
||||
|
||||
if (fromRegion == null)
|
||||
return false;
|
||||
|
||||
if (toRegion == null)
|
||||
return false;
|
||||
|
||||
// regions are the same, no need to go any further.
|
||||
if (fromRegion.equals(toRegion))
|
||||
return true;
|
||||
|
||||
//cant move up a level without stairs.
|
||||
if (!fromRegion.stairs)
|
||||
return false;
|
||||
|
||||
boolean movingUp = false;
|
||||
|
||||
Vector3fImmutable closestPoint = Vector3fImmutable.ClosestPointOnLine(fromRegion.lowLerp, fromRegion.highLerp, worldObject.getLoc());
|
||||
|
||||
//Closest point of a region higher than current region will always return highlerp.
|
||||
if (closestPoint.equals(fromRegion.highLerp))
|
||||
movingUp = true;
|
||||
//Stairs are always considered on the bottom floor.
|
||||
|
||||
if (movingUp){
|
||||
if(toRegion.level != fromRegion.level + 1)
|
||||
return false;
|
||||
}else if (toRegion.level != fromRegion.level)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean IsGroundLevel(Regions region, Building building){
|
||||
|
||||
if (region.lowLerp.y - building.getLoc().y > 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Building GetBuildingForRegion(Regions region){
|
||||
return BuildingManager.getBuildingFromCache(region.parentBuildingID);
|
||||
}
|
||||
public static Regions GetRegionForTeleport(Vector3fImmutable location){
|
||||
Regions region = null;
|
||||
|
||||
|
||||
//Find building
|
||||
for (AbstractWorldObject awo:WorldGrid.getObjectsInRangePartial(location, MBServerStatics.STRUCTURE_LOAD_RANGE, MBServerStatics.MASK_BUILDING)){
|
||||
Building building = (Building)awo;
|
||||
if (!Bounds.collide(location, building.getBounds()))
|
||||
continue;
|
||||
|
||||
//find regions that intersect x and z, check if object can enter.
|
||||
for (Regions toEnter: building.getBounds().getRegions()){
|
||||
if (toEnter.isPointInPolygon(location)){
|
||||
|
||||
if (region == null)
|
||||
region = toEnter;
|
||||
else // we're using a low level to high level tree structure, database not always in order low to high.
|
||||
//check for highest level index.
|
||||
if(region != null && toEnter.highLerp.y > region.highLerp.y)
|
||||
region = toEnter;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
public int getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
public boolean isOutside() {
|
||||
return outside;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public boolean collides(Vector3fImmutable collisionPoint) {
|
||||
|
||||
//test if inside triangle // Regions either have 3 or 4 points
|
||||
if (this.regionPoints.size() == 3) {
|
||||
float regionArea = FastMath.area(regionPoints.get(0).x, regionPoints.get(0).z, regionPoints.get(1).x, regionPoints.get(1).z, regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
float collisionArea1 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(0).x, regionPoints.get(0).z, regionPoints.get(1).x, regionPoints.get(1).z);
|
||||
float collisionArea2 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(1).x, regionPoints.get(1).z, regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
float collisionArea3 = FastMath.area(collisionPoint.x, collisionPoint.z, regionPoints.get(0).x, regionPoints.get(0).z, regionPoints.get(2).x, regionPoints.get(2).z);
|
||||
|
||||
if ((collisionArea1 + collisionArea2 + collisionArea3) == regionArea)
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
int i;
|
||||
int j;
|
||||
for (i = 0, j = this.regionPoints.size() - 1; i < this.regionPoints.size(); j = i++) {
|
||||
if ((regionPoints.get(i).z > collisionPoint.z) != (regionPoints.get(j).z > collisionPoint.z) &&
|
||||
(collisionPoint.x < (regionPoints.get(j).x - regionPoints.get(i).x) * (collisionPoint.z - regionPoints.get(i).z) / (regionPoints.get(j).z - regionPoints.get(i).z) + regionPoints.get(i).x)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPointInPolygon(Vector3fImmutable point) {
|
||||
boolean inside = false;
|
||||
for (int i = 0, j = regionPoints.size() - 1; i < regionPoints.size(); j = i++) {
|
||||
if (((regionPoints.get(i).z > point.z) != (regionPoints.get(j).z > point.z)) &&
|
||||
(point.x < (regionPoints.get(j).x - regionPoints.get(i).x) * (point.z - regionPoints.get(i).z) / (regionPoints.get(j).z - regionPoints.get(i).z) + regionPoints.get(i).x))
|
||||
inside = !inside;
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
||||
public float lerpY(AbstractWorldObject lerper) {
|
||||
|
||||
Vector3fImmutable lengthVector = this.highLerp.subtract2D(this.lowLerp);
|
||||
Vector3fImmutable characterVector = lerper.getLoc().subtract2D(this.lowLerp);
|
||||
float lengthVectorMagnitude = lengthVector.magnitude();
|
||||
float characterVectorMagnitude = characterVector.magnitude();
|
||||
float percentDistance = characterVectorMagnitude / lengthVectorMagnitude;
|
||||
float interpolatedY = this.lowLerp.interpolate(this.highLerp, percentDistance).y;
|
||||
|
||||
if (interpolatedY > this.highLerp.y)
|
||||
interpolatedY = this.highLerp.y;
|
||||
else if (interpolatedY < this.lowLerp.y)
|
||||
interpolatedY = this.lowLerp.y;
|
||||
return interpolatedY;
|
||||
}
|
||||
|
||||
public boolean isStairs() {
|
||||
return stairs;
|
||||
}
|
||||
|
||||
public boolean isExit() {
|
||||
return exit;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user