Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

299 lines
7.2 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef AI_BEHAVIOR_ASSAULT_H
#define AI_BEHAVIOR_ASSAULT_H
#ifdef _WIN32
#pragma once
#endif
#include "simtimer.h"
#include "ai_behavior.h"
#include "ai_goalentity.h"
#include "ai_moveshoot.h"
#include "ai_utils.h"
#define CUE_POINT_TOLERANCE (3.0*12.0)
enum RallySelectMethod_t
{
RALLY_POINT_SELECT_DEFAULT = 0,
RALLY_POINT_SELECT_RANDOM,
};
enum AssaultCue_t
{
CUE_NO_ASSAULT = 0, // used to indicate that no assault is being conducted presently
CUE_ENTITY_INPUT = 1,
CUE_PLAYER_GUNFIRE,
CUE_DONT_WAIT,
CUE_COMMANDER,
CUE_NONE,
};
enum
{
ASSAULT_SENTENCE_HIT_RALLY_POINT = SENTENCE_BASE_BEHAVIOR_INDEX,
ASSAULT_SENTENCE_HIT_ASSAULT_POINT,
ASSAULT_SENTENCE_SQUAD_ADVANCE_TO_RALLY,
ASSAULT_SENTENCE_SQUAD_ADVANCE_TO_ASSAULT,
ASSAULT_SENTENCE_COVER_NO_AMMO,
ASSAULT_SENTENCE_UNDER_ATTACK,
};
// Allow diversion from the assault up to this amount of time after last having an enemy
#define ASSAULT_DIVERSION_TIME 4
#define SF_ASSAULTPOINT_CLEARONARRIVAL 0x00000001
//=============================================================================
//=============================================================================
class CRallyPoint : public CPointEntity
{
DECLARE_CLASS( CRallyPoint, CPointEntity );
public:
CRallyPoint()
{
m_hLockedBy.Set(NULL);
m_sExclusivity = RALLY_EXCLUSIVE_NOT_EVALUATED;
}
bool Lock( CBaseEntity *pLocker )
{
if( IsLocked() )
{
// Already locked.
return false;
}
m_hLockedBy.Set( pLocker );
return true;
}
bool Unlock( CBaseEntity *pUnlocker )
{
if( IsLocked() )
{
if( m_hLockedBy.Get() != pUnlocker )
{
// Refuse! Only the locker may unlock.
return false;
}
}
m_hLockedBy.Set( NULL );
return true;
}
bool IsLocked( void ) { return (m_hLockedBy.Get() != NULL); }
int DrawDebugTextOverlays();
bool IsExclusive();
enum
{
RALLY_EXCLUSIVE_NOT_EVALUATED = -1,
RALLY_EXCLUSIVE_NO,
RALLY_EXCLUSIVE_YES,
};
string_t m_AssaultPointName;
string_t m_RallySequenceName;
float m_flAssaultDelay;
int m_iPriority;
int m_iStrictness;
bool m_bForceCrouch;
bool m_bIsUrgent;
short m_sExclusivity;
COutputEvent m_OnArrival;
DECLARE_DATADESC();
private:
EHANDLE m_hLockedBy;
};
//=============================================================================
//=============================================================================
class CAssaultPoint : public CPointEntity
{
DECLARE_CLASS( CAssaultPoint, CPointEntity );
public:
CAssaultPoint()
{
// This used to be a constant in code. Now it's a keyfield in hammer.
// So in the constructor, we set this value to the former constant
// default value, for legacy maps. (sjb)
m_flAssaultPointTolerance = CUE_POINT_TOLERANCE;
}
void InputSetClearOnContact( inputdata_t &inputdata )
{
m_bClearOnContact = inputdata.value.Bool();
}
void InputSetAllowDiversion( inputdata_t &inputdata )
{
m_bAllowDiversion = inputdata.value.Bool();
}
void InputSetForceClear( inputdata_t &inputdata )
{
m_bInputForcedClear = inputdata.value.Bool();
}
public:
string_t m_AssaultHintGroup;
string_t m_NextAssaultPointName;
COutputEvent m_OnAssaultClear;
float m_flAssaultTimeout;
bool m_bClearOnContact;
bool m_bAllowDiversion;
float m_flAllowDiversionRadius;
bool m_bNeverTimeout;
int m_iStrictness;
bool m_bForceCrouch;
bool m_bIsUrgent;
bool m_bInputForcedClear;
float m_flAssaultPointTolerance;
float m_flTimeLastUsed;
COutputEvent m_OnArrival;
DECLARE_DATADESC();
};
//=============================================================================
//=============================================================================
class CAI_AssaultBehavior : public CAI_SimpleBehavior
{
DECLARE_CLASS( CAI_AssaultBehavior, CAI_SimpleBehavior );
public:
CAI_AssaultBehavior();
virtual const char *GetName() { return "Assault"; }
virtual int DrawDebugTextOverlays( int text_offset );
virtual void OnRestore();
bool CanRunAScriptedNPCInteraction( bool bForced );
virtual bool CanSelectSchedule();
virtual void BeginScheduleSelection();
virtual void EndScheduleSelection();
bool HasHitRallyPoint() { return m_bHitRallyPoint; }
bool HasHitAssaultPoint() { return m_bHitAssaultPoint; }
void ClearAssaultPoint( void );
void OnHitAssaultPoint( void );
bool PollAssaultCue( void );
void ReceiveAssaultCue( AssaultCue_t cue );
bool HasAssaultCue( void ) { return m_AssaultCue != CUE_NO_ASSAULT; }
bool AssaultHasBegun();
CAssaultPoint *FindAssaultPoint( string_t iszAssaultPointName );
void SetAssaultPoint( CAssaultPoint *pAssaultPoint );
void GatherConditions( void );
void StartTask( const Task_t *pTask );
void RunTask( const Task_t *pTask );
void BuildScheduleTestBits();
int TranslateSchedule( int scheduleType );
void OnStartSchedule( int scheduleType );
void ClearSchedule( const char *szReason );
void InitializeBehavior();
void SetParameters( string_t rallypointname, AssaultCue_t assaultcue, int rallySelectMethod );
void SetParameters( CBaseEntity *pRallyEnt, AssaultCue_t assaultcue );
bool IsAllowedToDivert( void );
bool IsValidShootPosition( const Vector &vLocation, CAI_Node *pNode, CAI_Hint const *pHint );
float GetMaxTacticalLateralMovement( void );
void UpdateOnRemove();
bool OnStrictAssault( void );
bool UpdateForceCrouch( void );
bool IsForcingCrouch( void );
bool IsUrgent( void );
CRallyPoint *FindBestRallyPointInRadius( const Vector &vecCenter, float flRadius );;
void Disable( void ) { m_AssaultCue = CUE_NO_ASSAULT; m_bHitRallyPoint = false; m_bHitAssaultPoint = false; }
enum
{
SCHED_MOVE_TO_RALLY_POINT = BaseClass::NEXT_SCHEDULE, // Try to get out of the player's way
SCHED_ASSAULT_FAILED_TO_MOVE,
SCHED_FAIL_MOVE_TO_RALLY_POINT,
SCHED_MOVE_TO_ASSAULT_POINT,
SCHED_AT_ASSAULT_POINT,
SCHED_HOLD_RALLY_POINT,
SCHED_HOLD_ASSAULT_POINT,
SCHED_WAIT_AND_CLEAR,
SCHED_ASSAULT_MOVE_AWAY,
SCHED_CLEAR_ASSAULT_POINT,
NEXT_SCHEDULE,
TASK_GET_PATH_TO_RALLY_POINT = BaseClass::NEXT_TASK,
TASK_FACE_RALLY_POINT,
TASK_GET_PATH_TO_ASSAULT_POINT,
TASK_FACE_ASSAULT_POINT,
TASK_HIT_ASSAULT_POINT,
TASK_HIT_RALLY_POINT,
TASK_AWAIT_CUE,
TASK_AWAIT_ASSAULT_TIMEOUT,
TASK_ANNOUNCE_CLEAR,
TASK_WAIT_ASSAULT_DELAY,
TASK_ASSAULT_MOVE_AWAY_PATH,
TASK_ASSAULT_DEFER_SCHEDULE_SELECTION,
NEXT_TASK,
/*
COND_PUT_CONDITIONS_HERE = BaseClass::NEXT_CONDITION,
NEXT_CONDITION,
*/
};
DEFINE_CUSTOM_SCHEDULE_PROVIDER;
public:
CHandle<CAssaultPoint> m_hAssaultPoint;
CHandle<CRallyPoint> m_hRallyPoint;
public:
void UnlockRallyPoint( void );
private:
void OnScheduleChange();
virtual int SelectSchedule();
AssaultCue_t m_AssaultCue; // the cue we're waiting for to begin the assault
AssaultCue_t m_ReceivedAssaultCue; // the last assault cue we received from someone/thing external.
bool m_bHitRallyPoint;
bool m_bHitAssaultPoint;
// Diversion
bool m_bDiverting;
float m_flLastSawAnEnemyAt;
float m_flTimeDeferScheduleSelection;
string_t m_AssaultPointName;
//---------------------------------
DECLARE_DATADESC();
};
#endif // AI_BEHAVIOR_ASSAULT_H