#pragma once // struct Telegram; //#include "misc/cgdi.h" //#include "misc/TypeToString.h" #include "../Messaging/Telegram.h" struct Telegram; template struct Goal { public: enum { active, inactive, completed, failed }; protected: // an enumerated type specifying the type of goal int m_Type; // a pointer to the entity that owns this goal entity_type* m_Owner; // an enumerated value indicating the goal's status (active, inactive, // completed, failed) int m_Status; /* the following methods were created to factor out some of the commonality in the implementations of the Process method() */ // if m_Status = inactive this method sets it to active and calls Activate() void activateIfInactive(); // if m_Status is failed this method sets it to inactive so that the goal // will be reactivated (and therefore re-planned) on the next update-step. void reactivateIfFailed(); public: // note how goals start off in the inactive state Goal(entity_type* pE, int type) : m_Type(type), m_Owner(pE), m_Status(inactive) {} virtual ~Goal() {} // logic to run when the goal is activated. virtual void Activate() = 0; // logic to run each update-step virtual int Process() = 0; // logic to run when the goal is satisfied. (typically used to switch // off any active steering behaviors) virtual void Terminate() = 0; // goals can handle messages. Many don't though, so this defines a default // behavior virtual bool HandleMessage(const Telegram&) { return false; } virtual void markOwnerWithGoal() = 0; bool isComplete() const { return m_Status == completed; } bool isActive() const { return m_Status == active; } bool isInactive() const { return m_Status == inactive; } bool hasFailed() const { return m_Status == failed; } int getType() const { return m_Type; } /* //this is used to draw the name of the goal at the specific position //used for debugging virtual void RenderAtPos(Vector2D& pos, TypeToString* tts)const; //used to render any goal specific information virtual void Render(){} */ }; // if m_Status is failed this method sets it to inactive so that the goal // will be reactivated (replanned) on the next update-step. template void Goal::reactivateIfFailed() { if (hasFailed()) { m_Status = inactive; } } template void Goal::activateIfInactive() { if (isInactive()) { Activate(); } }