source-engine/game/server/AI_Criteria.h
FluorescentCIAAfricanAmerican 3bf9df6b27 1
2020-04-22 12:56:21 -04:00

240 lines
5.4 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef AI_CRITERIA_H
#define AI_CRITERIA_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/utlrbtree.h"
#include "tier1/utlsymbol.h"
#include "interval.h"
#include "mathlib/compressed_vector.h"
extern const char *SplitContext( const char *raw, char *key, int keylen, char *value, int valuelen, float *duration );
class AI_CriteriaSet
{
public:
AI_CriteriaSet();
AI_CriteriaSet( const AI_CriteriaSet& src );
~AI_CriteriaSet();
void AppendCriteria( const char *criteria, const char *value = "", float weight = 1.0f );
void RemoveCriteria( const char *criteria );
void Describe();
int GetCount() const;
int FindCriterionIndex( const char *name ) const;
const char *GetName( int index ) const;
const char *GetValue( int index ) const;
float GetWeight( int index ) const;
private:
struct CritEntry_t
{
CritEntry_t() :
criterianame( UTL_INVAL_SYMBOL ),
weight( 0.0f )
{
value[ 0 ] = 0;
}
CritEntry_t( const CritEntry_t& src )
{
criterianame = src.criterianame;
value[ 0 ] = 0;
weight = src.weight;
SetValue( src.value );
}
CritEntry_t& operator=( const CritEntry_t& src )
{
if ( this == &src )
return *this;
criterianame = src.criterianame;
weight = src.weight;
SetValue( src.value );
return *this;
}
static bool LessFunc( const CritEntry_t& lhs, const CritEntry_t& rhs )
{
return Q_stricmp( lhs.criterianame.String(), rhs.criterianame.String() ) < 0 ? true : false;
}
void SetValue( char const *str )
{
if ( !str )
{
value[ 0 ] = 0;
}
else
{
Q_strncpy( value, str, sizeof( value ) );
}
}
// We use CUtlRBTree CopyFrom() in ctor, so CritEntry_t must be POD. If you add
// CUtlString or something then you must change AI_CriteriaSet copy ctor.
CUtlSymbol criterianame;
char value[ 64 ];
float weight;
};
CUtlRBTree< CritEntry_t, short > m_Lookup;
};
#pragma pack(1)
template<typename T>
struct response_interval_t
{
T start;
T range;
interval_t &ToInterval( interval_t &dest ) const { dest.start = start; dest.range = range; return dest; }
void FromInterval( const interval_t &from ) { start = from.start; range = from.range; }
float Random() const { interval_t temp = { start, range }; return RandomInterval( temp ); }
};
typedef response_interval_t<float16_with_assign> responseparams_interval_t;
struct AI_ResponseParams
{
DECLARE_SIMPLE_DATADESC();
enum
{
RG_DELAYAFTERSPEAK = (1<<0),
RG_SPEAKONCE = (1<<1),
RG_ODDS = (1<<2),
RG_RESPEAKDELAY = (1<<3),
RG_SOUNDLEVEL = (1<<4),
RG_DONT_USE_SCENE = (1<<5),
RG_STOP_ON_NONIDLE = (1<<6),
RG_WEAPONDELAY = (1<<7),
RG_DELAYBEFORESPEAK = (1<<8),
};
AI_ResponseParams()
{
flags = 0;
odds = 100;
delay.start = 0;
delay.range = 0;
respeakdelay.start = 0;
respeakdelay.range = 0;
weapondelay.start = 0;
weapondelay.range = 0;
soundlevel = 0;
predelay.start = 0;
predelay.range = 0;
}
responseparams_interval_t delay; //4
responseparams_interval_t respeakdelay; //8
responseparams_interval_t weapondelay; //12
short odds; //14
short flags; //16
byte soundlevel; //17
responseparams_interval_t predelay; //21
};
#pragma pack()
//-----------------------------------------------------------------------------
// Purpose: Generic container for a response to a match to a criteria set
// This is what searching for a response returns
//-----------------------------------------------------------------------------
enum ResponseType_t
{
RESPONSE_NONE = 0,
RESPONSE_SPEAK,
RESPONSE_SENTENCE,
RESPONSE_SCENE,
RESPONSE_RESPONSE, // A reference to another response by name
RESPONSE_PRINT,
NUM_RESPONSES,
};
class AI_Response
{
public:
DECLARE_SIMPLE_DATADESC();
AI_Response();
AI_Response( const AI_Response &from );
~AI_Response();
AI_Response &operator=( const AI_Response &from );
void Release();
const char * GetNamePtr() const;
const char * GetResponsePtr() const;
const AI_ResponseParams *GetParams() const { return &m_Params; }
ResponseType_t GetType() const { return (ResponseType_t)m_Type; }
soundlevel_t GetSoundLevel() const;
float GetRespeakDelay() const;
float GetWeaponDelay() const;
bool GetSpeakOnce() const;
bool ShouldntUseScene( ) const;
bool ShouldBreakOnNonIdle( void ) const;
int GetOdds() const;
float GetDelay() const;
float GetPreDelay() const;
void SetContext( const char *context );
const char * GetContext( void ) const { return m_szContext.Length() ? m_szContext.Get() : NULL; }
bool IsApplyContextToWorld( void ) { return m_bApplyContextToWorld; }
void Describe();
const AI_CriteriaSet* GetCriteria();
void Init( ResponseType_t type,
const char *responseName,
const AI_CriteriaSet& criteria,
const AI_ResponseParams& responseparams,
const char *matchingRule,
const char *applyContext,
bool bApplyContextToWorld );
static const char *DescribeResponse( ResponseType_t type );
enum
{
MAX_RESPONSE_NAME = 64,
MAX_RULE_NAME = 64
};
private:
byte m_Type;
char m_szResponseName[ MAX_RESPONSE_NAME ];
char m_szMatchingRule[ MAX_RULE_NAME ];
// The initial criteria to which we are responsive
AI_CriteriaSet *m_pCriteria;
AI_ResponseParams m_Params;
CUtlString m_szContext;
bool m_bApplyContextToWorld;
};
#endif // AI_CRITERIA_H