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.TaskAttack;
import Roguelike.Tiles.GameTile;
import Roguelike.Tiles.Point;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.XmlReader.Element;
public class ActionAttack extends AbstractAction
{
public String key;
@Override
public BehaviourTreeState evaluate( GameEntity entity )
{
if ( entity.weaponSheathed )
{
State = BehaviourTreeState.FAILED;
return State;
}
Point target = (Point) getData( key, null );
// if no target, fail
if ( target == null )
{
State = BehaviourTreeState.FAILED;
return State;
}
// Find out preferred attack direction
int cx = 0;
int cy = 0;
int dst = Integer.MAX_VALUE;
for ( int x = 0; x < entity.size; x++ )
{
for ( int y = 0; y < entity.size; y++ )
{
int tmpdst = Math.abs( target.x - ( entity.tile[0][0].x + x ) ) + Math.abs( target.y - ( entity.tile[0][0].y + y ) );
if ( tmpdst < dst )
{
dst = tmpdst;
cx = entity.tile[0][0].x + x;
cy = entity.tile[0][0].y + y;
}
}
}
GameTile targetTile = entity.tile[0][0].level.getGameTile( target );
Direction preferredDir = Direction.getCardinalDirection( target.x - cx, target.y - cy );
Direction bestDir = preferredDir;
int bestCount = 0;
// Check for best direction
for ( Direction dir : Direction.values() )
{
if ( dir != Direction.CENTER && (Global.CanMoveDiagonal || dir.isCardinal()) )
{
Array<GameTile> hitTiles = TaskAttack.buildHitTileArray( entity, dir );
int targetCount = 0;
boolean valid = false;
for (GameTile tile : hitTiles)
{
if (tile == targetTile)
{
valid = true;
}
if (tile.entity != null && !tile.entity.isAllies( entity ))
{
targetCount++;
}
}
if (valid)
{
if (dir == preferredDir)
{
bestDir = preferredDir;
break;
}
if (targetCount > bestCount)
{
bestDir = dir;
bestCount = targetCount;
}
}
}
}
if (bestDir != Direction.CENTER)
{
TaskAttack task = new TaskAttack( bestDir );
if ( targetTile != null
&& targetTile.environmentEntity != null
&& targetTile.environmentEntity.canTakeDamage
&& task.canAttackTile( entity, targetTile ) )
{
entity.tasks.add( task );
State = BehaviourTreeState.SUCCEEDED;
return State;
}
else if ( task.checkHitSomething( entity ) )
{
entity.tasks.add( task );
State = BehaviourTreeState.SUCCEEDED;
return State;
}
}
State = BehaviourTreeState.FAILED;
return State;
}
@Override
public void cancel()
{
}
@Override
public void parse( Element xmlElement )
{
key = xmlElement.getAttribute( "Key" );
}
}