In a program I am currently developing, I have ran into an issue in my code. I doubt the error is in the AI plugin but instead in my implementation, but I am having trouble figuring out what I have done incorrectly. To explain the whole ordeal I am trying to do is this:
- I have many classes added to the world which are cover points for my enemy AI. These have a location, and 2 boolean values. Is line of sight? and is Cover?
- Each class draws a ray to me at body level and if it hits me first, isLOS is true. Then it makes a ray at ankle level, and if there is an obstruction within, say, 2 units, then cover is true.
- In my enemy class, I sort through the coverpoints; the ideal cover point has both booleans true, and is the closest out of all other points
- Then I use the location of that cover point as the destination and my location as the start in computing a path.
- I constantly run this method to update the enemy where he needs to go, so the path changes all the time.
I am not sure the best way to structure the movement if I change paths all the time for different senarios. This code has my first attempted approach but does work as expected and I am yet to find the problem.
[java] public void Update(float tpf) {
if (coverPoint.size() > 0) {
playerLoc = coverPoint.get(0).getPlayerLoc();
}
if (move) {
moveToDestination(tpf);
}
if (playerLoc != null){
ScanForEnemy();
}
findNextPoint();
//System.out.println(" move? " + move);
}
/* if enemy can see player, find the closest coverpoint with a Line of Sight
* if enemy can see player and no CP has Line of sight, shoot and move to closest wanderpoint
* if enemy can't see player, pick wanderpoint with highest score
*
*
*
*/
ArrayList<CoverPoint> LOSpoints = new ArrayList<CoverPoint>();
ArrayList<CoverPoint> LOSCoverpoints = new ArrayList<CoverPoint>();
public void findNextPoint() {
LOSCoverpoints.clear();
LOSpoints.clear();
if (canSeeEnemy) { //if an enemy is in view
if (playerLoc != null) {
lookAt(new Vector3f(playerLoc.x, 0, playerLoc.z), Vector3f.UNIT_Y);
}
//navi.clearPath();
//Shoot();
STATE = "Covering";
for (CoverPoint c : coverPoint) { //adds cover points vith LOS to new Array
if (c.isLOS()) {
LOSpoints.add(c);
}
}
for (CoverPoint d : LOSpoints) { //adds coverpoints with LOS and cover form enemy in Array
if (d.isCover()) {
LOSCoverpoints.add(d);
}
}
if (LOSCoverpoints.size() > 0) { //if their are multiple CP options
// System.out.println(" numOfLOSpoints " + LOSCoverpoints.size());
CoverPoint closest = null;
float closestdistance = 9999;
float distance = 0;
for (CoverPoint d : LOSCoverpoints) { //finds the distance to each coverpoint
distance = getWorldTranslation().distance(d.getWorldTranslation());
if (distance < closestdistance) {
closestdistance = distance;
closest = d;
}
}
//move to CP with closest distance here and TODO: highest score
navi.setPosition(this.getWorldTranslation());
navi.computePath(closest.getWorldTranslation());
System.out.println(" target " + navi.getPath().getLast());
// move = true;
}
if (LOSpoints.isEmpty()) { //if their are no ideal coverpoints with LOS
CoverPoint closest = null;
float closestdistance = 9999;
for (CoverPoint w : coverPoint) { //find closest CoverPoint here... (FOR NOW)
float distance = getWorldTranslation().distance(w.getWorldTranslation());
if (distance < closestdistance) {
closestdistance = distance;
closest = w;
}
}
//move to closets CP
if (closest != null) {
//navi.setPosition(getWorldTranslation());
//navi.computePath(closest.getWorldTranslation());
System.out.println(" moving to closest CP ");
move = true;
}
}
} else {
moveToWanderPoints();
}
}
int oldWanderPoint = 0;
private void moveToWanderPoints() { //if enemy cant see player
// System.out.println("next waypoint " + navi.getNextWaypoint());
if (navi.getNextWaypoint() == null) {
Random ran = new Random();
int x = ran.nextInt(3);
if (oldWanderPoint != x) {
oldWanderPoint = x;
navi.setPosition(getWorldTranslation());
navi.computePath(WanderPoint.get(x).getWorldTranslation());
move = true;
}
if (oldWanderPoint == x) {
while (x == oldWanderPoint) {
x = ran.nextInt(3);
}
navi.setPosition(getWorldTranslation());
navi.computePath(WanderPoint.get(x).getWorldTranslation());
move = true;
}
}
}
private void moveToDestination(float tpf) {
Path.Waypoint wayPoint = navi.getNextWaypoint();
if (wayPoint == null) {
return;
}
Vector3f vector = wayPoint.getPosition().subtract(getWorldTranslation());
Vector3f loc = wayPoint.getPosition();
if (vector.length() > 1) {
move(vector.normalizeLocal().multLocal(tpf * movementSpeed));
if (!canSeeEnemy) {
lookAt(new Vector3f(loc.x, loc.y, loc.z), Vector3f.UNIT_Y);
}
//return;
} else if (!navi.isAtGoalWaypoint()) {
//if we are at the waypoint already, go to the next one
navi.goToNextWaypoint();
}
System.out.println(" loc" + getWorldTranslation() + " nextWayPOint " + loc);
if (navi.isAtGoalWaypoint() && !canSeeEnemy) {
move = false;
navi.clearPath();
moveToWanderPoints();
}
if (canSeeEnemy) {
//move = false;
//navi.clearPath();
//findNextPoint();
}
}[/java]
the method findwanderpoint() works perfectly, but I only run that if the enemy cant see any opponents. And in my testing, I have canSeeEnemy as true so I see how it reacts as if it is always seeing me. Any suggestions about what I am doing wrong are appreciated.