Animal Tasks - UQcsse3200/2024-studio-1 GitHub Wiki

Overview

The Task system is a collection of AI behaviour components designed to create realistic and dynamic animal behaviours in our game. These tasks are built on top of the AI Task System, which allows for priority-based task execution and seamless switching between different behaviours based on which has the highest priority. Each task specifies its priority using static variables.

To configure these tasks for each animal, see NPC Configuration.

Tasks

Tasks are units of behaviour that NPCs can execute. Each task defines what the NPC does when the task is active and specifies a priority to determine when it should be executed. All tasks default to a priority of -1 when not active, however WanderTask and StraightWanderTask always have a constant priority of 1, making them the fallback tasks. The other tasks return their INACTIVE_PRIORITY when inactive and that conditions to be activated are met.

WanderTask

NPC wanders around within a specified range from its starting position.

  • Configuration:
    • wanderRadius: The radius within which the NPC wanders.
    • waitTime: Time to wait between movements.
    • wanderSpeed: Speed at which the NPC moves while wandering.
public class WanderTask extends DefaultTask implements PriorityTask {
  private static final int PRIORITY = 1;
  // ...
}

StraightWanderTask

NPC moves in a straight line in a random direction. On collision, it changes direction randomly. It is not compatible with WanderTask.

  • Configuration:
    • wanderSpeed: Speed at which the NPC moves.
public class StraightWanderTask extends DefaultTask implements PriorityTask {
  private static final int PRIORITY = 1;
  // ...
}

FollowTask

NPC follows the player or another target entity within a specified range.

  • Configuration:
    • followRadius: The radius within which the NPC follows the target.
    • waitTime: Time to wait between movements.
    • followSpeed: Speed at which the NPC moves while following.
public class FollowTask extends DefaultTask implements PriorityTask {
  private static final int PRIORITY = 1;
  // ...
}

ChaseTask

NPC chases a target entity when within a viewDistance until it gets too far away (chaseDistance) or loses line of sight.

  • Configuration:
    • viewDistance: Distance within which the NPC can see the target.
    • chaseDistance: Maximum distance the NPC will chase the target.
    • chaseSpeed: Speed at which the NPC chases the target.
    • maxTime: Maximum time the NPC will continue to chase.
public class ChaseTask extends DefaultTask implements PriorityTask {
  private static final int PRIORITY = 4;
  // ...
}

ChargeTask

NPC charges towards a target's current position. It can overshoot the target based on a distance multiplier and stops when colliding with entities or obstacles. It gives the task manager its inactive priority, when the target is with a specified range away from the charging entity.

  • Configuration:
    • activationMinRange and activationMaxRange: Range within which the task can activate.
    • chaseSpeed: Speed of the charge.
    • distanceMultiplier: Multiplier to determine how far beyond the target the NPC charges.
    • waitTime: Time to wait after charging.
    • cooldownTime: Cooldown before the task can activate again.
public class ChargeTask extends DefaultTask implements PriorityTask {
  private static final int ACTIVE_PRIORITY = 10;
  private static final int INACTIVE_PRIORITY = 8;
  // ...
}

JumpTask

NPC jumps toward a target, bypassing obstacles, and simulates a jump arc in the y-direction. Upon landing, it performs an AOE attack. It waits after the jump for a given amount of time, then stops. It activates when the target is with a specified range away from the charging entity then waits after the charge for a given amount of time before stopping.

  • Configuration:
    • activationMinRange and activationMaxRange: Range within which the task can activate.
    • jumpDuration: Duration of the jump.
    • waitTime: Time to wait after jumping.
    • cooldownTime: Cooldown before the task can activate again.
public class JumpTask extends DefaultTask implements PriorityTask {
  private static final int ACTIVE_PRIORITY = 10;
  private static final int INACTIVE_PRIORITY = 7;
  // ...
}

RunAwayTask

NPC runs away from a target when its health falls below a certain percentage and the target is within a certain set range of the NPC.

  • Configuration:
    • activationMinRange and activationMaxRange: Range within which the task can activate.
    • activationHealth: Health percentage below which the NPC will run away.
    • runSpeed: Speed at which the NPC runs away.
    • stopDistance: Distance to stop running.
    • maxRunTime: Maximum time to run.
    • cooldownTime: Cooldown before the task can activate again.
public class RunAwayTask extends DefaultTask implements PriorityTask {
  private static final int ACTIVE_PRIORITY = 10;
  private static final int INACTIVE_PRIORITY = 9;
  // ...
}

RangeAttackTask

NPC performs a ranged attack on a target entity. It gives the inactive priority when the target is within a specified range.

  • Configuration:
    • activationMinRange and activationMaxRange: Range within which the task can activate.
    • attackNum: Number of attacks to perform.
    • cooldownTime: Cooldown before the task can activate again.
    • attackType: Type of ranged attack ("single" or "spread").
public class RangeAttackTask extends DefaultTask implements PriorityTask {
  private static final int ACTIVE_PRIORITY = 9;
  private static final int SINGLE_INACTIVE_PRIORITY = 5;
  private static final int SPREAD_INACTIVE_PRIORITY = 6;
  // ...
}

AOEAttackTask

NPC performs an Area of Effect (AOE) attack with a preparation phase. It gives the inactive priority when the target is within a specified range.

  • Configuration:
    • activationMinRange and activationMaxRange: Range within which the task can activate.
    • preparationTime: Time spent preparing (e.g., charge-up animation).
    • cooldownTime: Cooldown before the task can activate again.
public class AOEAttackTask extends DefaultTask implements PriorityTask {
  private static final int ACTIVE_PRIORITY = 10;
  private static final int INACTIVE_PRIORITY = 6;
  // ...
}

BulletStormTask

An NPC moves to the centre of the room, enables BossRangeAttackComponent and becomes invincible. This runs after the NPC drops below 50% health and deactivates after a specified duration has passed. It can only be activated once. This has been designed for bosses to use.

public class BulletStormTask extends DefaultTask implements PriorityTask {
    private static final int TASK_PRIORITY = 15; // Highest priority
    private static final float ACTIVATION_HEALTH_PERCENTAGE = 50f;
    private final Vector2 centerPosition = new Vector2(7, 5); // Centre of room
    // ...

WaitTask

Task that does nothing other than waiting for a given time. Used within other tasks as it is not a priority task.

  • Configuration:
    • duration: Duration to wait.
public class WaitTask extends DefaultTask {
  // ...
}

MovementTask

Moves the entity to a given position, finishing when it gets close enough. Used within other tasks as it is not a priority task.

  • Configuration:
    • target: The target position.
    • stopDistance: Distance from the target at which to stop.
public class MovementTask extends DefaultTask {
  // ...
}

Implementation

The tasks are implemented in the NPCFactory class, which creates the AITaskComponent based on the configuration:

private void addAIComponent(Entity npc, Entity target, TaskConfig tasks) {
    AITaskComponent aiComponent = new AITaskComponent();
    Map<TaskType, Object> taskConfigs = tasks.getTaskConfigs();

    for (Map.Entry<TaskType, Object> entry : taskConfigs.entrySet()) {
      switch (entry.getKey()) {
        case WANDER -> aiComponent.addTask(new WanderTask((TaskConfig.WanderTaskConfig) entry.getValue()));
        case STRAIGHT_WANDER
                -> aiComponent.addTask(new StraightWanderTask((TaskConfig.StraightWanderTaskConfig) entry.getValue()));
        case FOLLOW -> aiComponent.addTask(new FollowTask((TaskConfig.FollowTaskConfig) entry.getValue()));
        case CHASE -> aiComponent.addTask(new ChaseTask(target, (TaskConfig.ChaseTaskConfig) entry.getValue()));
  // ... other tasks ...

  npc.addComponent(aiComponent);
}

Extensibility

The task system is designed to be easily extensible. To create a new task:

  1. Create a new configuration class in NPCConfigs.NPCConfig.TaskConfig.
  2. Implement the task class extending DefaultTask and implementing PriorityTask.
  3. Add the task creation logic in the NPCFactory.createAIComponent method.

This modular design allows for the creation of complex behaviors by combining simpler tasks, all configurable through the NPCConfigs class.


⬅ Back to Animal Overview