SpongePowered/SpongeAPI — pull request #315 by ST-DDT (2014-12-22 23:53:05+00:00)
Title: Added Entity AI API

Simple and easy to use AI API for (living) entities.

**Added**
- AIControlled (extends Entity)
- AIHandler
- GoalBasedAIHandler (vanilla)
- AIGoalEntry
- AIGoal
- CustomAIGoal (for plugins)
- AIRequirement (replaces mutex bit mask)
- BodyController (Move + Look)

**ToDo/TBD**
- GoalType (RandomStroll, DefendTamer....)
- Class and method names
- Improve BodyController
- Flags (OpenDoors, CanSwim, AvoidLight ...)
- Move Body parts?
- More AIRequirements?
- PhysicsHelper (Shoot arrows/projectiles (aiming support) etc)

**Example**
````java
GoalBasedAIHandler aiHandler = (GoalBasedAIHandler) entity.getAIHandler();
List goalEntries = new ArrayList();
// - loot at player
AIGoal lookAtPlayer = new CustomAIGoal() {

Set aiRequirements = ImmutableSet.of(AIRequirements.LOOK);
Player player = null;

public AIControlled getEntity() {
return entity;
}

public Set getAIRequirements() {
return aiRequirements;
}

public boolean shouldExecute(final boolean isRunning) {
player = getClosest();
return player != null;
}

public boolean isInterruptible() {
return true;
}

public void execute(final boolean isRunning) {
entity.getBodyController().lookAt(player, BodyController.DEFAULTROTATIONSPEED);
}

public void abort() {
player = null;
}
};
// - follow Player
AIGoal followPlayer = new CustomAIGoal() {

Player player = null;

public AIControlled getEntity() {
return entity;
}

Set aiRequirements = ImmutableSet.of(AIRequirements.MOVE);

public Set getAIRequirements() {
return aiRequirements;
}

public boolean shouldExecute(final boolean isRunning) {
player = getClosest();
if (player == null) {
return false;
} else {
return player.getLocation().getPosition().distance(entity.getLocation().getPosition()) < 15;
}
}

public boolean isInterruptible() {
return true;
}

public void execute(final boolean isRunning) {
entity.getBodyController().tryMoveTo(player, BodyController.DEFAULTMOVEMENTSPEED);
}

public void abort() {
player = null;
}
};
// create and set goal entries
final AIGoalEntry lookAtPlayerEntry = new AIGoalEntry(lookAtPlayer, 1);
goalEntries.add(lookAtPlayerEntry);
AIGoalEntry followPlayerEntry = new AIGoalEntry(followPlayer, 1);
goalEntries.add(followPlayerEntry);
goalEntries.add(new AIGoalEntry(new IdleAIGoal(entity), 2));
aiHandler.setGoalEntries(goalEntries);
````