Browse Source

system enabled

hull4
FatBoy-DOTC 1 year ago
parent
commit
136c8c4756
  1. 14
      src/engine/mobileAI/MobAI.java
  2. 132
      src/engine/mobileAI/utilities/MovementUtilities.java
  3. 13
      src/engine/objects/AbstractCharacter.java
  4. 3
      src/engine/objects/Mob.java
  5. 32
      src/engine/objects/Regions.java
  6. 2
      src/engine/powers/poweractions/TeleportPowerAction.java

14
src/engine/mobileAI/MobAI.java

@ -287,10 +287,10 @@ public class MobAI {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) { if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
Mob captain = (Mob) mob.guardCaptain; Mob captain = (Mob) mob.guardCaptain;
mob.destination = captain.destination.add(Formation.getOffset(2, mob.guardCaptain.minions.indexOf(mob.getObjectUUID()) + 3)); mob.setDestination(captain.destination.add(Formation.getOffset(2, mob.guardCaptain.minions.indexOf(mob.getObjectUUID()) + 3)));
mob.lastPatrolPointIndex = captain.lastPatrolPointIndex; mob.lastPatrolPointIndex = captain.lastPatrolPointIndex;
} else { } else {
mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex); mob.setDestination(mob.patrolPoints.get(mob.lastPatrolPointIndex));
mob.lastPatrolPointIndex += 1; mob.lastPatrolPointIndex += 1;
} }
@ -748,7 +748,7 @@ public class MobAI {
if (CombatUtilities.inRange2D(mob, mob.guardCaptain, 6)) if (CombatUtilities.inRange2D(mob, mob.guardCaptain, 6))
return; return;
mob.destination = mob.guardCaptain.getLoc(); mob.setDestination(mob.guardCaptain.getLoc());
MovementUtilities.moveToLocation(mob, mob.destination, 5, false); MovementUtilities.moveToLocation(mob, mob.destination, 5, false);
} else } else
chaseTarget(mob); chaseTarget(mob);
@ -904,7 +904,7 @@ public class MobAI {
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
if (mob.getRange() > 15) { if (mob.getRange() > 15) {
mob.destination = mob.getCombatTarget().getLoc(); mob.setDestination(mob.getCombatTarget().getLoc());
MovementUtilities.moveToLocation(mob, mob.destination, 0, false); MovementUtilities.moveToLocation(mob, mob.destination, 0, false);
} else { } else {
@ -913,11 +913,11 @@ public class MobAI {
switch (mob.getCombatTarget().getObjectType()) { switch (mob.getCombatTarget().getObjectType()) {
case PlayerCharacter: case PlayerCharacter:
case Mob: case Mob:
mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()); mob.setDestination(MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()));
MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange() + 1, false); MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange() + 1, false);
break; break;
case Building: case Building:
mob.destination = mob.getCombatTarget().getLoc(); mob.setDestination(mob.getCombatTarget().getLoc());
MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0, false); MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0, false);
break; break;
} }
@ -1240,7 +1240,7 @@ public class MobAI {
float xPoint = ThreadLocalRandom.current().nextInt(400) - 200; float xPoint = ThreadLocalRandom.current().nextInt(400) - 200;
float zPoint = ThreadLocalRandom.current().nextInt(400) - 200; float zPoint = ThreadLocalRandom.current().nextInt(400) - 200;
Vector3fImmutable TreePos = mob.getGuild().getOwnedCity().getLoc(); Vector3fImmutable TreePos = mob.getGuild().getOwnedCity().getLoc();
mob.destination = new Vector3fImmutable(TreePos.x + xPoint, TreePos.y, TreePos.z + zPoint); mob.setDestination(new Vector3fImmutable(TreePos.x + xPoint, TreePos.y, TreePos.z + zPoint));
MovementUtilities.aiMove(mob, mob.destination, true); MovementUtilities.aiMove(mob, mob.destination, true);

132
src/engine/mobileAI/utilities/MovementUtilities.java

@ -13,21 +13,27 @@ import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.ModType; import engine.Enum.ModType;
import engine.Enum.SourceType; import engine.Enum.SourceType;
import engine.InterestManagement.WorldGrid;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.ChatManager;
import engine.gameManager.MovementManager; import engine.gameManager.MovementManager;
import engine.math.Bounds;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.Threads.MobAIThread; import engine.mobileAI.Threads.MobAIThread;
import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.MoveToPointMsg;
import engine.objects.*; import engine.objects.*;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import static engine.math.FastMath.sqr; import static engine.math.FastMath.sqr;
import static engine.math.FastMath.sqrt; import static engine.math.FastMath.sqrt;
public class MovementUtilities { public class MovementUtilities {
private static final int cellGap = 4;
public static boolean inRangeOfBindLocation(Mob agent) { public static boolean inRangeOfBindLocation(Mob agent) {
@ -291,5 +297,129 @@ public class MovementUtilities {
return false; return false;
} }
public static void pathfind(AbstractCharacter character, Vector3fImmutable goal){
try {
ArrayList<Vector3fImmutable> path = getOptimizedPath(getPath(character.loc, goal), getPath(goal, character.loc));
if (path.isEmpty()) {
((Mob) character).setDestination(character.loc);
return; //no points to walk to
}
((Mob) character).destination = path.get(0);
} catch(Exception e){
//something failed
}
}
public static ArrayList<Vector3fImmutable> getOptimizedPath(ArrayList<Vector3fImmutable> startToGoal, ArrayList<Vector3fImmutable> goalToStart) {
ArrayList<Vector3fImmutable> optimalPath = new ArrayList<>();
optimalPath.add(startToGoal.get(0));
for(Vector3fImmutable point : startToGoal)
{
if(!goalToStart.contains(point))
{
continue;
}
optimalPath.add(point);
}
return optimalPath;
}
private static ArrayList<Vector3fImmutable> getPath(Vector3fImmutable start, Vector3fImmutable goal) {
ArrayList<Vector3fImmutable> path = new ArrayList<>();
path.add(start);
Vector3fImmutable current = start;
boolean obstructed = false;
while (current.distanceSquared(goal) > 9)
{
//gather the 8 cells around the player
ArrayList<Vector3fImmutable> surroundingCells = new ArrayList<>();
surroundingCells.add(current.add(new Vector3fImmutable(cellGap, 0, 0)));
surroundingCells.add(current.add(new Vector3fImmutable(cellGap, 0, cellGap)));
surroundingCells.add(current.add(new Vector3fImmutable(0, 0, cellGap)));
surroundingCells.add(current.add(new Vector3fImmutable(-cellGap, 0, 0)));
surroundingCells.add(current.add(new Vector3fImmutable(-cellGap, 0, -cellGap)));
surroundingCells.add(current.add(new Vector3fImmutable(0, 0, -cellGap)));
surroundingCells.add(current.add(new Vector3fImmutable(-cellGap, 0, cellGap)));
surroundingCells.add(current.add(new Vector3fImmutable(cellGap, 0, -cellGap)));
Vector3fImmutable cheapest = new Vector3fImmutable(-10000, 0, -10000);
for (Vector3fImmutable point : surroundingCells)
{
if (path.contains(point))
continue;
Regions region = Regions.getRegionAtLocation(point);
if(region != null) {
//if (!region.stairs)
// point.setY(region.center.y);
//else
// point.setY(region.lerpY(point));
path.add(new Vector3fImmutable(region.center.x,region.center.y,region.center.z)); //only use center points when travelling through regions
continue;
}
if (pointIsBlocked(point)) {
obstructed = true;
continue;
}
if (getCost(cheapest, current, goal) > getCost(point, current, goal))
cheapest = point;
}
current = cheapest;
path.add(cheapest);
}
if(obstructed) {
return path;
}else {
ArrayList<Vector3fImmutable> goalPath = new ArrayList<>();
goalPath.add(goal);
goalPath.add(start);
return goalPath; //if the path isn't obstructed we can walk directly from start to the goal
}
}
public static float getCost(Vector3fImmutable point, Vector3fImmutable start, Vector3fImmutable goal) {
float gCost = start.distanceSquared(point);
float hCost = goal.distanceSquared(point);
return gCost + hCost;
}
public static boolean pointIsBlocked(Vector3fImmutable point) {
//TODO figure out best way to decide if a walking point intersects a mesh collider from a building
Building building = BuildingManager.getBuildingAtLocation(point);
if(building == null) {
printToPlayers(point, "No Building Found At: " + point);
return false;//no building at this location means nothing obstructing the walking path
}
if(!collidesWithBuilding(building,point)) {
printToPlayers(point, "No Building Collision At: " + point);
return false;
}
if(Regions.getRegionAtLocation(point) != null) {
printToPlayers(point, "Region Found At: " + point);
return false;
}
printToPlayers(point, "Path Blocked At: " + point);
return true;
}
private static boolean collidesWithBuilding(Building building, Vector3fImmutable end){
MeshBounds mb = Bounds.meshBoundsCache.get(building.meshUUID);
return (end.x > mb.minX && end.x < mb.maxX && end.z > mb.minZ && end.z < mb.maxZ);
}
private static void printToPlayers(Vector3fImmutable loc, String message){
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER)){
PlayerCharacter pc = (PlayerCharacter)awo;
ChatManager.chatSystemInfo(pc, message);
}
}
} }

13
src/engine/objects/AbstractCharacter.java

@ -987,18 +987,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
@Override @Override
public final void setLoc(final Vector3fImmutable value) { public final void setLoc(final Vector3fImmutable value) {
Building building = BuildingManager.getBuildingAtLocation(this.loc); Regions region = Regions.getRegionAtLocation(value);
Regions region = null;
if(building != null) {
//look for region in the building we are in
for (Regions regionCycle : building.getBounds().getRegions()) {
float regionHeight = regionCycle.highLerp.y - regionCycle.lowLerp.y;
if(regionHeight < 10)
regionHeight = 10;
if (regionCycle.isPointInPolygon(value) && Math.abs(regionCycle.highLerp.y - value.y) < regionHeight)
region = regionCycle;
}
}
float regionHeightOffset = 0; float regionHeightOffset = 0;
if(region != null){ if(region != null){
this.region = region; this.region = region;

3
src/engine/objects/Mob.java

@ -20,6 +20,7 @@ import engine.jobs.DeferredPowerJob;
import engine.jobs.UpgradeNPCJob; import engine.jobs.UpgradeNPCJob;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.utilities.MovementUtilities;
import engine.net.ByteBufferWriter; import engine.net.ByteBufferWriter;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
@ -1899,4 +1900,6 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed {
public int compareTo(@NotNull Delayed o) { public int compareTo(@NotNull Delayed o) {
return toIntExact(this.respawnTime - ((Mob) o).respawnTime); return toIntExact(this.respawnTime - ((Mob) o).respawnTime);
} }
public void setDestination(Vector3fImmutable destination) {MovementUtilities.pathfind(this,destination);}
} }

32
src/engine/objects/Regions.java

@ -270,32 +270,18 @@ public class Regions {
return BuildingManager.getBuildingFromCache(region.parentBuildingID); return BuildingManager.getBuildingFromCache(region.parentBuildingID);
} }
public static Regions GetRegionForTeleport(Vector3fImmutable location) { public static Regions getRegionAtLocation(Vector3fImmutable location) {
Regions region = null; Regions region = null;
Building building = BuildingManager.getBuildingAtLocation(location);
//Find building
for (AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(location, 128, MBServerStatics.MASK_BUILDING)) {
Building building = (Building) awo;
if (!Bounds.collide(location, building.getBounds()))
continue;
if(building != null) { if(building != null) {
region = BuildingManager.GetRegion(building, location.x, location.y, location.z); //look for region in the building we are in
for (Regions regionCycle : building.getBounds().getRegions()) {
float regionHeight = regionCycle.highLerp.y - regionCycle.lowLerp.y;
if(regionHeight < 10)
regionHeight = 10;
if (regionCycle.isPointInPolygon(location) && Math.abs(regionCycle.highLerp.y - location.y) < regionHeight)
region = regionCycle;
} }
//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;
} }

2
src/engine/powers/poweractions/TeleportPowerAction.java

@ -96,7 +96,7 @@ public class TeleportPowerAction extends AbstractPowerAction {
//TODO verify target loc is valid loc //TODO verify target loc is valid loc
Regions region = Regions.GetRegionForTeleport(targetLoc); Regions region = Regions.getRegionAtLocation(targetLoc);
if (region != null && !region.isOutside()) if (region != null && !region.isOutside())
return; return;

Loading…
Cancel
Save