/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package transientlibs.objects.creatures.ai;
import transientlibs.processors.misc.Detonator;
import transientlibs.maps.units.Unit;
import transientlibs.objects.primitives.Coords;
import transientlibs.objects.general.ModeList;
import transientlibs.objects.general.ModeSelector;
/**
*
* @author kibertoad
*/
public abstract class BasicAIBrain extends AbstractAIBrain {
public ModeList activityTypes;
public ModeSelector activityType;
/**Tile that is selected for next movement step. */
public Coords nextTile = new Coords();
public boolean hasTargetTile = false;
/** How many times AI will attempt to step in random direction before failing. */
public int failCounter = 0;
public BasicAIBrain(Unit setHost, ModeList setModeList) {
super(setHost);
activityTypes = setModeList;
activityType = new ModeSelector(activityTypes);
}
public void resetTarget (){
host.resetTarget();
}
public Unit getTarget (){
return host.target;
}
/** Code that will be executed on aggressive bump. */
public void performAttackRoutine(){
}
public Unit getPlayer () {
return (Unit) host.onMap.getPlayer();
}
public boolean getIsAggressive (){
return false;
}
public void setMode (String toMode) {
this.activityType.switchMode(toMode);
}
public boolean inMode (String toMode) {
return activityType.inMode(toMode);
}
public void targetUnit (Unit theUnit) {
host.targetUnit(theUnit);
}
public abstract void selectNewTask();
public boolean canSeePlayer () {
return host.canSeePlayer;
}
public void performSimpleAttack (){
Detonator.INSTANCE.combatProcessor.performSimpleAttack();
}
public void setCanSeePlayer (boolean setValue) {
host.canSeePlayer = setValue;
}
/** Set self as attacker and target as target */
public void prepareCombatProcessor(){
//Detonator.INSTANCE.combatProcessor.attacker = host;
//Detonator.INSTANCE.combatProcessor.defender = host.target;
Detonator.INSTANCE.combatProcessor.setupParticipants(host, host.target);
}
/** Select next movement step from global destination */
public void getTargetTile() {
//host.targetTile(host.assignedTask.movementCoords);
//if ((host.assignedTask.targetCoords.returnDistance(host.mapCoords)) <= 1) {
// performAction();
//} else {
if (!(host.targettedCoords.isSame(host.mapCoords))) {
host.pathfinder.updatePath();
if (host.pathfinder.path != null) {
host.resetSteps();
nextTile.x = host.pathfinder.path.getX(host.stepCount);
nextTile.y = host.pathfinder.path.getY(host.stepCount);
hasTargetTile = true;
} else {
if (host.assignedTask != null) {
//Task.decreaseTaskPriority(minion.assignedTask);
}
}
}
//}
}
/** Make a step in next movement step direction */
public void chaseTargetTile() {
host.direction = host.mapCoords.calculateVector(nextTile);
//host.takeOneFractionalStep();
host.takeOneStep();
//host.mapCoords.checkIfApproximatelySame(nextTile);
if (host.mapCoords.isSame(nextTile)) {
hasTargetTile = false;
}
}
public void setRandomSpotAsTarget(int maxDeltaX, int maxDeltaY) {
//walk around idly
if (activityType.isNull()) {
//Log.info("Null map: "+(map == null));
//Log.info("Null host: "+(host == null));
int rndDeltaX;
int rndDeltaY;
do {
rndDeltaX = Detonator.INSTANCE.rng.nextInt (maxDeltaX);
rndDeltaY = Detonator.INSTANCE.rng.nextInt (maxDeltaY);
rndDeltaX = rndDeltaX + host.mapCoords.getIntX();
rndDeltaY = rndDeltaY + host.mapCoords.getIntY();
if (rndDeltaX > (map.getActualSizeX() - 2)) {
rndDeltaX = map.getActualSizeX() - 2;
}
if (rndDeltaY > (map.getActualSizeY() - 2)) {
rndDeltaY = map.getActualSizeY() - 2;
}
if (rndDeltaX <= 0) {
rndDeltaX = 1;
}
if (rndDeltaY <= 0) {
rndDeltaY = 1;
}
//Detonator.INSTANCE.rng.nextInt(map.getActualSizeX() - 2) + 1
host.targetTile(rndDeltaX, rndDeltaY);
} while (host.onMap.tileIsObstacle(host.targettedCoords.getIntX(), host.targettedCoords.getIntY()));
//Log.info("Go to "+rndDeltaX+"/"+rndDeltaY+" from "+host.mapCoords.getIntX()+"/"+host.mapCoords.getIntY());
activityType.switchMode("move");
}
}
/** If have no target tile, get one. If have one, make a step. */
public void performMovement() {
if (!hasTargetTile) {
//Log.info("Needs Target Tile");
getTargetTile();
}
if (hasTargetTile) {
//Log.info("Chase Target Tile");
chaseTargetTile();
}
if (!(host.pathfinder.pathAvailable())) {
//Log.info("No way");
//currentActivity = null;
host.resetPath();
}
}
public void stepInRandomDirection (){
failCounter = 0;
do {
do {host.direction = Detonator.INSTANCE.rng.nextInt(9)+1;}
while (host.direction == 5);
failCounter++;
} while ((!(host.move(host.direction))) && (failCounter<200));
//host.takeOneFractionalStep();
//host.takeOneStep();
}
/** Do something to achieve goal selected in selectNewTask */
public abstract void performTask();
/** If AI is standing near the target, pick an activity and perform some action */
public abstract void performAction();
@Override
public void process() {
if (activityType.isNull()) {
selectNewTask();
}
if (!(activityType.isNull())) {
performTask();
}
if ((host.targettedCoords.returnDistance(host.mapCoords)) <= 0.1) {
performAction();
}
if (host.targettedCoords != null) {
performMovement();
}
}
}