|
|
//========= 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
|