|
|
|
@ -1,7 +1,14 @@
@@ -1,7 +1,14 @@
|
|
|
|
|
package engine.mobileAI.utilities; |
|
|
|
|
import engine.Enum; |
|
|
|
|
import engine.exception.MsgSendException; |
|
|
|
|
import engine.gameManager.BuildingManager; |
|
|
|
|
import engine.gameManager.MovementManager; |
|
|
|
|
import engine.gameManager.ZoneManager; |
|
|
|
|
import engine.math.Vector2f; |
|
|
|
|
import engine.math.Vector3fImmutable; |
|
|
|
|
import engine.mobileAI.MobAI; |
|
|
|
|
import engine.net.client.msg.MoveToPointMsg; |
|
|
|
|
import engine.objects.AbstractCharacter; |
|
|
|
|
import engine.objects.Building; |
|
|
|
|
import engine.objects.Regions; |
|
|
|
|
import engine.objects.Zone; |
|
|
|
@ -41,4 +48,104 @@ public class PathingUtilities {
@@ -41,4 +48,104 @@ public class PathingUtilities {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static Node getClosestNode(Vector3fImmutable loc){ |
|
|
|
|
Zone zone = ZoneManager.findSmallestZone(loc); |
|
|
|
|
Regions region = Regions.getRegionAtLocation(loc); |
|
|
|
|
if(region != null){ |
|
|
|
|
for(Node node : zone.navNodes){ |
|
|
|
|
if(node.location == new Vector2f(region.center.x,region.center.z)) |
|
|
|
|
return node; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
float disSq = 10000000; |
|
|
|
|
Node closest = null; |
|
|
|
|
for(Node node : zone.navNodes){ |
|
|
|
|
if(node.location.distanceSquared(new Vector2f(loc.x,loc.z)) < disSq) |
|
|
|
|
closest = node; |
|
|
|
|
} |
|
|
|
|
return closest; |
|
|
|
|
} |
|
|
|
|
public static ArrayList<Node> getPath(Vector3fImmutable start, Vector3fImmutable goal){ |
|
|
|
|
ArrayList<Node> path = new ArrayList<>(); |
|
|
|
|
Node startNode = getClosestNode(start); |
|
|
|
|
Node goalNode = getClosestNode(goal); |
|
|
|
|
Node currentNode = startNode; |
|
|
|
|
path.add(startNode); |
|
|
|
|
int attempts = 0; |
|
|
|
|
while(!currentNode.equals(goalNode) && attempts < 250){ |
|
|
|
|
attempts ++; |
|
|
|
|
currentNode = getCheapestNeighbor(currentNode,new Vector2f(goal.x,goal.z)); |
|
|
|
|
path.add(currentNode); |
|
|
|
|
} |
|
|
|
|
return path; |
|
|
|
|
} |
|
|
|
|
public static Node getCheapestNeighbor(Node node, Vector2f goal){ |
|
|
|
|
Node cheapest = null; |
|
|
|
|
for(Node neighbor : node.getNeighbors()){ |
|
|
|
|
if(cheapest == null) { |
|
|
|
|
cheapest = neighbor; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
if(getCost(cheapest.location,node.location,goal) > getCost(neighbor.location,node.location,goal)){ |
|
|
|
|
cheapest = neighbor; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return cheapest; |
|
|
|
|
} |
|
|
|
|
public static float getCost(Vector2f point, Vector2f start, Vector2f goal) { |
|
|
|
|
float gCost = start.distanceSquared(point); |
|
|
|
|
float hCost = goal.distanceSquared(point); |
|
|
|
|
return gCost + hCost; |
|
|
|
|
} |
|
|
|
|
public static void followPath(AbstractCharacter character, ArrayList<Node> path){ |
|
|
|
|
character.isPathing = true; |
|
|
|
|
while(new Vector2f(character.loc.x,character.loc.z).distanceSquared(path.get(path.size() - 1).location) > 9 && path.size() > 0){ |
|
|
|
|
if( character.isMoving()) |
|
|
|
|
continue; |
|
|
|
|
if(character.combatTarget != null){ |
|
|
|
|
//need ot adjust new path for a moving combat target
|
|
|
|
|
if(character.combatTarget.loc.distanceSquared2D(new Vector3fImmutable(path.get(path.size() - 1).location.x,0,path.get(path.size() - 1).location.y)) > 625){ |
|
|
|
|
character.isPathing = false; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
move(character,new Vector3fImmutable(path.get(0).location.x,0,path.get(0).location.y)); |
|
|
|
|
path.remove(0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
public static void move(AbstractCharacter mob, Vector3fImmutable goal) { |
|
|
|
|
mob.destination = goal; |
|
|
|
|
if (mob.getObjectType().equals(Enum.GameObjectType.Mob)) { |
|
|
|
|
mob.setWalkMode(!(mob.combatTarget == null)); |
|
|
|
|
MovementManager.sendRWSSMsg(mob); |
|
|
|
|
} |
|
|
|
|
mob.endLoc = goal; |
|
|
|
|
|
|
|
|
|
MoveToPointMsg msg = new MoveToPointMsg(); |
|
|
|
|
|
|
|
|
|
msg.setSourceType(Enum.GameObjectType.Mob.ordinal()); |
|
|
|
|
msg.setSourceID(mob.getObjectUUID()); |
|
|
|
|
msg.setStartCoord(mob.loc); |
|
|
|
|
msg.setEndCoord(goal); |
|
|
|
|
Regions region = Regions.getRegionAtLocation(goal); |
|
|
|
|
if (region != null) { |
|
|
|
|
msg.setInBuildingFloor(region.room); |
|
|
|
|
msg.setInBuilding(region.level); |
|
|
|
|
msg.setStartLocType(0); |
|
|
|
|
msg.setInBuildingUUID(region.parentBuildingID); |
|
|
|
|
} else { |
|
|
|
|
msg.setInBuildingFloor(-1); |
|
|
|
|
msg.setInBuilding(-1); |
|
|
|
|
msg.setStartLocType(0); |
|
|
|
|
msg.setInBuildingUUID(0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
MovementManager.movement(msg, mob); |
|
|
|
|
} catch (MsgSendException e) { |
|
|
|
|
// TODO Figure out how we want to handle the msg send exception
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|