X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fai%2Fai.cpp;h=837c412f7280467336dd29afbdf22e8f889133d6;hb=d122d3e445d64f7d710c1cfaf285ff01bbe955b9;hp=1d424cc218c73c9224f3d0abe6eea37a41bae06f;hpb=150d065f431d665326fd8028748c48a74ad956bb;p=blank.git diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp index 1d424cc..837c412 100644 --- a/src/ai/ai.cpp +++ b/src/ai/ai.cpp @@ -1,4 +1,5 @@ #include "AIController.hpp" +#include "IdleState.hpp" #include "../model/geometry.hpp" #include "../rand/GaloisLFSR.hpp" @@ -13,22 +14,36 @@ namespace blank { +namespace { + +IdleState idle; + +} + AIController::AIController(GaloisLFSR &rand) : random(rand) -, chase_speed(2.0f) +, state(&idle) +, flee_target(nullptr) , flee_speed(-5.0f) -, stop_dist(10.0f) -, flee_dist(5.0f) +, seek_target(nullptr) +, seek_speed(-5.0f) +, wandering(false) , wander_pos(1.0f, 0.0f, 0.0f) , wander_dist(2.0f) , wander_radius(1.0f) , wander_disp(1.0f) , wander_speed(1.0f) { - + state->Enter(*this); } AIController::~AIController() { + state->Exit(*this); +} +void AIController::SetState(const AIState &s) { + state->Exit(*this); + state = &s; + state->Enter(*this); } void AIController::Update(Entity &e, float dt) { @@ -52,7 +67,23 @@ void AIController::Update(Entity &e, float dt) { } glm::vec3 AIController::ControlForce(const EntityState &state) const { - return (Heading(state) * wander_dist + wander_pos) * wander_speed; + glm::vec3 force(0.0f); + if (IsFleeing()) { + glm::vec3 diff(GetFleeTarget().GetState().Diff(state)); + if (dot(diff, diff) > std::numeric_limits::epsilon()) { + force += normalize(diff) * flee_speed; + } + } + if (IsSeeking()) { + glm::vec3 diff(state.Diff(GetSeekTarget().GetState())); + if (dot(diff, diff) > std::numeric_limits::epsilon()) { + force += normalize(diff) * seek_speed; + } + } + if (wandering) { + force += (Heading(state) * wander_dist + wander_pos) * wander_speed; + } + return force; } glm::vec3 AIController::Heading(const EntityState &state) noexcept { @@ -64,4 +95,57 @@ glm::vec3 AIController::Heading(const EntityState &state) noexcept { } } +void AIController::StartFleeing(const Entity &e, float speed) noexcept { + flee_target = &e; + flee_speed = speed; +} + +void AIController::StopFleeing() noexcept { + flee_target = nullptr; +} + +bool AIController::IsFleeing() const noexcept { + return flee_target; +} + +const Entity &AIController::GetFleeTarget() const noexcept { + return *flee_target; +} + +void AIController::StartSeeking(const Entity &e, float speed) noexcept { + seek_target = &e; + seek_speed = speed; +} + +void AIController::StopSeeking() noexcept { + seek_target = nullptr; +} + +bool AIController::IsSeeking() const noexcept { + return seek_target; +} + +const Entity &AIController::GetSeekTarget() const noexcept { + return *seek_target; +} + +void AIController::StartWandering() noexcept { + wandering = true; +} +void AIController::StopWandering() noexcept { + wandering = false; +} + + +void IdleState::Enter(AIController &ctrl) const { + ctrl.StartWandering(); +} + +void IdleState::Update(AIController &ctrl, Entity &e, float dt) const { +} + +void IdleState::Exit(AIController &ctrl) const { + ctrl.StopWandering(); +} + }