273 lines
6.0 KiB
C++
273 lines
6.0 KiB
C++
#include "task/Response/TaskGangs.h"
|
|
|
|
#include "Peds/Ped.h"
|
|
#include "Vehicles/vehicle.h"
|
|
#include "task/Combat/TaskNewCombat.h"
|
|
#include "task/Combat/TaskThreatResponse.h"
|
|
#include "task/Vehicle/TaskEnterVehicle.h"
|
|
|
|
CTaskGangPatrol::CTaskGangPatrol(CPed* pPrimaryTarget)
|
|
: m_pPrimaryTarget(pPrimaryTarget)
|
|
{
|
|
SetInternalTaskType(CTaskTypes::TASK_GANG_PATROL);
|
|
}
|
|
|
|
CTaskGangPatrol::~CTaskGangPatrol()
|
|
{
|
|
|
|
}
|
|
|
|
bool CTaskGangPatrol::ProcessMoveSignals()
|
|
{
|
|
CPed* pPed = GetPed();
|
|
|
|
if (pPed)
|
|
{
|
|
CVehicle* pVehicle = pPed->GetMyVehicle();
|
|
if (pVehicle)
|
|
{
|
|
pVehicle->m_nVehicleFlags.bDisablePretendOccupants = true;
|
|
pVehicle->m_nVehicleFlags.bPreventBeingDummyUnlessCollisionLoadedThisFrame = true;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
CTask::FSM_Return CTaskGangPatrol::UpdateFSM( const s32 iState, const FSM_Event iEvent )
|
|
{
|
|
FSM_Begin
|
|
FSM_State(State_Start)
|
|
FSM_OnUpdate
|
|
return Start_OnUpdate();
|
|
FSM_State(State_AttackTarget)
|
|
FSM_OnEnter
|
|
AttackTarget_OnEnter();
|
|
FSM_OnUpdate
|
|
return AttackTarget_OnUpdate();
|
|
FSM_State(State_EnterVehicle)
|
|
FSM_OnEnter
|
|
EnterVehicle_OnEnter();
|
|
FSM_OnUpdate
|
|
return EnterVehicle_OnUpdate();
|
|
FSM_State(State_WaitingForVehicleOccupants)
|
|
FSM_OnEnter
|
|
WaitingForVehicleOccupants_OnEnter();
|
|
FSM_OnUpdate
|
|
return WaitingForVehicleOccupants_OnUpdate();
|
|
FSM_State(State_Finish)
|
|
FSM_OnUpdate
|
|
return FSM_Quit;
|
|
FSM_End
|
|
}
|
|
|
|
#if !__FINAL
|
|
const char * CTaskGangPatrol::GetStaticStateName( s32 iState )
|
|
{
|
|
taskAssert(iState >= State_Start && iState <= State_Finish);
|
|
|
|
switch (iState)
|
|
{
|
|
case State_Start: return "State_Start";
|
|
case State_AttackTarget: return "State_AttackTarget";
|
|
case State_EnterVehicle: return "State_EnterVehicle";
|
|
case State_WaitingForVehicleOccupants: return "State_WaitingForVehicleOccupants";
|
|
case State_Finish: return "State_Finish";
|
|
default: taskAssert(0);
|
|
}
|
|
|
|
return "State_Invalid";
|
|
}
|
|
#endif // !__FINAL
|
|
|
|
CTask::FSM_Return CTaskGangPatrol::Start_OnUpdate()
|
|
{
|
|
RequestProcessMoveSignalCalls();
|
|
|
|
//Attack the target.
|
|
SetState(State_AttackTarget);
|
|
|
|
return FSM_Continue;
|
|
}
|
|
|
|
void CTaskGangPatrol::AttackTarget_OnEnter()
|
|
{
|
|
//Create the task.
|
|
CTaskThreatResponse* pTask = rage_new CTaskThreatResponse(m_pPrimaryTarget);
|
|
pTask->SetThreatResponseOverride(CTaskThreatResponse::TR_Fight);
|
|
pTask->GetConfigFlagsForCombat().SetFlag(CTaskCombat::ComF_RequiresOrder);
|
|
|
|
//Start the task.
|
|
SetNewTask(pTask);
|
|
}
|
|
|
|
CTask::FSM_Return CTaskGangPatrol::AttackTarget_OnUpdate()
|
|
{
|
|
//Check if the task has finished.
|
|
if(GetIsFlagSet(aiTaskFlags::SubTaskFinished))
|
|
{
|
|
//Check if the last used vehicle is close, and the driver is not dead.
|
|
if(IsLastUsedVehicleClose() && !IsDriverDead())
|
|
{
|
|
SetState(State_EnterVehicle);
|
|
}
|
|
else
|
|
{
|
|
SetState(State_Finish);
|
|
}
|
|
}
|
|
|
|
return FSM_Continue;
|
|
}
|
|
|
|
void CTaskGangPatrol::EnterVehicle_OnEnter()
|
|
{
|
|
//Assert that the vehicle is valid.
|
|
CVehicle* pVehicle = GetPed()->GetMyVehicle();
|
|
taskAssert(pVehicle);
|
|
|
|
//Create the task.
|
|
s32 iSeatIndex = pVehicle->GetSeatManager()->GetLastPedsSeatIndex(GetPed());
|
|
SeatRequestType srType = (iSeatIndex >= 0) ? SR_Specific : SR_Any;
|
|
CTaskEnterVehicle* pTask = rage_new CTaskEnterVehicle(pVehicle, srType, iSeatIndex);
|
|
|
|
//Start the task.
|
|
SetNewTask(pTask);
|
|
}
|
|
|
|
aiTask::FSM_Return CTaskGangPatrol::EnterVehicle_OnUpdate()
|
|
{
|
|
//Check if the sub-task has finished.
|
|
if(GetIsFlagSet(aiTaskFlags::SubTaskFinished))
|
|
{
|
|
//Check if we are driving the vehicle.
|
|
if(GetPed()->GetIsDrivingVehicle())
|
|
{
|
|
SetState(State_WaitingForVehicleOccupants);
|
|
}
|
|
else
|
|
{
|
|
SetState(State_Finish);
|
|
}
|
|
}
|
|
|
|
return FSM_Continue;
|
|
}
|
|
|
|
void CTaskGangPatrol::WaitingForVehicleOccupants_OnEnter()
|
|
{
|
|
//Assert that we are driving the vehicle.
|
|
taskAssert(GetPed()->GetIsDrivingVehicle());
|
|
}
|
|
|
|
aiTask::FSM_Return CTaskGangPatrol::WaitingForVehicleOccupants_OnUpdate()
|
|
{
|
|
//Check if we should not wait for vehicle occupants.
|
|
if(!ShouldWaitForVehicleOccupants())
|
|
{
|
|
SetState(State_Finish);
|
|
}
|
|
|
|
return FSM_Continue;
|
|
}
|
|
|
|
bool CTaskGangPatrol::IsDriverDead() const
|
|
{
|
|
//Ensure the vehicle is valid.
|
|
const CVehicle* pVehicle = GetPed()->GetMyVehicle();
|
|
if(!pVehicle)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Ensure the driver is valid.
|
|
const CPed* pDriver = (pVehicle->GetDriver()) ? pVehicle->GetDriver() :
|
|
pVehicle->GetSeatManager()->GetLastPedInSeat(Seat_driver);
|
|
if(!pDriver)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Ensure the driver is dead.
|
|
if(!pDriver->IsInjured())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CTaskGangPatrol::IsLastUsedVehicleClose() const
|
|
{
|
|
//Ensure the vehicle is valid.
|
|
const CVehicle* pVehicle = GetPed()->GetMyVehicle();
|
|
if(!pVehicle)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Ensure the distance is within the threshold.
|
|
ScalarV scDistSq = DistSquared(GetPed()->GetTransform().GetPosition(), pVehicle->GetTransform().GetPosition());
|
|
static dev_float s_fMaxDistance = 30.0f;
|
|
ScalarV scMaxDistSq = ScalarVFromF32(square(s_fMaxDistance));
|
|
if(IsGreaterThanAll(scDistSq, scMaxDistSq))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CTaskGangPatrol::ShouldWaitForVehicleOccupant(const CPed& rPed) const
|
|
{
|
|
//Ensure the ped is not dead.
|
|
if(rPed.IsInjured())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Ensure the ped is not in a vehicle.
|
|
if(rPed.GetIsInVehicle())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Check if the ped is getting in our vehicle.
|
|
if(rPed.GetVehiclePedEntering() == GetPed()->GetVehiclePedInside())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//Check if we have been in the state for a small amount of time.
|
|
static dev_float s_fMaxTime = 3.0f;
|
|
if(GetTimeInState() <= s_fMaxTime)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CTaskGangPatrol::ShouldWaitForVehicleOccupants() const
|
|
{
|
|
//Ensure the vehicle is valid.
|
|
const CVehicle* pVehicle = GetPed()->GetMyVehicle();
|
|
if(!pVehicle)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//Iterate over the seats.
|
|
for(s32 i = 1; i < pVehicle->GetSeatManager()->GetMaxSeats(); ++i)
|
|
{
|
|
//Check if we should wait for the last ped in the seat.
|
|
const CPed* pLastPedInSeat = pVehicle->GetSeatManager()->GetLastPedInSeat(i);
|
|
if(pLastPedInSeat && ShouldWaitForVehicleOccupant(*pLastPedInSeat))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|