ICT290 / src / scene / AIController / Goals / GoalThink.cpp
GoalThink.cpp
Raw
#include "GoalThink.h"
#include <list>
//#include "misc/Cgdi.h"
//#include "../Raven_ObjectEnumerations.h"
//#include "misc/utils.h"
//#include "../lua/Raven_Scriptor.h"

#include "GoalExplore.h"
#include "GoalMoveToPosition.h"
//#include "Goal_GetItem.h"
#include "ArcanistGoalTypes.h"
#include "GoalAttackTarget.h"
#include "GoalWander.h"

//#include "GetWeaponGoalEvaluator.h"
//#include "GetHealthGoalEvaluator.h"
//#include "ExploreGoalEvaluator.h"
#include "AttackTargetGoalEvaluator.h"
#include "WanderGoalEvaluator.h"

GoalThink::GoalThink(Vehicle* Bot) : GoalComposite<Vehicle>(Bot, goal_think) {
    // these biases could be loaded in from a script on a per bot basis
    // but for now we'll just give them some random values
    const float LowRangeOfBias = 0.5;
    const float HighRangeOfBias = 1.5;

    std::random_device rdevice{};
    std::default_random_engine num{rdevice()};
    std::uniform_real_distribution<float> random{LowRangeOfBias,
                                                 HighRangeOfBias};

    /*
      float HealthBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
      float ShotgunBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
      float RocketLauncherBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
      float RailgunBias = RandInRange(LowRangeOfBias, HighRangeOfBias);
      */
    // float exploreBias = random(num);
    float wanderBias = random(num);
    float attackBias = random(num);

    // create the evaluator objects
    // m_Evaluators.push_back(new GetHealthGoalEvaluator(HealthBias));
    // m_Evaluators.push_back(new ExploreGoalEvaluator(ExploreBias));
    m_Evaluators.push_back(new WanderGoalEvaluator(wanderBias));
    m_Evaluators.push_back(new AttackTargetGoalEvaluator(attackBias));
    /*
    m_Evaluators.push_back(new GetWeaponGoalEvaluator(ShotgunBias,
                                                       type_shotgun));
    m_Evaluators.push_back(new GetWeaponGoalEvaluator(RailgunBias,
                                                       type_rail_gun));
    m_Evaluators.push_back(new GetWeaponGoalEvaluator(RocketLauncherBias,
                                                       type_rocket_launcher));
                                                       */
}

//----------------------------- dtor ------------------------------------------
//-----------------------------------------------------------------------------
GoalThink::~GoalThink() {
    for (auto& curDes : m_Evaluators) {
        delete curDes;
    }
}

//------------------------------- Activate ------------------------------------
//-----------------------------------------------------------------------------
void GoalThink::Activate() {
    if (!m_Owner->isPossessed()) {
        Arbitrate();
    }

    m_Status = active;
}

//------------------------------ Process --------------------------------------
//
//  processes the subgoals
//-----------------------------------------------------------------------------
int GoalThink::Process() {
    activateIfInactive();

    int SubgoalStatus = processSubgoals();

    if (SubgoalStatus == completed || SubgoalStatus == failed) {
        if (!m_Owner->isPossessed()) {
            m_Status = inactive;
        }
    }

    return m_Status;
}

//----------------------------- Update ----------------------------------------
//
//  this method iterates through each goal option to determine which one has
//  the highest desirability.
//-----------------------------------------------------------------------------
void GoalThink::Arbitrate() {
    float best{0};
    GoalEvaluator* MostDesirable{nullptr};

    // iterate through all the evaluators to see which produces the highest
    // score
    for (auto& curDes : m_Evaluators) {
        float desirability = curDes->CalculateDesirability(m_Owner);

        if (desirability >= best) {
            best = desirability;
            MostDesirable = curDes;
        }
    }

    assert(MostDesirable && "<GoalThink::Arbitrate>: no evaluator selected");

    MostDesirable->SetGoal(m_Owner);
}

//---------------------------- notPresent --------------------------------------
//
//  returns true if the goal type passed as a parameter is the same as this
//  goal or any of its subgoals
//-----------------------------------------------------------------------------
bool GoalThink::notPresent(int GoalType) const {
    if (!m_SubGoals.empty()) {
        return m_SubGoals.front()->getType() != GoalType;
    }

    return true;
}

void GoalThink::addGoalMoveToPosition(glm::vec2 pos) {
    addSubgoal(new GoalMoveToPosition(m_Owner, pos));
}

void GoalThink::AddGoalWander() {
    if (notPresent(goal_wander)) {
        removeAllSubgoals();
        addSubgoal(new GoalWander(m_Owner));
    }
}

/*
void GoalThink::AddGoalExplore()
{
  if (notPresent(goal_explore))
  {
    removeAllSubgoals();
    addSubgoal( new GoalExplore(m_Owner));
  }
}*/

/*
void GoalThink::AddGoal_GetItem(unsigned int ItemType)
{
  if (notPresent(ItemTypeToGoalType(ItemType)))
  {
    removeAllSubgoals();
    addSubgoal( new Goal_GetItem(m_Owner, ItemType));
  }
}*/

void GoalThink::AddGoalAttackTarget() {
    if (notPresent(goal_attack_target)) {
        removeAllSubgoals();
        addSubgoal(new GoalAttackTarget(m_Owner));
    }
}

//-------------------------- Queue Goals --------------------------------------
//-----------------------------------------------------------------------------
void GoalThink::QueueGoalMoveToPosition(glm::vec2 pos) {
    m_SubGoals.push_back(new GoalMoveToPosition(m_Owner, pos));
}