package Roguelike.Entity.AI.BehaviourTree.Actions; import Roguelike.Global; import Roguelike.Global.Direction; import Roguelike.Entity.GameEntity; import Roguelike.Entity.AI.BehaviourTree.BehaviourTree.BehaviourTreeState; import Roguelike.Entity.Tasks.TaskMove; import Roguelike.Pathfinding.Pathfinder; import Roguelike.Tiles.GameTile; import Roguelike.Tiles.Point; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.XmlReader.Element; public class ActionMoveTo extends AbstractAction { public int dst; public boolean towards; public String key; @Override public BehaviourTreeState evaluate( GameEntity entity ) { Point target = (Point) getData( key, null ); // if no target, fail if ( target == null ) { State = BehaviourTreeState.FAILED; return State; } // if we arrived at our target, succeed if ( entity.tile[0][0].x == target.x && entity.tile[0][0].y == target.y ) { State = BehaviourTreeState.SUCCEEDED; return State; } Pathfinder pathFinder = new Pathfinder( entity.tile[0][0].level.getGrid(), entity.tile[0][0].x, entity.tile[0][0].y, target.x, target.y, Global.CanMoveDiagonal, entity.size, entity ); Array<Point> path = pathFinder.getPath( entity.getTravelType() ); // if couldnt find a valid path, fail if ( path.size < 2 ) { Global.PointPool.freeAll( path ); State = BehaviourTreeState.FAILED; return State; } GameTile nextTile = entity.tile[0][0].level.getGameTile( path.get( 1 ) ); // if next step is impassable then fail if ( !nextTile.getPassable( entity.getTravelType(), entity ) ) { Global.PointPool.freeAll( path ); State = BehaviourTreeState.FAILED; return State; } int[] offset = new int[] { path.get( 1 ).x - path.get( 0 ).x, path.get( 1 ).y - path.get( 0 ).y }; // if moving towards path to the object if ( towards ) { if ( path.size - 1 <= dst || ( offset[0] == 0 && offset[1] == 0 ) ) { Global.PointPool.freeAll( path ); State = BehaviourTreeState.SUCCEEDED; return State; } entity.tasks.add( new TaskMove( Direction.getDirection( offset ) ) ); } // if moving away then just run directly away else { if ( path.size - 1 >= dst || ( offset[0] == 0 && offset[1] == 0 ) ) { Global.PointPool.freeAll( path ); State = BehaviourTreeState.SUCCEEDED; return State; } entity.tasks.add( new TaskMove( Direction.getDirection( offset[0] * -1, offset[1] * -1 ) ) ); } Global.PointPool.freeAll( path ); State = BehaviourTreeState.RUNNING; return State; } @Override public void cancel() { } @Override public void parse( Element xmlElement ) { dst = Integer.parseInt( xmlElement.getAttribute( "Distance", "0" ) ); towards = Boolean.parseBoolean( xmlElement.getAttribute( "Towards", "true" ) ); key = xmlElement.getAttribute( "Key" ); } }