forked from MagicBane/Server
Compare commits
25 Commits
hull7
..
convex-data
| Author | SHA1 | Date | |
|---|---|---|---|
| 7405d71a90 | |||
| 89f9c0471f | |||
| a94056e9e1 | |||
| 021a5a5a5a | |||
| 892174ffe1 | |||
| 536ccc2143 | |||
| 2ced2f75af | |||
| 63248ef577 | |||
| 72412a98dd | |||
| a664c8790e | |||
| 9663d87088 | |||
| 4e642b0f42 | |||
| f9fafe90d5 | |||
| 3181c465cb | |||
| 9b8be777f1 | |||
| eb5bc14974 | |||
| 7e99e8c7a4 | |||
| 9b0f4d5aef | |||
| b58049968f | |||
| 9bf0d3f7d1 | |||
| 8300c47e4a | |||
| c73fcc19f2 | |||
| f93573177a | |||
| fe9c6437d8 | |||
| c110ffc4b1 |
@@ -15,12 +15,12 @@ import engine.Enum.ProtectionState;
|
||||
import engine.Enum.TaxType;
|
||||
import engine.gameManager.BuildingManager;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.math.Vector2f;
|
||||
import engine.math.Vector3fImmutable;
|
||||
import engine.objects.*;
|
||||
import org.joda.time.DateTime;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.awt.geom.Path2D;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@@ -549,7 +549,7 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void LOAD_MESH_HULLS() {
|
||||
public void LOAD_CONVEX_HULLS() {
|
||||
|
||||
int recordsRead = 0;
|
||||
|
||||
@@ -562,28 +562,40 @@ public class dbBuildingHandler extends dbHandlerBase {
|
||||
|
||||
recordsRead++;
|
||||
|
||||
int propID = rs.getInt("propID");
|
||||
String[] HullStrings = rs.getString("vertices").split(";");
|
||||
int meshID = rs.getInt("meshID");
|
||||
String[] hullString = rs.getString("vertices").split(";");
|
||||
|
||||
// Filter things that couldn't be wrapped
|
||||
|
||||
if (HullStrings.length < 3) {
|
||||
Logger.error("Prop : " + propID + " has less than 3 vertices.");
|
||||
if (hullString.length < 3) {
|
||||
Logger.error("Mesh : " + meshID + " has less than 3 vertices.");
|
||||
continue;
|
||||
}
|
||||
|
||||
Path2D.Float prop_path = BuildingManager.hullToPath2d(HullStrings);
|
||||
ArrayList<Vector2f> convexHull = new ArrayList<>();
|
||||
ArrayList<Float> floats = new ArrayList<>();
|
||||
|
||||
ArrayList<Path2D.Float> meshList;
|
||||
for (String read : hullString) {
|
||||
|
||||
if (BuildingManager._hull_data.get(propID) == null) {
|
||||
meshList = new ArrayList<>();
|
||||
meshList.add(prop_path);
|
||||
BuildingManager._hull_data.put(propID, meshList);
|
||||
floats.add(Float.parseFloat(read));
|
||||
|
||||
if (floats.size() == 2) {
|
||||
convexHull.add(new Vector2f(floats.get(0), floats.get(1)));
|
||||
floats.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ArrayList<ArrayList<Vector2f>> hullList;
|
||||
|
||||
if (BuildingManager._hull_data.get(meshID) == null) {
|
||||
hullList = new ArrayList<>();
|
||||
hullList.add(convexHull);
|
||||
BuildingManager._hull_data.put(meshID, hullList);
|
||||
|
||||
} else {
|
||||
meshList = BuildingManager._hull_data.get(propID);
|
||||
meshList.add(prop_path);
|
||||
hullList = BuildingManager._hull_data.get(meshID);
|
||||
hullList.add(convexHull);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,14 @@ public class RegionCmd extends AbstractDevCmd {
|
||||
output += "NavMesh Data" + newline;
|
||||
this.throwbackInfo(pc, output);
|
||||
}
|
||||
//Zone zone = ZoneManager.findSmallestZone(((AbstractCharacter) target).loc);
|
||||
//if(zone != null) {
|
||||
// output += "zone: " + zone.zoneName + newline;
|
||||
// output += "on navmesh: " + zone.navMesh.contains(((AbstractCharacter) target).loc.x,((AbstractCharacter) target).loc.z) + newline;
|
||||
//}else {
|
||||
// output += "zone: null" + newline;
|
||||
//}
|
||||
|
||||
output += "pointBlocked: " + NavigationManager.pointIsBlocked(((AbstractCharacter)target).loc);
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import engine.objects.*;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
@@ -41,15 +40,13 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
public enum BuildingManager {
|
||||
|
||||
BUILDINGMANAGER;
|
||||
|
||||
public static HashMap<Integer, ArrayList<Path2D.Float>> _hull_data = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<ArrayList<Vector2f>>> _hull_data = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<BuildingLocation>> _stuckLocations = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<BuildingLocation>> _slotLocations = new HashMap<>();
|
||||
|
||||
public static HashMap<Integer, ConcurrentHashMap<Integer, BuildingFriends>> _buildingFriends = new HashMap<>();
|
||||
public static HashMap<Integer, ConcurrentHashMap<Integer, Condemned>> _buildingCondemned = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<Vector3fImmutable>> _buildingPatrolPoints = new HashMap<>();
|
||||
|
||||
public static int getAvailableSlot(Building building) {
|
||||
|
||||
ArrayList<BuildingLocation> slotLocations = _slotLocations.get(building.meshUUID);
|
||||
@@ -146,7 +143,10 @@ public enum BuildingManager {
|
||||
if (Guild.sameGuild(building.getGuild(), player.getGuild()) && GuildStatusController.isInnerCouncil(player.getGuildStatus()))
|
||||
return true;
|
||||
|
||||
return Guild.sameGuild(building.getGuild(), player.getGuild()) && GuildStatusController.isGuildLeader(player.getGuildStatus());
|
||||
if (Guild.sameGuild(building.getGuild(), player.getGuild()) && GuildStatusController.isGuildLeader(player.getGuildStatus()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
//TODO test friends list once added
|
||||
//does not meet above criteria. Cannot access.
|
||||
@@ -964,100 +964,62 @@ public enum BuildingManager {
|
||||
}
|
||||
|
||||
public static void bakeNavMesh(Building building) {
|
||||
|
||||
building.meshes = new ArrayList<>();
|
||||
if (building.parentZone == null) {
|
||||
//Logger.error("Attempt to bake navmesh with no parent: " + building.getObjectUUID());
|
||||
Logger.error("Attempt to bake navmesh with no parent: " + building.getObjectUUID());
|
||||
return;
|
||||
}
|
||||
|
||||
// Build up navmesh by stencil of the
|
||||
// convex hull meshes that comprise the prop.
|
||||
|
||||
ArrayList<Path2D.Float> convexHullList;
|
||||
ArrayList<ArrayList<Vector2f>> convexHullList;
|
||||
convexHullList = _hull_data.get(building.meshUUID);
|
||||
|
||||
if (convexHullList == null) {
|
||||
//Logger.error("Attempt to bake navmesh with no meshes: " + building.getObjectUUID());
|
||||
Logger.error("Attempt to bake navmesh with no meshes: " + building.getObjectUUID());
|
||||
return;
|
||||
}
|
||||
|
||||
for (ArrayList<Vector2f> meshEntry : convexHullList) {
|
||||
Path2D.Float meshBound = new Path2D.Float();
|
||||
Vector3fImmutable offsetVect = new Vector3fImmutable(meshEntry.get(0).x + building.loc.x, building.loc.y,meshEntry.get(0).y + building.loc.z);
|
||||
Vector3fImmutable rotatedStart = Vector3fImmutable.rotateAroundPoint(building.loc,offsetVect,building.getRot().y);
|
||||
meshBound.moveTo(rotatedStart.x,rotatedStart.z);
|
||||
for (Vector2f vect : meshEntry) {
|
||||
if(meshEntry.indexOf(vect) == 0){
|
||||
continue;
|
||||
}
|
||||
Vector3fImmutable pos = new Vector3fImmutable(vect.x + building.loc.x, building.loc.y,vect.y + building.loc.z);
|
||||
Vector3fImmutable rotatedPos = Vector3fImmutable.rotateAroundPoint(building.loc,pos,building.getRot().getRotation());
|
||||
meshBound.lineTo(rotatedPos.x,rotatedPos.z);
|
||||
}
|
||||
meshBound.lineTo(rotatedStart.x,rotatedStart.z);
|
||||
meshBound.closePath();
|
||||
building.meshes.add(meshBound);
|
||||
building.parentZone.navObstacles.add(meshBound);
|
||||
}
|
||||
//add navNodes to parent zone list
|
||||
float X = building.getBounds().getHalfExtents().x;
|
||||
float Y = building.getBounds().getHalfExtents().y;
|
||||
ArrayList<Vector2f> cornersAndFaces = new ArrayList<>();
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x - X, building.loc.z - Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x + X, building.loc.z + Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x + X, building.loc.z - Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x - X, building.loc.z + Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x - X, building.loc.z));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x + X, building.loc.z));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x, building.loc.z - Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x, building.loc.z + Y));
|
||||
for (Vector2f point : cornersAndFaces) {
|
||||
if (!NavigationManager.pointIsBlocked(new Vector3fImmutable(point.x, building.loc.y, point.y))) {
|
||||
building.parentZone.navNodes.add(new PathingUtilities.Node(point, null, building));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x - X,building.loc.z - Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x + X,building.loc.z + Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x + X,building.loc.z - Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x - X,building.loc.z + Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x - X,building.loc.z));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x + X,building.loc.z));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x,building.loc.z - Y));
|
||||
cornersAndFaces.add(new Vector2f(building.loc.x,building.loc.z + Y));
|
||||
for(Vector2f point : cornersAndFaces){
|
||||
if(!NavigationManager.pointIsBlocked(new Vector3fImmutable(point.x,building.loc.y,point.y))){
|
||||
building.parentZone.navNodes.add(new PathingUtilities.Node(point,null,building));
|
||||
}
|
||||
}
|
||||
|
||||
//add region centers to the zones navNodes list
|
||||
for (Regions region : building.getBounds().getRegions()) {
|
||||
building.parentZone.navNodes.add(new PathingUtilities.Node(new Vector2f(region.center.x, region.center.z), region, building));
|
||||
}
|
||||
}
|
||||
|
||||
public static Path2D.Float hullToPath2d(String[] hullString) {
|
||||
|
||||
// Method builds convex hull from database vertices
|
||||
|
||||
ArrayList<Vector2f> vertices = new ArrayList<>();
|
||||
ArrayList<Float> floats = new ArrayList<>();
|
||||
Path2D.Float outPath = new Path2D.Float();
|
||||
|
||||
// Build Arraylist of vertices
|
||||
|
||||
for (String floatString : hullString) {
|
||||
|
||||
floats.add(Float.parseFloat(floatString));
|
||||
|
||||
if (floats.size() == 2) {
|
||||
vertices.add(new Vector2f(floats.get(0), floats.get(1)));
|
||||
floats.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Build Path from vertices
|
||||
|
||||
for (Vector2f vertex : vertices)
|
||||
if (outPath.getCurrentPoint() == null)
|
||||
outPath.moveTo(vertex.x, vertex.y);
|
||||
else
|
||||
outPath.lineTo(vertex.x, vertex.y);
|
||||
|
||||
outPath.closePath();
|
||||
return outPath;
|
||||
}
|
||||
|
||||
public static void loadColliders(Building building) {
|
||||
|
||||
// Load colliders for this building
|
||||
|
||||
building.meshes = new ArrayList<>();
|
||||
|
||||
if (_hull_data.get(building.meshUUID) == null ||
|
||||
_hull_data.get(building.meshUUID).size() < 1)
|
||||
return;
|
||||
|
||||
for (Path2D.Float path : _hull_data.get(building.meshUUID)) {
|
||||
|
||||
Path2D.Float translatedPath = new Path2D.Float(path);
|
||||
AffineTransform offset = AffineTransform.getTranslateInstance(building.loc.x, building.loc.y);
|
||||
|
||||
translatedPath.transform(offset);
|
||||
|
||||
AffineTransform rotate = AffineTransform.getRotateInstance(Math.toRadians(building.getBounds().getQuaternion().angleY), building.loc.x, building.loc.z);
|
||||
translatedPath.transform(rotate);
|
||||
|
||||
building.meshes.add(translatedPath);
|
||||
for(Regions region : building.getBounds().getRegions()){
|
||||
building.parentZone.navNodes.add(new PathingUtilities.Node(new Vector2f(region.center.x,region.center.z),region,building));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,15 +111,27 @@ public class NavigationManager {
|
||||
return false;
|
||||
}
|
||||
public static boolean pointIsBlocked(Vector3fImmutable point) {
|
||||
|
||||
Building building = BuildingManager.getBuildingAtLocation(point);
|
||||
if(building != null) {
|
||||
for (Path2D.Float mesh : building.meshes) {
|
||||
if (mesh.contains(point.x,point.z)) {
|
||||
return true;
|
||||
}
|
||||
Zone zone = ZoneManager.findSmallestZone(point);
|
||||
if(zone != null){
|
||||
for(Path2D.Float obstacle : zone.navObstacles)
|
||||
if (obstacle.contains(point.x,point.z)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Building building = BuildingManager.getBuildingAtLocation(point);
|
||||
//if(building != null) {
|
||||
//for (Path2D.Float mesh : building.meshes) {
|
||||
//if (mesh.contains(point.x,point.z)) {
|
||||
//return true;
|
||||
//}
|
||||
//}
|
||||
//for (Regions region : building.getBounds().getRegions()) {
|
||||
//if (region.isPointInPolygon(point))
|
||||
//if (Math.abs(region.lerpY(point) - point.y) > stepHeight) // get the height distance between current height and target location height
|
||||
//return true;
|
||||
//}
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ public class MobAI {
|
||||
aiMove(mob, true,0);
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: Patrol" + " " + e.getMessage());
|
||||
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1349,11 +1349,11 @@ public class MobAI {
|
||||
if(mob.isMoving()) {
|
||||
return;
|
||||
}
|
||||
//if(!mob.isPathing){
|
||||
// ArrayList<PathingUtilities.Node> path = PathingUtilities.getPath(mob, mob.destination);
|
||||
// if(path != null && path.size() > 0)
|
||||
// PathingUtilities.followPath(mob,path);
|
||||
//}
|
||||
if(!mob.isPathing){
|
||||
ArrayList<PathingUtilities.Node> path = PathingUtilities.getPath(mob, mob.destination);
|
||||
if(path != null && path.size() > 0)
|
||||
PathingUtilities.followPath(mob,path);
|
||||
}
|
||||
}
|
||||
|
||||
public static void directMove(AbstractCharacter mob,boolean isWalking){
|
||||
|
||||
@@ -34,7 +34,6 @@ import engine.net.client.msg.UpdateObjectMsg;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
@@ -914,7 +913,7 @@ public class Building extends AbstractWorldObject {
|
||||
|
||||
// Note: We handle R8 tree edge case for mesh and health
|
||||
// after city is loaded to avoid recursive result set call
|
||||
// in City resulting in a stack ovreflow.
|
||||
// in City resulting in a stack overflow.
|
||||
|
||||
if (blueprint != null) {
|
||||
|
||||
@@ -1008,7 +1007,6 @@ public class Building extends AbstractWorldObject {
|
||||
if (this.upgradeDateTime != null)
|
||||
BuildingManager.submitUpgradeJob(this);
|
||||
|
||||
BuildingManager.loadColliders(this); // load building colliders
|
||||
BuildingManager.bakeNavMesh(this); // update the navmesh of the parent zone
|
||||
}
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@ public class WorldServer {
|
||||
BuildingLocation.loadBuildingLocations();
|
||||
|
||||
Logger.info("Loading mesh hulls.");
|
||||
DbManager.BuildingQueries.LOAD_MESH_HULLS();
|
||||
DbManager.BuildingQueries.LOAD_CONVEX_HULLS();
|
||||
|
||||
// Starting before loading of structures/guilds/characters
|
||||
// so the database connections are available to write
|
||||
|
||||
Reference in New Issue
Block a user