This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

229 lines
6.1 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef AI_CRITERIA_H
#define AI_CRITERIA_H
#ifdef _WIN32
#pragma once
#endif
#include "interval.h"
#include "mathlib/compressed_vector.h"
#include "tier1/utlrbtree.h"
#include "tier1/utlsymbol.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