//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef AI_SCRIPTCONDITIONS_H #define AI_SCRIPTCONDITIONS_H #include "ai_npcstate.h" #include "baseentity.h" #include "entityoutput.h" #include "simtimer.h" #if defined(_WIN32) #pragma once #endif //----------------------------------------------------------------------------- class CAI_ProxTester { public: CAI_ProxTester() : m_distSq(0), m_fInside(false) {} void Init(float dist) { m_fInside = (dist > 0); m_distSq = dist * dist; } bool Check(CBaseEntity *pEntity1, CBaseEntity *pEntity2) { if (m_distSq != 0) { float distSq = (pEntity1->GetAbsOrigin() - pEntity2->GetAbsOrigin()) .LengthSqr(); bool fInside = (distSq < m_distSq); return (m_fInside == fInside); } return true; } DECLARE_SIMPLE_DATADESC(); private: float m_distSq; bool m_fInside; }; //----------------------------------------------------------------------------- class CAI_ScriptConditionsElement { public: DECLARE_SIMPLE_DATADESC(); void SetActor(CBaseEntity *pEntity) { m_hActor = pEntity; } CBaseEntity *GetActor(void) { return m_hActor.Get(); } void SetTimer(CSimTimer timer) { m_Timer = timer; } CSimTimer *GetTimer(void) { return &m_Timer; } void SetTimeOut(CSimTimer timeout) { m_Timeout = timeout; } CSimTimer *GetTimeOut(void) { return &m_Timeout; } private: EHANDLE m_hActor; CSimTimer m_Timer; CSimTimer m_Timeout; }; //----------------------------------------------------------------------------- // class CAI_ScriptConditions // // Purpose: Watches a set of conditions relative to a given NPC, and when they // are all satisfied, fires the relevant output //----------------------------------------------------------------------------- class CAI_ScriptConditions : public CBaseEntity, public IEntityListener { DECLARE_CLASS(CAI_ScriptConditions, CBaseEntity); public: CAI_ScriptConditions() : m_fDisabled(true), m_flRequiredTime(0), m_fMinState(NPC_STATE_IDLE), m_fMaxState(NPC_STATE_IDLE), m_fScriptStatus(TRS_NONE), m_fActorSeePlayer(TRS_NONE), m_flPlayerActorProximity(0), m_flPlayerActorFOV(-1), m_fPlayerActorLOS(TRS_NONE), m_fActorSeeTarget(TRS_NONE), m_flActorTargetProximity(0), m_flPlayerTargetProximity(0), m_flPlayerTargetFOV(0), m_fPlayerTargetLOS(TRS_NONE), m_fPlayerBlockingActor(TRS_NONE), m_flMinTimeout(0), m_flMaxTimeout(0), m_fActorInPVS(TRS_NONE), m_fActorInVehicle(TRS_NONE), m_fPlayerInVehicle(TRS_NONE) { #ifndef HL2_EPISODIC m_hActor = NULL; #endif } private: void Spawn(); void Activate(); void EvaluationThink(); void Enable(); void Disable(); void SetThinkTime() { SetNextThink(gpGlobals->curtime + 0.250); } // Evaluators struct EvalArgs_t { CBaseEntity *pActor; CBasePlayer *pPlayer; CBaseEntity *pTarget; }; bool EvalState(const EvalArgs_t &args); bool EvalActorSeePlayer(const EvalArgs_t &args); bool EvalPlayerActorLook(const EvalArgs_t &args); bool EvalPlayerTargetLook(const EvalArgs_t &args); bool EvalPlayerActorProximity(const EvalArgs_t &args); bool EvalPlayerTargetProximity(const EvalArgs_t &args); bool EvalActorTargetProximity(const EvalArgs_t &args); bool EvalActorSeeTarget(const EvalArgs_t &args); bool EvalPlayerActorLOS(const EvalArgs_t &args); bool EvalPlayerTargetLOS(const EvalArgs_t &args); bool EvalPlayerBlockingActor(const EvalArgs_t &args); bool EvalActorInPVS(const EvalArgs_t &args); bool EvalPlayerInVehicle(const EvalArgs_t &args); bool EvalActorInVehicle(const EvalArgs_t &args); void OnEntitySpawned(CBaseEntity *pEntity); int AddNewElement(CBaseEntity *pActor); bool ActorInList(CBaseEntity *pActor); void UpdateOnRemove(void); // Input handlers void InputEnable(inputdata_t &inputdata); void InputDisable(inputdata_t &inputdata); // Output handlers COutputEvent m_OnConditionsSatisfied; COutputEvent m_OnConditionsTimeout; COutputEvent m_NoValidActors; //--------------------------------- #ifndef HL2_EPISODIC CBaseEntity *GetActor() { return m_hActor.Get(); } #endif CBasePlayer *GetPlayer() { return UTIL_GetLocalPlayer(); } //--------------------------------- // @Note (toml 07-17-02): At some point, it may be desireable to switch to // using function objects instead of functions. Probably if support for NPCs // addiing custom conditions becomes necessary typedef bool (CAI_ScriptConditions::*EvaluationFunc_t)( const EvalArgs_t &args); struct EvaluatorInfo_t { EvaluationFunc_t pfnEvaluator; const char *pszName; }; static EvaluatorInfo_t gm_Evaluators[]; //--------------------------------- // Evaluation helpers static bool IsInFOV(CBaseEntity *pViewer, CBaseEntity *pViewed, float fov, bool bTrueCone); static bool PlayerHasLineOfSight(CBaseEntity *pViewer, CBaseEntity *pViewed, bool fNot); static bool ActorInPlayersPVS(CBaseEntity *pActor, bool bNot); virtual void OnRestore(void); //--------------------------------- // General conditions info bool m_fDisabled; bool m_bLeaveAsleep; EHANDLE m_hTarget; float m_flRequiredTime; // How long should the conditions me true #ifndef HL2_EPISODIC EHANDLE m_hActor; CSimTimer m_Timer; // @TODO (toml 07-16-02): save/load of timer once Jay // has save/load of contained objects CSimTimer m_Timeout; #endif //--------------------------------- // Specific conditions data NPC_STATE m_fMinState; NPC_STATE m_fMaxState; ThreeState_t m_fScriptStatus; ThreeState_t m_fActorSeePlayer; string_t m_Actor; float m_flPlayerActorProximity; CAI_ProxTester m_PlayerActorProxTester; float m_flPlayerActorFOV; bool m_bPlayerActorFOVTrueCone; ThreeState_t m_fPlayerActorLOS; ThreeState_t m_fActorSeeTarget; float m_flActorTargetProximity; CAI_ProxTester m_ActorTargetProxTester; float m_flPlayerTargetProximity; CAI_ProxTester m_PlayerTargetProxTester; float m_flPlayerTargetFOV; bool m_bPlayerTargetFOVTrueCone; ThreeState_t m_fPlayerTargetLOS; ThreeState_t m_fPlayerBlockingActor; ThreeState_t m_fActorInPVS; float m_flMinTimeout; float m_flMaxTimeout; ThreeState_t m_fActorInVehicle; ThreeState_t m_fPlayerInVehicle; CUtlVector m_ElementList; //--------------------------------- DECLARE_DATADESC(); }; //============================================================================= #endif // AI_SCRIPTCONDITIONS_H