- if (!line_of_sight) {
- Controlled().TargetVelocity(glm::vec3(0.0f));
- } else if (dist > stop_dist) {
- Controlled().TargetVelocity(norm_diff * chase_speed);
- } else if (dist < flee_dist) {
- Controlled().TargetVelocity(norm_diff * flee_speed);
+bool AIController::DecisionDue() const noexcept {
+ return decision_timer.HitOnce();
+}
+
+unsigned int AIController::Decide(unsigned int num_choices) noexcept {
+ return world.Random().Next<unsigned int>() % num_choices;
+}
+
+
+// chase
+
+void ChaseState::Enter(AIController &ctrl, Entity &e) const {
+ e.GetSteering()
+ .SetAcceleration(5.0f)
+ .SetSpeed(4.0f)
+ .Enable(Steering::PURSUE_TARGET)
+ ;
+}
+
+void ChaseState::Update(AIController &ctrl, Entity &e, float dt) const {
+ Steering &steering = e.GetSteering();
+ // check if target still alive and in sight
+ if (
+ !steering.HasTargetEntity() || // lost
+ steering.GetTargetEntity().Dead() || // dead
+ !ctrl.LineOfSight(e, steering.GetTargetEntity()) // escaped
+ ) {
+ steering.ClearTargetEntity();
+ ctrl.SetState(idle, e);
+ return;
+ }
+ // halt if we're close enough, flee if we're too close
+ float dist_sq = glm::length2(e.AbsoluteDifference(steering.GetTargetEntity()));
+ if (dist_sq < 8.0f) {
+ ctrl.SetState(flee, e);
+ } else if (dist_sq < 25.0f) {
+ steering.Enable(Steering::HALT).Disable(Steering::PURSUE_TARGET);