Files
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

206 lines
4.2 KiB
C++

//
// filename: TaskComplex.cpp
// description: Base class for all complex tasks. Complex tasks don't control the ped
// directly, so there is no ProcessPed function for complex tasks. A complex
// task can generate a simple task to control the ped or create another
// complex task which might then generate a simple or complex task and so on.
// But the final task should always be a simple task.
// Framework headers
#include "fwmaths\random.h"
// Game headers
#include "Peds/Ped.h"
#include "Peds/PedIntelligence.h"
#include "Scene/DynamicEntity.h"
#include "Task/General/TaskBasic.h"
#include "Task/Movement/TaskGoTo.h"
AI_OPTIMISATIONS()
//-------------------------------------------------------------------------
// CTaskComplex
//-------------------------------------------------------------------------
CTaskComplex::CTaskComplex()
: m_pNewTaskToSet(NULL)
{
}
CTaskComplex::~CTaskComplex()
{
Assert(m_pNewTaskToSet == NULL);
}
void CTaskComplex::CleanUp()
{
if (m_pNewTaskToSet)
{
delete m_pNewTaskToSet;
m_pNewTaskToSet = NULL;
}
tBaseClass::CleanUp();
}
bool CTaskComplex::IsValidForMotionTask(CTaskMotionBase & task) const
{
bool isValid = tBaseClass::IsValidForMotionTask(task);
if(!isValid && GetSubTask())
{
//This task is not valid, but an active subtask might be.
isValid = GetSubTask()->IsValidForMotionTask(task);
}
return isValid;
}
//
//
// Basic FSM implementation, for the inherited class
CTask::FSM_Return CTaskComplex::UpdateFSM(const s32 iState, const FSM_Event iEvent)
{
CPed *pPed = GetPed(); //Get the ped ptr.
FSM_Begin
FSM_State(State_CreateFirstSubTask)
FSM_OnEnter
return StateCreateFirstSubTask_OnEnter(pPed);
FSM_OnUpdate
return StateCreateFirstSubTask_OnUpdate(pPed);
FSM_State(State_ControlSubTask)
FSM_OnEnter
return StateControlSubTask_OnEnter(pPed);
FSM_OnUpdate
return StateControlSubTask_OnUpdate(pPed);
FSM_State(State_CreateNextSubTask)
FSM_OnEnter
return StateCreateNextSubTask_OnEnter(pPed);
FSM_OnUpdate
return StateCreateNextSubTask_OnUpdate(pPed);
FSM_State(State_Quit)
FSM_OnUpdate
return FSM_Quit;
FSM_End
}
//
//
//
CTask::FSM_Return CTaskComplex::StateCreateFirstSubTask_OnEnter(CPed* pPed)
{
m_pNewTaskToSet = CreateFirstSubTask(pPed);
if(m_pNewTaskToSet)
{
return FSM_Continue;
}
return FSM_Quit;
}
//
//
//
CTask::FSM_Return CTaskComplex::StateCreateFirstSubTask_OnUpdate(CPed* UNUSED_PARAM(pPed))
{
SetState(State_ControlSubTask);
return FSM_Continue;
}
//
//
//
CTask::FSM_Return CTaskComplex::StateControlSubTask_OnEnter(CPed* UNUSED_PARAM(pPed))
{
if(m_pNewTaskToSet)//is a new task ready to be set, if so set it
{
SetNewTask(m_pNewTaskToSet);
m_pNewTaskToSet = NULL;
}
return FSM_Continue;
}
//
//
//
CTask::FSM_Return CTaskComplex::StateControlSubTask_OnUpdate(CPed* pPed)
{
if(taskVerifyf(GetSubTask(), "GetSubTask is NULL"))
{
//If the subtask has ended or doesn't exit go to the CreateNextSubTask state.
if( GetIsFlagSet(aiTaskFlags::SubTaskFinished))
{
SetState(State_CreateNextSubTask);
return FSM_Continue;
}
aiTask* pTask = ControlSubTask(pPed);
//is there a new task?
if(pTask && pTask != GetSubTask())
{
m_pNewTaskToSet = pTask;
SetFlag(aiTaskFlags::RestartCurrentState);
}
else if( pTask == NULL )//no task, so just quit
{
return FSM_Quit;
}
return FSM_Continue;
}
else
{
#if !__FINAL
pPed->GetPedIntelligence()->GetTaskManager()->SpewAllTasks(aiTaskSpew::SPEW_ASSERT);
#endif // !__FINAL
}
return FSM_Quit;
}
//
//
//
CTask::FSM_Return CTaskComplex::StateCreateNextSubTask_OnEnter(CPed* pPed)
{
m_pNewTaskToSet = CreateNextSubTask(pPed);
return FSM_Continue;
}
//
//
//
CTask::FSM_Return CTaskComplex::StateCreateNextSubTask_OnUpdate(CPed* UNUSED_PARAM(pPed))
{
if(m_pNewTaskToSet)//if there is a new task go to the control sub task state.
{
SetState(State_ControlSubTask);
return FSM_Continue;
}
else
{
return FSM_Quit;//no new task so quit
}
}
#if !__FINAL
const char * CTaskComplex::GetStaticStateName( s32 iState )
{
static const char* sStateNames[] =
{
"State_CreateFirstSubTask",
"State_ControlSubTask",
"State_CreateNextSubTask",
"Quit",
};
return sStateNames[iState];
}
#endif