mirror of
https://github.com/s1lentq/ReGameDLL_CS.git
synced 2025-01-27 14:08:00 +03:00
WIP CZ: Reversed some functions of bots.
Cleanup.
This commit is contained in:
parent
51e921b0f6
commit
6f51a65ae9
@ -28,7 +28,7 @@ Archive's bin directory contains 2 subdirectories, 'bugfixed' and 'pure'
|
||||
## Current status
|
||||
<ul>
|
||||
<li> Counter-Strike 1.6 - 100%</li>
|
||||
<li> Counter-Strike: Condition Zero - 63%</li>
|
||||
<li> Counter-Strike: Condition Zero - 90%</li>
|
||||
</ul>
|
||||
|
||||
## Build instructions
|
||||
|
@ -170,7 +170,7 @@ void setupToolchain(NativeBinarySpec b)
|
||||
'_vsnprintf': 'vsnprintf',
|
||||
'_write' : 'write',
|
||||
'_close' : 'close',
|
||||
'_vsnwprintf' : 'vsnwprintf'
|
||||
'_vsnwprintf' : 'vswprintf'
|
||||
])
|
||||
|
||||
cfg.linkerOptions.args '-no-opt-class-analysis'
|
||||
|
@ -32,17 +32,17 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef PLAY_GAMEDLL
|
||||
|
||||
// probably gamedll compiled with flag /fpmath:fasted,
|
||||
// so we need to use type double, otherwise will be the test failed
|
||||
|
||||
typedef double float_precision;
|
||||
|
||||
#else // HOOK_GAMEDLL
|
||||
|
||||
typedef float float_precision;
|
||||
|
||||
#ifdef PLAY_GAMEDLL
|
||||
|
||||
// probably gamedll compiled with flag /fpmath:fasted,
|
||||
// so we need to use type double, otherwise will be the test failed
|
||||
|
||||
typedef double float_precision;
|
||||
|
||||
#else // PLAY_GAMEDLL
|
||||
|
||||
typedef float float_precision;
|
||||
|
||||
#endif // PLAY_GAMEDLL
|
||||
|
||||
/* <42b7f> ../common/mathlib.h:3 */
|
||||
@ -76,6 +76,22 @@ T Q_max(T a, T b) { return (a > b) ? a : b; }
|
||||
template <typename T>
|
||||
T clamp(T a, T min, T max) { return (a > max) ? max : (a < min) ? min : a; }
|
||||
|
||||
// bitwise operators templates
|
||||
template<class T, class type=typename std::underlying_type<T>::type>
|
||||
inline T operator~ (T a) { return (T)~(type)a; }
|
||||
template<class T, class type=typename std::underlying_type<T>::type>
|
||||
inline T operator| (T a, T b) { return (T)((type)a | (type)b); }
|
||||
template<class T, class type=typename std::underlying_type<T>::type>
|
||||
inline T operator& (T a, T b) { return (T)((type)a & (type)b); }
|
||||
template<class T, class type=typename std::underlying_type<T>::type>
|
||||
inline T operator^ (T a, T b) { return (T)((type)a ^ (type)b); }
|
||||
template<class T, class type=typename std::underlying_type<T>::type>
|
||||
inline T& operator|= (T& a, T b){ return (T&)((type&)a |= (type)b); }
|
||||
template<class T, class type=typename std::underlying_type<T>::type>
|
||||
inline T& operator&= (T& a, T b){ return (T&)((type&)a &= (type)b); }
|
||||
template<class T, class type=typename std::underlying_type<T>::type>
|
||||
inline T& operator^= (T& a, T b){ return (T&)((type&)a ^= (type)b); }
|
||||
|
||||
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
|
||||
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
|
||||
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
|
||||
|
@ -32,12 +32,9 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define ACTIVITY_NOT_AVAILABLE -1
|
||||
|
||||
typedef enum
|
||||
{
|
||||
//TODO: i think it need added (from hlbeta2)
|
||||
//ACT_INVALID = -1,
|
||||
ACT_INVALID = -1,
|
||||
|
||||
ACT_RESET = 0, // Set m_Activity to this invalid value to force a reset to m_IdealActivity
|
||||
ACT_IDLE,
|
||||
|
@ -119,7 +119,7 @@ int LookupActivity(void *pmodel, entvars_t *pev, int activity)
|
||||
}
|
||||
}
|
||||
|
||||
return ACTIVITY_NOT_AVAILABLE;
|
||||
return ACT_INVALID;
|
||||
}
|
||||
|
||||
/* <1539a> ../cstrike/dlls/animation.cpp:149 */
|
||||
@ -134,7 +134,7 @@ int LookupActivityHeaviest(void *pmodel, entvars_t *pev, int activity)
|
||||
|
||||
mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
|
||||
int weight = 0;
|
||||
int seq = ACTIVITY_NOT_AVAILABLE;
|
||||
int seq = ACT_INVALID;
|
||||
|
||||
for (int i = 0; i < pstudiohdr->numseq; i++)
|
||||
{
|
||||
@ -179,13 +179,16 @@ int LookupSequence(void *pmodel, const char *label)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Look up by sequence name.
|
||||
mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex);
|
||||
for (int i = 0; i < pstudiohdr->numseq; i++)
|
||||
{
|
||||
if (!Q_stricmp(pseqdesc[i].label, label))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
|
||||
// Not found
|
||||
return ACT_INVALID;
|
||||
}
|
||||
|
||||
/* <1518c> ../cstrike/dlls/animation.cpp:215 */
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,7 @@
|
||||
#define UNDEFINED_COUNT 0xFFFF
|
||||
#define MAX_PLACES_PER_MAP 64
|
||||
#define UNDEFINED_SUBJECT (-1)
|
||||
#define COUNT_MANY 4
|
||||
#define COUNT_MANY 4 // equal to or greater than this is "many"
|
||||
|
||||
class CCSBot;
|
||||
class BotChatterInterface;
|
||||
@ -43,27 +43,41 @@ class BotChatterInterface;
|
||||
typedef unsigned int PlaceCriteria;
|
||||
typedef unsigned int CountCriteria;
|
||||
|
||||
// A meme is a unit information that bots use to
|
||||
// transmit information to each other via the radio
|
||||
|
||||
/* <2fe97b> ../cstrike/dlls/bot/cs_bot_chatter.h:42 */
|
||||
class BotMeme
|
||||
{
|
||||
public:
|
||||
NOBODY void Transmit(CCSBot *sender) const;
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const = 0;
|
||||
void Transmit(CCSBot *sender) const; // transmit meme to other bots
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const = 0; // cause the given bot to act on this meme
|
||||
|
||||
};/* size: 4, cachelines: 1, members: 1 */
|
||||
|
||||
class BotAllHostagesGoneMeme: public BotMeme
|
||||
{
|
||||
public:
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
};/* size: 4, cachelines: 1, members: 1 */
|
||||
|
||||
class BotHostageBeingTakenMeme: public BotMeme
|
||||
{
|
||||
public:
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
};/* size: 4, cachelines: 1, members: 1 */
|
||||
|
||||
@ -75,7 +89,14 @@ public:
|
||||
{
|
||||
m_place = place;
|
||||
}
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
private:
|
||||
Place m_place;
|
||||
|
||||
@ -85,24 +106,27 @@ private:
|
||||
class BotBombsiteStatusMeme: public BotMeme
|
||||
{
|
||||
public:
|
||||
enum StatusType
|
||||
{
|
||||
CLEAR = 0,
|
||||
PLANTED
|
||||
};
|
||||
enum StatusType { CLEAR, PLANTED };
|
||||
|
||||
BotBombsiteStatusMeme(int zoneIndex, StatusType status)
|
||||
{
|
||||
m_zoneIndex = zoneIndex;
|
||||
m_status = status;
|
||||
}
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
private:
|
||||
int m_zoneIndex;
|
||||
StatusType m_status;
|
||||
int m_zoneIndex; // the bombsite
|
||||
StatusType m_status; // whether it is cleared or the bomb is there (planted)
|
||||
|
||||
};/* size: 12, cachelines: 1, members: 3 */
|
||||
|
||||
|
||||
/* <2ff6de> ../cstrike/dlls/bot/cs_bot_chatter.h:87 */
|
||||
class BotBombStatusMeme: public BotMeme
|
||||
{
|
||||
@ -112,8 +136,16 @@ public:
|
||||
m_state = state;
|
||||
m_pos = pos;
|
||||
}
|
||||
|
||||
public:
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
private:
|
||||
CSGameState::BombState m_state;
|
||||
Vector m_pos;
|
||||
@ -124,7 +156,13 @@ private:
|
||||
class BotFollowMeme: public BotMeme
|
||||
{
|
||||
public:
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
};/* size: 4, cachelines: 1, members: 1 */
|
||||
|
||||
@ -136,7 +174,14 @@ public:
|
||||
{
|
||||
m_pos = pos;
|
||||
}
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
private:
|
||||
Vector m_pos;
|
||||
|
||||
@ -146,7 +191,13 @@ private:
|
||||
class BotWhereBombMeme: public BotMeme
|
||||
{
|
||||
public:
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
};/* size: 4, cachelines: 1, members: 1 */
|
||||
|
||||
@ -154,13 +205,19 @@ public:
|
||||
class BotRequestReportMeme: public BotMeme
|
||||
{
|
||||
public:
|
||||
NOBODY virtual void Interpret(CCSBot *sender, CCSBot *receiver) const;
|
||||
virtual void Interpret(CCSBot *sender, CCSBot *receiver) const; // cause the given bot to act on this meme
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void Interpret_(CCSBot *sender, CCSBot *receiver) const;
|
||||
|
||||
#endif //HOOK_GAMEDLL
|
||||
|
||||
};/* size: 4, cachelines: 1, members: 1 */
|
||||
|
||||
enum BotStatementType
|
||||
{
|
||||
REPORT_VISIBLE_ENEMIES = 0,
|
||||
REPORT_VISIBLE_ENEMIES,
|
||||
REPORT_ENEMY_ACTION,
|
||||
REPORT_MY_CURRENT_TASK,
|
||||
REPORT_MY_INTENTION,
|
||||
@ -171,13 +228,17 @@ enum BotStatementType
|
||||
REPORT_MY_PLAN,
|
||||
REPORT_INFORMATION,
|
||||
REPORT_EMOTE,
|
||||
REPORT_ACKNOWLEDGE,
|
||||
REPORT_ACKNOWLEDGE, // affirmative or negative
|
||||
REPORT_ENEMIES_REMAINING,
|
||||
REPORT_FRIENDLY_FIRE,
|
||||
REPORT_KILLED_FRIEND,
|
||||
//REPORT_ENEMY_LOST
|
||||
|
||||
NUM_BOT_STATEMENT_TYPES,
|
||||
};
|
||||
|
||||
// BotSpeakables are the smallest unit of bot chatter.
|
||||
// They represent a specific wav file of a phrase, and the criteria for which it is useful
|
||||
class BotSpeakable
|
||||
{
|
||||
public:
|
||||
@ -194,53 +255,45 @@ public:
|
||||
typedef std::STD_VECTOR<BotSpeakable *> BotSpeakableVector;
|
||||
typedef std::STD_VECTOR<BotSpeakableVector *> BotVoiceBankVector;
|
||||
|
||||
// The BotPhrase class is a collection of Speakables associated with a name, ID, and criteria
|
||||
class BotPhrase
|
||||
{
|
||||
public:
|
||||
NOBODY BotPhrase(unsigned int id, bool isPlace);
|
||||
NOBODY ~BotPhrase(void);
|
||||
|
||||
NOBODY void InitVoiceBank(int bankIndex);
|
||||
char *GetSpeakable(int bankIndex, float *duration = NULL) const;
|
||||
char *GetSpeakable(int bankIndex, float *duration = NULL) const; // return a random speakable and its duration in seconds that meets the current criteria
|
||||
|
||||
// NOTE: Criteria must be set just before the GetSpeakable() call, since they are shared among all bots
|
||||
void ClearCriteria(void) const;
|
||||
void SetPlaceCriteria(PlaceCriteria place) const;
|
||||
void SetCountCriteria(CountCriteria count) const;
|
||||
void SetPlaceCriteria(PlaceCriteria place) const; // all returned phrases must have this place criteria
|
||||
void SetCountCriteria(CountCriteria count) const; // all returned phrases must have this count criteria
|
||||
|
||||
const char *GetName(void) const { return m_name; }
|
||||
Place GetID(void) const { return m_id; }
|
||||
GameEventType GetRadioEquivalent(void) const { return m_radioEvent; }
|
||||
bool IsImportant(void) const { return m_isImportant; } // return true if this phrase is part of an important statement
|
||||
|
||||
bool IsPlace(void) const { return m_isPlace; }
|
||||
void Randomize(void); // randomly shuffle the speakable order
|
||||
|
||||
#ifndef HOOK_GAMEDLL
|
||||
private:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
const char *GetName(void) const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
Place GetID(void) const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
GameEventType GetRadioEquivalent(void) const
|
||||
{
|
||||
return m_radioEvent;
|
||||
}
|
||||
bool IsImportant(void) const
|
||||
{
|
||||
return m_isImportant;
|
||||
}
|
||||
bool IsPlace(void) const
|
||||
{
|
||||
return m_isPlace;
|
||||
}
|
||||
NOBODY void Randomize(void);
|
||||
//private:
|
||||
public:
|
||||
friend class BotPhraseManager;
|
||||
BotPhrase(unsigned int id, bool isPlace);
|
||||
~BotPhrase(void);
|
||||
|
||||
char *m_name;
|
||||
Place m_id;
|
||||
bool m_isPlace;
|
||||
bool m_isPlace; // true if this is a Place phrase
|
||||
GameEventType m_radioEvent;
|
||||
bool m_isImportant;
|
||||
mutable BotVoiceBankVector m_voiceBank;
|
||||
std::STD_VECTOR<int> m_count;
|
||||
mutable std::STD_VECTOR< int > m_index;
|
||||
int m_numVoiceBanks;
|
||||
bool m_isImportant; // mission-critical statement
|
||||
|
||||
mutable BotVoiceBankVector m_voiceBank; // array of voice banks (arrays of speakables)
|
||||
std::STD_VECTOR<int> m_count; // number of speakables
|
||||
mutable std::STD_VECTOR< int > m_index; // index of next speakable to return
|
||||
int m_numVoiceBanks; // number of voice banks that have been initialized
|
||||
void InitVoiceBank(int bankIndex); // sets up the vector of voice banks for the first bankIndex voice banks
|
||||
|
||||
mutable PlaceCriteria m_placeCriteria;
|
||||
mutable CountCriteria m_countCriteria;
|
||||
|
||||
@ -271,33 +324,30 @@ inline void BotPhrase::SetCountCriteria(CountCriteria count) const
|
||||
class BotPhraseManager
|
||||
{
|
||||
public:
|
||||
NOBODY BotPhraseManager(void);
|
||||
NOBODY ~BotPhraseManager(void);
|
||||
BotPhraseManager(void);
|
||||
~BotPhraseManager(void);
|
||||
|
||||
// initialize phrase system from database file for a specific voice bank (0 is the default voice bank)
|
||||
NOBODY bool Initialize(const char *filename, int bankIndex);
|
||||
bool Initialize(const char *filename, int bankIndex);
|
||||
|
||||
// invoked when round resets
|
||||
void OnRoundRestart(void);
|
||||
|
||||
// invoked when map changes
|
||||
NOBODY void OnMapChange(void);
|
||||
void OnMapChange(void);
|
||||
Place NameToID(const char *name) const;
|
||||
const char *IDToName(Place id) const;
|
||||
|
||||
// given a name, return the associated phrase collection
|
||||
NOBODY const BotPhrase *GetPhrase(const char *name) const;
|
||||
const BotPhrase *GetPhrase(const char *name) const;
|
||||
|
||||
// given a name, return the associated Place phrase collection
|
||||
NOBODY const BotPhrase *GetPlace(const char *name) const;
|
||||
const BotPhrase *GetPlace(const char *name) const;
|
||||
|
||||
// given an id, return the associated Place phrase collection
|
||||
NOBODY const BotPhrase *GetPlace(PlaceCriteria place) const;
|
||||
const BotPhrase *GetPlace(PlaceCriteria place) const;
|
||||
|
||||
const BotPhraseList *GetPlaceList(void) const
|
||||
{
|
||||
return &m_placeList;
|
||||
}
|
||||
const BotPhraseList *GetPlaceList(void) const { return &m_placeList; }
|
||||
|
||||
// return time last statement of given type was emitted by a teammate for the given place
|
||||
float GetPlaceStatementInterval(Place place) const;
|
||||
@ -307,8 +357,6 @@ public:
|
||||
|
||||
#ifndef HOOK_GAMEDLL
|
||||
private:
|
||||
#else
|
||||
public:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
int FindPlaceIndex(Place where) const;
|
||||
@ -338,12 +386,14 @@ inline int BotPhraseManager::FindPlaceIndex(Place where) const
|
||||
if (m_placeStatementHistory[i].placeID == where)
|
||||
return i;
|
||||
}
|
||||
|
||||
if (m_placeCount < MAX_PLACES_PER_MAP)
|
||||
{
|
||||
m_placeStatementHistory[++m_placeCount].placeID = where;
|
||||
m_placeStatementHistory[++m_placeCount].timer.Invalidate();
|
||||
return m_placeCount-1;
|
||||
return m_placeCount - 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -365,6 +415,7 @@ inline float BotPhraseManager::GetPlaceStatementInterval(Place place) const
|
||||
inline void BotPhraseManager::ResetPlaceStatementInterval(Place place) const
|
||||
{
|
||||
int index = FindPlaceIndex(place);
|
||||
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
@ -374,56 +425,38 @@ inline void BotPhraseManager::ResetPlaceStatementInterval(Place place) const
|
||||
m_placeStatementHistory[index].timer.Reset();
|
||||
}
|
||||
|
||||
// Statements are meaningful collections of phrases
|
||||
class BotStatement
|
||||
{
|
||||
public:
|
||||
NOBODY BotStatement(BotChatterInterface *chatter, BotStatementType type, float expireDuration);
|
||||
NOBODY ~BotStatement(void);
|
||||
BotStatement(BotChatterInterface *chatter, BotStatementType type, float expireDuration);
|
||||
~BotStatement(void);
|
||||
|
||||
public:
|
||||
BotChatterInterface *GetChatter(void) const
|
||||
{
|
||||
return m_chatter;
|
||||
}
|
||||
NOBODY CCSBot *GetOwner(void) const;
|
||||
BotStatementType GetType(void) const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
NOBODY bool IsImportant(void) const;
|
||||
bool HasSubject(void) const
|
||||
{
|
||||
return (m_subject != UNDEFINED_SUBJECT);
|
||||
}
|
||||
void SetSubject(int playerID)
|
||||
{
|
||||
m_subject = playerID;
|
||||
}
|
||||
int GetSubject(void) const
|
||||
{
|
||||
return m_subject;
|
||||
}
|
||||
bool HasPlace(void) const
|
||||
{
|
||||
return (GetPlace()) ? true : false;
|
||||
}
|
||||
NOBODY Place GetPlace(void) const;
|
||||
void SetPlace(Place where)
|
||||
{
|
||||
m_place = where;
|
||||
}
|
||||
NOBODY bool HasCount(void) const;
|
||||
NOBODY bool IsRedundant(const BotStatement *say) const;
|
||||
NOBODY bool IsObsolete(void) const;
|
||||
NOBODY void Convert(const BotStatement *say);
|
||||
NOBODY void AppendPhrase(const BotPhrase *phrase);
|
||||
void SetStartTime(float timestamp)
|
||||
{
|
||||
m_startTime = timestamp;
|
||||
}
|
||||
float GetStartTime(void) const
|
||||
{
|
||||
return m_startTime;
|
||||
}
|
||||
BotChatterInterface *GetChatter(void) const { return m_chatter; }
|
||||
CCSBot *GetOwner(void) const;
|
||||
|
||||
BotStatementType GetType(void) const { return m_type; } // return the type of statement this is
|
||||
bool IsImportant(void) const; // return true if this statement is "important" and not personality chatter
|
||||
|
||||
bool HasSubject(void) const { return (m_subject != UNDEFINED_SUBJECT); }
|
||||
void SetSubject(int playerID) { m_subject = playerID; } // who this statement is about
|
||||
int GetSubject(void) const { return m_subject; } // who this statement is about
|
||||
|
||||
bool HasPlace(void) const { return (GetPlace()) ? true : false; }
|
||||
Place GetPlace(void) const; // if this statement refers to a specific place, return that place
|
||||
void SetPlace(Place where) { m_place = where; } // explicitly set place
|
||||
|
||||
bool HasCount(void) const; // return true if this statement has an associated count
|
||||
|
||||
bool IsRedundant(const BotStatement *say) const; // return true if this statement is the same as the given one
|
||||
bool IsObsolete(void) const; // return true if this statement is no longer appropriate to say
|
||||
void Convert(const BotStatement *say); // possibly change what were going to say base on what teammate is saying
|
||||
|
||||
void AppendPhrase(const BotPhrase *phrase);
|
||||
|
||||
void SetStartTime(float timestamp) { m_startTime = timestamp; } // define the earliest time this statement can be spoken
|
||||
float GetStartTime(void) const { return m_startTime; }
|
||||
|
||||
enum ConditionType
|
||||
{
|
||||
@ -433,8 +466,8 @@ public:
|
||||
NUM_CONDITIONS,
|
||||
};
|
||||
|
||||
NOBODY void AddCondition(ConditionType condition);
|
||||
NOBODY bool IsValid(void) const;
|
||||
void AddCondition(ConditionType condition); // conditions must be true for the statement to be spoken
|
||||
bool IsValid(void) const; // verify all attached conditions
|
||||
|
||||
enum ContextType
|
||||
{
|
||||
@ -444,34 +477,33 @@ public:
|
||||
LONG_DELAY,
|
||||
ACCUMULATE_ENEMIES_DELAY,
|
||||
};
|
||||
NOBODY void AppendPhrase(ContextType contextPhrase);
|
||||
void AppendPhrase(ContextType contextPhrase); // special phrases that depend on the context
|
||||
|
||||
bool Update(void); // emit statement over time, return false if statement is done
|
||||
bool IsSpeaking(void) const { return m_isSpeaking; } // return true if this statement is currently being spoken
|
||||
float GetTimestamp(void) const { return m_timestamp; } // get time statement was created (but not necessarily started talking)
|
||||
|
||||
void AttachMeme(BotMeme *meme); // attach a meme to this statement, to be transmitted to other friendly bots when spoken
|
||||
|
||||
NOBODY bool Update(void);
|
||||
NOBODY bool IsSpeaking(void) const
|
||||
{
|
||||
return m_isSpeaking;
|
||||
}
|
||||
NOBODY float GetTimestamp(void) const
|
||||
{
|
||||
return m_timestamp;
|
||||
}
|
||||
NOBODY void AttachMeme(BotMeme *meme);
|
||||
public:
|
||||
friend class BotChatterInterface;
|
||||
|
||||
BotChatterInterface *m_chatter;
|
||||
BotStatement *m_next;
|
||||
BotStatement *m_prev;
|
||||
BotStatementType m_type;
|
||||
int m_subject;
|
||||
Place m_place;
|
||||
BotMeme *m_meme;
|
||||
float m_timestamp;
|
||||
float m_startTime;
|
||||
float m_expireTime;
|
||||
float m_speakTimestamp;
|
||||
bool m_isSpeaking;
|
||||
float m_nextTime;
|
||||
BotChatterInterface *m_chatter; // the chatter system this statement is part of
|
||||
|
||||
BotStatement *m_next, *m_prev; // linked list hooks
|
||||
|
||||
BotStatementType m_type; // what kind of statement this is
|
||||
int m_subject; // who this subject is about
|
||||
Place m_place; // explicit place - note some phrases have implicit places as well
|
||||
BotMeme *m_meme; // a statement can only have a single meme for now
|
||||
|
||||
float m_timestamp; // time when message was created
|
||||
float m_startTime; // the earliest time this statement can be spoken
|
||||
float m_expireTime; // time when this statement is no longer valid
|
||||
float m_speakTimestamp; // time when message began being spoken
|
||||
bool m_isSpeaking; // true if this statement is current being spoken
|
||||
|
||||
float m_nextTime; // time for next phrase to begin
|
||||
|
||||
enum { MAX_BOT_PHRASES = 4 };
|
||||
struct
|
||||
@ -482,115 +514,124 @@ public:
|
||||
const BotPhrase *phrase;
|
||||
ContextType context;
|
||||
};
|
||||
} m_statement[ MAX_BOT_PHRASES ];
|
||||
|
||||
}
|
||||
m_statement[ MAX_BOT_PHRASES ];
|
||||
|
||||
enum { MAX_BOT_CONDITIONS = 4 };
|
||||
|
||||
ConditionType m_condition[ MAX_BOT_CONDITIONS ];
|
||||
ConditionType m_condition[ MAX_BOT_CONDITIONS ]; // conditions that must be true for the statement to be said
|
||||
int m_conditionCount;
|
||||
int m_index;
|
||||
|
||||
int m_index; // m_index refers to the phrase currently being spoken, or -1 if we havent started yet
|
||||
int m_count;
|
||||
|
||||
};/* size: 112, cachelines: 2, members: 18 */
|
||||
|
||||
// This class defines the interface to the bot radio chatter system
|
||||
class BotChatterInterface
|
||||
{
|
||||
public:
|
||||
BotChatterInterface(void) {};
|
||||
|
||||
NOBODY BotChatterInterface(CCSBot *me);
|
||||
NOBODY ~BotChatterInterface();
|
||||
BotChatterInterface(CCSBot *me);
|
||||
~BotChatterInterface();
|
||||
|
||||
NOBODY void Reset(void);
|
||||
NOBODY void Update(void);
|
||||
void Reset(void); // reset to initial state
|
||||
void Update(void); // process ongoing chatter
|
||||
|
||||
NOBODY void OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *other);
|
||||
NOBODY void OnDeath(void);
|
||||
void OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *other); // invoked when event occurs in the game (some events have NULL entities)
|
||||
void OnDeath(void); // invoked when we die
|
||||
|
||||
enum VerbosityType
|
||||
{
|
||||
NORMAL,
|
||||
MINIMAL,
|
||||
RADIO,
|
||||
OFF,
|
||||
NORMAL, // full chatter
|
||||
MINIMAL, // only scenario-critical events
|
||||
RADIO, // use the standard radio instead
|
||||
OFF // no chatter at all
|
||||
};
|
||||
VerbosityType GetVerbosity(void) const; // return our current level of verbosity
|
||||
|
||||
VerbosityType GetVerbosity(void) const;
|
||||
NOBODY CCSBot *GetOwner(void) const
|
||||
{
|
||||
return m_me;
|
||||
}
|
||||
bool IsTalking(void) const;
|
||||
NOBODY float GetRadioSilenceDuration(void);
|
||||
NOBODY void ResetRadioSilenceDuration(void);
|
||||
CCSBot *GetOwner(void) const { return m_me; }
|
||||
bool IsTalking(void) const; // return true if we are currently talking
|
||||
float GetRadioSilenceDuration(void); // return time since any teammate said anything
|
||||
void ResetRadioSilenceDuration(void);
|
||||
|
||||
enum { MUST_ADD = 1 };
|
||||
void AddStatement(BotStatement *statement, bool mustAdd = false); // register a statement for speaking
|
||||
void RemoveStatement(BotStatement *statement); // remove a statement
|
||||
|
||||
NOBODY void AddStatement(BotStatement *statement, bool mustAdd = false);
|
||||
NOBODY void RemoveStatement(BotStatement *statement);
|
||||
BotStatement *GetActiveStatement(void); // returns the statement that is being spoken, or is next to be spoken if no-one is speaking now
|
||||
BotStatement *GetStatement(void) const; // returns our current statement, or NULL if we aren't speaking
|
||||
|
||||
NOBODY BotStatement *GetActiveStatement(void);
|
||||
BotStatement *GetStatement(void) const;
|
||||
|
||||
int GetPitch(void) const
|
||||
{
|
||||
return m_pitch;
|
||||
}
|
||||
int GetPitch(void) const { return m_pitch; }
|
||||
|
||||
// things the bots can say
|
||||
void Say(const char *phraseName, float lifetime = 3.0f, float delay = 0.0f);
|
||||
|
||||
NOBODY void AnnouncePlan(const char *phraseName, Place place);
|
||||
NOBODY void Affirmative(void);
|
||||
NOBODY void Negative(void);
|
||||
void AnnouncePlan(const char *phraseName, Place place);
|
||||
void Affirmative(void);
|
||||
void Negative(void);
|
||||
|
||||
NOBODY void EnemySpotted(void);
|
||||
NOBODY void KilledMyEnemy(int victimID);
|
||||
NOBODY void EnemiesRemaining(void);
|
||||
void EnemySpotted(void); // report enemy sightings
|
||||
void KilledMyEnemy(int victimID);
|
||||
void EnemiesRemaining(void);
|
||||
|
||||
NOBODY void Clear(Place place);
|
||||
NOBODY void ReportIn(void);
|
||||
NOBODY void ReportingIn(void);
|
||||
NOBODY bool NeedBackup(void);
|
||||
NOBODY void PinnedDown(void);
|
||||
NOBODY void Scared(void);
|
||||
NOBODY void HeardNoise(const Vector *pos);
|
||||
NOBODY void TheyPickedUpTheBomb(void);
|
||||
NOBODY void GoingToPlantTheBomb(Place place);
|
||||
NOBODY void BombsiteClear(int zoneIndex);
|
||||
NOBODY void FoundPlantedBomb(int zoneIndex);
|
||||
NOBODY void PlantingTheBomb(Place place);
|
||||
NOBODY void SpottedBomber(CBasePlayer *bomber);
|
||||
NOBODY void SpottedLooseBomb(CBaseEntity *bomb);
|
||||
NOBODY void GuardingLooseBomb(CBaseEntity *bomb);
|
||||
NOBODY void RequestBombLocation(void);
|
||||
NOBODY void GuardingHostages(Place place, bool isPlan);
|
||||
NOBODY void GuardingHostageEscapeZone(bool isPlan);
|
||||
NOBODY void HostagesBeingTaken(void);
|
||||
NOBODY void HostagesTaken(void);
|
||||
NOBODY void TalkingToHostages(void);
|
||||
NOBODY void EscortingHostages(void);
|
||||
NOBODY void HostageDown(void);
|
||||
NOBODY void CelebrateWin(void);
|
||||
NOXREF void Clear(Place place);
|
||||
|
||||
NOBODY void Encourage(const char *phraseName, float repeatInterval = 10.0f, float lifetime = 3.0f);
|
||||
NOBODY void KilledFriend(void);
|
||||
NOBODY void FriendlyFire(void);
|
||||
public:
|
||||
static CountdownTimer m_encourageTimer;
|
||||
static IntervalTimer m_radioSilenceInterval[2];
|
||||
void ReportIn(void); // ask for current situation
|
||||
void ReportingIn(void); // report current situation
|
||||
|
||||
bool NeedBackup(void);
|
||||
void PinnedDown(void);
|
||||
void Scared(void);
|
||||
void HeardNoise(const Vector *pos);
|
||||
|
||||
void TheyPickedUpTheBomb(void);
|
||||
void GoingToPlantTheBomb(Place place);
|
||||
void BombsiteClear(int zoneIndex);
|
||||
void FoundPlantedBomb(int zoneIndex);
|
||||
void PlantingTheBomb(Place place);
|
||||
void SpottedBomber(CBasePlayer *bomber);
|
||||
void SpottedLooseBomb(CBaseEntity *bomb);
|
||||
NOXREF void GuardingLooseBomb(CBaseEntity *bomb);
|
||||
void RequestBombLocation(void);
|
||||
|
||||
void GuardingHostages(Place place, bool isPlan);
|
||||
void GuardingHostageEscapeZone(bool isPlan);
|
||||
void HostagesBeingTaken(void);
|
||||
void HostagesTaken(void);
|
||||
void TalkingToHostages(void);
|
||||
void EscortingHostages(void);
|
||||
NOXREF void HostageDown(void);
|
||||
|
||||
void CelebrateWin(void);
|
||||
|
||||
void Encourage(const char *phraseName, float repeatInterval = 10.0f, float lifetime = 3.0f); // "encourage" the player to do the scenario
|
||||
|
||||
void KilledFriend(void);
|
||||
void FriendlyFire(void);
|
||||
|
||||
bool SeesAtLeastOneEnemy(void) const { return m_seeAtLeastOneEnemy; }
|
||||
|
||||
#ifndef HOOK_GAMEDLL
|
||||
private:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
NOBODY void ReportEnemies(void);
|
||||
NOBODY bool ShouldSpeak(void) const;
|
||||
BotStatement *m_statementList; // list of all active/pending messages for this bot
|
||||
void ReportEnemies(void); // track nearby enemy count and generate enemy activity statements
|
||||
bool ShouldSpeak(void) const; // return true if we speaking makes sense now
|
||||
|
||||
BotStatement *m_statementList;
|
||||
CCSBot *m_me;
|
||||
CCSBot *m_me; // the bot this chatter is for
|
||||
|
||||
bool m_seeAtLeastOneEnemy;
|
||||
float m_timeWhenSawFirstEnemy;
|
||||
bool m_reportedEnemies;
|
||||
bool m_requestedBombLocation;
|
||||
bool m_requestedBombLocation; // true if we already asked where the bomb has been planted
|
||||
|
||||
int m_pitch;
|
||||
|
||||
static IntervalTimer IMPL(m_radioSilenceInterval)[2]; // one timer for each team
|
||||
|
||||
IntervalTimer m_needBackupInterval;
|
||||
IntervalTimer m_spottedBomberInterval;
|
||||
IntervalTimer m_scaredInterval;
|
||||
@ -598,6 +639,8 @@ private:
|
||||
CountdownTimer m_spottedLooseBombTimer;
|
||||
CountdownTimer m_heardNoiseTimer;
|
||||
CountdownTimer m_escortingHostageTimer;
|
||||
static CountdownTimer IMPL(m_encourageTimer); // timer to know when we can "encourage" the human player again - shared by all bots
|
||||
|
||||
};/* size: 64, cachelines: 1, members: 16 */
|
||||
|
||||
/* <2fec2d> ../cstrike/dlls/bot/cs_bot_chatter.h:572 */
|
||||
@ -623,8 +666,11 @@ inline BotChatterInterface::VerbosityType BotChatterInterface::GetVerbosity(void
|
||||
/* <2fec4a> ../cstrike/dlls/bot/cs_bot_chatter.h:590 */
|
||||
inline bool BotChatterInterface::IsTalking(void) const
|
||||
{
|
||||
if (m_statementList)
|
||||
if (m_statementList != NULL)
|
||||
{
|
||||
return m_statementList->IsSpeaking();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -647,14 +693,14 @@ extern CBaseEntity *g_pSelectedZombieSpawn;
|
||||
/* <5c4dcf> ../cstrike/dlls/bot/cs_bot_chatter.h:604 */
|
||||
inline void BotChatterInterface::Say(const char *phraseName, float lifetime, float delay)
|
||||
{
|
||||
/*BotStatement *say = new BotStatement(this, REPORT_MY_INTENTION, lifetime);
|
||||
BotStatement *say = new BotStatement(this, REPORT_MY_INTENTION, lifetime);
|
||||
|
||||
say->AppendPhrase(TheBotPhrases->GetPhrase(phraseName));
|
||||
|
||||
if (delay > 0.0f)
|
||||
say->SetStartTime(gpGlobals->curtime + delay);
|
||||
say->SetStartTime(gpGlobals->time + delay);
|
||||
|
||||
AddStatement(say);*/
|
||||
AddStatement(say);
|
||||
}
|
||||
|
||||
const Vector *GetRandomSpotAtPlace(Place place);
|
||||
@ -664,12 +710,12 @@ const Vector *GetRandomSpotAtPlace(Place place);
|
||||
typedef void (BotStatement::*APPEND_PHRASE_CONTEXT)(BotStatement::ContextType);
|
||||
typedef void (BotStatement::*APPEND_PHRASE_BOTPHRASE)(const BotPhrase *);
|
||||
|
||||
typedef const BotPhraseManager *(BotPhraseManager::*GET_PLACE_NAME)(const char *name) const;
|
||||
typedef const BotPhraseManager *(BotPhraseManager::*GET_PLACE_PLACE)(PlaceCriteria place) const;
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
typedef const BotPhrase *(BotPhraseManager::*GET_PLACE_NAME)(const char *name) const;
|
||||
typedef const BotPhrase *(BotPhraseManager::*GET_PLACE_PLACE)(PlaceCriteria place) const;
|
||||
|
||||
// refs
|
||||
extern void (*pBotPhrase__Randomize)(void);
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
#endif // CS_BOT_CHATTER_H
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <31d087> ../cstrike/dlls/bot/cs_bot_event.cpp:22 */
|
||||
void CCSBot::__MAKE_VHOOK(OnEvent)(GameEventType event, CBaseEntity *entity, CBaseEntity *other)
|
||||
NOBODY void CCSBot::__MAKE_VHOOK(OnEvent)(GameEventType event, CBaseEntity *entity, CBaseEntity *other)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 63
|
||||
|
@ -1,7 +1,76 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/*
|
||||
* Globals initialization
|
||||
*/
|
||||
#ifndef HOOK_GAMEDLL
|
||||
|
||||
cvar_t cv_bot_traceview = { "bot_traceview", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_stop = { "bot_stop", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_show_nav = { "bot_show_nav", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_show_danger = { "bot_show_danger", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_nav_edit = { "bot_nav_edit", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_nav_zdraw = { "bot_nav_zdraw", "4", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_walk = { "bot_walk", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_difficulty = { "bot_difficulty", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_debug = { "bot_debug", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_quicksave = { "bot_quicksave", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_quota = { "bot_quota", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_quota_match = { "bot_quota_match", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_prefix = { "bot_prefix", "", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_rogues = { "bot_allow_rogues", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_pistols = { "bot_allow_pistols", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_shotguns = { "bot_allow_shotguns", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_sub_machine_guns = { "bot_allow_sub_machine_guns", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_rifles = { "bot_allow_rifles", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_machine_guns = { "bot_allow_machine_guns", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_grenades = { "bot_allow_grenades", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_snipers = { "bot_allow_snipers", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_allow_shield = { "bot_allow_shield", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_join_team = { "bot_join_team", "any", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_join_after_player = { "bot_join_after_player", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_auto_vacate = { "bot_auto_vacate", "1", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_zombie = { "bot_zombie", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_defer_to_human = { "bot_defer_to_human", "0", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_chatter = { "bot_chatter", "normal", FCVAR_SERVER, 0.0f, NULL };
|
||||
cvar_t cv_bot_profile_db = { "bot_profile_db", "BotProfile.db", FCVAR_SERVER, 0.0f, NULL };
|
||||
|
||||
#else // HOOK_GAMEDLL
|
||||
|
||||
cvar_t cv_bot_traceview;
|
||||
cvar_t cv_bot_stop;
|
||||
cvar_t cv_bot_show_nav;
|
||||
cvar_t cv_bot_show_danger;
|
||||
cvar_t cv_bot_nav_edit;
|
||||
cvar_t cv_bot_nav_zdraw;
|
||||
cvar_t cv_bot_walk;
|
||||
cvar_t cv_bot_difficulty;
|
||||
cvar_t cv_bot_debug;
|
||||
cvar_t cv_bot_quicksave;
|
||||
cvar_t cv_bot_quota;
|
||||
cvar_t cv_bot_quota_match;
|
||||
cvar_t cv_bot_prefix;
|
||||
cvar_t cv_bot_allow_rogues;
|
||||
cvar_t cv_bot_allow_pistols;
|
||||
cvar_t cv_bot_allow_shotguns;
|
||||
cvar_t cv_bot_allow_sub_machine_guns;
|
||||
cvar_t cv_bot_allow_rifles;
|
||||
cvar_t cv_bot_allow_machine_guns;
|
||||
cvar_t cv_bot_allow_grenades;
|
||||
cvar_t cv_bot_allow_snipers;
|
||||
cvar_t cv_bot_allow_shield;
|
||||
cvar_t cv_bot_join_team;
|
||||
cvar_t cv_bot_join_after_player;
|
||||
cvar_t cv_bot_auto_vacate;
|
||||
cvar_t cv_bot_zombie;
|
||||
cvar_t cv_bot_defer_to_human;
|
||||
cvar_t cv_bot_chatter;
|
||||
cvar_t cv_bot_profile_db;
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
/* <333bca> ../cstrike/dlls/bot/cs_bot_init.cpp:57 */
|
||||
NOBODY void InstallBotControl(void)
|
||||
void InstallBotControl(void)
|
||||
{
|
||||
if (TheBots != NULL)
|
||||
{
|
||||
@ -11,6 +80,8 @@ NOBODY void InstallBotControl(void)
|
||||
TheBots = new CCSBotManager;
|
||||
}
|
||||
|
||||
// Engine callback for custom server commands
|
||||
|
||||
/* <333cb3> ../cstrike/dlls/bot/cs_bot_init.cpp:68 */
|
||||
void Bot_ServerCommand(void)
|
||||
{
|
||||
@ -58,52 +129,35 @@ void Bot_RegisterCvars(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor
|
||||
|
||||
/* <333d1e> ../cstrike/dlls/bot/cs_bot_init.cpp:129 */
|
||||
//CCSBot::CCSBot(void)
|
||||
//{
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// IdleState(IdleState *const this); // 129
|
||||
// MoveToState(MoveToState *const this); // 129
|
||||
// HuntState(HuntState *const this); // 129
|
||||
// FetchBombState(FetchBombState *const this); // 129
|
||||
// AttackState(AttackState *const this); // 129
|
||||
// InvestigateNoiseState(InvestigateNoiseState *const this); // 129
|
||||
// BuyState(BuyState *const this); // 129
|
||||
// PlantBombState(PlantBombState *const this); // 129
|
||||
// DefuseBombState(DefuseBombState *const this); // 129
|
||||
// HideState(HideState *const this); // 129
|
||||
// EscapeFromBombState(EscapeFromBombState *const this); // 129
|
||||
// FollowState(FollowState *const this); // 129
|
||||
// UseEntityState(UseEntityState *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// IntervalTimer(IntervalTimer *const this); // 129
|
||||
// _List_iterator(_List_iterator<CNavArea*> *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
// CountdownTimer(CountdownTimer *const this); // 129
|
||||
//}
|
||||
CCSBot::CCSBot(void) : m_chatter(this), m_gameState(this)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// Prepare bot for action
|
||||
|
||||
/* <3342ac> ../cstrike/dlls/bot/cs_bot_init.cpp:137 */
|
||||
NOBODY bool CCSBot::__MAKE_VHOOK(Initialize)(const BotProfile *profile)
|
||||
bool CCSBot::__MAKE_VHOOK(Initialize)(const BotProfile *profile)
|
||||
{
|
||||
// extend
|
||||
CBot::Initialize(profile);
|
||||
|
||||
// CS bot initialization
|
||||
m_diedLastRound = false;
|
||||
m_morale = POSITIVE;
|
||||
m_morale = POSITIVE; // starting a new round makes everyone a little happy
|
||||
|
||||
m_combatRange = RANDOM_FLOAT(325, 425);
|
||||
|
||||
m_navNodeList = NULL;
|
||||
m_currentNode = NULL;
|
||||
|
||||
m_combatRange = RANDOM_FLOAT(325, 425);
|
||||
m_name[0] = '\0';
|
||||
m_safeTime = m_profile->GetAggression() * 5 + 15;
|
||||
// set initial safe time guess for this map
|
||||
m_safeTime = 15.0f + 5.0f * GetProfile()->GetAggression();
|
||||
|
||||
m_name[0] = '\000';
|
||||
|
||||
ResetValues();
|
||||
StartNormalProcess();
|
||||
@ -111,18 +165,13 @@ NOBODY bool CCSBot::__MAKE_VHOOK(Initialize)(const BotProfile *profile)
|
||||
return true;
|
||||
}
|
||||
|
||||
void (*pCCSBot__ResetValues)(void);
|
||||
// Reset internal data to initial state
|
||||
|
||||
/* <3341dc> ../cstrike/dlls/bot/cs_bot_init.cpp:167 */
|
||||
NOBODY void __declspec(naked) CCSBot::ResetValues(void)
|
||||
void CCSBot::ResetValues(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
jmp pCCSBot__ResetValues
|
||||
}
|
||||
/*
|
||||
m_chatter.Reset();//TODO: Reverse me
|
||||
m_gameState.Reset();//TODO: Reverse me
|
||||
m_chatter.Reset();
|
||||
m_gameState.Reset();
|
||||
|
||||
m_avoid = NULL;
|
||||
m_avoidTimestamp = 0.0f;
|
||||
@ -136,28 +185,28 @@ NOBODY void __declspec(naked) CCSBot::ResetValues(void)
|
||||
|
||||
m_pathLength = 0;
|
||||
m_pathIndex = 0;
|
||||
|
||||
m_areaEnteredTimestamp = 0.0f;
|
||||
m_currentArea = NULL;
|
||||
m_lastKnownArea = NULL;
|
||||
|
||||
m_avoidFriendTimer.Invalidate();
|
||||
|
||||
m_isFriendInTheWay = false;
|
||||
m_isWaitingBehindFriend = false;
|
||||
|
||||
m_disposition = ENGAGE_AND_INVESTIGATE;
|
||||
|
||||
m_enemy = NULL;
|
||||
|
||||
m_isWaitingToTossGrenade = false;
|
||||
m_wasSafe = true;
|
||||
|
||||
m_nearbyEnemyCount = 0;
|
||||
m_enemyPlace = 0;
|
||||
m_nearbyFriendCount = 0;
|
||||
|
||||
m_closestVisibleFriend = NULL;
|
||||
m_closestVisibleHumanFriend = NULL;
|
||||
|
||||
for (int w = 0; w < ARRAYSIZE(m_watchInfo); w++)
|
||||
for (int w = 0; w < ARRAYSIZE(m_watchInfo); ++w)
|
||||
{
|
||||
m_watchInfo[w].timestamp = 0.0f;
|
||||
m_watchInfo[w].isEnemy = false;
|
||||
@ -165,24 +214,20 @@ NOBODY void __declspec(naked) CCSBot::ResetValues(void)
|
||||
|
||||
m_isEnemyVisible = false;
|
||||
m_visibleEnemyParts = NONE;
|
||||
|
||||
m_lastSawEnemyTimestamp = 0.0f;
|
||||
m_firstSawEnemyTimestamp = 0.0f;
|
||||
m_currentEnemyAcquireTimestamp = 0.0f;
|
||||
|
||||
m_isLastEnemyDead = true;
|
||||
|
||||
m_attacker = NULL;
|
||||
m_attackedTimestamp = 0.0f;
|
||||
m_enemyDeathTimestamp = 0.0f;
|
||||
m_lastVictimID = 0;
|
||||
m_isAimingAtEnemy = false;
|
||||
|
||||
m_fireWeaponTimestamp = 0.0f;
|
||||
m_equipTimer.Invalidate();
|
||||
|
||||
m_isFollowing = false;
|
||||
m_leader = NULL;
|
||||
|
||||
m_followTimestamp = 0.0f;
|
||||
m_allowAutoFollowTime = 0.0f;
|
||||
|
||||
@ -193,47 +238,40 @@ NOBODY void __declspec(naked) CCSBot::ResetValues(void)
|
||||
|
||||
m_lookAroundStateTimestamp = 0.0f;
|
||||
m_inhibitLookAroundTimestamp = 0.0f;
|
||||
|
||||
m_lookPitch = 0.0f;
|
||||
m_lookPitchVel = 0.0f;
|
||||
m_lookYaw = 0.0f;
|
||||
m_lookYawVel = 0.0f;
|
||||
|
||||
m_aimOffsetTimestamp = 0.0f;
|
||||
m_aimSpreadTimestamp = 0.0f;
|
||||
|
||||
m_lookAtSpotState = NOT_LOOKING_AT_SPOT;
|
||||
m_spotEncounter = NULL;
|
||||
|
||||
m_spotEncounter = NULL;
|
||||
m_spotCheckTimestamp = 0.0f;
|
||||
m_peripheralTimestamp = 0.0f;
|
||||
|
||||
m_avgVelIndex = 0;
|
||||
m_avgVelCount = 0;
|
||||
|
||||
if (pev)
|
||||
{
|
||||
m_lastOrigin = pev->origin;
|
||||
}
|
||||
else
|
||||
m_lastOrigin = Vector(0, 0, 0);
|
||||
m_lastOrigin = (pev != NULL) ? pev->origin : Vector(0, 0, 0);
|
||||
|
||||
m_lastRadioCommand = EVENT_INVALID;
|
||||
|
||||
m_lastRadioRecievedTimestamp = 0.0f;
|
||||
m_lastRadioSentTimestamp = 0.0f;
|
||||
m_radioSubject = NULL;
|
||||
|
||||
m_noisePosition = Vector(0, 0, 0);
|
||||
m_noiseTimestamp = 0.0f;
|
||||
m_noiseCheckTimestamp = 0.0f;
|
||||
|
||||
m_voiceFeedbackEndTimestamp = 0.0f;
|
||||
|
||||
m_hostageEscortCount = 0;
|
||||
m_hostageEscortCountTimestamp = 0.0f;
|
||||
|
||||
m_noisePosition = Vector(0, 0, 0);
|
||||
m_noiseTimestamp = 0.0f;
|
||||
m_noiseCheckTimestamp = 0.0f;
|
||||
m_isNoiseTravelRangeChecked = false;
|
||||
m_stateTimestamp = 0.0f;
|
||||
|
||||
m_stateTimestamp = 0.0f;
|
||||
m_task = SEEK_AND_DESTROY;
|
||||
m_taskEntity = NULL;
|
||||
|
||||
@ -245,38 +283,49 @@ NOBODY void __declspec(naked) CCSBot::ResetValues(void)
|
||||
|
||||
StandUp();
|
||||
Run();
|
||||
|
||||
m_pathLadder = NULL;
|
||||
m_mustRunTimer.Invalidate();
|
||||
m_repathTimer.Invalidate();
|
||||
m_pathLadder = NULL;
|
||||
|
||||
m_huntState.ClearHuntArea();
|
||||
|
||||
// adjust morale - if we died, our morale decreased,
|
||||
// but if we live, no adjustement (round win/loss also adjusts morale
|
||||
if (m_diedLastRound)
|
||||
{
|
||||
DecreaseMorale();
|
||||
}
|
||||
|
||||
m_diedLastRound = false;
|
||||
|
||||
// IsRogue() randomly changes this
|
||||
m_isRogue = false;
|
||||
|
||||
m_surpriseDelay = 0.0f;
|
||||
m_surpriseTimestamp = 0.0f;
|
||||
|
||||
// even though these are EHANDLEs, they need to be NULL-ed
|
||||
m_goalEntity = NULL;
|
||||
m_avoid = NULL;
|
||||
m_enemy = NULL;
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
for (int i = 0; i < MAX_ENEMY_QUEUE; ++i)
|
||||
{
|
||||
m_enemyQueue[i].player = NULL;
|
||||
m_enemyQueue[i].isReloading = false;
|
||||
m_enemyQueue[i].isProtectedByShield = false;
|
||||
}
|
||||
#endif // REGAMEDLL_FIXES
|
||||
|
||||
// start in idle state
|
||||
StopAttacking();//TODO: Reverse me
|
||||
Idle();//TODO: Reverse me
|
||||
*/
|
||||
StopAttacking();
|
||||
Idle();
|
||||
}
|
||||
|
||||
// Called when bot is placed in map, and when bots are reset after a round ends.
|
||||
// NOTE: For some reason, this can be called twice when a bot is added.
|
||||
|
||||
/* <3342e4> ../cstrike/dlls/bot/cs_bot_init.cpp:336 */
|
||||
NOBODY void CCSBot::__MAKE_VHOOK(SpawnBot)(void)
|
||||
void CCSBot::__MAKE_VHOOK(SpawnBot)(void)
|
||||
{
|
||||
CCSBotManager *ctrl = TheCSBots();
|
||||
|
||||
@ -288,7 +337,7 @@ NOBODY void CCSBot::__MAKE_VHOOK(SpawnBot)(void)
|
||||
SetState(&m_buyState);
|
||||
SetTouch(&CCSBot::BotTouch);
|
||||
|
||||
if (!TheNavAreaList.empty() && !ctrl->IsLearningMap())
|
||||
if (TheNavAreaList.empty() && !ctrl->IsLearningMap())
|
||||
{
|
||||
ctrl->SetLearningMapFlag();
|
||||
StartLearnProcess();
|
||||
@ -296,8 +345,11 @@ NOBODY void CCSBot::__MAKE_VHOOK(SpawnBot)(void)
|
||||
}
|
||||
|
||||
/* <3338f7> ../cstrike/dlls/bot/cs_bot_init.cpp:366 */
|
||||
NOBODY void CCSBot::__MAKE_VHOOK(RoundRespawn)(void)
|
||||
void CCSBot::__MAKE_VHOOK(RoundRespawn)(void)
|
||||
{
|
||||
// do the normal player spawn process
|
||||
CBasePlayer::RoundRespawn();
|
||||
EndVoiceFeedback();
|
||||
}
|
||||
|
||||
/* <334332> ../cstrike/dlls/bot/cs_bot_init.cpp:378 */
|
||||
@ -305,11 +357,9 @@ void CCSBot::Disconnect(void)
|
||||
{
|
||||
EndVoiceFeedback();
|
||||
|
||||
if (m_processMode)
|
||||
if (m_processMode != PROCESS_NORMAL)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgBotProgress);
|
||||
WRITE_BYTE(FLAG_PROGRESS_HIDE);
|
||||
MESSAGE_END();
|
||||
hideProgressMeter();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,64 +1,126 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/*
|
||||
* Globals initialization
|
||||
*/
|
||||
#ifndef HOOK_GAMEDLL
|
||||
|
||||
const float updateTimesliceDuration = 0.0f;
|
||||
|
||||
#else
|
||||
|
||||
const float updateTimesliceDuration = 0.0;//TODO: what value?? check it.
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
const float updateTimesliceDuration = 0.5f;
|
||||
|
||||
int _navAreaCount;
|
||||
int _currentIndex;
|
||||
|
||||
/* <343cbe> ../cstrike/dlls/bot/cs_bot_learn.cpp:95 */
|
||||
NOBODY inline class CNavNode *LadderEndSearch(CBaseEntity *entity, const Vector *pos, NavDirType mountDir)
|
||||
inline CNavNode *LadderEndSearch(CBaseEntity *entity, const Vector *pos, NavDirType mountDir)
|
||||
{
|
||||
// {
|
||||
// Vector center; // 97
|
||||
// {
|
||||
// int d; // 103
|
||||
// {
|
||||
// Vector tryPos; // 105
|
||||
// Vector tryNormal; // 118
|
||||
// float const fudge; // 123
|
||||
// TraceResult result; // 124
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Vector center = *pos;
|
||||
AddDirectionVector(¢er, mountDir, HalfHumanWidth);
|
||||
|
||||
// Test the ladder dismount point first, then each cardinal direction one and two steps away
|
||||
|
||||
for (int d = (-1); d < 2 * NUM_DIRECTIONS; ++d)
|
||||
{
|
||||
Vector tryPos = center;
|
||||
|
||||
if (d >= NUM_DIRECTIONS)
|
||||
AddDirectionVector(&tryPos, (NavDirType)(d - NUM_DIRECTIONS), GenerationStepSize * 2.0f);
|
||||
else if (d >= 0)
|
||||
AddDirectionVector(&tryPos, (NavDirType)d, GenerationStepSize);
|
||||
|
||||
// step up a rung, to ensure adjacent floors are below us
|
||||
tryPos.z += GenerationStepSize;
|
||||
SnapToGrid(&tryPos);
|
||||
|
||||
// adjust height to account for sloping areas
|
||||
Vector tryNormal;
|
||||
if (GetGroundHeight(&tryPos, &tryPos.z, &tryNormal) == false)
|
||||
continue;
|
||||
|
||||
// make sure this point is not on the other side of a wall
|
||||
const float fudge = 2.0f;
|
||||
TraceResult result;
|
||||
UTIL_TraceLine(center + Vector(0, 0, fudge), tryPos + Vector(0, 0, fudge), ignore_monsters, dont_ignore_glass, ENT(entity->pev), &result);
|
||||
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
if (result.flFraction != 1.0f)
|
||||
continue;
|
||||
#else
|
||||
if (result.flFraction != 1.0f || result.fStartSolid)
|
||||
continue;
|
||||
#endif // REGAMEDLL_ADD
|
||||
|
||||
// if no node exists here, create one and continue the search
|
||||
if (CNavNode::GetNode(&tryPos) == NULL)
|
||||
{
|
||||
return new CNavNode(&tryPos, &tryNormal, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* <343a56> ../cstrike/dlls/bot/cs_bot_learn.cpp:30 */
|
||||
NOBODY CNavNode *CCSBot::AddNode(const Vector *destPos, const Vector *normal, NavDirType dir, CNavNode *source)
|
||||
CNavNode *CCSBot::AddNode(const Vector *destPos, const Vector *normal, NavDirType dir, CNavNode *source)
|
||||
{
|
||||
// {
|
||||
// class CNavNode *node; // 34
|
||||
// bool useNew; // 37
|
||||
// float const zTolerance; // 48
|
||||
// TraceResult result; // 63
|
||||
// Vector floor; // 64
|
||||
// Vector ceiling; // 64
|
||||
// bool crouch; // 65
|
||||
// MarkAsVisited(CNavNode *const this,
|
||||
// enum NavDirType dir); // 52
|
||||
// {
|
||||
// float y; // 66
|
||||
// {
|
||||
// float x; // 68
|
||||
// }
|
||||
// }
|
||||
// SetAttributes(CNavNode *const this,
|
||||
// unsigned char bits); // 89
|
||||
// }
|
||||
// check if a node exists at this location
|
||||
CNavNode *node = const_cast<CNavNode *>(CNavNode::GetNode(destPos));
|
||||
|
||||
// if no node exists, create one
|
||||
bool useNew = false;
|
||||
if (node == NULL)
|
||||
{
|
||||
node = new CNavNode(destPos, normal, source);
|
||||
useNew = true;
|
||||
}
|
||||
|
||||
// connect source node to new node
|
||||
source->ConnectTo(node, dir);
|
||||
|
||||
// optimization: if deltaZ changes very little, assume connection is commutative
|
||||
const float zTolerance = 10.0f; // 50.0f;
|
||||
if (fabs(source->GetPosition()->z - destPos->z) < zTolerance)
|
||||
{
|
||||
node->ConnectTo(source, OppositeDirection(dir));
|
||||
node->MarkAsVisited(OppositeDirection(dir));
|
||||
}
|
||||
|
||||
if (useNew)
|
||||
{
|
||||
// new node becomes current node
|
||||
m_currentNode = node;
|
||||
}
|
||||
|
||||
Vector ceiling;
|
||||
Vector floor;
|
||||
TraceResult result;
|
||||
|
||||
bool crouch = false;
|
||||
const float epsilon = 0.1f;
|
||||
|
||||
for (float y = -16.0f; y <= 16.0f + epsilon; y += 16.0f)
|
||||
{
|
||||
for (float x = -16.0f; x <= 16.0f + epsilon; x += 16.0f)
|
||||
{
|
||||
floor = *destPos + Vector(x, y, 5.0f);
|
||||
ceiling = *destPos + Vector(x, y, 72.0f - epsilon);
|
||||
|
||||
UTIL_TraceLine(floor, ceiling, ignore_monsters, dont_ignore_glass, ENT(pev), &result);
|
||||
|
||||
if (result.flFraction != 1.0f)
|
||||
{
|
||||
crouch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (crouch)
|
||||
{
|
||||
node->SetAttributes(NAV_CROUCH);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/* <343b40> ../cstrike/dlls/bot/cs_bot_learn.cpp:150 */
|
||||
NOXREF void drawProgressMeter(float progress, char *title)
|
||||
void drawProgressMeter(float progress, char *title)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgBotProgress);
|
||||
WRITE_BYTE(FLAG_PROGRESS_DRAW);
|
||||
@ -68,7 +130,7 @@ NOXREF void drawProgressMeter(float progress, char *title)
|
||||
}
|
||||
|
||||
/* <3435ce> ../cstrike/dlls/bot/cs_bot_learn.cpp:159 */
|
||||
NOXREF void startProgressMeter(const char *title)
|
||||
void startProgressMeter(const char *title)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgBotProgress);
|
||||
WRITE_BYTE(FLAG_PROGRESS_START);
|
||||
@ -77,7 +139,7 @@ NOXREF void startProgressMeter(const char *title)
|
||||
}
|
||||
|
||||
/* <3435a8> ../cstrike/dlls/bot/cs_bot_learn.cpp:167 */
|
||||
NOXREF void hideProgressMeter(void)
|
||||
void hideProgressMeter(void)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgBotProgress);
|
||||
WRITE_BYTE(FLAG_PROGRESS_HIDE);
|
||||
@ -85,115 +147,228 @@ NOXREF void hideProgressMeter(void)
|
||||
}
|
||||
|
||||
/* <343b63> ../cstrike/dlls/bot/cs_bot_learn.cpp:182 */
|
||||
NOBODY void CCSBot::StartLearnProcess(void)
|
||||
void CCSBot::StartLearnProcess(void)
|
||||
{
|
||||
// {
|
||||
// Vector pos; // 192
|
||||
// Vector normal; // 195
|
||||
// startProgressMeter(const char *title); // 184
|
||||
// drawProgressMeter(float progress,
|
||||
// char *title); // 185
|
||||
// Vector(Vector *const this,
|
||||
// const Vector &v); // 192
|
||||
// SnapToGrid(Vector *pos); // 193
|
||||
// StartNormalProcess(CCSBot *const this); // 199
|
||||
// }
|
||||
|
||||
Vector pos;
|
||||
Vector normal;
|
||||
|
||||
startProgressMeter("#CZero_LearningMap");
|
||||
drawProgressMeter(0, "#CZero_LearningMap");
|
||||
BuildLadders();
|
||||
|
||||
Vector normal;
|
||||
Vector pos = pev->origin;
|
||||
|
||||
SnapToGrid(&pos.x);
|
||||
SnapToGrid(&pos.y);
|
||||
|
||||
if (!GetGroundHeight(&pos, &pos.z, &normal))
|
||||
{
|
||||
CONSOLE_ECHO("ERROR: Start position invalid\n\n");
|
||||
m_processMode = PROCESS_NORMAL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentNode = new CNavNode(&pos, &normal);
|
||||
m_goalPosition = pev->origin;
|
||||
m_processMode = PROCESS_LEARN;
|
||||
}
|
||||
|
||||
// Search the world and build a map of possible movements.
|
||||
// The algorithm begins at the bot's current location, and does a recursive search
|
||||
// outwards, tracking all valid steps and generating a directed graph of CNavNodes.
|
||||
// Sample the map one "step" in a cardinal direction to learn the map.
|
||||
// Returns true if sampling needs to continue, or false if done.
|
||||
|
||||
/* <343d37> ../cstrike/dlls/bot/cs_bot_learn.cpp:217 */
|
||||
NOBODY bool CCSBot::LearnStep(void)
|
||||
bool CCSBot::LearnStep(void)
|
||||
{
|
||||
// {
|
||||
// int dir; // 249
|
||||
// {
|
||||
// float feetOffset; // 256
|
||||
// Vector pos; // 259
|
||||
// int cx; // 262
|
||||
// int cy; // 263
|
||||
// TraceResult result; // 283
|
||||
// Vector from; // 284
|
||||
// Vector to; // 284
|
||||
// Vector toNormal; // 289
|
||||
// Vector fromOrigin; // 298
|
||||
// Vector toOrigin; // 299
|
||||
// bool walkable; // 303
|
||||
// IsEntityWalkable(entvars_t *entity,
|
||||
// unsigned int flags); // 362
|
||||
// {
|
||||
// float toGround; // 309
|
||||
// float fromGround; // 310
|
||||
// float epsilon; // 312
|
||||
// {
|
||||
// Vector delta; // 322
|
||||
// float const inc; // 323
|
||||
// float along; // 324
|
||||
// bool done; // 325
|
||||
// float ground; // 326
|
||||
// Vector normal; // 327
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 322
|
||||
// {
|
||||
// Vector p; // 333
|
||||
// operator*(const Vector *const this,
|
||||
// float fl); // 343
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 343
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// VARS(edict_t *pent); // 362
|
||||
// GetFeetZ(const class CCSBot *const this); // 256
|
||||
// Vector(Vector *const this,
|
||||
// const Vector &v); // 259
|
||||
// MarkAsVisited(CNavNode *const this,
|
||||
// enum NavDirType dir); // 280
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 294
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 298
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 299
|
||||
// {
|
||||
// class CNavNode *newNode; // 376
|
||||
// AddNode(CCSBot *const this,
|
||||
// const Vector *destPos,
|
||||
// const Vector *normal,
|
||||
// enum NavDirType dir,
|
||||
// class CNavNode *source); // 376
|
||||
// }
|
||||
// }
|
||||
// HasVisited(CNavNode *const this,
|
||||
// enum NavDirType dir); // 251
|
||||
// }
|
||||
// {
|
||||
// iterator iter; // 225
|
||||
// {
|
||||
// class CNavLadder *ladder; // 227
|
||||
// LadderEndSearch(CBaseEntity *entity,
|
||||
// const Vector *pos,
|
||||
// enum NavDirType mountDir); // 230
|
||||
// LadderEndSearch(CBaseEntity *entity,
|
||||
// const Vector *pos,
|
||||
// enum NavDirType mountDir); // 234
|
||||
// }
|
||||
// operator++(_List_iterator<CNavLadder*> *const this); // 225
|
||||
// }
|
||||
UNTESTED
|
||||
// take a step
|
||||
while (true)
|
||||
{
|
||||
if (m_currentNode == NULL)
|
||||
{
|
||||
// search is exhausted - continue search from ends of ladders
|
||||
NavLadderList::iterator iter;
|
||||
for (iter = TheNavLadderList.begin(); iter != TheNavLadderList.end(); ++iter)
|
||||
{
|
||||
CNavLadder *ladder = (*iter);
|
||||
|
||||
// check ladder bottom
|
||||
if ((m_currentNode = LadderEndSearch(ladder->m_entity, &ladder->m_bottom, ladder->m_dir)) != 0)
|
||||
break;
|
||||
|
||||
// check ladder top
|
||||
if ((m_currentNode = LadderEndSearch(ladder->m_entity, &ladder->m_top, ladder->m_dir)) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_currentNode == NULL)
|
||||
{
|
||||
// all seeds exhausted, sampling complete
|
||||
GenerateNavigationAreaMesh();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Take a step from this node
|
||||
for (int dir = NORTH; dir < NUM_DIRECTIONS; dir++)
|
||||
{
|
||||
if (!m_currentNode->HasVisited((NavDirType)dir))
|
||||
{
|
||||
float feetOffset = pev->origin.z - GetFeetZ();
|
||||
|
||||
// start at current node position
|
||||
Vector pos = *m_currentNode->GetPosition();
|
||||
|
||||
// snap to grid
|
||||
int cx = SnapToGrid(pos.x);
|
||||
int cy = SnapToGrid(pos.y);
|
||||
|
||||
// attempt to move to adjacent node
|
||||
switch (dir)
|
||||
{
|
||||
case NORTH: cy -= GenerationStepSize; break;
|
||||
case SOUTH: cy += GenerationStepSize; break;
|
||||
case EAST: cx += GenerationStepSize; break;
|
||||
case WEST: cx -= GenerationStepSize; break;
|
||||
}
|
||||
|
||||
pos.x = cx;
|
||||
pos.y = cy;
|
||||
|
||||
m_generationDir = (NavDirType)dir;
|
||||
|
||||
// mark direction as visited
|
||||
m_currentNode->MarkAsVisited(m_generationDir);
|
||||
|
||||
// test if we can move to new position
|
||||
TraceResult result;
|
||||
Vector from, to;
|
||||
|
||||
// modify position to account for change in ground level during step
|
||||
to.x = pos.x;
|
||||
to.y = pos.y;
|
||||
Vector toNormal;
|
||||
if (GetGroundHeight(&pos, &to.z, &toNormal) == false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
from = *m_currentNode->GetPosition();
|
||||
|
||||
Vector fromOrigin = from + Vector(0, 0, feetOffset);
|
||||
Vector toOrigin = to + Vector(0, 0, feetOffset);
|
||||
|
||||
UTIL_SetOrigin(pev, toOrigin);
|
||||
UTIL_TraceLine(fromOrigin, toOrigin, ignore_monsters, dont_ignore_glass, ENT(pev), &result);
|
||||
|
||||
bool walkable;
|
||||
|
||||
if (result.flFraction == 1.0f && !result.fStartSolid)
|
||||
{
|
||||
// the trace didnt hit anything - clear
|
||||
float toGround = to.z;
|
||||
float fromGround = from.z;
|
||||
|
||||
float epsilon = 0.1f;
|
||||
|
||||
// check if ledge is too high to reach or will cause us to fall to our death
|
||||
if (toGround - fromGround > JumpCrouchHeight + epsilon || fromGround - toGround > DeathDrop)
|
||||
{
|
||||
walkable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// check surface normals along this step to see if we would cross any impassable slopes
|
||||
Vector delta = to - from;
|
||||
const float inc = 2.0f;
|
||||
float along = inc;
|
||||
bool done = false;
|
||||
float ground;
|
||||
Vector normal;
|
||||
|
||||
walkable = true;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
Vector p;
|
||||
|
||||
// need to guarantee that we test the exact edges
|
||||
if (along >= GenerationStepSize)
|
||||
{
|
||||
p = to;
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = from + delta * (along / GenerationStepSize);
|
||||
}
|
||||
|
||||
if (GetGroundHeight(&p, &ground, &normal) == false)
|
||||
{
|
||||
walkable = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// check for maximum allowed slope
|
||||
if (normal.z < 0.7f)
|
||||
{
|
||||
walkable = false;
|
||||
break;
|
||||
}
|
||||
|
||||
along += inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TraceLine hit something...
|
||||
else
|
||||
{
|
||||
if (IsEntityWalkable(VARS(result.pHit), WALK_THRU_EVERYTHING))
|
||||
{
|
||||
walkable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
walkable = false;
|
||||
}
|
||||
}
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
// if we're incrementally generating, don't overlap existing nav areas
|
||||
CNavArea *overlap = TheNavAreaGrid.GetNavArea(&to, HumanHeight);
|
||||
if (overlap != NULL)
|
||||
{
|
||||
walkable = false;
|
||||
}
|
||||
#endif // REGAMEDLL_FIXES
|
||||
if (walkable)
|
||||
{
|
||||
// we can move here
|
||||
// create a new navigation node, and update current node pointer
|
||||
CNavNode *newNode = AddNode(&to, &toNormal, m_generationDir, m_currentNode);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// all directions have been searched from this node - pop back to its parent and continue
|
||||
m_currentNode = m_currentNode->GetParent();
|
||||
}
|
||||
}
|
||||
|
||||
/* <34489e> ../cstrike/dlls/bot/cs_bot_learn.cpp:392 */
|
||||
NOBODY void CCSBot::UpdateLearnProcess(void)
|
||||
void CCSBot::UpdateLearnProcess(void)
|
||||
{
|
||||
// {
|
||||
// float startTime; // 394
|
||||
// }
|
||||
float startTime = g_engfuncs.pfnTime();
|
||||
while (g_engfuncs.pfnTime() - startTime >= updateTimesliceDuration)
|
||||
{
|
||||
if (LearnStep() == false)
|
||||
{
|
||||
StartAnalyzeAlphaProcess();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* <344750> ../cstrike/dlls/bot/cs_bot_learn.cpp:409 */
|
||||
@ -213,72 +388,114 @@ void CCSBot::StartAnalyzeAlphaProcess(void)
|
||||
}
|
||||
|
||||
/* <34396c> ../cstrike/dlls/bot/cs_bot_learn.cpp:427 */
|
||||
NOBODY inline bool CCSBot::AnalyzeAlphaStep(void)
|
||||
bool CCSBot::AnalyzeAlphaStep(void)
|
||||
{
|
||||
// {
|
||||
// class CNavArea *area; // 432
|
||||
// }
|
||||
if (m_analyzeIter == TheNavAreaList.end())
|
||||
return false;
|
||||
|
||||
CNavArea *area = (*m_analyzeIter);
|
||||
|
||||
++_currentIndex;
|
||||
area->ComputeHidingSpots();
|
||||
area->ComputeApproachAreas();
|
||||
++m_analyzeIter;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* <3448de> ../cstrike/dlls/bot/cs_bot_learn.cpp:443 */
|
||||
NOBODY void CCSBot::UpdateAnalyzeAlphaProcess(void)
|
||||
void CCSBot::UpdateAnalyzeAlphaProcess(void)
|
||||
{
|
||||
// {
|
||||
// float startTime; // 445
|
||||
// float progress; // 462
|
||||
// AnalyzeAlphaStep(CCSBot *const this); // 451
|
||||
// drawProgressMeter(float progress,
|
||||
// char *title); // 454
|
||||
// StartAnalyzeBetaProcess(CCSBot *const this); // 456
|
||||
// drawProgressMeter(float progress,
|
||||
// char *title); // 463
|
||||
// }
|
||||
float startTime = g_engfuncs.pfnTime();
|
||||
float progress = _currentIndex / _navAreaCount * 50.0f;
|
||||
|
||||
while (AnalyzeAlphaStep())
|
||||
{
|
||||
if (g_engfuncs.pfnTime() - startTime >= updateTimesliceDuration)
|
||||
{
|
||||
drawProgressMeter(progress, "#CZero_AnalyzingHidingSpots");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
drawProgressMeter(50, "#CZero_AnalyzingHidingSpots");
|
||||
CleanupApproachAreaAnalysisPrep();
|
||||
StartAnalyzeBetaProcess();
|
||||
}
|
||||
|
||||
/* <344aed> ../cstrike/dlls/bot/cs_bot_learn.cpp:467 */
|
||||
NOBODY void CCSBot::StartAnalyzeBetaProcess(void)
|
||||
void CCSBot::StartAnalyzeBetaProcess(void)
|
||||
{
|
||||
// size(const class list<CNavArea*, std::allocator<CNavArea*>> *const this); // 471
|
||||
m_processMode = PROCESS_ANALYZE_BETA;
|
||||
m_analyzeIter = TheNavAreaList.begin();
|
||||
|
||||
_navAreaCount = TheNavAreaList.size();
|
||||
_currentIndex = 0;
|
||||
}
|
||||
|
||||
/* <3437c8> ../cstrike/dlls/bot/cs_bot_learn.cpp:479 */
|
||||
NOBODY inline bool CCSBot::AnalyzeBetaStep(void)
|
||||
bool CCSBot::AnalyzeBetaStep(void)
|
||||
{
|
||||
// {
|
||||
// class CNavArea *area; // 484
|
||||
// }
|
||||
if (m_analyzeIter == TheNavAreaList.end())
|
||||
return false;
|
||||
|
||||
CNavArea *area = (*m_analyzeIter);
|
||||
|
||||
++_currentIndex;
|
||||
area->ComputeSpotEncounters();
|
||||
area->ComputeSniperSpots();
|
||||
++m_analyzeIter;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* <344b8d> ../cstrike/dlls/bot/cs_bot_learn.cpp:495 */
|
||||
NOBODY void CCSBot::UpdateAnalyzeBetaProcess(void)
|
||||
void CCSBot::UpdateAnalyzeBetaProcess(void)
|
||||
{
|
||||
// {
|
||||
// float startTime; // 497
|
||||
// float progress; // 512
|
||||
// AnalyzeBetaStep(CCSBot *const this); // 503
|
||||
// drawProgressMeter(float progress,
|
||||
// char *title); // 506
|
||||
// StartSaveProcess(CCSBot *const this); // 507
|
||||
// drawProgressMeter(float progress,
|
||||
// char *title); // 513
|
||||
// }
|
||||
float startTime = g_engfuncs.pfnTime();
|
||||
float progress = (_currentIndex / _navAreaCount + 1.0f) * 50.0f;
|
||||
|
||||
while (AnalyzeBetaStep())
|
||||
{
|
||||
if (g_engfuncs.pfnTime() - startTime >= updateTimesliceDuration)
|
||||
{
|
||||
drawProgressMeter(progress, "#CZero_AnalyzingApproachPoints");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
drawProgressMeter(100, "#CZero_AnalyzingApproachPoints");
|
||||
StartSaveProcess();
|
||||
}
|
||||
|
||||
/* <344d1f> ../cstrike/dlls/bot/cs_bot_learn.cpp:517 */
|
||||
NOBODY void CCSBot::StartSaveProcess(void)
|
||||
void CCSBot::StartSaveProcess(void)
|
||||
{
|
||||
m_processMode = PROCESS_SAVE;
|
||||
}
|
||||
|
||||
/* <344d41> ../cstrike/dlls/bot/cs_bot_learn.cpp:527 */
|
||||
NOBODY void CCSBot::UpdateSaveProcess(void)
|
||||
void CCSBot::UpdateSaveProcess(void)
|
||||
{
|
||||
// {
|
||||
// char filename; // 530
|
||||
// char msg; // 538
|
||||
// char cmd; // 548
|
||||
// hideProgressMeter(void); // 542
|
||||
// StartNormalProcess(CCSBot *const this); // 545
|
||||
// }
|
||||
char filename[256];
|
||||
char msg[256];
|
||||
char cmd[128];
|
||||
|
||||
GET_GAME_DIR(filename);
|
||||
filename[Q_strlen(filename)] = '\\';
|
||||
Q_strcat(filename, TheBots->GetNavMapFilename());
|
||||
|
||||
HintMessageToAllPlayers("Saving...");
|
||||
SaveNavigationMap(filename);
|
||||
|
||||
Q_sprintf(msg, "Navigation file '%s' saved.", filename);
|
||||
HintMessageToAllPlayers(msg);
|
||||
|
||||
hideProgressMeter();
|
||||
StartNormalProcess();
|
||||
|
||||
Q_sprintf(cmd, "map %s\n", STRING(gpGlobals->mapname));
|
||||
SERVER_COMMAND(cmd);
|
||||
}
|
||||
|
||||
/* <344e24> ../cstrike/dlls/bot/cs_bot_learn.cpp:554 */
|
||||
|
@ -1,92 +1,214 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// Listen for enemy noises, and determine if we should react to them.
|
||||
// Returns true if heard a noise and should move to investigate.
|
||||
|
||||
/* <354545> ../cstrike/dlls/bot/cs_bot_listen.cpp:17 */
|
||||
NOBODY bool CCSBot::ShouldInvestigateNoise(float *retNoiseDist)
|
||||
bool CCSBot::ShouldInvestigateNoise(float *retNoiseDist)
|
||||
{
|
||||
// IsNoiseHeard(const class CCSBot *const this); // 32
|
||||
// {
|
||||
// float const noiseCheckInterval; // 36
|
||||
// Vector toNoise; // 44
|
||||
// float noiseDist; // 45
|
||||
// float const maxNoiseDist; // 46
|
||||
// float const oneStoreyHeight; // 49
|
||||
// float chance; // 72
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 44
|
||||
// Length(const Vector *const this); // 45
|
||||
// {
|
||||
// class PathCost pc; // 53
|
||||
// float travelDistToNoise; // 54
|
||||
// float const tooFar; // 58
|
||||
// NavAreaTravelDistance<PathCost>(CNavArea *startArea,
|
||||
// class CNavArea *endArea,
|
||||
// class PathCost &costFunc); // 54
|
||||
// }
|
||||
// {
|
||||
// float friendFactor; // 78
|
||||
// }
|
||||
// }
|
||||
if (m_isNoiseTravelRangeChecked)
|
||||
return false;
|
||||
|
||||
// don't investigate noises during safe time
|
||||
if (!IsWellPastSafe())
|
||||
return false;
|
||||
|
||||
// if our disposition is not to investigate, dont investigate
|
||||
if (GetDisposition() != ENGAGE_AND_INVESTIGATE)
|
||||
return false;
|
||||
|
||||
// listen for enemy noises
|
||||
if (IsNoiseHeard() && gpGlobals->time - m_noiseCheckTimestamp >= 0.25f)
|
||||
{
|
||||
m_noiseCheckTimestamp = gpGlobals->time;
|
||||
Vector toNoise = m_noisePosition - pev->origin;
|
||||
float noiseDist = toNoise.Length();
|
||||
|
||||
float const oneStoreyHeight = 120.0f;
|
||||
if (abs(int64(toNoise.z)) > oneStoreyHeight)
|
||||
{
|
||||
PathCost pc(this);
|
||||
float travelDistToNoise = NavAreaTravelDistance(m_lastKnownArea, m_noiseArea, pc);
|
||||
m_isNoiseTravelRangeChecked = true;
|
||||
|
||||
const float tooFar = 1500.0f;
|
||||
if (travelDistToNoise < 0.0f || travelDistToNoise > tooFar)
|
||||
return false;
|
||||
|
||||
if (noiseDist <= travelDistToNoise)
|
||||
noiseDist = travelDistToNoise;
|
||||
}
|
||||
|
||||
// if we are hiding, only react to noises very nearby, depending on how aggressive we are
|
||||
if (IsAtHidingSpot() && noiseDist > 100.0f + 400.0f * GetProfile()->GetAggression())
|
||||
return false;
|
||||
|
||||
// chance of investigating is inversely proportional to distance
|
||||
const float maxNoiseDist = 2000.0f;
|
||||
float chance = (1.0f - (noiseDist / maxNoiseDist));
|
||||
|
||||
// modify chance by number of friends remaining
|
||||
// if we have lots of friends, presumably one of them is closer and will check it out
|
||||
if (GetFriendsRemaining() >= 3)
|
||||
{
|
||||
float friendFactor = 0.05f * GetFriendsRemaining();
|
||||
if (friendFactor > 0.5f)
|
||||
friendFactor = 0.5f;
|
||||
|
||||
chance -= friendFactor;
|
||||
}
|
||||
|
||||
if (RANDOM_FLOAT(0.0f, 1.0f) <= chance)
|
||||
{
|
||||
if (retNoiseDist)
|
||||
*retNoiseDist = noiseDist;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if we hear nearby threatening enemy gunfire within given range
|
||||
// -1 == infinite range
|
||||
|
||||
/* <354c8d> ../cstrike/dlls/bot/cs_bot_listen.cpp:104 */
|
||||
NOBODY bool CCSBot::CanHearNearbyEnemyGunfire(float range)
|
||||
bool CCSBot::CanHearNearbyEnemyGunfire(float range) const
|
||||
{
|
||||
// {
|
||||
// float gunfireDistSq; // 125
|
||||
// float enemyDistSq; // 126
|
||||
// float const muchCloserSq; // 127
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 126
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 125
|
||||
// LengthSquared(const Vector *const this); // 125
|
||||
// LengthSquared(const Vector *const this); // 126
|
||||
// }
|
||||
// CanSeeNoisePosition(const class CCSBot *const this); // 119
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 115
|
||||
// IsLengthGreaterThan(const Vector *const this,
|
||||
// float length); // 115
|
||||
// only attend to noise if it just happened
|
||||
if (gpGlobals->time - m_noiseTimestamp > 0.5f)
|
||||
return false;
|
||||
|
||||
// gunfire is high priority
|
||||
if (m_noisePriority < PRIORITY_HIGH)
|
||||
return false;
|
||||
|
||||
// check noise range
|
||||
if (range > 0.0f && (pev->origin - m_noisePosition).IsLengthGreaterThan(range))
|
||||
return false;
|
||||
|
||||
// if we dont have line of sight, it's not threatening (cant get shot)
|
||||
if (!CanSeeNoisePosition())
|
||||
return false;
|
||||
|
||||
if (IsAttacking() && m_enemy != NULL)
|
||||
{
|
||||
// gunfire is only threatening if it is closer than our current enemy
|
||||
float gunfireDistSq = (m_noisePosition - pev->origin).LengthSquared();
|
||||
float enemyDistSq = (m_enemy->pev->origin - pev->origin).LengthSquared();
|
||||
const float muchCloserSq = 100.0f * 100.0f;
|
||||
if (gunfireDistSq > enemyDistSq - muchCloserSq)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return true if we directly see where we think the noise came from
|
||||
// NOTE: Dont check FOV, since this is used to determine if we should turn our head to look at the noise
|
||||
// NOTE: Dont use IsVisible(), because smoke shouldnt cause us to not look toward noises
|
||||
|
||||
/* <354e7b> ../cstrike/dlls/bot/cs_bot_listen.cpp:141 */
|
||||
NOBODY bool CCSBot::CanSeeNoisePosition(void)
|
||||
bool CCSBot::CanSeeNoisePosition(void) const
|
||||
{
|
||||
// {
|
||||
// TraceResult result; // 143
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 144
|
||||
// GetEyePosition(const class CCSBot *const this); // 144
|
||||
// }
|
||||
TraceResult result;
|
||||
UTIL_TraceLine(GetEyePosition(), m_noisePosition + Vector(0, 0, HalfHumanHeight), ignore_monsters, ignore_glass, ENT(pev), &result);
|
||||
|
||||
if (result.flFraction == 1.0f)
|
||||
{
|
||||
// we can see the source of the noise
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if we decided to look towards the most recent noise source
|
||||
// Assumes m_noisePosition is valid.
|
||||
|
||||
/* <354f48> ../cstrike/dlls/bot/cs_bot_listen.cpp:160 */
|
||||
NOBODY bool CCSBot::UpdateLookAtNoise(void)
|
||||
bool CCSBot::UpdateLookAtNoise(void)
|
||||
{
|
||||
// {
|
||||
// bool nearbyThreat; // 176
|
||||
// float const recentThreatTime; // 177
|
||||
// float const closeThreatRange; // 178
|
||||
// Vector spot; // 190
|
||||
// enum PriorityType pri; // 231
|
||||
// IsNoiseHeard(const class CCSBot *const this); // 163
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 181
|
||||
// IsLengthLessThan(const Vector *const this,
|
||||
// float length); // 181
|
||||
// CanSeeNoisePosition(const class CCSBot *const this); // 193
|
||||
// {
|
||||
// int nearIdx; // 200
|
||||
// float nearRangeSq; // 201
|
||||
// {
|
||||
// int i; // 202
|
||||
// {
|
||||
// float distanceSq; // 206
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 206
|
||||
// LengthSquared(const Vector *const this); // 206
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// make sure a noise exists
|
||||
if (!IsNoiseHeard() || gpGlobals->time - m_noiseTimestamp > 0.5f)
|
||||
return false;
|
||||
|
||||
bool nearbyThreat = false;
|
||||
float const recentThreatTime = 5.0f;
|
||||
if (GetTimeSinceLastSawEnemy() < recentThreatTime)
|
||||
{
|
||||
const float closeThreatRange = 750.0f;
|
||||
if ((pev->origin - m_lastEnemyPosition).IsLengthLessThan(closeThreatRange))
|
||||
{
|
||||
nearbyThreat = true;
|
||||
}
|
||||
}
|
||||
|
||||
Vector spot;
|
||||
|
||||
// if we have clear line of sight to noise position, look directly at it
|
||||
if ((!IsAtHidingSpot() && nearbyThreat) || CanSeeNoisePosition())
|
||||
{
|
||||
// TODO: adjust noise Z to keep consistent with current height while fighting
|
||||
spot = m_noisePosition + Vector(0, 0, HalfHumanHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// line of sight is blocked, bend it
|
||||
|
||||
if (m_approachPointCount == 0)
|
||||
return false;
|
||||
|
||||
int nearIdx = -1;
|
||||
float nearRangeSq = 9.9999998e10f;
|
||||
|
||||
for (int i = 0; i < m_approachPointCount; ++i)
|
||||
{
|
||||
float distanceSq = (m_approachPoint[i] - m_noisePosition).LengthSquared();
|
||||
|
||||
if (distanceSq < nearRangeSq)
|
||||
{
|
||||
nearRangeSq = distanceSq;
|
||||
nearIdx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (nearIdx != -1)
|
||||
{
|
||||
// line of sight is blocked, bend it
|
||||
if (BendLineOfSight(&pev->origin, &m_approachPoint[nearIdx], &spot) == false)
|
||||
return false;
|
||||
|
||||
spot.z += HalfHumanHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// prior bend failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// it's always important to look at enemy noises, because they come from ... enemies!
|
||||
PriorityType pri = (GetNoisePriority() == PRIORITY_HIGH) ? PRIORITY_HIGH : PRIORITY_MEDIUM;
|
||||
|
||||
// look longer if we're hiding
|
||||
if (IsAtHidingSpot())
|
||||
{
|
||||
// if there is only one enemy left, look for a long time
|
||||
if (GetEnemiesRemaining() == 1)
|
||||
{
|
||||
SetLookAt("Noise", &spot, pri, RANDOM_FLOAT(5.0f, 15.0f), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLookAt("Noise", &spot, pri, RANDOM_FLOAT(2.0f, 5.0f), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLookAt("Noise", &spot, pri, RANDOM_FLOAT(1.0f, 2.0f), true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,36 +36,6 @@
|
||||
|
||||
#define TheBots (*pTheBots)
|
||||
|
||||
#define cv_bot_traceview (*pcv_bot_traceview)
|
||||
#define cv_bot_stop (*pcv_bot_stop)
|
||||
#define cv_bot_show_nav (*pcv_bot_show_nav)
|
||||
#define cv_bot_show_danger (*pcv_bot_show_danger)
|
||||
#define cv_bot_nav_edit (*pcv_bot_nav_edit)
|
||||
#define cv_bot_nav_zdraw (*pcv_bot_nav_zdraw)
|
||||
#define cv_bot_walk (*pcv_bot_walk)
|
||||
#define cv_bot_difficulty (*pcv_bot_difficulty)
|
||||
#define cv_bot_debug (*pcv_bot_debug)
|
||||
#define cv_bot_quicksave (*pcv_bot_quicksave)
|
||||
#define cv_bot_quota (*pcv_bot_quota)
|
||||
#define cv_bot_quota_match (*pcv_bot_quota_match)
|
||||
#define cv_bot_prefix (*pcv_bot_prefix)
|
||||
#define cv_bot_allow_rogues (*pcv_bot_allow_rogues)
|
||||
#define cv_bot_allow_pistols (*pcv_bot_allow_pistols)
|
||||
#define cv_bot_allow_shotguns (*pcv_bot_allow_shotguns)
|
||||
#define cv_bot_allow_sub_machine_guns (*pcv_bot_allow_sub_machine_guns)
|
||||
#define cv_bot_allow_rifles (*pcv_bot_allow_rifles)
|
||||
#define cv_bot_allow_machine_guns (*pcv_bot_allow_machine_guns)
|
||||
#define cv_bot_allow_grenades (*pcv_bot_allow_grenades)
|
||||
#define cv_bot_allow_snipers (*pcv_bot_allow_snipers)
|
||||
#define cv_bot_allow_shield (*pcv_bot_allow_shield)
|
||||
#define cv_bot_join_team (*pcv_bot_join_team)
|
||||
#define cv_bot_join_after_player (*pcv_bot_join_after_player)
|
||||
#define cv_bot_auto_vacate (*pcv_bot_auto_vacate)
|
||||
#define cv_bot_zombie (*pcv_bot_zombie)
|
||||
#define cv_bot_defer_to_human (*pcv_bot_defer_to_human)
|
||||
#define cv_bot_chatter (*pcv_bot_chatter)
|
||||
#define cv_bot_profile_db (*pcv_bot_profile_db)
|
||||
|
||||
//#define m_flNextCVarCheck (*pm_flNextCVarCheck)
|
||||
//#define m_isMapDataLoaded (*pm_isMapDataLoaded)
|
||||
//#define m_editCmd (*pm_editCmd)
|
||||
@ -77,57 +47,28 @@
|
||||
|
||||
extern CBotManager *TheBots;
|
||||
|
||||
extern cvar_t cv_bot_traceview;
|
||||
extern cvar_t cv_bot_stop;
|
||||
extern cvar_t cv_bot_show_nav;
|
||||
extern cvar_t cv_bot_show_danger;
|
||||
extern cvar_t cv_bot_nav_edit;
|
||||
extern cvar_t cv_bot_nav_zdraw;
|
||||
extern cvar_t cv_bot_walk;
|
||||
extern cvar_t cv_bot_difficulty;
|
||||
extern cvar_t cv_bot_debug;
|
||||
extern cvar_t cv_bot_quicksave;
|
||||
extern cvar_t cv_bot_quota;
|
||||
extern cvar_t cv_bot_quota_match;
|
||||
extern cvar_t cv_bot_prefix;
|
||||
extern cvar_t cv_bot_allow_rogues;
|
||||
extern cvar_t cv_bot_allow_pistols;
|
||||
extern cvar_t cv_bot_allow_shotguns;
|
||||
extern cvar_t cv_bot_allow_sub_machine_guns;
|
||||
extern cvar_t cv_bot_allow_rifles;
|
||||
extern cvar_t cv_bot_allow_machine_guns;
|
||||
extern cvar_t cv_bot_allow_grenades;
|
||||
extern cvar_t cv_bot_allow_snipers;
|
||||
extern cvar_t cv_bot_allow_shield;
|
||||
extern cvar_t cv_bot_join_team;
|
||||
extern cvar_t cv_bot_join_after_player;
|
||||
extern cvar_t cv_bot_auto_vacate;
|
||||
extern cvar_t cv_bot_zombie;
|
||||
extern cvar_t cv_bot_defer_to_human;
|
||||
extern cvar_t cv_bot_chatter;
|
||||
extern cvar_t cv_bot_profile_db;
|
||||
|
||||
// The manager for Counter-Strike specific bots
|
||||
class CCSBotManager: public CBotManager
|
||||
{
|
||||
public:
|
||||
CCSBotManager(void);
|
||||
public:
|
||||
CCSBotManager();
|
||||
|
||||
virtual void ClientDisconnect(CBasePlayer *pPlayer);
|
||||
virtual BOOL ClientCommand(CBasePlayer *pPlayer, const char *pcmd);
|
||||
|
||||
virtual void ServerActivate(void);
|
||||
virtual void ServerDeactivate(void);
|
||||
|
||||
NOBODY virtual void ServerCommand(const char *pcmd);
|
||||
virtual void ServerCommand(const char *pcmd);
|
||||
virtual void AddServerCommand(const char *cmd);
|
||||
virtual void AddServerCommands(void);
|
||||
|
||||
virtual void RestartRound(void);
|
||||
NOBODY virtual void StartFrame(void);
|
||||
virtual void RestartRound(void); // (EXTEND) invoked when a new round begins
|
||||
virtual void StartFrame(void); // (EXTEND) called each frame
|
||||
|
||||
virtual void OnEvent(GameEventType event, CBaseEntity *entity = NULL, CBaseEntity *other = NULL);
|
||||
NOBODY virtual unsigned int GetPlayerPriority(CBasePlayer *player) const;
|
||||
NOBODY virtual bool IsImportantPlayer(CBasePlayer *player);
|
||||
virtual unsigned int GetPlayerPriority(CBasePlayer *player) const; // return priority of player (0 = max pri)
|
||||
virtual bool IsImportantPlayer(CBasePlayer *player) const; // return true if player is important to scenario (VIP, bomb carrier, etc)
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
@ -142,31 +83,19 @@ public:
|
||||
void StartFrame_(void);
|
||||
void OnEvent_(GameEventType event, CBaseEntity *entity, CBaseEntity *other);
|
||||
unsigned int GetPlayerPriority_(CBasePlayer *player) const;
|
||||
bool IsImportantPlayer_(CBasePlayer *player);
|
||||
bool IsImportantPlayer_(CBasePlayer *player) const;
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
public:
|
||||
void ValidateMapData(void);
|
||||
bool IsLearningMap(void)
|
||||
{
|
||||
return IMPL(m_isLearningMap);
|
||||
}
|
||||
void SetLearningMapFlag(void)
|
||||
{
|
||||
IMPL(m_isLearningMap) = true;
|
||||
}
|
||||
bool IsAnalysisRequested(void)
|
||||
{
|
||||
return IMPL(m_isAnalysisRequested);
|
||||
}
|
||||
void RequestAnalysis(void)
|
||||
{
|
||||
IMPL(m_isAnalysisRequested) = true;
|
||||
}
|
||||
void AckAnalysisRequest(void)
|
||||
{
|
||||
IMPL(m_isAnalysisRequested) = false;
|
||||
}
|
||||
bool IsLearningMap(void) const { return IMPL(m_isLearningMap); }
|
||||
void SetLearningMapFlag(void) { IMPL(m_isLearningMap) = true;}
|
||||
bool IsAnalysisRequested(void) const { return IMPL(m_isAnalysisRequested); }
|
||||
void RequestAnalysis(void) { IMPL(m_isAnalysisRequested) = true; }
|
||||
void AckAnalysisRequest(void) { IMPL(m_isAnalysisRequested) = false; }
|
||||
|
||||
// difficulty levels
|
||||
static BotDifficultyType GetDifficultyLevel(void)
|
||||
{
|
||||
if (cv_bot_difficulty.value < 0.9f)
|
||||
@ -181,41 +110,42 @@ public:
|
||||
return BOT_EXPERT;
|
||||
}
|
||||
|
||||
// the supported game scenarios
|
||||
enum GameScenarioType
|
||||
{
|
||||
SCENARIO_DEATHMATCH,
|
||||
SCENARIO_DEFUSE_BOMB,
|
||||
SCENARIO_RESCUE_HOSTAGES,
|
||||
SCENARIO_ESCORT_VIP,
|
||||
SCENARIO_ESCORT_VIP
|
||||
};
|
||||
GameScenarioType GetScenario(void)
|
||||
{
|
||||
return m_gameScenario;
|
||||
}
|
||||
GameScenarioType GetScenario(void) const { return m_gameScenario; }
|
||||
|
||||
enum { MAX_ZONES = 4, MAX_ZONE_NAV_AREAS = 16 };
|
||||
// "zones"
|
||||
// depending on the game mode, these are bomb zones, rescue zones, etc.
|
||||
enum { MAX_ZONES = 4 }; // max # of zones in a map
|
||||
enum { MAX_ZONE_NAV_AREAS = 16 }; // max # of nav areas in a zone
|
||||
struct Zone
|
||||
{
|
||||
CBaseEntity *m_entity;
|
||||
CNavArea *m_area[MAX_ZONE_NAV_AREAS];
|
||||
CBaseEntity *m_entity; // the map entity
|
||||
CNavArea *m_area[MAX_ZONE_NAV_AREAS]; // nav areas that overlap this zone
|
||||
int m_areaCount;
|
||||
Vector m_center;
|
||||
bool m_isLegacy;
|
||||
bool m_isLegacy; // if true, use pev->origin and 256 unit radius as zone
|
||||
int m_index;
|
||||
Extent m_extent;
|
||||
|
||||
};/* size: 116, cachelines: 2, members: 7 */
|
||||
|
||||
const Zone *GetZone(int i) const
|
||||
{
|
||||
return &m_zone[i];
|
||||
}
|
||||
NOBODY const Zone *GetZone(const Vector *pos) const;
|
||||
const Zone *GetClosestZone(const Vector *pos) const;
|
||||
const Zone *GetClosestZone(const CBaseEntity *entity) const
|
||||
{
|
||||
return GetClosestZone(&entity->pev->origin);
|
||||
}
|
||||
const Zone *GetZone(int i) const { return &m_zone[i]; }
|
||||
const Zone *GetZone(const Vector *pos) const; // return the zone that contains the given position
|
||||
const Zone *GetClosestZone(const Vector *pos) const; // return the closest zone to the given position
|
||||
const Zone *GetClosestZone(const CBaseEntity *entity) const { return GetClosestZone(&entity->pev->origin); } // return the closest zone to the given entity
|
||||
int GetZoneCount(void) const { return m_zoneCount; }
|
||||
|
||||
const Vector *GetRandomPositionInZone(const Zone *zone) const;
|
||||
CNavArea *GetRandomAreaInZone(const Zone *zone) const;
|
||||
|
||||
// Return the zone closest to the given position, using the given cost heuristic
|
||||
template<typename CostFunctor>
|
||||
const Zone *GetClosestZone(CNavArea *startArea, CostFunctor costFunc, float *travelDistance = NULL) const
|
||||
{
|
||||
@ -225,7 +155,7 @@ public:
|
||||
if (startArea == NULL)
|
||||
return NULL;
|
||||
|
||||
for (int i = 0; i < m_zoneCount; i++)
|
||||
for (int i = 0; i < m_zoneCount; ++i)
|
||||
{
|
||||
if (m_zone[i].m_areaCount == 0)
|
||||
continue;
|
||||
@ -233,7 +163,9 @@ public:
|
||||
if (m_zone[i].m_isBlocked)
|
||||
continue;
|
||||
|
||||
// just use the first overlapping nav area as a reasonable approximation
|
||||
float dist = NavAreaTravelDistance(startArea, m_zone[i].m_area[0], costFunc);
|
||||
|
||||
if (dist >= 0.0f && dist < closeDist)
|
||||
{
|
||||
closeZone = &m_zone[i];
|
||||
@ -241,17 +173,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (travelDistance)
|
||||
if (travelDistance != NULL)
|
||||
*travelDistance = closeDist;
|
||||
|
||||
return closeZone;
|
||||
}
|
||||
int GetZoneCount(void) const
|
||||
{
|
||||
return m_zoneCount;
|
||||
}
|
||||
NOBODY const Vector *GetRandomPositionInZone(const Zone *zone) const;
|
||||
NOBODY CNavArea *GetRandomAreaInZone(const Zone *zone) const;
|
||||
|
||||
// pick a zone at random and return it
|
||||
const Zone *GetRandomZone(void) const
|
||||
@ -261,172 +187,89 @@ public:
|
||||
|
||||
return &m_zone[ RANDOM_LONG(0, m_zoneCount - 1) ];
|
||||
}
|
||||
// returns true if bomb has been planted
|
||||
bool IsBombPlanted(void) const
|
||||
{
|
||||
return m_isBombPlanted;
|
||||
}
|
||||
// return time bomb was planted
|
||||
float GetBombPlantTimestamp(void)
|
||||
{
|
||||
return m_bombPlantTimestamp;
|
||||
}
|
||||
// return true if it's ok to try to plant bomb
|
||||
bool IsTimeToPlantBomb(void) const
|
||||
{
|
||||
return (gpGlobals->time >= m_earliestBombPlantTimestamp);
|
||||
}
|
||||
CBasePlayer *GetBombDefuser(void) const
|
||||
{
|
||||
return m_bombDefuser;
|
||||
}
|
||||
NOBODY float GetBombTimeLeft(void) const;
|
||||
// return the bomb if it is loose on the ground
|
||||
CBaseEntity *GetLooseBomb(void)
|
||||
{
|
||||
return m_looseBomb;
|
||||
}
|
||||
// return area that bomb is in/near
|
||||
CNavArea *GetLooseBombArea(void) const
|
||||
{
|
||||
return m_looseBombArea;
|
||||
}
|
||||
|
||||
bool IsBombPlanted(void) const { return m_isBombPlanted; } // returns true if bomb has been planted
|
||||
float GetBombPlantTimestamp(void) const { return m_bombPlantTimestamp; } // return time bomb was planted
|
||||
bool IsTimeToPlantBomb(void) const { return (gpGlobals->time >= m_earliestBombPlantTimestamp); } // return true if it's ok to try to plant bomb
|
||||
CBasePlayer *GetBombDefuser(void) const { return m_bombDefuser; } // return the player currently defusing the bomb, or NULL
|
||||
float GetBombTimeLeft(void) const; // get the time remaining before the planted bomb explodes
|
||||
CBaseEntity *GetLooseBomb(void) { return m_looseBomb; } // return the bomb if it is loose on the ground
|
||||
CNavArea *GetLooseBombArea(void) const { return m_looseBombArea; } // return area that bomb is in/near
|
||||
void SetLooseBomb(CBaseEntity *bomb);
|
||||
NOBODY float GetRadioMessageTimestamp(GameEventType event, int teamID);
|
||||
NOBODY float GetRadioMessageInterval(GameEventType event, int teamID);
|
||||
NOBODY void SetRadioMessageTimestamp(GameEventType event, int teamID);
|
||||
|
||||
float GetRadioMessageTimestamp(GameEventType event, int teamID) const; // return the last time the given radio message was sent for given team
|
||||
float GetRadioMessageInterval(GameEventType event, int teamID) const; // return the interval since the last time this message was sent
|
||||
void SetRadioMessageTimestamp(GameEventType event, int teamID);
|
||||
void ResetRadioMessageTimestamps(void);
|
||||
|
||||
// return the last time anyone has seen an enemy
|
||||
float GetLastSeenEnemyTimestamp(void) const
|
||||
{
|
||||
return m_lastSeenEnemyTimestamp;
|
||||
}
|
||||
void SetLastSeenEnemyTimestamp(void)
|
||||
{
|
||||
m_lastSeenEnemyTimestamp = gpGlobals->time;
|
||||
}
|
||||
float GetRoundStartTime(void) const
|
||||
{
|
||||
return m_roundStartTimestamp;
|
||||
}
|
||||
// return the elapsed time since the current round began
|
||||
float GetElapsedRoundTime(void) const
|
||||
{
|
||||
return gpGlobals->time - m_roundStartTimestamp;
|
||||
}
|
||||
bool AllowRogues(void) const
|
||||
{
|
||||
return cv_bot_allow_rogues.value != 0;
|
||||
}
|
||||
bool AllowPistols(void) const
|
||||
{
|
||||
return cv_bot_allow_pistols.value != 0;
|
||||
}
|
||||
bool AllowShotguns(void) const
|
||||
{
|
||||
return cv_bot_allow_shotguns.value != 0;
|
||||
}
|
||||
bool AllowSubMachineGuns(void) const
|
||||
{
|
||||
return cv_bot_allow_sub_machine_guns.value != 0;
|
||||
}
|
||||
bool AllowRifles(void) const
|
||||
{
|
||||
return cv_bot_allow_rifles.value != 0;
|
||||
}
|
||||
bool AllowMachineGuns(void) const
|
||||
{
|
||||
return cv_bot_allow_machine_guns.value != 0;
|
||||
}
|
||||
bool AllowGrenades(void) const
|
||||
{
|
||||
return cv_bot_allow_grenades.value != 0;
|
||||
}
|
||||
bool AllowSnipers(void) const
|
||||
{
|
||||
return cv_bot_allow_snipers.value != 0;
|
||||
}
|
||||
bool AllowTacticalShield(void) const
|
||||
{
|
||||
return cv_bot_allow_shield.value != 0;
|
||||
}
|
||||
bool AllowFriendlyFireDamage(void) const
|
||||
{
|
||||
return friendlyfire.value != 0;
|
||||
}
|
||||
bool IsWeaponUseable(CBasePlayerItem *item) const;
|
||||
bool IsDefenseRushing(void) const
|
||||
{
|
||||
return m_isDefenseRushing;
|
||||
}
|
||||
NOBODY bool IsOnDefense(CBasePlayer *player) const;
|
||||
NOBODY bool IsOnOffense(CBasePlayer *player) const;
|
||||
bool IsRoundOver(void) const
|
||||
{
|
||||
return m_isRoundOver;
|
||||
}
|
||||
unsigned int GetNavPlace(void) const
|
||||
{
|
||||
return m_navPlace;
|
||||
}
|
||||
void SetNavPlace(unsigned int place)
|
||||
{
|
||||
m_navPlace = place;
|
||||
}
|
||||
float GetLastSeenEnemyTimestamp(void) const { return m_lastSeenEnemyTimestamp; } // return the last time anyone has seen an enemy
|
||||
void SetLastSeenEnemyTimestamp(void) { m_lastSeenEnemyTimestamp = gpGlobals->time; }
|
||||
|
||||
enum SkillType
|
||||
{
|
||||
LOW,
|
||||
AVERAGE,
|
||||
HIGH,
|
||||
RANDOM
|
||||
};
|
||||
float GetRoundStartTime(void) const { return m_roundStartTimestamp; }
|
||||
float GetElapsedRoundTime(void) const { return gpGlobals->time - m_roundStartTimestamp; } // return the elapsed time since the current round began
|
||||
|
||||
bool AllowRogues(void) const { return cv_bot_allow_rogues.value != 0.0f; }
|
||||
bool AllowPistols(void) const { return cv_bot_allow_pistols.value != 0.0f; }
|
||||
bool AllowShotguns(void) const { return cv_bot_allow_shotguns.value != 0.0f; }
|
||||
bool AllowSubMachineGuns(void) const { return cv_bot_allow_sub_machine_guns.value != 0.0f; }
|
||||
bool AllowRifles(void) const { return cv_bot_allow_rifles.value != 0.0f; }
|
||||
bool AllowMachineGuns(void) const { return cv_bot_allow_machine_guns.value != 0.0f; }
|
||||
bool AllowGrenades(void) const { return cv_bot_allow_grenades.value != 0.0f; }
|
||||
bool AllowSnipers(void) const { return cv_bot_allow_snipers.value != 0.0f; }
|
||||
bool AllowTacticalShield(void) const { return cv_bot_allow_shield.value != 0.0f; }
|
||||
bool AllowFriendlyFireDamage(void) const { return friendlyfire.value != 0.0f; }
|
||||
|
||||
bool IsWeaponUseable(CBasePlayerItem *item) const; // return true if the bot can use this weapon
|
||||
|
||||
bool IsDefenseRushing(void) const { return m_isDefenseRushing; } // returns true if defense team has "decided" to rush this round
|
||||
bool IsOnDefense(CBasePlayer *player) const; // return true if this player is on "defense"
|
||||
bool IsOnOffense(CBasePlayer *player) const; // return true if this player is on "offense"
|
||||
|
||||
bool IsRoundOver(void) const { return m_isRoundOver; } // return true if the round has ended
|
||||
|
||||
unsigned int GetNavPlace(void) const { return m_navPlace; }
|
||||
void SetNavPlace(unsigned int place) { m_navPlace = place; }
|
||||
|
||||
enum SkillType { LOW, AVERAGE, HIGH, RANDOM };
|
||||
NOXREF NOBODY const char *GetRandomBotName(SkillType skill);
|
||||
|
||||
NOBODY static void MonitorBotCVars(void);
|
||||
NOBODY static void MaintainBotQuota(void);
|
||||
static void MonitorBotCVars(void);
|
||||
static void MaintainBotQuota(void);
|
||||
NOBODY static bool AddBot(const BotProfile *profile, BotProfileTeamType team);
|
||||
NOBODY static bool BotAddCommand(BotProfileTeamType team, bool isFromConsole = true);
|
||||
|
||||
#define FROM_CONSOLE true
|
||||
static bool BotAddCommand(BotProfileTeamType team, bool isFromConsole = false); // process the "bot_add" console command
|
||||
|
||||
#ifndef HOOK_GAMEDLL
|
||||
private:
|
||||
#else
|
||||
public:
|
||||
#endif // HOOK_GAMEDLL
|
||||
static float IMPL(m_flNextCVarCheck);
|
||||
static bool IMPL(m_isMapDataLoaded);
|
||||
static bool IMPL(m_isMapDataLoaded); // true if we've attempted to load map data
|
||||
static bool IMPL(m_isLearningMap);
|
||||
static bool IMPL(m_isAnalysisRequested);
|
||||
#ifdef HOOK_GAMEDLL
|
||||
private:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
GameScenarioType m_gameScenario;// TODO: must be on Windows offsetof - 16
|
||||
GameScenarioType m_gameScenario; // what kind of game are we playing
|
||||
|
||||
Zone m_zone[ MAX_ZONES ];
|
||||
int m_zoneCount;
|
||||
bool m_isBombPlanted;
|
||||
float m_bombPlantTimestamp;
|
||||
float m_earliestBombPlantTimestamp;
|
||||
CBasePlayer *m_bombDefuser;
|
||||
EHANDLE m_looseBomb;
|
||||
CNavArea *m_looseBombArea;
|
||||
bool m_isRoundOver;
|
||||
|
||||
bool m_isBombPlanted; // true if bomb has been planted
|
||||
float m_bombPlantTimestamp; // time bomb was planted
|
||||
float m_earliestBombPlantTimestamp; // don't allow planting until after this time has elapsed
|
||||
CBasePlayer *m_bombDefuser; // the player currently defusing a bomb
|
||||
EHANDLE m_looseBomb; // will be non-NULL if bomb is loose on the ground
|
||||
CNavArea *m_looseBombArea; // area that bomb is is/near
|
||||
|
||||
bool m_isRoundOver; // true if the round has ended
|
||||
|
||||
float m_radioMsgTimestamp[24][2];
|
||||
|
||||
float m_lastSeenEnemyTimestamp;
|
||||
float m_roundStartTimestamp;
|
||||
bool m_isDefenseRushing;
|
||||
float m_roundStartTimestamp; // the time when the current round began
|
||||
|
||||
bool m_isDefenseRushing; // whether defensive team is rushing this round or not
|
||||
|
||||
#ifndef HOOK_GAMEDLL
|
||||
private:
|
||||
#else
|
||||
public:
|
||||
#endif // HOOK_GAMEDLL
|
||||
static NavEditCmdType IMPL(m_editCmd);
|
||||
#ifdef HOOK_GAMEDLL
|
||||
private:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
unsigned int m_navPlace;
|
||||
CountdownTimer m_respawnTimer;
|
||||
bool m_isRespawnStarted;
|
||||
@ -448,7 +291,7 @@ inline CCSBotManager *TheCSBots(void)
|
||||
}
|
||||
|
||||
void PrintAllEntities(void);
|
||||
NOBODY void UTIL_DrawBox(Extent *extent, int lifetime, int red, int green, int blue);
|
||||
void UTIL_DrawBox(Extent *extent, int lifetime, int red, int green, int blue);
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
|
@ -1,218 +1,468 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// Reset the stuck-checker.
|
||||
|
||||
/* <37c284> ../cstrike/dlls/bot/cs_bot_nav.cpp:16 */
|
||||
NOBODY void CCSBot::ResetStuckMonitor(void)
|
||||
void CCSBot::ResetStuckMonitor(void)
|
||||
{
|
||||
if (m_isStuck)
|
||||
{
|
||||
if (IsLocalPlayerWatchingMe() && cv_bot_debug.value > 0.0f)
|
||||
{
|
||||
EMIT_SOUND(edict(), CHAN_ITEM, "buttons/bell1.wav", VOL_NORM, ATTN_NORM);
|
||||
}
|
||||
}
|
||||
|
||||
m_isStuck = false;
|
||||
m_stuckTimestamp = 0.0f;
|
||||
m_stuckJumpTimestamp = 0.0f;
|
||||
|
||||
m_avgVelIndex = 0;
|
||||
m_avgVelCount = 0;
|
||||
|
||||
m_areaEnteredTimestamp = gpGlobals->time;
|
||||
}
|
||||
|
||||
// Test if we have become stuck
|
||||
|
||||
/* <37c2a6> ../cstrike/dlls/bot/cs_bot_nav.cpp:37 */
|
||||
NOBODY void CCSBot::StuckCheck(void)
|
||||
void CCSBot::StuckCheck(void)
|
||||
{
|
||||
// {
|
||||
// Vector delta; // 42
|
||||
// float const unstuckRange; // 44
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 42
|
||||
// IsLengthGreaterThan(const Vector *const this,
|
||||
// float length); // 45
|
||||
// ResetStuckMonitor(CCSBot *const this); // 48
|
||||
// }
|
||||
// {
|
||||
// Vector vel; // 57
|
||||
// float moveDist; // 64
|
||||
// float deltaT; // 66
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 57
|
||||
// Length(const Vector *const this); // 64
|
||||
// {
|
||||
// float avgVel; // 81
|
||||
// float stuckVel; // 88
|
||||
// {
|
||||
// int t; // 82
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (m_isStuck)
|
||||
{
|
||||
// we are stuck - see if we have moved far enough to be considered unstuck
|
||||
Vector delta = pev->origin - m_stuckSpot;
|
||||
|
||||
const float unstuckRange = 75.0f;
|
||||
if (delta.IsLengthGreaterThan(unstuckRange))
|
||||
{
|
||||
// we are no longer stuck
|
||||
ResetStuckMonitor();
|
||||
PrintIfWatched("UN-STUCK\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if we are stuck
|
||||
// compute average velocity over a short period (for stuck check)
|
||||
Vector vel = pev->origin - m_lastOrigin;
|
||||
|
||||
// if we are jumping, ignore Z
|
||||
if (IsJumping())
|
||||
vel.z = 0.0f;
|
||||
|
||||
// cannot be Length2D, or will break ladder movement (they are only Z)
|
||||
float moveDist = vel.Length();
|
||||
float deltaT = g_flBotFullThinkInterval;
|
||||
|
||||
m_avgVel[ m_avgVelIndex++ ] = moveDist / deltaT;
|
||||
|
||||
if (m_avgVelIndex == MAX_VEL_SAMPLES)
|
||||
m_avgVelIndex = 0;
|
||||
|
||||
if (m_avgVelCount < MAX_VEL_SAMPLES)
|
||||
{
|
||||
m_avgVelCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have enough samples to know if we're stuck
|
||||
float avgVel = 0.0f;
|
||||
for (int t = 0; t < m_avgVelCount; ++t)
|
||||
avgVel += m_avgVel[t];
|
||||
|
||||
avgVel /= m_avgVelCount;
|
||||
|
||||
// cannot make this velocity too high, or bots will get "stuck" when going down ladders
|
||||
float stuckVel = (IsUsingLadder()) ? 10.0f : 20.0f;
|
||||
|
||||
if (avgVel < stuckVel)
|
||||
{
|
||||
// we are stuck - note when and where we initially become stuck
|
||||
m_stuckTimestamp = gpGlobals->time;
|
||||
m_stuckSpot = pev->origin;
|
||||
m_stuckJumpTimestamp = gpGlobals->time + RANDOM_FLOAT(0.0f, 0.5f);
|
||||
|
||||
PrintIfWatched("STUCK\n");
|
||||
if (IsLocalPlayerWatchingMe() && cv_bot_debug.value > 0.0f)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "buttons/button11.wav", VOL_NORM, ATTN_NORM);
|
||||
}
|
||||
|
||||
m_isStuck = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// always need to track this
|
||||
m_lastOrigin = pev->origin;
|
||||
}
|
||||
|
||||
// Check if we need to jump due to height change
|
||||
|
||||
/* <37c05d> ../cstrike/dlls/bot/cs_bot_nav.cpp:114 */
|
||||
NOBODY bool CCSBot::DiscontinuityJump(float ground, bool onlyJumpDown, bool mustJump)
|
||||
bool CCSBot::DiscontinuityJump(float ground, bool onlyJumpDown, bool mustJump)
|
||||
{
|
||||
// {
|
||||
// float dz; // 119
|
||||
// }
|
||||
// don't try to jump again.
|
||||
if (m_isJumpCrouching)
|
||||
return false;
|
||||
|
||||
float_precision dz = ground - GetFeetZ();
|
||||
|
||||
if (dz > StepHeight && !onlyJumpDown)
|
||||
{
|
||||
// dont restrict jump time when going up
|
||||
if (Jump(MUST_JUMP))
|
||||
{
|
||||
m_isJumpCrouching = true;
|
||||
m_isJumpCrouched = false;
|
||||
|
||||
StandUp();
|
||||
|
||||
m_jumpCrouchTimestamp = gpGlobals->time;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (!IsUsingLadder() && dz < -JumpHeight)
|
||||
{
|
||||
if (Jump(mustJump))
|
||||
{
|
||||
m_isJumpCrouching = true;
|
||||
m_isJumpCrouched = false;
|
||||
|
||||
StandUp();
|
||||
|
||||
m_jumpCrouchTimestamp = gpGlobals->time;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find "simple" ground height, treating current nav area as part of the floor
|
||||
|
||||
/* <37c448> ../cstrike/dlls/bot/cs_bot_nav.cpp:154 */
|
||||
NOBODY bool CCSBot::GetSimpleGroundHeightWithFloor(const Vector *pos, float *height, Vector *normal)
|
||||
bool CCSBot::GetSimpleGroundHeightWithFloor(const Vector *pos, float *height, Vector *normal)
|
||||
{
|
||||
// GetSimpleGroundHeightWithFloor(CCSBot *const this,
|
||||
// const Vector *pos,
|
||||
// float *height,
|
||||
// Vector *normal); // 154
|
||||
if (GetSimpleGroundHeight(pos, height, normal))
|
||||
{
|
||||
// our current nav area also serves as a ground polygon
|
||||
if (m_lastKnownArea != NULL && m_lastKnownArea->IsOverlapping(pos))
|
||||
{
|
||||
*height = Q_max((*height), m_lastKnownArea->GetZ(pos));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* <37c4b8> ../cstrike/dlls/bot/cs_bot_nav.cpp:172 */
|
||||
NOBODY Place CCSBot::GetPlace(void)
|
||||
Place CCSBot::GetPlace(void) const
|
||||
{
|
||||
if (m_lastKnownArea != NULL)
|
||||
return m_lastKnownArea->GetPlace();
|
||||
|
||||
return UNDEFINED_PLACE;
|
||||
}
|
||||
|
||||
/* <37c4de> ../cstrike/dlls/bot/cs_bot_nav.cpp:184 */
|
||||
NOBODY void CCSBot::MoveTowardsPosition(const Vector *pos)
|
||||
void CCSBot::MoveTowardsPosition(const Vector *pos)
|
||||
{
|
||||
// {
|
||||
// float angle; // 249
|
||||
// class Vector2D dir; // 251
|
||||
// class Vector2D lat; // 252
|
||||
// class Vector2D to; // 255
|
||||
// float toProj; // 259
|
||||
// float latProj; // 260
|
||||
// float const c; // 262
|
||||
// {
|
||||
// float ground; // 200
|
||||
// Vector aheadRay; // 201
|
||||
// bool jumped; // 207
|
||||
// NormalizeInPlace(Vector *const this); // 202
|
||||
// {
|
||||
// float const farLookAheadRange; // 210
|
||||
// Vector normal; // 211
|
||||
// Vector stepAhead; // 212
|
||||
// operator*(float fl,
|
||||
// const Vector &v); // 212
|
||||
// GetSimpleGroundHeightWithFloor(CCSBot *const this,
|
||||
// const Vector *pos,
|
||||
// float *height,
|
||||
// Vector *normal); // 215
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 212
|
||||
// DiscontinuityJump(CCSBot *const this,
|
||||
// float ground,
|
||||
// bool onlyJumpDown,
|
||||
// bool mustJump); // 218
|
||||
// }
|
||||
// {
|
||||
// float const lookAheadRange; // 225
|
||||
// Vector stepAhead; // 226
|
||||
// operator*(float fl,
|
||||
// const Vector &v); // 226
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 226
|
||||
// GetSimpleGroundHeightWithFloor(CCSBot *const this,
|
||||
// const Vector *pos,
|
||||
// float *height,
|
||||
// Vector *normal); // 228
|
||||
// DiscontinuityJump(CCSBot *const this,
|
||||
// float ground,
|
||||
// bool onlyJumpDown,
|
||||
// bool mustJump); // 230
|
||||
// }
|
||||
// {
|
||||
// float const lookAheadRange; // 237
|
||||
// Vector stepAhead; // 238
|
||||
// operator*(float fl,
|
||||
// const Vector &v); // 238
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 238
|
||||
// GetSimpleGroundHeightWithFloor(CCSBot *const this,
|
||||
// const Vector *pos,
|
||||
// float *height,
|
||||
// Vector *normal); // 240
|
||||
// DiscontinuityJump(CCSBot *const this,
|
||||
// float ground,
|
||||
// bool onlyJumpDown,
|
||||
// bool mustJump); // 242
|
||||
// }
|
||||
// }
|
||||
// NormalizeInPlace(Vector2D *const this); // 256
|
||||
// }
|
||||
// Jump up on ledges
|
||||
// Because we may not be able to get to our goal position and enter the next
|
||||
// area because our extent collides with a nearby vertical ledge, make sure
|
||||
// we look far enough ahead to avoid this situation.
|
||||
// Can't look too far ahead, or bots will try to jump up slopes.
|
||||
|
||||
// NOTE: We need to do this frequently to catch edges at the right time
|
||||
// TODO: Look ahead *along path* instead of straight line
|
||||
if ((m_lastKnownArea == NULL || !(m_lastKnownArea->GetAttributes() & NAV_NO_JUMP)) &&
|
||||
!IsOnLadder() && !m_isJumpCrouching)
|
||||
{
|
||||
float ground;
|
||||
Vector aheadRay(pos->x - pev->origin.x, pos->y - pev->origin.y, 0);
|
||||
aheadRay.NormalizeInPlace();
|
||||
|
||||
// look far ahead to allow us to smoothly jump over gaps, ledges, etc
|
||||
// only jump if ground is flat at lookahead spot to avoid jumping up slopes
|
||||
bool jumped = false;
|
||||
|
||||
if (IsRunning())
|
||||
{
|
||||
const float farLookAheadRange = 80.0f;
|
||||
Vector normal;
|
||||
Vector stepAhead = pev->origin + farLookAheadRange * aheadRay;
|
||||
stepAhead.z += HalfHumanHeight;
|
||||
|
||||
if (GetSimpleGroundHeightWithFloor(&stepAhead, &ground, &normal))
|
||||
{
|
||||
if (normal.z > 0.9f)
|
||||
jumped = DiscontinuityJump(ground, ONLY_JUMP_DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!jumped)
|
||||
{
|
||||
// close up jumping
|
||||
// cant be less or will miss jumps over low walls
|
||||
const float lookAheadRange = 30.0f;
|
||||
Vector stepAhead = pev->origin + lookAheadRange * aheadRay;
|
||||
stepAhead.z += HalfHumanHeight;
|
||||
|
||||
if (GetSimpleGroundHeightWithFloor(&stepAhead, &ground))
|
||||
{
|
||||
jumped = DiscontinuityJump(ground);
|
||||
}
|
||||
}
|
||||
|
||||
if (!jumped)
|
||||
{
|
||||
// about to fall gap-jumping
|
||||
const float lookAheadRange = 10.0f;
|
||||
Vector stepAhead = pev->origin + lookAheadRange * aheadRay;
|
||||
stepAhead.z += HalfHumanHeight;
|
||||
|
||||
if (GetSimpleGroundHeightWithFloor(&stepAhead, &ground))
|
||||
{
|
||||
jumped = DiscontinuityJump(ground, ONLY_JUMP_DOWN, MUST_JUMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compute our current forward and lateral vectors
|
||||
float angle = pev->v_angle.y;
|
||||
|
||||
Vector2D dir(BotCOS(angle), BotSIN(angle));
|
||||
Vector2D lat(-dir.y, dir.x);
|
||||
|
||||
// compute unit vector to goal position
|
||||
Vector2D to(pos->x - pev->origin.x, pos->y - pev->origin.y);
|
||||
to.NormalizeInPlace();
|
||||
|
||||
// move towards the position independant of our view direction
|
||||
float toProj = to.x * dir.x + to.y * dir.y;
|
||||
float latProj = to.x * lat.x + to.y * lat.y;
|
||||
|
||||
const float c = 0.25f;
|
||||
if (toProj > c)
|
||||
MoveForward();
|
||||
else if (toProj < -c)
|
||||
MoveBackward();
|
||||
|
||||
// if we are avoiding someone via strafing, don't override
|
||||
if (m_avoid != NULL)
|
||||
return;
|
||||
|
||||
if (latProj >= c)
|
||||
StrafeLeft();
|
||||
else if (latProj <= -c)
|
||||
StrafeRight();
|
||||
}
|
||||
|
||||
// Move away from position, independant of view angle
|
||||
|
||||
/* <37ca96> ../cstrike/dlls/bot/cs_bot_nav.cpp:282 */
|
||||
NOBODY void CCSBot::MoveAwayFromPosition(const Vector *pos)
|
||||
NOXREF void CCSBot::MoveAwayFromPosition(const Vector *pos)
|
||||
{
|
||||
// {
|
||||
// float angle; // 285
|
||||
// class Vector2D dir; // 287
|
||||
// class Vector2D lat; // 288
|
||||
// class Vector2D to; // 291
|
||||
// float toProj; // 295
|
||||
// float latProj; // 296
|
||||
// float const c; // 298
|
||||
// NormalizeInPlace(Vector2D *const this); // 292
|
||||
// }
|
||||
// compute our current forward and lateral vectors
|
||||
float angle = pev->v_angle[ YAW ];
|
||||
|
||||
Vector2D dir(BotCOS(angle), BotSIN(angle));
|
||||
Vector2D lat(-dir.y, dir.x);
|
||||
|
||||
// compute unit vector to goal position
|
||||
Vector2D to(pos->x - pev->origin.x, pos->y - pev->origin.y);
|
||||
to.NormalizeInPlace();
|
||||
|
||||
// move away from the position independant of our view direction
|
||||
float toProj = to.x * dir.x + to.y * dir.y;
|
||||
float latProj = to.x * lat.x + to.y * lat.y;
|
||||
|
||||
const float c = 0.5f;
|
||||
if (toProj > c)
|
||||
MoveBackward();
|
||||
else if (toProj < -c)
|
||||
MoveForward();
|
||||
|
||||
if (latProj >= c)
|
||||
StrafeRight();
|
||||
else if (latProj <= -c)
|
||||
StrafeLeft();
|
||||
}
|
||||
|
||||
// Strafe (sidestep) away from position, independant of view angle
|
||||
|
||||
/* <37cb85> ../cstrike/dlls/bot/cs_bot_nav.cpp:314 */
|
||||
NOBODY void CCSBot::StrafeAwayFromPosition(const Vector *pos)
|
||||
void CCSBot::StrafeAwayFromPosition(const Vector *pos)
|
||||
{
|
||||
// {
|
||||
// float angle; // 317
|
||||
// class Vector2D dir; // 319
|
||||
// class Vector2D lat; // 320
|
||||
// class Vector2D to; // 323
|
||||
// float latProj; // 326
|
||||
// NormalizeInPlace(Vector2D *const this); // 324
|
||||
// }
|
||||
// compute our current forward and lateral vectors
|
||||
float angle = pev->v_angle[ YAW ];
|
||||
|
||||
Vector2D dir(BotCOS(angle), BotSIN(angle));
|
||||
Vector2D lat(-dir.y, dir.x);
|
||||
|
||||
// compute unit vector to goal position
|
||||
Vector2D to(pos->x - pev->origin.x, pos->y - pev->origin.y);
|
||||
to.NormalizeInPlace();
|
||||
|
||||
float latProj = to.x * lat.x + to.y * lat.y;
|
||||
|
||||
if (latProj >= 0.0f)
|
||||
StrafeRight();
|
||||
else
|
||||
StrafeLeft();
|
||||
}
|
||||
|
||||
// For getting un-stuck
|
||||
|
||||
/* <37cc52> ../cstrike/dlls/bot/cs_bot_nav.cpp:338 */
|
||||
NOBODY void CCSBot::Wiggle(void)
|
||||
void CCSBot::Wiggle(void)
|
||||
{
|
||||
// ResetStuckMonitor(CCSBot *const this); // 342
|
||||
if (IsCrouching())
|
||||
{
|
||||
ResetStuckMonitor();
|
||||
return;
|
||||
}
|
||||
|
||||
// for wiggling
|
||||
if (gpGlobals->time >= m_wiggleTimestamp)
|
||||
{
|
||||
m_wiggleDirection = (NavRelativeDirType)RANDOM_LONG(0, 3);
|
||||
m_wiggleTimestamp = RANDOM_FLOAT(0.5, 1.5) + gpGlobals->time;
|
||||
}
|
||||
|
||||
// TODO: implement checking of the movement to fall down
|
||||
switch (m_wiggleDirection)
|
||||
{
|
||||
case LEFT:
|
||||
StrafeLeft();
|
||||
break;
|
||||
case RIGHT:
|
||||
StrafeRight();
|
||||
break;
|
||||
case FORWARD:
|
||||
MoveForward();
|
||||
break;
|
||||
case BACKWARD:
|
||||
MoveBackward();
|
||||
break;
|
||||
}
|
||||
|
||||
if (gpGlobals->time >= m_stuckJumpTimestamp)
|
||||
{
|
||||
if (Jump())
|
||||
{
|
||||
m_stuckJumpTimestamp = RANDOM_FLOAT(1.0, 2.0) + gpGlobals->time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine approach points from eye position and approach areas of current area
|
||||
|
||||
/* <37cc94> ../cstrike/dlls/bot/cs_bot_nav.cpp:383 */
|
||||
NOBODY void CCSBot::ComputeApproachPoints(void)
|
||||
void CCSBot::ComputeApproachPoints(void)
|
||||
{
|
||||
// {
|
||||
// Vector eye; // 391
|
||||
// Vector ap; // 393
|
||||
// float halfWidth; // 394
|
||||
// Vector(Vector *const this,
|
||||
// const Vector &v); // 391
|
||||
// {
|
||||
// int i; // 395
|
||||
// {
|
||||
// const class ApproachInfo *info; // 397
|
||||
// Vector bendPoint; // 415
|
||||
// }
|
||||
// GetApproachInfoCount(const class CNavArea *const this); // 395
|
||||
// }
|
||||
// }
|
||||
m_approachPointCount = 0;
|
||||
|
||||
if (m_lastKnownArea == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// assume we're crouching for now
|
||||
Vector eye = pev->origin;
|
||||
|
||||
Vector ap;
|
||||
float halfWidth;
|
||||
for (int i = 0; i < m_lastKnownArea->GetApproachInfoCount() && m_approachPointCount < MAX_APPROACH_POINTS; ++i)
|
||||
{
|
||||
const CNavArea::ApproachInfo *info = m_lastKnownArea->GetApproachInfo(i);
|
||||
|
||||
if (info->here.area == NULL || info->prev.area == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// compute approach point (approach area is "info->here")
|
||||
if (info->prevToHereHow <= GO_WEST)
|
||||
{
|
||||
info->prev.area->ComputePortal(info->here.area, (NavDirType)info->prevToHereHow, &ap, &halfWidth);
|
||||
ap.z = info->here.area->GetZ(&ap);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use the area's center as an approach point
|
||||
ap = *info->here.area->GetCenter();
|
||||
}
|
||||
|
||||
// "bend" our line of sight around corners until we can see the approach point
|
||||
Vector bendPoint;
|
||||
if (BendLineOfSight(&eye, &ap, &bendPoint))
|
||||
{
|
||||
m_approachPoint[ m_approachPointCount++ ] = bendPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* <37cd67> ../cstrike/dlls/bot/cs_bot_nav.cpp:422 */
|
||||
NOBODY void CCSBot::DrawApproachPoints(void)
|
||||
void CCSBot::DrawApproachPoints(void)
|
||||
{
|
||||
// {
|
||||
// int i; // 427
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 428
|
||||
// Vector(Vector *const this,
|
||||
// const Vector &v); // 428
|
||||
// }
|
||||
for (int i = 0; i < m_approachPointCount; ++i)
|
||||
{
|
||||
UTIL_DrawBeamPoints(m_approachPoint[i], m_approachPoint[i] + Vector(0, 0, 50), 3, 0, 255, 255);
|
||||
}
|
||||
}
|
||||
|
||||
// Find the approach point that is nearest to our current path, ahead of us
|
||||
|
||||
/* <37ce12> ../cstrike/dlls/bot/cs_bot_nav.cpp:435 */
|
||||
NOBODY bool CCSBot::FindApproachPointNearestPath(const Vector *pos)
|
||||
NOXREF bool CCSBot::FindApproachPointNearestPath(Vector *pos)
|
||||
{
|
||||
// {
|
||||
// Vector target; // 446
|
||||
// Vector close; // 446
|
||||
// float targetRangeSq; // 447
|
||||
// bool found; // 448
|
||||
// int start; // 450
|
||||
// int end; // 451
|
||||
// float const nearPathSq; // 457
|
||||
// {
|
||||
// int i; // 459
|
||||
// {
|
||||
// float rangeSq; // 464
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 464
|
||||
// LengthSquared(const Vector *const this); // 464
|
||||
// }
|
||||
// }
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 478
|
||||
// }
|
||||
if (!HasPath())
|
||||
return false;
|
||||
|
||||
// make sure approach points are accurate
|
||||
ComputeApproachPoints();
|
||||
|
||||
if (m_approachPointCount == 0)
|
||||
return false;
|
||||
|
||||
Vector target = Vector(0, 0, 0), close;
|
||||
float targetRangeSq = 0.0f;
|
||||
bool found = false;
|
||||
|
||||
int start = m_pathIndex;
|
||||
int end = m_pathLength;
|
||||
|
||||
// We dont want the strictly closest point, but the farthest approach point
|
||||
// from us that is near our path
|
||||
const float nearPathSq = 10000.0f;
|
||||
|
||||
for (int i = 0; i < m_approachPointCount; ++i)
|
||||
{
|
||||
if (FindClosestPointOnPath(&m_approachPoint[i], start, end, &close) == false)
|
||||
continue;
|
||||
|
||||
float rangeSq = (m_approachPoint[i] - close).LengthSquared();
|
||||
if (rangeSq > nearPathSq)
|
||||
continue;
|
||||
|
||||
if (rangeSq > targetRangeSq)
|
||||
{
|
||||
target = close;
|
||||
targetRangeSq = rangeSq;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
*pos = target + Vector(0, 0, HalfHumanHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,64 +1,334 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <3a397f> ../cstrike/dlls/bot/cs_bot_radio.cpp:220 */
|
||||
NOBODY void CCSBot::StartVoiceFeedback(float duration)
|
||||
{
|
||||
// {
|
||||
// class CBasePlayer *pPlayer; // 227
|
||||
// MESSAGE_BEGIN(int msg_dest,
|
||||
// int msg_type,
|
||||
// const float *pOrigin,
|
||||
// entvars_t *ent); // 230
|
||||
// edict(CBaseEntity *const this); // 232
|
||||
// ENTINDEX(edict_t *pEdict); // 232
|
||||
// }
|
||||
// Returns true if the radio message is an order to do something
|
||||
// NOTE: "Report in" is not considered a "command" because it doesnt ask the bot to go somewhere, or change its mind
|
||||
/* <3a3689> ../cstrike/dlls/bot/cs_bot_radio.cpp:19 */
|
||||
bool CCSBot::IsRadioCommand(GameEventType event) const
|
||||
{
|
||||
if (event == EVENT_RADIO_AFFIRMATIVE
|
||||
|| event == EVENT_RADIO_NEGATIVE
|
||||
|| event == EVENT_RADIO_ENEMY_SPOTTED
|
||||
|| event == EVENT_RADIO_SECTOR_CLEAR
|
||||
|| event == EVENT_RADIO_REPORTING_IN
|
||||
|| event == EVENT_RADIO_REPORT_IN_TEAM
|
||||
|| event == EVENT_RADIO_ENEMY_DOWN)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* <3a3a32> ../cstrike/dlls/bot/cs_bot_radio.cpp:241 */
|
||||
void CCSBot::EndVoiceFeedback(bool force)
|
||||
{
|
||||
if (!force && !m_voiceFeedbackEndTimestamp)
|
||||
return;
|
||||
|
||||
m_voiceFeedbackEndTimestamp = 0;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgBotVoice);
|
||||
WRITE_BYTE(0);
|
||||
WRITE_BYTE(ENTINDEX(edict()));
|
||||
MESSAGE_END();
|
||||
}
|
||||
// Respond to radio commands from HUMAN players
|
||||
|
||||
/* <3a3bcd> ../cstrike/dlls/bot/cs_bot_radio.cpp:259 */
|
||||
NOBODY bool CCSBot::RespondToHelpRequest(CBasePlayer *them, Place place, float maxRange)
|
||||
{
|
||||
// {
|
||||
// class PathCost pc; // 272
|
||||
// float travelDistance; // 273
|
||||
// NavAreaTravelDistance<PathCost>(CNavArea *startArea,
|
||||
// class CNavArea *endArea,
|
||||
// class PathCost &costFunc); // 273
|
||||
// }
|
||||
// {
|
||||
// float rangeSq; // 287
|
||||
// float const close; // 288
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 287
|
||||
// LengthSquared(const Vector *const this); // 287
|
||||
// }
|
||||
// {
|
||||
// const Vector *pos; // 301
|
||||
// }
|
||||
// Say(BotChatterInterface *const this,
|
||||
// const char *phraseName,
|
||||
// float lifetime,
|
||||
// float delay); // 309
|
||||
/* <3a36e0> ../cstrike/dlls/bot/cs_bot_radio.cpp:37 */
|
||||
void CCSBot::RespondToRadioCommands(void)
|
||||
{
|
||||
// bots use the chatter system to respond to each other
|
||||
if (m_radioSubject != NULL && m_radioSubject->IsPlayer())
|
||||
{
|
||||
CBasePlayer *player = m_radioSubject;
|
||||
if (player->IsBot())
|
||||
{
|
||||
m_lastRadioCommand = EVENT_INVALID;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_lastRadioCommand == EVENT_INVALID)
|
||||
return;
|
||||
|
||||
// a human player has issued a radio command
|
||||
GetChatter()->ResetRadioSilenceDuration();
|
||||
|
||||
// if we are doing something important, ignore the radio
|
||||
// unless it is a "report in" request - we can do that while we continue to do other things
|
||||
// TODO: Create "uninterruptable" flag
|
||||
if (m_lastRadioCommand != EVENT_RADIO_REPORT_IN_TEAM)
|
||||
{
|
||||
if (IsBusy())
|
||||
{
|
||||
// consume command
|
||||
m_lastRadioCommand = EVENT_INVALID;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// wait for reaction time before responding
|
||||
// delay needs to be long enough for the radio message we're responding to to finish
|
||||
float respondTime = 1.0f + 2.0f * GetProfile()->GetReactionTime();
|
||||
if (IsRogue())
|
||||
respondTime += 2.0f;
|
||||
|
||||
if (gpGlobals->time - m_lastRadioRecievedTimestamp < respondTime)
|
||||
return;
|
||||
|
||||
// rogues won't follow commands, unless already following the player
|
||||
if (!IsFollowing() && IsRogue())
|
||||
{
|
||||
if (IsRadioCommand(m_lastRadioCommand))
|
||||
{
|
||||
GetChatter()->Negative();
|
||||
}
|
||||
|
||||
// consume command
|
||||
m_lastRadioCommand = EVENT_INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
CBasePlayer *player = m_radioSubject;
|
||||
if (player == NULL)
|
||||
return;
|
||||
|
||||
// respond to command
|
||||
bool canDo = false;
|
||||
const float inhibitAutoFollowDuration = 60.0f;
|
||||
switch (m_lastRadioCommand)
|
||||
{
|
||||
case EVENT_RADIO_REPORT_IN_TEAM:
|
||||
{
|
||||
GetChatter()->ReportingIn();
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_FOLLOW_ME:
|
||||
case EVENT_RADIO_COVER_ME:
|
||||
case EVENT_RADIO_STICK_TOGETHER_TEAM:
|
||||
case EVENT_RADIO_REGROUP_TEAM:
|
||||
{
|
||||
if (!IsFollowing())
|
||||
{
|
||||
Follow(player);
|
||||
player->AllowAutoFollow();
|
||||
canDo = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_ENEMY_SPOTTED:
|
||||
case EVENT_RADIO_NEED_BACKUP:
|
||||
case EVENT_RADIO_TAKING_FIRE:
|
||||
{
|
||||
if (!IsFollowing())
|
||||
{
|
||||
Follow(player);
|
||||
GetChatter()->Say("OnMyWay");
|
||||
player->AllowAutoFollow();
|
||||
canDo = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_TEAM_FALL_BACK:
|
||||
{
|
||||
if (TryToRetreat())
|
||||
canDo = true;
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_HOLD_THIS_POSITION:
|
||||
{
|
||||
// find the leader's area
|
||||
SetTask(HOLD_POSITION);
|
||||
StopFollowing();
|
||||
player->InhibitAutoFollow(inhibitAutoFollowDuration);
|
||||
Hide(TheNavAreaGrid.GetNearestNavArea(&m_radioPosition));
|
||||
canDo = true;
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_GO_GO_GO:
|
||||
case EVENT_RADIO_STORM_THE_FRONT:
|
||||
{
|
||||
StopFollowing();
|
||||
Hunt();
|
||||
canDo = true;
|
||||
player->InhibitAutoFollow(inhibitAutoFollowDuration);
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_GET_OUT_OF_THERE:
|
||||
{
|
||||
if (TheCSBots()->IsBombPlanted())
|
||||
{
|
||||
EscapeFromBomb();
|
||||
player->InhibitAutoFollow(inhibitAutoFollowDuration);
|
||||
canDo = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_RADIO_SECTOR_CLEAR:
|
||||
{
|
||||
// if this is a defusal scenario, and the bomb is planted,
|
||||
// and a human player cleared a bombsite, check it off our list too
|
||||
if (TheCSBots()->GetScenario() == CCSBotManager::SCENARIO_DEFUSE_BOMB)
|
||||
{
|
||||
if (m_iTeam == CT && TheCSBots()->IsBombPlanted())
|
||||
{
|
||||
const CCSBotManager::Zone *zone = TheCSBots()->GetClosestZone(player);
|
||||
|
||||
if (zone != NULL)
|
||||
{
|
||||
GetGameState()->ClearBombsite(zone->m_index);
|
||||
|
||||
// if we are huting for the planted bomb, re-select bombsite
|
||||
if (GetTask() == FIND_TICKING_BOMB)
|
||||
Idle();
|
||||
|
||||
canDo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// ignore all other radio commands for now
|
||||
return;
|
||||
}
|
||||
|
||||
if (canDo)
|
||||
{
|
||||
// affirmative
|
||||
GetChatter()->Affirmative();
|
||||
|
||||
// if we agreed to follow a new command, put away our grenade
|
||||
if (IsRadioCommand(m_lastRadioCommand) && IsUsingGrenade())
|
||||
{
|
||||
EquipBestWeapon();
|
||||
}
|
||||
}
|
||||
|
||||
// consume command
|
||||
m_lastRadioCommand = EVENT_INVALID;
|
||||
}
|
||||
|
||||
/* <3a4316> ../cstrike/dlls/bot/cs_bot_radio.cpp:319 */
|
||||
NOBODY void CCSBot::SendRadioMessage(GameEventType event)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 328
|
||||
// char slot; // 333
|
||||
// }
|
||||
}
|
||||
// Send voice chatter. Also sends the entindex.
|
||||
|
||||
/* <3a397f> ../cstrike/dlls/bot/cs_bot_radio.cpp:220 */
|
||||
void CCSBot::StartVoiceFeedback(float duration)
|
||||
{
|
||||
m_voiceFeedbackStartTimestamp = gpGlobals->time;
|
||||
m_voiceFeedbackEndTimestamp = duration + gpGlobals->time;
|
||||
|
||||
CBasePlayer *pPlayer = NULL;
|
||||
while ((pPlayer = GetNextRadioRecipient(pPlayer)) != NULL)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgBotVoice, NULL, pPlayer->pev);
|
||||
WRITE_BYTE(1); // active is talking
|
||||
WRITE_BYTE(entindex()); // client index speaking
|
||||
MESSAGE_END();
|
||||
}
|
||||
}
|
||||
|
||||
/* <3a3a32> ../cstrike/dlls/bot/cs_bot_radio.cpp:241 */
|
||||
void CCSBot::EndVoiceFeedback(bool force)
|
||||
{
|
||||
if (!force && !m_voiceFeedbackEndTimestamp)
|
||||
return;
|
||||
|
||||
m_voiceFeedbackEndTimestamp = 0;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgBotVoice);
|
||||
WRITE_BYTE(0);
|
||||
WRITE_BYTE(ENTINDEX(edict()));
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
// Decide if we should move to help the player, return true if we will
|
||||
|
||||
/* <3a3bcd> ../cstrike/dlls/bot/cs_bot_radio.cpp:259 */
|
||||
bool CCSBot::RespondToHelpRequest(CBasePlayer *them, Place place, float maxRange)
|
||||
{
|
||||
if (IsRogue())
|
||||
return false;
|
||||
|
||||
// if we're busy, ignore
|
||||
if (IsBusy())
|
||||
return false;
|
||||
|
||||
// if we are too far away, ignore
|
||||
if (maxRange > 0.0f)
|
||||
{
|
||||
// compute actual travel distance
|
||||
PathCost pc(this);
|
||||
float_precision travelDistance = NavAreaTravelDistance(m_lastKnownArea, TheNavAreaGrid.GetNearestNavArea(&them->pev->origin), pc);
|
||||
if (travelDistance < 0.0f)
|
||||
return false;
|
||||
|
||||
if (travelDistance > maxRange)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (place == UNDEFINED_PLACE)
|
||||
{
|
||||
// if we have no "place" identifier, go directly to them
|
||||
|
||||
// if we are already there, ignore
|
||||
float rangeSq = (them->pev->origin - pev->origin).LengthSquared();
|
||||
const float close = 750.0f * 750.0f;
|
||||
|
||||
if (rangeSq < close)
|
||||
return true;
|
||||
|
||||
MoveTo(&them->pev->origin, FASTEST_ROUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we are already there, ignore
|
||||
if (GetPlace() == place)
|
||||
return true;
|
||||
|
||||
// go to where help is needed
|
||||
const Vector *pos = GetRandomSpotAtPlace(place);
|
||||
if (pos != NULL)
|
||||
{
|
||||
MoveTo(pos, FASTEST_ROUTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveTo(&them->pev->origin, FASTEST_ROUTE);
|
||||
}
|
||||
}
|
||||
|
||||
// acknowledge
|
||||
GetChatter()->Say("OnMyWay");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send a radio message
|
||||
|
||||
/* <3a4316> ../cstrike/dlls/bot/cs_bot_radio.cpp:319 */
|
||||
void CCSBot::SendRadioMessage(GameEventType event)
|
||||
{
|
||||
// make sure this is a radio event
|
||||
if (event <= EVENT_START_RADIO_1 || event >= EVENT_END_RADIO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CCSBotManager *ctrl = TheCSBots();
|
||||
PrintIfWatched("%3.1f: SendRadioMessage( %s )\n", gpGlobals->time, GameEventName[ event ]);
|
||||
|
||||
// note the time the message was sent
|
||||
ctrl->SetRadioMessageTimestamp(event, m_iTeam);
|
||||
|
||||
m_lastRadioSentTimestamp = gpGlobals->time;
|
||||
|
||||
char slot[2];
|
||||
slot[1] = '\000';
|
||||
|
||||
if (event > EVENT_START_RADIO_1 && event < EVENT_START_RADIO_2)
|
||||
{
|
||||
slot[0] = event - EVENT_START_RADIO_1;
|
||||
ClientCommand("radio1");
|
||||
//Radio1(this, event - EVENT_START_RADIO_3);
|
||||
}
|
||||
else if (event > EVENT_START_RADIO_2 && event < EVENT_START_RADIO_3)
|
||||
{
|
||||
slot[0] = event - EVENT_START_RADIO_2;
|
||||
ClientCommand("radio2");
|
||||
//Radio2(this, event - EVENT_START_RADIO_3);
|
||||
}
|
||||
else
|
||||
{
|
||||
slot[0] = event - EVENT_START_RADIO_3;
|
||||
ClientCommand("radio3");
|
||||
//Radio3(this, event - EVENT_START_RADIO_3);
|
||||
}
|
||||
|
||||
ClientCommand("menuselect", slot);
|
||||
ClientCommand("menuselect", "10");
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// This method is the ONLY legal way to change a bot's current state
|
||||
|
||||
/* <3b3a2a> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:16 */
|
||||
void CCSBot::SetState(BotState *state)
|
||||
{
|
||||
PrintIfWatched("SetState: %s -> %s\n", (m_state != NULL) ? m_state->GetName() : "NULL", state->GetName());
|
||||
|
||||
// if we changed state from within the special Attack state, we are no longer attacking
|
||||
if (m_isAttacking)
|
||||
{
|
||||
StopAttacking();
|
||||
}
|
||||
|
||||
if (m_state)
|
||||
{
|
||||
if (m_state != NULL)
|
||||
m_state->OnExit(this);
|
||||
}
|
||||
|
||||
state->OnEnter(this);
|
||||
|
||||
@ -29,144 +28,256 @@ void CCSBot::Idle(void)
|
||||
}
|
||||
|
||||
/* <3b3afa> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:41 */
|
||||
NOBODY void CCSBot::EscapeFromBomb(void)
|
||||
void CCSBot::EscapeFromBomb(void)
|
||||
{
|
||||
// SetTask(CCSBot::EscapeFromBomb(// enum TaskType task,
|
||||
// class CBaseEntity *entity); // 43
|
||||
SetTask(ESCAPE_FROM_BOMB);
|
||||
SetState(&m_escapeFromBombState);
|
||||
}
|
||||
|
||||
/* <3b3b4b> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:48 */
|
||||
NOBODY void CCSBot::Follow(CBasePlayer *player)
|
||||
void CCSBot::Follow(CBasePlayer *player)
|
||||
{
|
||||
// SetTask(CCSBot *const this,
|
||||
// enum TaskType task,
|
||||
// class CBaseEntity *entity); // 60
|
||||
// SetLeader(FollowState *const this,
|
||||
// class CBasePlayer *player); // 61
|
||||
if (player == NULL)
|
||||
return;
|
||||
|
||||
// note when we began following
|
||||
if (!m_isFollowing || m_leader != player)
|
||||
m_followTimestamp = gpGlobals->time;
|
||||
|
||||
m_isFollowing = true;
|
||||
m_leader = player;
|
||||
|
||||
SetTask(FOLLOW);
|
||||
m_followState.SetLeader(player);
|
||||
SetState(&m_followState);
|
||||
}
|
||||
|
||||
// Continue following our leader after finishing what we were doing
|
||||
|
||||
/* <3b3bd1> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:69 */
|
||||
NOBODY void CCSBot::ContinueFollowing(void)
|
||||
void CCSBot::ContinueFollowing(void)
|
||||
{
|
||||
// {
|
||||
// class CBasePlayer *leader; // 73
|
||||
// SetTask(CCSBot *const this,
|
||||
// enum TaskType task,
|
||||
// class CBaseEntity *entity); // 71
|
||||
// SetLeader(FollowState *const this,
|
||||
// class CBasePlayer *player); // 74
|
||||
// }
|
||||
SetTask(FOLLOW);
|
||||
m_followState.SetLeader(m_leader);
|
||||
SetState(&m_followState);
|
||||
}
|
||||
|
||||
// Stop following
|
||||
|
||||
/* <3b3c57> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:83 */
|
||||
NOBODY void CCSBot::StopFollowing(void)
|
||||
void CCSBot::StopFollowing(void)
|
||||
{
|
||||
m_isFollowing = false;
|
||||
m_leader = NULL;
|
||||
m_allowAutoFollowTime = gpGlobals->time + 10.0f;
|
||||
}
|
||||
|
||||
// Begin process of rescuing hostages
|
||||
|
||||
/* <3b3c7e> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:94 */
|
||||
NOBODY void CCSBot::RescueHostages(void)
|
||||
void CCSBot::RescueHostages(void)
|
||||
{
|
||||
// SetTask(CCSBot::RescueHostages(// enum TaskType task,
|
||||
// class CBaseEntity *entity); // 96
|
||||
SetTask(RESCUE_HOSTAGES);
|
||||
}
|
||||
|
||||
// Use the entity
|
||||
|
||||
/* <3b3cc9> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:103 */
|
||||
NOBODY void CCSBot::UseEntity(CBaseEntity *entity)
|
||||
void CCSBot::UseEntity(CBaseEntity *entity)
|
||||
{
|
||||
// SetEntity(UseEntityState *const this,
|
||||
// class CBaseEntity *entity); // 105
|
||||
m_useEntityState.SetEntity(entity);
|
||||
SetState(&m_useEntityState);
|
||||
}
|
||||
|
||||
// DEPRECATED: Use TryToHide() instead.
|
||||
// Move to a hiding place.
|
||||
// If 'searchFromArea' is non-NULL, hiding spots are looked for from that area first.
|
||||
|
||||
/* <3b3d23> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:116 */
|
||||
NOBODY void CCSBot::Hide(CNavArea *searchFromArea, float duration, float hideRange, bool holdPosition)
|
||||
void CCSBot::Hide(CNavArea *searchFromArea, float duration, float hideRange, bool holdPosition)
|
||||
{
|
||||
// {
|
||||
// class CNavArea *source; // 120
|
||||
// Vector sourcePos; // 121
|
||||
// const Vector *pos; // 146
|
||||
// DestroyPath(CCSBot *const this); // 118
|
||||
// SetDuration(HideState *const this,
|
||||
// float time); // 142
|
||||
// SetSearchArea(HideState *const this,
|
||||
// class CNavArea *area); // 140
|
||||
// SetSearchRange(HideState *const this,
|
||||
// float range); // 141
|
||||
// SetHoldPosition(HideState *const this,
|
||||
// bool hold); // 143
|
||||
// SetHidingSpot(HideState *const this,
|
||||
// const Vector *pos); // 154
|
||||
// Idle(CCSBot *const this); // 160
|
||||
// }
|
||||
DestroyPath();
|
||||
|
||||
CNavArea *source;
|
||||
Vector sourcePos;
|
||||
if (searchFromArea)
|
||||
{
|
||||
source = searchFromArea;
|
||||
sourcePos = *searchFromArea->GetCenter();
|
||||
}
|
||||
else
|
||||
{
|
||||
source = m_lastKnownArea;
|
||||
sourcePos = pev->origin;
|
||||
}
|
||||
|
||||
if (source == NULL)
|
||||
{
|
||||
PrintIfWatched("Hide from area is NULL.\n");
|
||||
Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
m_hideState.SetSearchArea(source);
|
||||
m_hideState.SetSearchRange(hideRange);
|
||||
m_hideState.SetDuration(duration);
|
||||
m_hideState.SetHoldPosition(holdPosition);
|
||||
|
||||
// search around source area for a good hiding spot
|
||||
Vector useSpot;
|
||||
|
||||
const Vector *pos = FindNearbyHidingSpot(this, &sourcePos, source, hideRange, IsSniper());
|
||||
if (pos == NULL)
|
||||
{
|
||||
PrintIfWatched("No available hiding spots.\n");
|
||||
// hide at our current position
|
||||
useSpot = pev->origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
useSpot = *pos;
|
||||
}
|
||||
|
||||
m_hideState.SetHidingSpot(useSpot);
|
||||
|
||||
// build a path to our new hiding spot
|
||||
if (ComputePath(TheNavAreaGrid.GetNavArea(&useSpot), &useSpot, FASTEST_ROUTE) == false)
|
||||
{
|
||||
PrintIfWatched("Can't pathfind to hiding spot\n");
|
||||
Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
SetState(&m_hideState);
|
||||
}
|
||||
|
||||
// Move to the given hiding place
|
||||
|
||||
/* <3b3e98> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:171 */
|
||||
NOBODY void CCSBot::Hide(const Vector *hidingSpot, float duration, bool holdPosition)
|
||||
void CCSBot::Hide(const Vector *hidingSpot, float duration, bool holdPosition)
|
||||
{
|
||||
// {
|
||||
// class CNavArea *hideArea; // 173
|
||||
// DestroyPath(CCSBot *const this); // 181
|
||||
// SetHoldPosition(HideState *const this,
|
||||
// bool hold); // 186
|
||||
// SetSearchArea(HideState *const this,
|
||||
// class CNavArea *area); // 183
|
||||
// SetSearchRange(HideState *const this,
|
||||
// float range); // 184
|
||||
// SetDuration(HideState *const this,
|
||||
// float time); // 185
|
||||
// SetHidingSpot(HideState *const this,
|
||||
// const Vector *pos); // 187
|
||||
// Idle(CCSBot *const this); // 193
|
||||
// }
|
||||
CNavArea *hideArea = TheNavAreaGrid.GetNearestNavArea(hidingSpot);
|
||||
if (hideArea == NULL)
|
||||
{
|
||||
PrintIfWatched("Hiding spot off nav mesh\n");
|
||||
Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
DestroyPath();
|
||||
|
||||
m_hideState.SetSearchArea(hideArea);
|
||||
m_hideState.SetSearchRange(750.0f);
|
||||
m_hideState.SetDuration(duration);
|
||||
m_hideState.SetHoldPosition(holdPosition);
|
||||
m_hideState.SetHidingSpot(*hidingSpot);
|
||||
|
||||
// build a path to our new hiding spot
|
||||
if (ComputePath(hideArea, hidingSpot, FASTEST_ROUTE) == false)
|
||||
{
|
||||
PrintIfWatched("Can't pathfind to hiding spot\n");
|
||||
Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
SetState(&m_hideState);
|
||||
}
|
||||
|
||||
// Try to hide nearby. Return true if hiding, false if can't hide here.
|
||||
// If 'searchFromArea' is non-NULL, hiding spots are looked for from that area first.
|
||||
|
||||
/* <3b3fc1> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:205 */
|
||||
NOBODY bool CCSBot::TryToHide(CNavArea *searchFromArea, float duration, float hideRange, bool holdPosition, bool useNearest)
|
||||
bool CCSBot::TryToHide(CNavArea *searchFromArea, float duration, float hideRange, bool holdPosition, bool useNearest)
|
||||
{
|
||||
// {
|
||||
// class CNavArea *source; // 207
|
||||
// Vector sourcePos; // 208
|
||||
// const Vector *pos; // 232
|
||||
// SetDuration(HideState *const this,
|
||||
// float time); // 228
|
||||
// SetSearchArea(HideState *const this,
|
||||
// class CNavArea *area); // 226
|
||||
// SetSearchRange(HideState *const this,
|
||||
// float range); // 227
|
||||
// SetHoldPosition(HideState *const this,
|
||||
// bool hold); // 229
|
||||
// SetHidingSpot(HideState *const this,
|
||||
// const Vector *pos); // 239
|
||||
// }
|
||||
CNavArea *source;
|
||||
Vector sourcePos;
|
||||
if (searchFromArea)
|
||||
{
|
||||
source = searchFromArea;
|
||||
sourcePos = *searchFromArea->GetCenter();
|
||||
}
|
||||
else
|
||||
{
|
||||
source = m_lastKnownArea;
|
||||
sourcePos = pev->origin;
|
||||
}
|
||||
|
||||
if (source == NULL)
|
||||
{
|
||||
PrintIfWatched("Hide from area is NULL.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hideState.SetSearchArea(source);
|
||||
m_hideState.SetSearchRange(hideRange);
|
||||
m_hideState.SetDuration(duration);
|
||||
m_hideState.SetHoldPosition(holdPosition);
|
||||
|
||||
// search around source area for a good hiding spot
|
||||
const Vector *pos = FindNearbyHidingSpot(this, &sourcePos, source, hideRange, IsSniper(), useNearest);
|
||||
if (pos == NULL)
|
||||
{
|
||||
PrintIfWatched("No available hiding spots.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hideState.SetHidingSpot(*pos);
|
||||
|
||||
// build a path to our new hiding spot
|
||||
if (ComputePath(TheNavAreaGrid.GetNavArea(pos), pos, FASTEST_ROUTE) == false)
|
||||
{
|
||||
PrintIfWatched("Can't pathfind to hiding spot\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
SetState(&m_hideState);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Retreat to a nearby hiding spot, away from enemies
|
||||
|
||||
/* <3b40ed> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:256 */
|
||||
NOBODY bool CCSBot::TryToRetreat(void)
|
||||
bool CCSBot::TryToRetreat(void)
|
||||
{
|
||||
// {
|
||||
// const Vector *spot; // 258
|
||||
// {
|
||||
// float holdTime; // 265
|
||||
// Hide(CCSBot *const this,
|
||||
// const Vector *hidingSpot,
|
||||
// float duration,
|
||||
// bool holdPosition); // 268
|
||||
// }
|
||||
// }
|
||||
const float maxRange = 1000.0f;
|
||||
const Vector *spot = FindNearbyRetreatSpot(this, maxRange);
|
||||
|
||||
if (spot != NULL)
|
||||
{
|
||||
// ignore enemies for a second to give us time to hide
|
||||
// reaching our hiding spot clears our disposition
|
||||
IgnoreEnemies(10.0f);
|
||||
|
||||
float holdTime = RANDOM_FLOAT(3.0f, 15.0f);
|
||||
|
||||
StandUp();
|
||||
Run();
|
||||
Hide(spot, holdTime);
|
||||
|
||||
PrintIfWatched("Retreating to a safe spot!\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* <3b426a> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:280 */
|
||||
NOBODY void CCSBot::Hunt(void)
|
||||
void CCSBot::Hunt(void)
|
||||
{
|
||||
SetState(&m_huntState);
|
||||
}
|
||||
|
||||
// Attack our the given victim
|
||||
// NOTE: Attacking does not change our task.
|
||||
|
||||
/* <3b4291> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:290 */
|
||||
NOBODY void CCSBot::Attack(CBasePlayer *victim)
|
||||
void CCSBot::Attack(CBasePlayer *victim)
|
||||
{
|
||||
if (victim == NULL)
|
||||
return;
|
||||
|
||||
// zombies never attack
|
||||
if (cv_bot_zombie.value)
|
||||
if (cv_bot_zombie.value != 0.0f)
|
||||
return;
|
||||
|
||||
// cannot attack if we are reloading
|
||||
@ -183,11 +294,11 @@ NOBODY void CCSBot::Attack(CBasePlayer *victim)
|
||||
if (IsAtHidingSpot())
|
||||
m_attackState.SetCrouchAndHold((RANDOM_FLOAT(0, 100) < 60.0f) != 0);
|
||||
else
|
||||
m_attackState.SetCrouchAndHold(0);
|
||||
m_attackState.SetCrouchAndHold(false);
|
||||
|
||||
PrintIfWatched("ATTACK BEGIN (reaction time = %g (+ update time), surprise time = %g, attack delay = %g)\n");
|
||||
m_isAttacking = true;
|
||||
m_attackState.OnEnter(this);// TODO: Reverse me
|
||||
m_attackState.OnEnter(this);
|
||||
|
||||
// cheat a bit and give the bot the initial location of its victim
|
||||
m_lastEnemyPosition = victim->pev->origin;
|
||||
@ -196,18 +307,16 @@ NOBODY void CCSBot::Attack(CBasePlayer *victim)
|
||||
|
||||
// compute the angle difference between where are looking, and where we need to look
|
||||
Vector toEnemy = victim->pev->origin - pev->origin;
|
||||
Vector idealAngle;
|
||||
Vector idealAngle = UTIL_VecToAngles(toEnemy);
|
||||
|
||||
idealAngle = UTIL_VecToAngles(toEnemy);
|
||||
|
||||
float deltaYaw = (float)abs(m_lookYaw - idealAngle.y);
|
||||
float deltaYaw = abs((int)(m_lookYaw - idealAngle.y));
|
||||
|
||||
while (deltaYaw > 180.0f)
|
||||
deltaYaw -= 360.0f;
|
||||
|
||||
if (deltaYaw < 0.0f)
|
||||
deltaYaw = -deltaYaw;
|
||||
|
||||
|
||||
// immediately aim at enemy - accuracy penalty depending on how far we must turn to aim
|
||||
// accuracy is halved if we have to turn 180 degrees
|
||||
float turn = deltaYaw / 180.0f;
|
||||
@ -220,11 +329,13 @@ NOBODY void CCSBot::Attack(CBasePlayer *victim)
|
||||
m_aimOffsetTimestamp = gpGlobals->time + RANDOM_FLOAT(0.25f + turn, 1.5f);
|
||||
}
|
||||
|
||||
// Exit the Attack state
|
||||
|
||||
/* <3b4416> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:366 */
|
||||
void CCSBot::StopAttacking(void)
|
||||
{
|
||||
PrintIfWatched("ATTACK END\n");
|
||||
m_attackState.OnExit(this);//TODO: Reverse me
|
||||
m_attackState.OnExit(this);
|
||||
m_isAttacking = false;
|
||||
|
||||
// if we are following someone, go to the Idle state after the attack to decide whether we still want to follow
|
||||
@ -240,11 +351,19 @@ bool CCSBot::IsAttacking(void) const
|
||||
return m_isAttacking;
|
||||
}
|
||||
|
||||
// Return true if we are escaping from the bomb
|
||||
|
||||
/* <3b449f> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:387 */
|
||||
NOBODY bool CCSBot::IsEscapingFromBomb(void) const
|
||||
bool CCSBot::IsEscapingFromBomb(void) const
|
||||
{
|
||||
if (m_state == static_cast<const BotState *>(&m_escapeFromBombState))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if we are defusing the bomb
|
||||
|
||||
/* <3b44c6> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:399 */
|
||||
bool CCSBot::IsDefusingBomb(void) const
|
||||
{
|
||||
@ -254,6 +373,8 @@ bool CCSBot::IsDefusingBomb(void) const
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if we are hiding
|
||||
|
||||
/* <3b44ed> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:411 */
|
||||
bool CCSBot::IsHiding(void) const
|
||||
{
|
||||
@ -263,6 +384,8 @@ bool CCSBot::IsHiding(void) const
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if we are hiding and at our hiding spot
|
||||
|
||||
/* <3b450f> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:423 */
|
||||
bool CCSBot::IsAtHidingSpot(void) const
|
||||
{
|
||||
@ -272,16 +395,30 @@ bool CCSBot::IsAtHidingSpot(void) const
|
||||
return m_hideState.IsAtSpot();
|
||||
}
|
||||
|
||||
// Return true if we are huting
|
||||
|
||||
/* <3b454a> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:435 */
|
||||
NOBODY bool CCSBot::IsHunting(void) const
|
||||
bool CCSBot::IsHunting(void) const
|
||||
{
|
||||
if (m_state == static_cast<const BotState *>(&m_huntState))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if we are in the MoveTo state
|
||||
|
||||
/* <3b4571> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:447 */
|
||||
NOBODY bool CCSBot::IsMovingTo(void) const
|
||||
bool CCSBot::IsMovingTo(void) const
|
||||
{
|
||||
if (m_state == static_cast<const BotState *>(&m_moveToState))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if we are buying
|
||||
|
||||
/* <3b4598> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:460 */
|
||||
bool CCSBot::IsBuying(void) const
|
||||
{
|
||||
@ -291,31 +428,40 @@ bool CCSBot::IsBuying(void) const
|
||||
return false;
|
||||
}
|
||||
|
||||
// Move to potentially distant position
|
||||
|
||||
/* <3b45bf> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:472 */
|
||||
NOBODY void CCSBot::MoveTo(const Vector *pos, RouteType route)
|
||||
void CCSBot::MoveTo(const Vector *pos, RouteType route)
|
||||
{
|
||||
// SetGoalPosition(MoveToState *const this,
|
||||
// const Vector *pos); // 474
|
||||
// SetRouteType(MoveToState *const this,
|
||||
// enum RouteType route); // 475
|
||||
m_moveToState.SetGoalPosition(*pos);
|
||||
m_moveToState.SetRouteType(route);
|
||||
SetState(&m_moveToState);
|
||||
}
|
||||
|
||||
/* <3b463c> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:480 */
|
||||
NOBODY void CCSBot::PlantBomb(void)
|
||||
void CCSBot::PlantBomb(void)
|
||||
{
|
||||
SetState(&m_plantBombState);
|
||||
}
|
||||
|
||||
// Bomb has been dropped - go get it
|
||||
|
||||
/* <3b4663> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:489 */
|
||||
NOBODY void CCSBot::FetchBomb(void)
|
||||
void CCSBot::FetchBomb(void)
|
||||
{
|
||||
SetState(&m_fetchBombState);
|
||||
}
|
||||
|
||||
/* <3b468a> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:495 */
|
||||
NOBODY void CCSBot::DefuseBomb(void)
|
||||
void CCSBot::DefuseBomb(void)
|
||||
{
|
||||
SetState(&m_defuseBombState);
|
||||
}
|
||||
|
||||
// Investigate recent enemy noise
|
||||
|
||||
/* <3b46b1> ../cstrike/dlls/bot/cs_bot_statemachine.cpp:504 */
|
||||
NOBODY void CCSBot::InvestigateNoise(void)
|
||||
void CCSBot::InvestigateNoise(void)
|
||||
{
|
||||
SetState(&m_investigateNoiseState);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// Lightweight maintenance, invoked frequently
|
||||
|
||||
/* <3c635f> ../cstrike/dlls/bot/cs_bot_update.cpp:26 */
|
||||
void CCSBot::__MAKE_VHOOK(Upkeep)(void)
|
||||
{
|
||||
@ -11,10 +13,12 @@ void CCSBot::__MAKE_VHOOK(Upkeep)(void)
|
||||
if (m_isRapidFiring)
|
||||
TogglePrimaryAttack();
|
||||
|
||||
// aiming must be smooth - update often
|
||||
if (IsAimingAtEnemy())
|
||||
{
|
||||
UpdateAimOffset();
|
||||
|
||||
// aim at enemy, if he's still alive
|
||||
if (m_enemy != NULL)
|
||||
{
|
||||
float feetOffset = pev->origin.z - GetFeetZ();
|
||||
@ -30,13 +34,14 @@ void CCSBot::__MAKE_VHOOK(Upkeep)(void)
|
||||
m_aimSpot = m_enemy->pev->origin;
|
||||
|
||||
bool aimBlocked = false;
|
||||
const float sharpshooter = 0.8f;
|
||||
|
||||
if (IsUsingAWP() || IsUsingShotgun() || IsUsingMachinegun() || GetProfile()->GetSkill() < 0.8f
|
||||
if (IsUsingAWP() || IsUsingShotgun() || IsUsingMachinegun() || GetProfile()->GetSkill() < sharpshooter
|
||||
|| (IsActiveWeaponRecoilHigh() && !IsUsingPistol() && !IsUsingSniperRifle()))
|
||||
{
|
||||
if (IsEnemyPartVisible(CHEST))
|
||||
{
|
||||
// No headshots in this game, go for the chest.
|
||||
// No headshots, go for the chest.
|
||||
aimBlocked = true;
|
||||
}
|
||||
}
|
||||
@ -130,11 +135,12 @@ void CCSBot::__MAKE_VHOOK(Upkeep)(void)
|
||||
}
|
||||
|
||||
float driftAmplitude = 2.0f;
|
||||
const float sharpshooter = 0.5f;
|
||||
|
||||
// have view "drift" very slowly, so view looks "alive"
|
||||
if (IsUsingSniperRifle() && IsUsingScope())
|
||||
driftAmplitude = sharpshooter;
|
||||
{
|
||||
driftAmplitude = 0.5f;
|
||||
}
|
||||
|
||||
m_lookYaw += driftAmplitude * BotCOS(33.0f * gpGlobals->time);
|
||||
m_lookPitch += driftAmplitude * BotSIN(13.0f * gpGlobals->time);
|
||||
@ -147,7 +153,7 @@ void CCSBot::__MAKE_VHOOK(Upkeep)(void)
|
||||
void (*pCCSBot__Update)(void);
|
||||
|
||||
/* <3c6e1e> ../cstrike/dlls/bot/cs_bot_update.cpp:208 */
|
||||
void __declspec(naked) CCSBot::__MAKE_VHOOK(Update)(void)
|
||||
NOBODY void __declspec(naked) CCSBot::__MAKE_VHOOK(Update)(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
@ -326,6 +332,12 @@ void __declspec(naked) CCSBot::__MAKE_VHOOK(Update)(void)
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
// NavAreaBuildPath<PathCost> hook
|
||||
bool NavAreaBuildPath__PathCost__wrapper(CNavArea *startArea, CNavArea *goalArea, const Vector *goalPos, PathCost &costFunc, CNavArea **closestArea)
|
||||
{
|
||||
return NavAreaBuildPath(startArea, goalArea, goalPos, costFunc, closestArea);
|
||||
}
|
||||
|
||||
void CCSBot::Upkeep(void)
|
||||
{
|
||||
Upkeep_();
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,292 +1,702 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <3fca3c> ../cstrike/dlls/bot/cs_gamestate.cpp:13 */
|
||||
NOBODY CSGameState::CSGameState(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* <3fcd6b> ../cstrike/dlls/bot/cs_gamestate.cpp:27 */
|
||||
NOBODY CSGameState::CSGameState(CCSBot *owner)
|
||||
CSGameState::CSGameState(CCSBot *owner)
|
||||
{
|
||||
// IntervalTimer(IntervalTimer *const this); // 27
|
||||
// {
|
||||
// int i; // 41
|
||||
// }
|
||||
// IntervalTimer(IntervalTimer *const this); // 27
|
||||
// CountdownTimer(CountdownTimer *const this); // 27
|
||||
m_owner = owner;
|
||||
m_isRoundOver = false;
|
||||
m_bombState = MOVING;
|
||||
|
||||
m_lastSawBomber.Invalidate();
|
||||
m_lastSawLooseBomb.Invalidate();
|
||||
m_validateInterval.Invalidate();
|
||||
m_isPlantedBombPosKnown = false;
|
||||
m_plantedBombsite = UNKNOWN;
|
||||
|
||||
m_bombsiteCount = 0;
|
||||
m_bombsiteSearchIndex = 0;
|
||||
|
||||
for (int i = 0; i < MAX_HOSTAGES; ++i)
|
||||
{
|
||||
HostageInfo *info = &m_hostage[i];
|
||||
|
||||
info->hostage = NULL;
|
||||
info->knownPos = Vector(0, 0, 0);
|
||||
info->isValid = false;
|
||||
info->isAlive = false;
|
||||
info->isFree = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset at round start
|
||||
|
||||
/* <3fd4f4> ../cstrike/dlls/bot/cs_gamestate.cpp:55 */
|
||||
NOBODY void CSGameState::Reset(void)
|
||||
void CSGameState::Reset(void)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 66
|
||||
// int i; // 69
|
||||
// Invalidate(IntervalTimer *const this); // 61
|
||||
// Invalidate(IntervalTimer *const this); // 62
|
||||
// {
|
||||
// int swap; // 81
|
||||
// int rnd; // 82
|
||||
// }
|
||||
// }
|
||||
int i;
|
||||
CCSBotManager *ctrl = TheCSBots();
|
||||
|
||||
m_isRoundOver = false;
|
||||
|
||||
// bomb
|
||||
m_bombState = MOVING;
|
||||
m_lastSawBomber.Invalidate();
|
||||
m_lastSawLooseBomb.Invalidate();
|
||||
m_bombsiteCount = ctrl->GetZoneCount();
|
||||
|
||||
m_isPlantedBombPosKnown = false;
|
||||
m_plantedBombsite = UNKNOWN;
|
||||
|
||||
for (i = 0; i < m_bombsiteCount; ++i)
|
||||
{
|
||||
m_isBombsiteClear[i] = false;
|
||||
m_bombsiteSearchOrder[i] = i;
|
||||
}
|
||||
|
||||
// shuffle the bombsite search order
|
||||
// allows T's to plant at random site, and TEAM_CT's to search in a random order
|
||||
// NOTE: VS6 std::random_shuffle() doesn't work well with an array of two elements (most maps)
|
||||
for (i = 0; i < m_bombsiteCount; ++i)
|
||||
{
|
||||
int swap = m_bombsiteSearchOrder[i];
|
||||
int rnd = RANDOM_LONG(i, m_bombsiteCount - 1);
|
||||
|
||||
m_bombsiteSearchOrder[i] = m_bombsiteSearchOrder[rnd];
|
||||
m_bombsiteSearchOrder[rnd] = swap;
|
||||
}
|
||||
|
||||
m_bombsiteSearchIndex = 0;
|
||||
InitializeHostageInfo();
|
||||
}
|
||||
|
||||
// Update game state based on events we have received
|
||||
|
||||
/* <3fce67> ../cstrike/dlls/bot/cs_gamestate.cpp:97 */
|
||||
NOBODY void CSGameState::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *other)
|
||||
void CSGameState::OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *other)
|
||||
{
|
||||
// SetBombState(CSGameState *const this,
|
||||
// enum BombState state); // 104
|
||||
// UpdatePlantedBomb(CSGameState *const this,
|
||||
// const Vector *pos); // 109
|
||||
// SetBombState(CSGameState *const this,
|
||||
// enum BombState state); // 117
|
||||
// SetBombState(CSGameState *const this,
|
||||
// enum BombState state); // 124
|
||||
switch (event)
|
||||
{
|
||||
case EVENT_BOMB_PLANTED:
|
||||
SetBombState(PLANTED);
|
||||
if (m_owner->m_iTeam == TERRORIST && other != NULL)
|
||||
{
|
||||
UpdatePlantedBomb(&other->pev->origin);
|
||||
}
|
||||
break;
|
||||
case EVENT_BOMB_DEFUSED:
|
||||
SetBombState(DEFUSED);
|
||||
break;
|
||||
case EVENT_BOMB_EXPLODED:
|
||||
SetBombState(EXPLODED);
|
||||
break;
|
||||
case EVENT_ALL_HOSTAGES_RESCUED:
|
||||
m_allHostagesRescued = true;
|
||||
break;
|
||||
case EVENT_TERRORISTS_WIN:
|
||||
case EVENT_CTS_WIN:
|
||||
case EVENT_ROUND_DRAW:
|
||||
m_isRoundOver = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// True if round has been won or lost (but not yet reset)
|
||||
|
||||
/* <3fcf9c> ../cstrike/dlls/bot/cs_gamestate.cpp:144 */
|
||||
NOBODY bool CSGameState::IsRoundOver(void) const
|
||||
bool CSGameState::IsRoundOver(void) const
|
||||
{
|
||||
return m_isRoundOver;
|
||||
}
|
||||
|
||||
/* <3fcfc6> ../cstrike/dlls/bot/cs_gamestate.cpp:150 */
|
||||
NOBODY void CSGameState::SetBombState(BombState state)
|
||||
void CSGameState::SetBombState(BombState state)
|
||||
{
|
||||
// if state changed, reset "last seen" timestamps
|
||||
if (m_bombState != state)
|
||||
{
|
||||
m_bombState = state;
|
||||
}
|
||||
}
|
||||
|
||||
/* <3fcff2> ../cstrike/dlls/bot/cs_gamestate.cpp:160 */
|
||||
NOBODY void CSGameState::UpdateLooseBomb(const Vector *pos)
|
||||
void CSGameState::UpdateLooseBomb(const Vector *pos)
|
||||
{
|
||||
// SetBombState(CSGameState *const this,
|
||||
// enum BombState state); // 166
|
||||
// Reset(IntervalTimer *const this); // 163
|
||||
m_looseBombPos = *pos;
|
||||
m_lastSawLooseBomb.Reset();
|
||||
|
||||
// we saw the loose bomb, update our state
|
||||
SetBombState(LOOSE);
|
||||
}
|
||||
|
||||
/* <3fd06e> ../cstrike/dlls/bot/cs_gamestate.cpp:170 */
|
||||
NOBODY float CSGameState::TimeSinceLastSawLooseBomb(void) const
|
||||
float CSGameState::TimeSinceLastSawLooseBomb(void) const
|
||||
{
|
||||
// GetElapsedTime(const class IntervalTimer *const this); // 172
|
||||
return m_lastSawLooseBomb.GetElapsedTime();
|
||||
}
|
||||
|
||||
/* <3fd0f4> ../cstrike/dlls/bot/cs_gamestate.cpp:176 */
|
||||
NOBODY bool CSGameState::IsLooseBombLocationKnown(void) const
|
||||
bool CSGameState::IsLooseBombLocationKnown(void) const
|
||||
{
|
||||
// HasStarted(const class IntervalTimer *const this); // 181
|
||||
if (m_bombState != LOOSE)
|
||||
return false;
|
||||
|
||||
return (m_lastSawLooseBomb.HasStarted()) ? true : false;
|
||||
}
|
||||
|
||||
/* <3fd135> ../cstrike/dlls/bot/cs_gamestate.cpp:185 */
|
||||
NOBODY void CSGameState::UpdateBomber(const Vector *pos)
|
||||
void CSGameState::UpdateBomber(const Vector *pos)
|
||||
{
|
||||
// Reset(IntervalTimer *const this); // 188
|
||||
// SetBombState(CSGameState *const this,
|
||||
// enum BombState state); // 191
|
||||
m_bomberPos = *pos;
|
||||
m_lastSawBomber.Reset();
|
||||
|
||||
// we saw the bomber, update our state
|
||||
SetBombState(MOVING);
|
||||
}
|
||||
|
||||
/* <3fd1b1> ../cstrike/dlls/bot/cs_gamestate.cpp:195 */
|
||||
NOBODY float CSGameState::TimeSinceLastSawBomber(void) const
|
||||
float CSGameState::TimeSinceLastSawBomber(void) const
|
||||
{
|
||||
// GetElapsedTime(const class IntervalTimer *const this); // 197
|
||||
return m_lastSawBomber.GetElapsedTime();
|
||||
}
|
||||
|
||||
/* <3fd237> ../cstrike/dlls/bot/cs_gamestate.cpp:201 */
|
||||
NOBODY bool CSGameState::IsPlantedBombLocationKnown(void) const
|
||||
bool CSGameState::IsPlantedBombLocationKnown(void) const
|
||||
{
|
||||
if (m_bombState != PLANTED)
|
||||
return false;
|
||||
|
||||
return m_isPlantedBombPosKnown;
|
||||
}
|
||||
|
||||
// Return the zone index of the planted bombsite, or UNKNOWN
|
||||
|
||||
/* <3fd25a> ../cstrike/dlls/bot/cs_gamestate.cpp:213 */
|
||||
NOBODY int CSGameState::GetPlantedBombsite(void) const
|
||||
int CSGameState::GetPlantedBombsite(void) const
|
||||
{
|
||||
if (m_bombState != PLANTED)
|
||||
return UNKNOWN;
|
||||
|
||||
return m_plantedBombsite;
|
||||
}
|
||||
|
||||
// Return true if we are currently in the bombsite where the bomb is planted
|
||||
|
||||
/* <3fd284> ../cstrike/dlls/bot/cs_gamestate.cpp:225 */
|
||||
NOBODY bool CSGameState::IsAtPlantedBombsite(void) const
|
||||
bool CSGameState::IsAtPlantedBombsite(void) const
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 230
|
||||
// const class Zone *zone; // 231
|
||||
// }
|
||||
if (m_bombState != PLANTED)
|
||||
return false;
|
||||
|
||||
CCSBotManager *ctrl = TheCSBots();
|
||||
const CCSBotManager::Zone *zone = ctrl->GetClosestZone(&m_owner->pev->origin);
|
||||
|
||||
if (zone != NULL)
|
||||
{
|
||||
return (m_plantedBombsite == zone->m_index);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the zone index of the next bombsite to search
|
||||
|
||||
/* <3fd2d2> ../cstrike/dlls/bot/cs_gamestate.cpp:246 */
|
||||
NOBODY int CSGameState::GetNextBombsiteToSearch(void)
|
||||
int CSGameState::GetNextBombsiteToSearch(void)
|
||||
{
|
||||
// {
|
||||
// int i; // 251
|
||||
// {
|
||||
// int z; // 256
|
||||
// }
|
||||
// }
|
||||
if (m_bombsiteCount <= 0)
|
||||
return 0;
|
||||
|
||||
int i;
|
||||
// return next non-cleared bombsite index
|
||||
for (i = m_bombsiteSearchIndex; i < m_bombsiteCount; ++i)
|
||||
{
|
||||
int z = m_bombsiteSearchOrder[i];
|
||||
if (!m_isBombsiteClear[z])
|
||||
{
|
||||
m_bombsiteSearchIndex = i;
|
||||
return z;
|
||||
}
|
||||
}
|
||||
|
||||
// all the bombsites are clear, someone must have been mistaken - start search over
|
||||
for (i = 0; i < m_bombsiteCount; ++i)
|
||||
{
|
||||
m_isBombsiteClear[i] = false;
|
||||
}
|
||||
|
||||
m_bombsiteSearchIndex = 0;
|
||||
return GetNextBombsiteToSearch();
|
||||
}
|
||||
|
||||
// Returns position of bomb in its various states (moving, loose, planted),
|
||||
// or NULL if we don't know where the bomb is
|
||||
|
||||
/* <3fd32c> ../cstrike/dlls/bot/cs_gamestate.cpp:277 */
|
||||
NOBODY const Vector *CSGameState::GetBombPosition(void) const
|
||||
const Vector *CSGameState::GetBombPosition(void) const
|
||||
{
|
||||
// HasStarted(const class IntervalTimer *const this); // 283
|
||||
switch (m_bombState)
|
||||
{
|
||||
case MOVING:
|
||||
{
|
||||
if (!m_lastSawBomber.HasStarted())
|
||||
return NULL;
|
||||
|
||||
return &m_bomberPos;
|
||||
}
|
||||
case LOOSE:
|
||||
{
|
||||
if (IsLooseBombLocationKnown())
|
||||
return &m_looseBombPos;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
case PLANTED:
|
||||
{
|
||||
if (IsPlantedBombLocationKnown())
|
||||
return &m_plantedBombPos;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// We see the planted bomb at 'pos'
|
||||
|
||||
/* <3fd373> ../cstrike/dlls/bot/cs_gamestate.cpp:313 */
|
||||
NOBODY void CSGameState::UpdatePlantedBomb(const Vector *pos)
|
||||
void CSGameState::UpdatePlantedBomb(const Vector *pos)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 315
|
||||
// const class Zone *zone; // 316
|
||||
// SetBombState(CSGameState *const this,
|
||||
// enum BombState state); // 330
|
||||
// }
|
||||
CCSBotManager *ctrl = TheCSBots();
|
||||
const CCSBotManager::Zone *zone = ctrl->GetClosestZone(pos);
|
||||
|
||||
if (zone == NULL)
|
||||
{
|
||||
CONSOLE_ECHO("ERROR: Bomb planted outside of a zone!\n");
|
||||
m_plantedBombsite = UNKNOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_plantedBombsite = zone->m_index;
|
||||
}
|
||||
|
||||
m_plantedBombPos = *pos;
|
||||
m_isPlantedBombPosKnown = true;
|
||||
SetBombState(PLANTED);
|
||||
}
|
||||
|
||||
// Someone told us where the bomb is planted
|
||||
|
||||
/* <3fd3dd> ../cstrike/dlls/bot/cs_gamestate.cpp:337 */
|
||||
NOBODY void CSGameState::MarkBombsiteAsPlanted(int zoneIndex)
|
||||
void CSGameState::MarkBombsiteAsPlanted(int zoneIndex)
|
||||
{
|
||||
// SetBombState(CSGameState *const this,
|
||||
// enum BombState state); // 340
|
||||
m_plantedBombsite = zoneIndex;
|
||||
SetBombState(PLANTED);
|
||||
}
|
||||
|
||||
// Someone told us a bombsite is clear
|
||||
|
||||
/* <3fd43a> ../cstrike/dlls/bot/cs_gamestate.cpp:347 */
|
||||
NOBODY void CSGameState::ClearBombsite(int zoneIndex)
|
||||
void CSGameState::ClearBombsite(int zoneIndex)
|
||||
{
|
||||
if (zoneIndex >= 0 && zoneIndex < m_bombsiteCount)
|
||||
m_isBombsiteClear[zoneIndex] = true;
|
||||
}
|
||||
|
||||
/* <3fd475> ../cstrike/dlls/bot/cs_gamestate.cpp:354 */
|
||||
NOBODY bool CSGameState::IsBombsiteClear(int zoneIndex) const
|
||||
bool CSGameState::IsBombsiteClear(int zoneIndex) const
|
||||
{
|
||||
if (zoneIndex >= 0 && zoneIndex < m_bombsiteCount)
|
||||
return m_isBombsiteClear[zoneIndex];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* <3fd4b0> ../cstrike/dlls/bot/cs_gamestate.cpp:367 */
|
||||
NOBODY void CSGameState::InitializeHostageInfo(void)
|
||||
void CSGameState::InitializeHostageInfo(void)
|
||||
{
|
||||
// {
|
||||
// class CBaseEntity *hostage; // 373
|
||||
// }
|
||||
m_hostageCount = 0;
|
||||
m_allHostagesRescued = 0;
|
||||
m_haveSomeHostagesBeenTaken = 0;
|
||||
|
||||
CBaseEntity *hostage = NULL;
|
||||
while ((hostage = UTIL_FindEntityByClassname(hostage, "hostage_entity")) != NULL)
|
||||
{
|
||||
if (m_hostageCount >= MAX_HOSTAGES)
|
||||
break;
|
||||
|
||||
if (hostage->pev->takedamage != DAMAGE_YES)
|
||||
continue;
|
||||
|
||||
m_hostage[m_hostageCount].hostage = static_cast<CHostage *>(hostage);
|
||||
m_hostage[m_hostageCount].knownPos = hostage->pev->origin;
|
||||
m_hostage[m_hostageCount].isValid = true;
|
||||
m_hostage[m_hostageCount].isAlive = true;
|
||||
m_hostage[m_hostageCount].isFree = true;
|
||||
++m_hostageCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the closest free and live hostage
|
||||
// If we are a CT this information is perfect.
|
||||
// Otherwise, this is based on our individual memory of the game state.
|
||||
// If NULL is returned, we don't think there are any hostages left, or we dont know where they are.
|
||||
// NOTE: a T can remember a hostage who has died. knowPos will be filled in, but NULL will be
|
||||
// returned, since CHostages get deleted when they die.
|
||||
|
||||
/* <3fd5ab> ../cstrike/dlls/bot/cs_gamestate.cpp:398 */
|
||||
NOBODY CHostage *CSGameState::GetNearestFreeHostage(Vector *knowPos)
|
||||
CHostage *CSGameState::GetNearestFreeHostage(Vector *knowPos) const
|
||||
{
|
||||
// {
|
||||
// class CNavArea *startArea; // 403
|
||||
// class CHostage *close; // 407
|
||||
// const Vector *closePos; // 408
|
||||
// float closeDistance; // 409
|
||||
// {
|
||||
// int i; // 411
|
||||
// {
|
||||
// const Vector *hostagePos; // 413
|
||||
// class CNavArea *hostageArea; // 435
|
||||
// {
|
||||
// class ShortestPathCost pc; // 438
|
||||
// float travelDistance; // 439
|
||||
// NavAreaTravelDistance<ShortestPathCost>(CNavArea *startArea,
|
||||
// class CNavArea *endArea,
|
||||
// class ShortestPathCost &costFunc); // 439
|
||||
// }
|
||||
// IsValid(CHostage *const this); // 418
|
||||
// IsFollowingSomeone(CHostage *const this); // 421
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (m_owner == NULL)
|
||||
return NULL;
|
||||
|
||||
CNavArea *startArea = m_owner->GetLastKnownArea();
|
||||
|
||||
if (startArea == NULL)
|
||||
return NULL;
|
||||
|
||||
CHostage *close = NULL;
|
||||
const Vector *closePos = NULL;
|
||||
float closeDistance = 9999999999.9f;
|
||||
|
||||
for (int i = 0; i < m_hostageCount; ++i)
|
||||
{
|
||||
CHostage *hostage = m_hostage[i].hostage;
|
||||
const Vector *hostagePos = NULL;
|
||||
|
||||
if (m_owner->m_iTeam == CT)
|
||||
{
|
||||
// we know exactly where the hostages are, and if they are alive
|
||||
if (!m_hostage[i].hostage || !m_hostage[i].hostage->IsValid())
|
||||
continue;
|
||||
|
||||
if (m_hostage[i].hostage->IsFollowingSomeone())
|
||||
continue;
|
||||
|
||||
hostagePos = &hostage->pev->origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use our memory of where we think the hostages are
|
||||
if (m_hostage[i].isValid == false)
|
||||
continue;
|
||||
|
||||
hostagePos = &m_hostage[i].knownPos;
|
||||
}
|
||||
|
||||
CNavArea *hostageArea = TheNavAreaGrid.GetNearestNavArea(hostagePos);
|
||||
|
||||
if (hostageArea != NULL)
|
||||
{
|
||||
ShortestPathCost pc;
|
||||
float travelDistance = NavAreaTravelDistance(startArea, hostageArea, pc);
|
||||
|
||||
if (travelDistance >= 0.0f && travelDistance < closeDistance)
|
||||
{
|
||||
closePos = hostagePos;
|
||||
closeDistance = travelDistance;
|
||||
close = hostage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return where we think the hostage is
|
||||
if (knowPos != NULL && closePos != NULL)
|
||||
{
|
||||
knowPos = const_cast<Vector *>(closePos);
|
||||
}
|
||||
|
||||
return close;
|
||||
}
|
||||
|
||||
// Return the location of a "free" hostage, or NULL if we dont know of any
|
||||
|
||||
/* <3fdbd3> ../cstrike/dlls/bot/cs_gamestate.cpp:461 */
|
||||
NOBODY const Vector *CSGameState::GetRandomFreeHostagePosition(void)
|
||||
const Vector *CSGameState::GetRandomFreeHostagePosition(void)
|
||||
{
|
||||
// {
|
||||
// const Vector *freePos; // 466
|
||||
// int freeCount; // 467
|
||||
// {
|
||||
// int i; // 469
|
||||
// {
|
||||
// const class HostageInfo *info; // 471
|
||||
// IsFollowingSomeone(CHostage *const this); // 480
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// TODO: use static?
|
||||
const Vector *freePos[MAX_HOSTAGES];
|
||||
int freeCount = 0;
|
||||
|
||||
if (m_owner == NULL)
|
||||
return NULL;
|
||||
|
||||
for (int i = 0; i < m_hostageCount; ++i)
|
||||
{
|
||||
const HostageInfo *info = &m_hostage[i];
|
||||
const Vector *hostagePos = NULL;
|
||||
|
||||
if (m_owner->m_iTeam == CT)
|
||||
{
|
||||
// we know exactly where the hostages are, and if they are alive
|
||||
if (!info->hostage || !info->hostage->IsAlive())
|
||||
continue;
|
||||
|
||||
// escorted hostages are not "free"
|
||||
if (info->hostage->IsFollowingSomeone())
|
||||
continue;
|
||||
|
||||
freePos[ freeCount++ ] = &info->hostage->pev->origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use our memory of where we think the hostages are
|
||||
if (info->isValid == false)
|
||||
continue;
|
||||
|
||||
freePos[ freeCount++ ] = &info->knownPos;
|
||||
}
|
||||
}
|
||||
|
||||
if (freeCount)
|
||||
{
|
||||
return freePos[RANDOM_LONG(0, freeCount - 1)];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If we can see any of the positions where we think a hostage is, validate it
|
||||
// Return status of any changes (a hostage died or was moved)
|
||||
|
||||
/* <3fdcd2> ../cstrike/dlls/bot/cs_gamestate.cpp:509 */
|
||||
NOBODY unsigned char CSGameState::ValidateHostagePositions(void)
|
||||
CSGameState::ValidateStatusType CSGameState::ValidateHostagePositions(void)
|
||||
{
|
||||
// {
|
||||
// float const validateInterval; // 515
|
||||
// TraceResult result; // 520
|
||||
// unsigned char status; // 521
|
||||
// int i; // 523
|
||||
// int startValidCount; // 524
|
||||
// int endValidCount; // 605
|
||||
// IsElapsed(const class CountdownTimer *const this); // 512
|
||||
// Start(CountdownTimer *const this,
|
||||
// float duration); // 516
|
||||
// {
|
||||
// class HostageInfo *info; // 531
|
||||
// {
|
||||
// float const tolerance; // 594
|
||||
// IsValid(CHostage *const this); // 576
|
||||
// IsFollowingSomeone(CHostage *const this); // 586
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 595
|
||||
// IsLengthGreaterThan(const Vector *const this,
|
||||
// float length); // 595
|
||||
// }
|
||||
// IsFollowingSomeone(CHostage *const this); // 541
|
||||
// }
|
||||
// }
|
||||
// limit how often we validate
|
||||
if (!m_validateInterval.IsElapsed())
|
||||
return NO_CHANGE;
|
||||
|
||||
const float validateInterval = 0.5f;
|
||||
m_validateInterval.Start(validateInterval);
|
||||
|
||||
// check the status of hostages
|
||||
ValidateStatusType status = NO_CHANGE;
|
||||
|
||||
int i;
|
||||
int startValidCount = 0;
|
||||
for (i = 0; i < m_hostageCount; ++i)
|
||||
{
|
||||
if (m_hostage[i].isValid)
|
||||
++startValidCount;
|
||||
}
|
||||
|
||||
for (i = 0; i < m_hostageCount; ++i)
|
||||
{
|
||||
HostageInfo *info = &m_hostage[i];
|
||||
|
||||
if (!info->hostage)
|
||||
continue;
|
||||
|
||||
// if we can see a hostage, update our knowledge of it
|
||||
if (m_owner->IsVisible(&info->hostage->pev->origin, CHECK_FOV))
|
||||
{
|
||||
if (info->hostage->pev->takedamage == DAMAGE_YES)
|
||||
{
|
||||
// live hostage
|
||||
// if hostage is being escorted by a CT, we don't "see" it, we see the CT
|
||||
if (info->hostage->IsFollowingSomeone())
|
||||
{
|
||||
info->isValid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->knownPos = info->hostage->pev->origin;
|
||||
info->isValid = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// dead hostage
|
||||
// if we thought it was alive, this is news to us
|
||||
if (info->isAlive)
|
||||
status |= HOSTAGE_DIED;
|
||||
|
||||
info->isAlive = false;
|
||||
info->isValid = false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we dont know where this hostage is, nothing to validate
|
||||
if (!info->isValid)
|
||||
continue;
|
||||
|
||||
// can't directly see this hostage
|
||||
// check line of sight to where we think this hostage is, to see if we noticed that is has moved
|
||||
if (m_owner->IsVisible(&info->knownPos, CHECK_FOV))
|
||||
{
|
||||
// we can see where we thought the hostage was - verify it is still there and alive
|
||||
if (info->hostage->pev->takedamage != DAMAGE_YES)
|
||||
{
|
||||
// since we have line of sight to an invalid hostage, it must be dead
|
||||
// discovered that hostage has been killed
|
||||
status |= HOSTAGE_DIED;
|
||||
|
||||
info->isAlive = false;
|
||||
info->isValid = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info->hostage->IsFollowingSomeone())
|
||||
{
|
||||
// discovered the hostage has been taken
|
||||
status |= HOSTAGE_GONE;
|
||||
info->isValid = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
const float tolerance = 50.0f;
|
||||
if ((info->hostage->pev->origin - info->knownPos).IsLengthGreaterThan(tolerance))
|
||||
{
|
||||
// discovered that hostage has been moved
|
||||
status |= HOSTAGE_GONE;
|
||||
info->isValid = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int endValidCount = 0;
|
||||
for (i = 0; i < m_hostageCount; ++i)
|
||||
{
|
||||
if (m_hostage[i].isValid)
|
||||
++endValidCount;
|
||||
}
|
||||
|
||||
if (endValidCount == 0 && startValidCount > 0)
|
||||
{
|
||||
// we discovered all the hostages are gone
|
||||
status &= ~HOSTAGE_GONE;
|
||||
status |= HOSTAGES_ALL_GONE;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// Return the nearest visible free hostage
|
||||
// Since we can actually see any hostage we return, we know its actual position
|
||||
|
||||
/* <3fdef7> ../cstrike/dlls/bot/cs_gamestate.cpp:626 */
|
||||
NOBODY CHostage *CSGameState::GetNearestVisibleFreeHostage(void)
|
||||
CHostage *CSGameState::GetNearestVisibleFreeHostage(void) const
|
||||
{
|
||||
// {
|
||||
// class CHostage *close; // 628
|
||||
// float closeRangeSq; // 629
|
||||
// float rangeSq; // 630
|
||||
// Vector pos; // 632
|
||||
// {
|
||||
// int i; // 634
|
||||
// {
|
||||
// const class HostageInfo *info; // 636
|
||||
// IsFollowingSomeone(CHostage *const this); // 643
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 647
|
||||
// operator-(const Vector *const this,
|
||||
// const Vector &v); // 648
|
||||
// LengthSquared(const Vector *const this); // 648
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
CHostage *close = NULL;
|
||||
float closeRangeSq = 999999999.9f;
|
||||
float rangeSq;
|
||||
|
||||
Vector pos;
|
||||
|
||||
for (int i = 0; i < m_hostageCount; ++i)
|
||||
{
|
||||
const HostageInfo *info = &m_hostage[i];
|
||||
|
||||
if (!info->hostage)
|
||||
continue;
|
||||
|
||||
// if the hostage is dead or rescued, its not free
|
||||
if (info->hostage->pev->takedamage != DAMAGE_YES)
|
||||
continue;
|
||||
|
||||
// if this hostage is following someone, its not free
|
||||
if (info->hostage->IsFollowingSomeone())
|
||||
continue;
|
||||
|
||||
// TODO: Use travel distance here
|
||||
pos = info->hostage->pev->origin + Vector(0, 0, HumanHeight * 0.75f);
|
||||
rangeSq = (pos - m_owner->pev->origin).LengthSquared();
|
||||
|
||||
if (rangeSq < closeRangeSq)
|
||||
{
|
||||
if (!m_owner->IsVisible(&pos))
|
||||
continue;
|
||||
|
||||
close = info->hostage;
|
||||
closeRangeSq = rangeSq;
|
||||
}
|
||||
}
|
||||
|
||||
return close;
|
||||
}
|
||||
|
||||
// Return true if there are no free hostages
|
||||
|
||||
/* <3fe064> ../cstrike/dlls/bot/cs_gamestate.cpp:668 */
|
||||
NOBODY bool CSGameState::AreAllHostagesBeingRescued(void)
|
||||
bool CSGameState::AreAllHostagesBeingRescued(void) const
|
||||
{
|
||||
// {
|
||||
// bool isAllDead; // 674
|
||||
// {
|
||||
// int i; // 676
|
||||
// {
|
||||
// const class HostageInfo *info; // 678
|
||||
// IsValid(CHostage *const this); // 683
|
||||
// IsFollowingSomeone(CHostage *const this); // 685
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if the hostages have all been rescued, they are not being rescued any longer
|
||||
if (m_allHostagesRescued)
|
||||
return false;
|
||||
|
||||
bool isAllDead = true;
|
||||
|
||||
for (int i = 0; i < m_hostageCount; ++i)
|
||||
{
|
||||
const HostageInfo *info = &m_hostage[i];
|
||||
|
||||
if (m_owner->m_iTeam == CT)
|
||||
{
|
||||
// CT's have perfect knowledge via their radar
|
||||
if (info->hostage != NULL && info->hostage->IsValid())
|
||||
{
|
||||
if (!info->hostage->IsFollowingSomeone())
|
||||
return false;
|
||||
|
||||
isAllDead = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->isValid && info->isAlive)
|
||||
return false;
|
||||
|
||||
if (info->isAlive)
|
||||
isAllDead = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if all of the remaining hostages are dead, they arent being rescued
|
||||
if (isAllDead)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// All hostages have been rescued or are dead
|
||||
|
||||
/* <3fe148> ../cstrike/dlls/bot/cs_gamestate.cpp:712 */
|
||||
NOBODY bool CSGameState::AreAllHostagesGone(void)
|
||||
bool CSGameState::AreAllHostagesGone(void) const
|
||||
{
|
||||
// {
|
||||
// int i; // 718
|
||||
// {
|
||||
// const class HostageInfo *info; // 720
|
||||
// }
|
||||
// }
|
||||
if (m_allHostagesRescued)
|
||||
return true;
|
||||
|
||||
// do we know that all the hostages are dead
|
||||
for (int i = 0; i < m_hostageCount; ++i)
|
||||
{
|
||||
const HostageInfo *info = &m_hostage[i];
|
||||
|
||||
if (m_owner->m_iTeam == CT)
|
||||
{
|
||||
// CT's have perfect knowledge via their radar
|
||||
if (info->hostage->IsAlive())// == DAMAGE_YES)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->isValid && info->isAlive)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Someone told us all the hostages are gone
|
||||
|
||||
/* <3fe1a2> ../cstrike/dlls/bot/cs_gamestate.cpp:742 */
|
||||
NOBODY void CSGameState::AllHostagesGone(void)
|
||||
void CSGameState::AllHostagesGone(void)
|
||||
{
|
||||
// {
|
||||
// int i; // 744
|
||||
// }
|
||||
for (int i = 0; i < m_hostageCount; ++i)
|
||||
m_hostage[i].isValid = false;
|
||||
}
|
||||
|
@ -33,29 +33,19 @@
|
||||
#endif
|
||||
|
||||
class CCSBot;
|
||||
//class CHostage;
|
||||
|
||||
// This class represents the game state as known by a particular bot
|
||||
class CSGameState
|
||||
{
|
||||
public:
|
||||
CSGameState(void);
|
||||
CSGameState() {};
|
||||
CSGameState(CCSBot *owner);
|
||||
|
||||
struct HostageInfo
|
||||
{
|
||||
CHostage *hostage;
|
||||
Vector knownPos;
|
||||
bool isValid;
|
||||
bool isAlive;
|
||||
bool isFree;
|
||||
};/* size: 20, cachelines: 1, members: 5 */
|
||||
|
||||
NOBODY void Reset(void);
|
||||
// Event handling
|
||||
NOBODY void OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *other);
|
||||
// true if round has been won or lost (but not yet reset)
|
||||
NOBODY bool IsRoundOver(void) const;
|
||||
void Reset(void);
|
||||
void OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *other); // Event handling
|
||||
bool IsRoundOver(void) const; // true if round has been won or lost (but not yet reset)
|
||||
|
||||
// bomb defuse scenario
|
||||
enum BombState
|
||||
{
|
||||
MOVING, // being carried by a Terrorist
|
||||
@ -64,106 +54,101 @@ public:
|
||||
DEFUSED, // the bomb has been defused
|
||||
EXPLODED, // the bomb has exploded
|
||||
};
|
||||
bool IsBombMoving(void) const
|
||||
{
|
||||
return (m_bombState == MOVING);
|
||||
}
|
||||
bool IsBombLoose(void) const
|
||||
{
|
||||
return (m_bombState == LOOSE);
|
||||
}
|
||||
bool IsBombPlanted(void) const
|
||||
{
|
||||
return (m_bombState == PLANTED);
|
||||
}
|
||||
bool IsBombDefused(void) const
|
||||
{
|
||||
return (m_bombState == DEFUSED);
|
||||
}
|
||||
bool IsBombExploded(void) const
|
||||
{
|
||||
return (m_bombState == EXPLODED);
|
||||
}
|
||||
// we see the loose bomb
|
||||
NOBODY void UpdateLooseBomb(const Vector *pos);
|
||||
// how long has is been since we saw the loose bomb
|
||||
NOBODY float TimeSinceLastSawLooseBomb(void) const;
|
||||
// do we know where the loose bomb is
|
||||
NOBODY bool IsLooseBombLocationKnown(void) const;
|
||||
// we see the bomber
|
||||
NOBODY void UpdateBomber(const Vector *pos);
|
||||
// how long has is been since we saw the bomber
|
||||
NOBODY float TimeSinceLastSawBomber(void) const;
|
||||
// we see the planted bomb
|
||||
NOBODY void UpdatePlantedBomb(const Vector *pos);
|
||||
// do we know where the bomb was planted
|
||||
NOBODY bool IsPlantedBombLocationKnown(void) const;
|
||||
// mark bombsite as the location of the planted bomb
|
||||
NOBODY void MarkBombsiteAsPlanted(int zoneIndex);
|
||||
|
||||
enum { UNKNOWN = -1 };
|
||||
// return the zone index of the planted bombsite, or UNKNOWN
|
||||
NOBODY int GetPlantedBombsite(void) const;
|
||||
// return true if we are currently in the bombsite where the bomb is planted
|
||||
NOBODY bool IsAtPlantedBombsite(void) const;
|
||||
// return the zone index of the next bombsite to search
|
||||
NOBODY int GetNextBombsiteToSearch(void);
|
||||
// return true if given bombsite has been cleared
|
||||
NOBODY bool IsBombsiteClear(int zoneIndex) const;
|
||||
// mark bombsite as clear
|
||||
NOBODY void ClearBombsite(int zoneIndex);
|
||||
// return where we think the bomb is, or NULL if we don't know
|
||||
NOBODY const Vector *GetBombPosition(void) const;
|
||||
bool IsBombMoving(void) const { return (m_bombState == MOVING); }
|
||||
bool IsBombLoose(void) const { return (m_bombState == LOOSE); }
|
||||
bool IsBombPlanted(void) const { return (m_bombState == PLANTED); }
|
||||
bool IsBombDefused(void) const { return (m_bombState == DEFUSED); }
|
||||
bool IsBombExploded(void) const { return (m_bombState == EXPLODED); }
|
||||
|
||||
void UpdateLooseBomb(const Vector *pos); // we see the loose bomb
|
||||
float TimeSinceLastSawLooseBomb(void) const; // how long has is been since we saw the loose bomb
|
||||
bool IsLooseBombLocationKnown(void) const; // do we know where the loose bomb is
|
||||
|
||||
NOBODY CHostage *GetNearestFreeHostage(Vector *knowPos);
|
||||
NOBODY const Vector *GetRandomFreeHostagePosition(void);
|
||||
NOBODY bool AreAllHostagesBeingRescued(void);
|
||||
NOBODY bool AreAllHostagesGone(void);
|
||||
NOBODY void AllHostagesGone(void);
|
||||
bool HaveSomeHostagesBeenTaken(void)
|
||||
{
|
||||
return m_haveSomeHostagesBeenTaken;
|
||||
}
|
||||
void HostageWasTaken(void)
|
||||
{
|
||||
m_haveSomeHostagesBeenTaken = true;
|
||||
}
|
||||
NOBODY CHostage *GetNearestVisibleFreeHostage(void);
|
||||
NOBODY unsigned char ValidateHostagePositions(void);
|
||||
NOBODY void SetBombState(BombState state);
|
||||
BombState GetBombState(void)
|
||||
{
|
||||
return m_bombState;
|
||||
}
|
||||
CBaseEntity *GetNearestHostage(void)
|
||||
{
|
||||
UNTESTED
|
||||
// TODO: Not implemented
|
||||
void UpdateBomber(const Vector *pos); // we see the bomber
|
||||
float TimeSinceLastSawBomber(void) const; // how long has is been since we saw the bomber
|
||||
|
||||
//CHostage *pHostage = g_pHostages->GetClosestHostage(m_owner->pev->origin);
|
||||
//return GetClassPtr((CHostage *)pHostage->pev);
|
||||
}
|
||||
NOBODY void InitializeHostageInfo(void);
|
||||
void UpdatePlantedBomb(const Vector *pos); // we see the planted bomb
|
||||
bool IsPlantedBombLocationKnown(void) const; // do we know where the bomb was planted
|
||||
void MarkBombsiteAsPlanted(int zoneIndex); // mark bombsite as the location of the planted bomb
|
||||
|
||||
enum { UNKNOWN = -1 };
|
||||
int GetPlantedBombsite(void) const; // return the zone index of the planted bombsite, or UNKNOWN
|
||||
bool IsAtPlantedBombsite(void) const; // return true if we are currently in the bombsite where the bomb is planted
|
||||
|
||||
int GetNextBombsiteToSearch(void); // return the zone index of the next bombsite to search
|
||||
bool IsBombsiteClear(int zoneIndex) const; // return true if given bombsite has been cleared
|
||||
void ClearBombsite(int zoneIndex); // mark bombsite as clear
|
||||
|
||||
const Vector *GetBombPosition(void) const; // return where we think the bomb is, or NULL if we don't know
|
||||
|
||||
// hostage rescue scenario
|
||||
CHostage *GetNearestFreeHostage(Vector *knowPos = NULL) const; // return the closest free hostage, and where we think it is (knowPos)
|
||||
const Vector *GetRandomFreeHostagePosition(void);
|
||||
bool AreAllHostagesBeingRescued(void) const; // return true if there are no free hostages
|
||||
bool AreAllHostagesGone(void) const; // all hostages have been rescued or are dead
|
||||
void AllHostagesGone(void); // someone told us all the hostages are gone
|
||||
bool HaveSomeHostagesBeenTaken(void) const { return m_haveSomeHostagesBeenTaken; } // return true if one or more hostages have been moved by the CT's
|
||||
void HostageWasTaken(void) { m_haveSomeHostagesBeenTaken = true; } // someone told us a CT is talking to a hostage
|
||||
|
||||
CHostage *GetNearestVisibleFreeHostage(void) const;
|
||||
|
||||
// hostage rescue scenario
|
||||
enum ValidateStatusType:uint8
|
||||
{
|
||||
NO_CHANGE = 0x00,
|
||||
HOSTAGE_DIED = 0x01,
|
||||
HOSTAGE_GONE = 0x02,
|
||||
HOSTAGES_ALL_GONE = 0x04
|
||||
};
|
||||
ValidateStatusType ValidateHostagePositions(void); // update our knowledge with what we currently see - returns bitflag events
|
||||
|
||||
#ifndef HOOK_GAMEDLL
|
||||
private:
|
||||
CCSBot *m_owner;
|
||||
bool m_isRoundOver;
|
||||
BombState m_bombState;
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
CCSBot *m_owner; // who owns this gamestate
|
||||
bool m_isRoundOver; // true if round is over, but no yet reset
|
||||
|
||||
// bomb defuse scenario
|
||||
void SetBombState(BombState state);
|
||||
BombState GetBombState(void) { return m_bombState; }
|
||||
|
||||
BombState m_bombState; // what we think the bomb is doing
|
||||
|
||||
IntervalTimer m_lastSawBomber;
|
||||
Vector m_bomberPos;
|
||||
|
||||
IntervalTimer m_lastSawLooseBomb;
|
||||
Vector m_looseBombPos;
|
||||
bool m_isBombsiteClear[4];
|
||||
int m_bombsiteSearchOrder[4];
|
||||
|
||||
bool m_isBombsiteClear[4]; // corresponds to zone indices in CCSBotManager
|
||||
int m_bombsiteSearchOrder[4]; // randomized order of bombsites to search
|
||||
int m_bombsiteCount;
|
||||
int m_bombsiteSearchIndex;
|
||||
int m_plantedBombsite;
|
||||
bool m_isPlantedBombPosKnown;
|
||||
int m_bombsiteSearchIndex; // the next step in the search
|
||||
|
||||
int m_plantedBombsite; // zone index of the bombsite where the planted bomb is
|
||||
|
||||
bool m_isPlantedBombPosKnown; // if true, we know the exact location of the bomb
|
||||
Vector m_plantedBombPos;
|
||||
struct HostageInfo m_hostage[12];
|
||||
int m_hostageCount;
|
||||
|
||||
// hostage rescue scenario
|
||||
struct HostageInfo
|
||||
{
|
||||
CHostage *hostage;
|
||||
Vector knownPos;
|
||||
bool isValid;
|
||||
bool isAlive;
|
||||
bool isFree; // not being escorted by a CT
|
||||
}
|
||||
m_hostage[ MAX_HOSTAGES ];
|
||||
int m_hostageCount; // number of hostages left in map
|
||||
CountdownTimer m_validateInterval;
|
||||
bool m_allHostagesRescued;
|
||||
bool m_haveSomeHostagesBeenTaken;
|
||||
NOXREF CBaseEntity *GetNearestHostage(void) const; // return the closest live hostage
|
||||
void InitializeHostageInfo(void); // initialize our knowledge of the number and location of hostages
|
||||
|
||||
bool m_allHostagesRescued; // if true, so every hostages been is rescued
|
||||
bool m_haveSomeHostagesBeenTaken; // true if a hostage has been moved by a CT (and we've seen it)
|
||||
|
||||
};/* size: 348, cachelines: 6, members: 19 */
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <519735> ../cstrike/dlls/bot/states/cs_bot_attack.cpp:16 */
|
||||
NOBODY void AttackState::OnEnter(CCSBot *me)
|
||||
NOBODY void AttackState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CBasePlayer *enemy; // 18
|
||||
@ -43,7 +43,7 @@ NOBODY void AttackState::StopAttacking(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <51997e> ../cstrike/dlls/bot/states/cs_bot_attack.cpp:152 */
|
||||
NOBODY void AttackState::OnUpdate(CCSBot *me)
|
||||
NOBODY void AttackState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CBasePlayerWeapon *weapon; // 161
|
||||
@ -149,7 +149,7 @@ NOBODY void AttackState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <5198d4> ../cstrike/dlls/bot/states/cs_bot_attack.cpp:578 */
|
||||
NOBODY void AttackState::OnExit(CCSBot *me)
|
||||
NOBODY void AttackState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
// ForgetNoise(CCSBot *const this); // 585
|
||||
// PopPostureContext(CBot *const this); // 589
|
||||
@ -157,3 +157,22 @@ NOBODY void AttackState::OnExit(CCSBot *me)
|
||||
// StopRapidFire(CCSBot *const this); // 597
|
||||
// ClearSurpriseDelay(CCSBot *const this); // 598
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void AttackState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void AttackState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void AttackState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
@ -6,7 +6,7 @@ NOBODY bool HasDefaultPistol(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <5299e4> ../cstrike/dlls/bot/states/cs_bot_buy.cpp:37 */
|
||||
NOBODY void BuyState::OnEnter(CCSBot *me)
|
||||
NOBODY void BuyState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 48
|
||||
@ -27,7 +27,7 @@ NOBODY inline WeaponType GetWeaponType(const char *alias)
|
||||
}
|
||||
|
||||
/* <529753> ../cstrike/dlls/bot/states/cs_bot_buy.cpp:241 */
|
||||
NOBODY void BuyState::OnUpdate(CCSBot *me)
|
||||
NOBODY void BuyState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// bool inBuyZone; // 273
|
||||
@ -84,6 +84,25 @@ NOBODY void BuyState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <5296f1> ../cstrike/dlls/bot/states/cs_bot_buy.cpp:529 */
|
||||
NOBODY void BuyState::OnExit(CCSBot *me)
|
||||
NOBODY void BuyState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void BuyState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void BuyState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void BuyState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <539f0e> ../cstrike/dlls/bot/states/cs_bot_defuse_bomb.cpp:16 */
|
||||
NOBODY void DefuseBombState::OnEnter(CCSBot *me)
|
||||
NOBODY void DefuseBombState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// Say(BotChatterInterface *const this,
|
||||
// const char *phraseName,
|
||||
@ -10,7 +10,7 @@ NOBODY void DefuseBombState::OnEnter(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <539eac> ../cstrike/dlls/bot/states/cs_bot_defuse_bomb.cpp:27 */
|
||||
NOBODY void DefuseBombState::OnUpdate(CCSBot *me)
|
||||
NOBODY void DefuseBombState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// const Vector *bombPos; // 29
|
||||
@ -19,10 +19,29 @@ NOBODY void DefuseBombState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <539e36> ../cstrike/dlls/bot/states/cs_bot_defuse_bomb.cpp:73 */
|
||||
NOBODY void DefuseBombState::OnExit(CCSBot *me)
|
||||
NOBODY void DefuseBombState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
// SetTask(CCSBot *const this,
|
||||
// enum TaskType task,
|
||||
// class CBaseEntity *entity); // 77
|
||||
// ClearLookAt(CCSBot *const this); // 79
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void DefuseBombState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void DefuseBombState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void DefuseBombState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <5499ae> ../cstrike/dlls/bot/states/cs_bot_escape_from_bomb.cpp:16 */
|
||||
NOBODY void EscapeFromBombState::OnEnter(CCSBot *me)
|
||||
NOBODY void EscapeFromBombState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// DestroyPath(CCSBot *const this); // 20
|
||||
}
|
||||
|
||||
/* <549be9> ../cstrike/dlls/bot/states/cs_bot_escape_from_bomb.cpp:28 */
|
||||
NOBODY void EscapeFromBombState::OnUpdate(CCSBot *me)
|
||||
NOBODY void EscapeFromBombState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// const Vector *bombPos; // 30
|
||||
@ -21,6 +21,25 @@ NOBODY void EscapeFromBombState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <549976> ../cstrike/dlls/bot/states/cs_bot_escape_from_bomb.cpp:60 */
|
||||
NOBODY void EscapeFromBombState::OnExit(CCSBot *me)
|
||||
NOBODY void EscapeFromBombState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void EscapeFromBombState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void EscapeFromBombState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void EscapeFromBombState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <5587b3> ../cstrike/dlls/bot/states/cs_bot_fetch_bomb.cpp:17 */
|
||||
NOBODY void FetchBombState::OnEnter(CCSBot *me)
|
||||
NOBODY void FetchBombState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// DestroyPath(CCSBot *const this); // 19
|
||||
}
|
||||
|
||||
/* <5587fa> ../cstrike/dlls/bot/states/cs_bot_fetch_bomb.cpp:26 */
|
||||
NOBODY void FetchBombState::OnUpdate(CCSBot *me)
|
||||
NOBODY void FetchBombState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 28
|
||||
@ -15,3 +15,17 @@ NOBODY void FetchBombState::OnUpdate(CCSBot *me)
|
||||
// GetLooseBomb(CCSBotManager *const this); // 30
|
||||
// }
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void FetchBombState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void FetchBombState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <56918b> ../cstrike/dlls/bot/states/cs_bot_follow.cpp:16 */
|
||||
NOBODY void FollowState::OnEnter(CCSBot *me)
|
||||
NOBODY void FollowState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// DestroyPath(CCSBot *const this); // 20
|
||||
// Invalidate(CountdownTimer *const this); // 33
|
||||
@ -27,7 +27,7 @@ NOBODY void FollowState::ComputeLeaderMotionState(float leaderSpeed)
|
||||
}
|
||||
|
||||
/* <569368> ../cstrike/dlls/bot/states/cs_bot_follow.cpp:164 */
|
||||
NOBODY void FollowState::OnUpdate(CCSBot *me)
|
||||
NOBODY void FollowState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// float leaderSpeed; // 194
|
||||
@ -98,6 +98,25 @@ NOBODY void FollowState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <569231> ../cstrike/dlls/bot/states/cs_bot_follow.cpp:353 */
|
||||
NOBODY void FollowState::OnExit(CCSBot *me)
|
||||
NOBODY void FollowState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void FollowState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void FollowState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void FollowState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <57c261> ../cstrike/dlls/bot/states/cs_bot_hide.cpp:22 */
|
||||
NOBODY void HideState::OnEnter(CCSBot *me)
|
||||
NOBODY void HideState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// GetFollowLeader(CCSBot *const this); // 50
|
||||
}
|
||||
|
||||
/* <57c35e> ../cstrike/dlls/bot/states/cs_bot_hide.cpp:59 */
|
||||
NOBODY void HideState::OnUpdate(CCSBot *me)
|
||||
NOBODY void HideState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 61
|
||||
@ -110,7 +110,7 @@ NOBODY void HideState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <57c2c8> ../cstrike/dlls/bot/states/cs_bot_hide.cpp:450 */
|
||||
NOBODY void HideState::OnExit(CCSBot *me)
|
||||
NOBODY void HideState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
// ClearLookAt(CCSBot *const this); // 456
|
||||
// ClearApproachPoints(CCSBot *const this); // 457
|
||||
@ -118,3 +118,22 @@ NOBODY void HideState::OnExit(CCSBot *me)
|
||||
// OnExit(HideState *const this,
|
||||
// class CCSBot *me); // 450
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void HideState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void HideState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void HideState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <58e6e0> ../cstrike/dlls/bot/states/cs_bot_hunt.cpp:18 */
|
||||
NOBODY void HuntState::OnEnter(CCSBot *me)
|
||||
NOBODY void HuntState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// SetTask(CCSBot *const this,
|
||||
// enum TaskType task,
|
||||
@ -10,7 +10,7 @@ NOBODY void HuntState::OnEnter(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <58e452> ../cstrike/dlls/bot/states/cs_bot_hunt.cpp:38 */
|
||||
NOBODY void HuntState::OnUpdate(CCSBot *me)
|
||||
NOBODY void HuntState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 40
|
||||
@ -58,6 +58,25 @@ NOBODY void HuntState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <58e418> ../cstrike/dlls/bot/states/cs_bot_hunt.cpp:211 */
|
||||
NOBODY void HuntState::OnExit(CCSBot *me)
|
||||
NOBODY void HuntState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void HuntState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void HuntState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void HuntState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
@ -1,7 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <5a12ee> ../cstrike/dlls/bot/states/cs_bot_idle.cpp:26 */
|
||||
NOBODY void IdleState::OnEnter(CCSBot *me)
|
||||
NOBODY void IdleState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// DestroyPath(CCSBot *const this); // 28
|
||||
// SetTask(CCSBot *const this,
|
||||
@ -10,7 +10,7 @@ NOBODY void IdleState::OnEnter(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <5a0c66> ../cstrike/dlls/bot/states/cs_bot_idle.cpp:46 */
|
||||
NOBODY void IdleState::OnUpdate(CCSBot *me)
|
||||
NOBODY void IdleState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 59
|
||||
@ -154,3 +154,17 @@ NOBODY void IdleState::OnUpdate(CCSBot *me)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void IdleState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void IdleState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -7,14 +7,14 @@ NOBODY void InvestigateNoiseState::AttendCurrentNoise(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <5b2f37> ../cstrike/dlls/bot/states/cs_bot_investigate_noise.cpp:38 */
|
||||
NOBODY void InvestigateNoiseState::OnEnter(CCSBot *me)
|
||||
NOBODY void InvestigateNoiseState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// AttendCurrentNoise(InvestigateNoiseState *const this,
|
||||
// class CCSBot *me); // 40
|
||||
}
|
||||
|
||||
/* <5b2fa2> ../cstrike/dlls/bot/states/cs_bot_investigate_noise.cpp:47 */
|
||||
NOBODY void InvestigateNoiseState::OnUpdate(CCSBot *me)
|
||||
NOBODY void InvestigateNoiseState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// float newNoiseDist; // 50
|
||||
@ -40,6 +40,25 @@ NOBODY void InvestigateNoiseState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <5b2e95> ../cstrike/dlls/bot/states/cs_bot_investigate_noise.cpp:129 */
|
||||
NOBODY void InvestigateNoiseState::OnExit(CCSBot *me)
|
||||
NOBODY void InvestigateNoiseState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void InvestigateNoiseState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void InvestigateNoiseState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void InvestigateNoiseState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
/* <5c4e91> ../cstrike/dlls/bot/states/cs_bot_move_to.cpp:21 */
|
||||
NOBODY void MoveToState::OnEnter(CCSBot *me)
|
||||
NOBODY void MoveToState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// enum RouteType route; // 30
|
||||
@ -9,7 +9,7 @@ NOBODY void MoveToState::OnEnter(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <5c4edf> ../cstrike/dlls/bot/states/cs_bot_move_to.cpp:55 */
|
||||
NOBODY void MoveToState::OnUpdate(CCSBot *me)
|
||||
NOBODY void MoveToState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 76
|
||||
@ -82,6 +82,25 @@ NOBODY void MoveToState::OnUpdate(CCSBot *me)
|
||||
}
|
||||
|
||||
/* <5c4e54> ../cstrike/dlls/bot/states/cs_bot_move_to.cpp:320 */
|
||||
NOBODY void MoveToState::OnExit(CCSBot *me)
|
||||
NOBODY void MoveToState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void MoveToState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void MoveToState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void MoveToState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,35 +1,79 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// Plant the bomb.
|
||||
|
||||
/* <5d4160> ../cstrike/dlls/bot/states/cs_bot_plant_bomb.cpp:17 */
|
||||
NOBODY void PlantBombState::OnEnter(CCSBot *me)
|
||||
void PlantBombState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// float yaw; // 25
|
||||
// class Vector2D dir; // 26
|
||||
// Vector down; // 28
|
||||
// GetFeetZ(const class CCSBot *const this); // 28
|
||||
// Vector(Vector *const this,
|
||||
// float X,
|
||||
// float Y,
|
||||
// float Z); // 28
|
||||
// }
|
||||
me->Crouch();
|
||||
me->SetDisposition(CCSBot::SELF_DEFENSE);
|
||||
|
||||
float yaw = me->pev->v_angle.y;
|
||||
Vector2D dir(BotCOS(yaw), BotSIN(yaw));
|
||||
|
||||
Vector down(me->pev->origin.x + 10.0f * dir.x, me->pev->origin.y + 10.0f * dir.y, me->GetFeetZ());
|
||||
me->SetLookAt("Plant bomb on floor", &down, PRIORITY_HIGH);
|
||||
}
|
||||
|
||||
// Plant the bomb.
|
||||
|
||||
/* <5d40d0> ../cstrike/dlls/bot/states/cs_bot_plant_bomb.cpp:36 */
|
||||
NOBODY void PlantBombState::OnUpdate(CCSBot *me)
|
||||
void PlantBombState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// class CBasePlayerWeapon *gun; // 38
|
||||
// bool holdingC4; // 39
|
||||
// float const timeout; // 59
|
||||
// SetTask(CCSBot *const this,
|
||||
// enum TaskType task,
|
||||
// class CBaseEntity *entity); // 54
|
||||
// }
|
||||
CBasePlayerWeapon *gun = me->GetActiveWeapon();
|
||||
bool holdingC4 = false;
|
||||
if (gun != NULL)
|
||||
{
|
||||
if (FStrEq(STRING(gun->pev->classname), "weapon_c4"))
|
||||
holdingC4 = true;
|
||||
}
|
||||
|
||||
// if we aren't holding the C4, grab it, otherwise plant it
|
||||
if (holdingC4)
|
||||
me->PrimaryAttack();
|
||||
else
|
||||
me->SelectItem("weapon_c4");
|
||||
|
||||
// if we no longer have the C4, we've successfully planted
|
||||
if (!me->IsCarryingBomb())
|
||||
{
|
||||
// move to a hiding spot and watch the bomb
|
||||
me->SetTask(CCSBot::GUARD_TICKING_BOMB);
|
||||
me->Hide();
|
||||
}
|
||||
|
||||
// if we time out, it's because we slipped into a non-plantable area
|
||||
const float timeout = 5.0f;
|
||||
if (gpGlobals->time - me->GetStateTimestamp() > timeout)
|
||||
me->Idle();
|
||||
}
|
||||
|
||||
/* <5d4088> ../cstrike/dlls/bot/states/cs_bot_plant_bomb.cpp:65 */
|
||||
NOBODY void PlantBombState::OnExit(CCSBot *me)
|
||||
void PlantBombState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
// ClearLookAt(CCSBot *const this); // 72
|
||||
// equip our rifle (in case we were interrupted while holding C4)
|
||||
me->EquipBestWeapon();
|
||||
me->StandUp();
|
||||
me->ResetStuckMonitor();
|
||||
me->SetDisposition(CCSBot::ENGAGE_AND_INVESTIGATE);
|
||||
me->ClearLookAt();
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void PlantBombState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void PlantBombState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void PlantBombState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
@ -1,26 +1,68 @@
|
||||
#include "precompiled.h"
|
||||
|
||||
// Face the entity and "use" it
|
||||
// NOTE: This state assumes we are standing in range of the entity to be used, with no obstructions.
|
||||
|
||||
/* <5e3017> ../cstrike/dlls/bot/states/cs_bot_use_entity.cpp:17 */
|
||||
NOBODY void UseEntityState::OnEnter(CCSBot *me)
|
||||
void UseEntityState::__MAKE_VHOOK(OnEnter)(CCSBot *me)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/* <5e308c> ../cstrike/dlls/bot/states/cs_bot_use_entity.cpp:21 */
|
||||
NOBODY void UseEntityState::OnUpdate(CCSBot *me)
|
||||
void UseEntityState::__MAKE_VHOOK(OnUpdate)(CCSBot *me)
|
||||
{
|
||||
// {
|
||||
// float const useTimeout; // 25
|
||||
// Vector pos; // 33
|
||||
// {
|
||||
// class CCSBotManager *ctrl; // 39
|
||||
// }
|
||||
// }
|
||||
// OnUpdate(UseEntityState *const this,
|
||||
// class CCSBot *me); // 21
|
||||
// in the very rare situation where two or more bots "used" a hostage at the same time,
|
||||
// one bot will fail and needs to time out of this state
|
||||
const float useTimeout = 5.0f;
|
||||
if (me->GetStateTimestamp() - gpGlobals->time > useTimeout)
|
||||
{
|
||||
me->Idle();
|
||||
return;
|
||||
}
|
||||
|
||||
// look at the entity
|
||||
Vector pos = m_entity->pev->origin + Vector(0, 0, HumanHeight * 0.5f);
|
||||
me->SetLookAt("Use entity", &pos, PRIORITY_HIGH);
|
||||
|
||||
// if we are looking at the entity, "use" it and exit
|
||||
if (me->IsLookingAtPosition(&pos))
|
||||
{
|
||||
if (TheCSBots()->GetScenario() == CCSBotManager::SCENARIO_RESCUE_HOSTAGES
|
||||
&& me->m_iTeam == CT
|
||||
&& me->GetTask() == CCSBot::COLLECT_HOSTAGES)
|
||||
{
|
||||
// we are collecting a hostage, assume we were successful - the update check will correct us if we weren't
|
||||
me->IncreaseHostageEscortCount();
|
||||
}
|
||||
|
||||
me->UseEnvironment();
|
||||
me->Idle();
|
||||
}
|
||||
}
|
||||
|
||||
/* <5e304a> ../cstrike/dlls/bot/states/cs_bot_use_entity.cpp:54 */
|
||||
NOBODY void UseEntityState::OnExit(CCSBot *me)
|
||||
void UseEntityState::__MAKE_VHOOK(OnExit)(CCSBot *me)
|
||||
{
|
||||
// ClearLookAt(CCSBot *const this); // 56
|
||||
me->ClearLookAt();
|
||||
me->ResetStuckMonitor();
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void UseEntityState::OnEnter(CCSBot *me)
|
||||
{
|
||||
OnEnter_(me);
|
||||
}
|
||||
|
||||
void UseEntityState::OnUpdate(CCSBot *me)
|
||||
{
|
||||
OnUpdate_(me);
|
||||
}
|
||||
|
||||
void UseEntityState::OnExit(CCSBot *me)
|
||||
{
|
||||
OnExit_(me);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
@ -184,17 +184,12 @@ void CCareerTask::OnWeaponKill(int weaponId, int weaponClassId, bool headshot, b
|
||||
|
||||
while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL)
|
||||
{
|
||||
CHostage *hostage = (CHostage *)hostageEntity;
|
||||
|
||||
if (!hostage || hostage->pev->takedamage != DAMAGE_YES)
|
||||
if (hostageEntity->pev->takedamage != DAMAGE_YES)
|
||||
continue;
|
||||
|
||||
if (hostage->m_improv)
|
||||
{
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
continue;
|
||||
}
|
||||
else if (!hostage->m_hTargetEnt || hostage->m_State != CHostage::FOLLOW)
|
||||
CHostage *hostage = static_cast<CHostage *>(hostageEntity);
|
||||
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
continue;
|
||||
|
||||
if (hostage->IsValid() && hostage->m_target == pAttacker)
|
||||
@ -274,19 +269,10 @@ void CCareerTask::__MAKE_VHOOK(OnEvent)(GameEventType event, CBasePlayer *pVicti
|
||||
if (hostageEntity->pev->takedamage != DAMAGE_YES)
|
||||
continue;
|
||||
|
||||
CHostage *hostage = reinterpret_cast<CHostage *>(hostageEntity);
|
||||
CHostage *hostage = static_cast<CHostage *>(hostageEntity);
|
||||
|
||||
if (hostage->m_improv)
|
||||
{
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (hostage->m_hTargetEnt == NULL || hostage->m_State != CHostage::FOLLOW)
|
||||
{
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hostage->IsValid() && hostage->m_target == pAttacker)
|
||||
++hostages_;
|
||||
|
@ -43,10 +43,7 @@ public:
|
||||
public:
|
||||
virtual void OnEvent(GameEventType event, CBasePlayer *pAttacker, CBasePlayer *pVictim);
|
||||
virtual void Reset(void);
|
||||
virtual bool IsTaskCompletableThisRound(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool IsTaskCompletableThisRound(void) { return true; }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
@ -61,26 +58,13 @@ public:
|
||||
void OnWeaponKill(int weaponId, int weaponClassId, bool headshot, bool killerHasShield, CBasePlayer *pAttacker, CBasePlayer *pVictim);
|
||||
void OnWeaponInjury(int weaponId, int weaponClassId, bool attackerHasShield, CBasePlayer *pAttacker);
|
||||
|
||||
bool IsComplete(void)
|
||||
{
|
||||
return m_isComplete;
|
||||
}
|
||||
const char *GetTaskName(void)
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
int GetWeaponId(void)
|
||||
{
|
||||
return m_weaponId;
|
||||
}
|
||||
int GetWeaponClassId(void)
|
||||
{
|
||||
return m_weaponClassId;
|
||||
}
|
||||
bool IsValidFor(CBasePlayer *pPlayer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool IsComplete(void) { return m_isComplete;}
|
||||
const char *GetTaskName(void) { return m_name; }
|
||||
|
||||
int GetWeaponId(void) { return m_weaponId; }
|
||||
int GetWeaponClassId(void) { return m_weaponClassId; }
|
||||
|
||||
bool IsValidFor(CBasePlayer *pPlayer) { return true; }
|
||||
void SendPartialNotification(void);
|
||||
|
||||
private:
|
||||
@ -102,10 +86,37 @@ private:
|
||||
|
||||
};/* size: 44, cachelines: 1, members: 15 */
|
||||
|
||||
typedef std::list<CCareerTask *> CareerTaskList;
|
||||
|
||||
typedef std::STD_LIST<CCareerTask *> CareerTaskList;
|
||||
typedef CareerTaskList::iterator CareerTaskListIt;
|
||||
|
||||
typedef CCareerTask *(*TaskFactoryFunction)(const char *taskName, GameEventType event, const char *weaponName, int eventCount, bool mustLive, bool crossRounds, int nextId, bool isComplete);
|
||||
|
||||
/* <1ef56d> ../cstrike/dlls/career_tasks.cpp:139 */
|
||||
class CPreventDefuseTask: public CCareerTask
|
||||
{
|
||||
public:
|
||||
CPreventDefuseTask(const char *taskName, GameEventType event, const char *weaponName, int n, bool mustLive, bool crossRounds, int id, bool isComplete);
|
||||
public:
|
||||
virtual void OnEvent(GameEventType event, CBasePlayer *pAttacker, CBasePlayer *pVictim);
|
||||
virtual void Reset(void);
|
||||
virtual bool IsTaskCompletableThisRound(void) { return m_bombPlantedThisRound && !m_defuseStartedThisRound; }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void OnEvent_(GameEventType event, CBasePlayer *pAttacker, CBasePlayer *pVictim);
|
||||
void Reset_(void);
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
public:
|
||||
static CCareerTask *NewTask(const char *taskName, GameEventType event, const char *weaponName, int n, bool mustLive, bool crossRounds, int id, bool isComplete);
|
||||
|
||||
protected:
|
||||
bool m_bombPlantedThisRound;
|
||||
bool m_defuseStartedThisRound;
|
||||
|
||||
};/* size: 48, cachelines: 1, members: 3 */
|
||||
|
||||
/* <1efed1> ../cstrike/dlls/career_tasks.cpp:636 */
|
||||
class CCareerTaskManager
|
||||
{
|
||||
@ -128,32 +139,15 @@ public:
|
||||
bool AreAllTasksComplete(void);
|
||||
int GetNumRemainingTasks(void);
|
||||
float GetRoundElapsedTime(void);
|
||||
int GetTaskTime(void)
|
||||
{
|
||||
return m_taskTime;
|
||||
}
|
||||
int GetTaskTime(void) { return m_taskTime; }
|
||||
void SetFinishedTaskTime(int val);
|
||||
int GetFinishedTaskTime(void)
|
||||
{
|
||||
return m_finishedTaskTime;
|
||||
}
|
||||
int GetFinishedTaskRound(void)
|
||||
{
|
||||
return m_finishedTaskRound;
|
||||
}
|
||||
CareerTaskList *GetTasks(void)
|
||||
{
|
||||
return &m_tasks;
|
||||
}
|
||||
int GetFinishedTaskTime(void) { return m_finishedTaskTime; }
|
||||
int GetFinishedTaskRound(void) { return m_finishedTaskRound; }
|
||||
CareerTaskList *GetTasks(void) { return &m_tasks; }
|
||||
void LatchRoundEndMessage(void);
|
||||
void UnlatchRoundEndMessage(void);
|
||||
|
||||
private:
|
||||
|
||||
#if defined(_WIN32) && defined(HOOK_GAMEDLL)
|
||||
int unknown_padding1;
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
CareerTaskList m_tasks;
|
||||
|
||||
int m_nextId;
|
||||
@ -167,8 +161,6 @@ private:
|
||||
|
||||
};/* size: 36, cachelines: 1, members: 8 */
|
||||
|
||||
typedef CCareerTask *(*TaskFactoryFunction)(const char *taskName, GameEventType event, const char *weaponName, int eventCount, bool mustLive, bool crossRounds, int nextId, bool isComplete);
|
||||
|
||||
struct TaskInfo
|
||||
{
|
||||
const char *taskName;
|
||||
@ -177,35 +169,6 @@ struct TaskInfo
|
||||
|
||||
};/* size: 12, cachelines: 1, members: 3 */
|
||||
|
||||
/* <1ef56d> ../cstrike/dlls/career_tasks.cpp:139 */
|
||||
class CPreventDefuseTask: public CCareerTask
|
||||
{
|
||||
public:
|
||||
CPreventDefuseTask(const char *taskName, GameEventType event, const char *weaponName, int n, bool mustLive, bool crossRounds, int id, bool isComplete);
|
||||
public:
|
||||
virtual void OnEvent(GameEventType event, CBasePlayer *pAttacker, CBasePlayer *pVictim);
|
||||
virtual void Reset(void);
|
||||
virtual bool IsTaskCompletableThisRound(void)
|
||||
{
|
||||
return m_bombPlantedThisRound && !m_defuseStartedThisRound;
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void OnEvent_(GameEventType event, CBasePlayer *pAttacker, CBasePlayer *pVictim);
|
||||
void Reset_(void);
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
public:
|
||||
static CCareerTask *NewTask(const char *taskName, GameEventType event, const char *weaponName, int n, bool mustLive, bool crossRounds, int id, bool isComplete);
|
||||
|
||||
protected:
|
||||
bool m_bombPlantedThisRound;
|
||||
bool m_defuseStartedThisRound;
|
||||
|
||||
};/* size: 48, cachelines: 1, members: 3 */
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
#define TheCareerTasks (*pTheCareerTasks)
|
||||
|
@ -277,7 +277,7 @@ public:
|
||||
|
||||
operator int();
|
||||
operator CBaseEntity*();
|
||||
operator CBasePlayer*() { return (CBasePlayer *)GET_PRIVATE(Get()); } // custom
|
||||
operator CBasePlayer*() { return static_cast<CBasePlayer *>(GET_PRIVATE(Get())); } // custom
|
||||
|
||||
CBaseEntity *operator=(CBaseEntity *pEntity);
|
||||
CBaseEntity *operator->();
|
||||
|
@ -711,6 +711,7 @@ void Host_Say(edict_t *pEntity, int teamonly)
|
||||
char *pszConsoleFormat = NULL;
|
||||
bool consoleUsesPlaceName = false;
|
||||
|
||||
// team only
|
||||
if (teamonly)
|
||||
{
|
||||
if (UTIL_IsGame("czero") && (player->m_iTeam == CT || player->m_iTeam == TERRORIST))
|
||||
@ -773,6 +774,7 @@ void Host_Say(edict_t *pEntity, int teamonly)
|
||||
pszConsoleFormat = "(Spectator) %s : %s";
|
||||
}
|
||||
}
|
||||
// everyone
|
||||
else
|
||||
{
|
||||
if (bSenderDead)
|
||||
@ -2006,14 +2008,17 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
|
||||
break;
|
||||
case MENU_SLOT_TEAM_VIP:
|
||||
{
|
||||
if (mp->m_iMapHasVIPSafetyZone != MAP_HAVE_VIP_SAFETYZONE_YES || player->m_iTeam != CT)
|
||||
if (mp->m_iMapHasVIPSafetyZone == MAP_HAVE_VIP_SAFETYZONE_YES && player->m_iTeam == CT)
|
||||
{
|
||||
mp->AddToVIPQueue(player);
|
||||
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mp->AddToVIPQueue(player);
|
||||
CLIENT_COMMAND(ENT(player->pev), "slot10\n");
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
case MENU_SLOT_TEAM_RANDOM:
|
||||
{
|
||||
@ -2198,6 +2203,7 @@ BOOL HandleMenu_ChooseTeam(CBasePlayer *player, int slot)
|
||||
}
|
||||
}
|
||||
|
||||
// If we already died and changed teams once, deny
|
||||
if (player->m_bTeamChanged)
|
||||
{
|
||||
if (player->pev->deadflag != DEAD_NO)
|
||||
@ -4504,6 +4510,20 @@ void ClientPrecache(void)
|
||||
PRECACHE_GENERIC("sprites/scope_arc_sw.tga");
|
||||
|
||||
m_usResetDecals = g_engfuncs.pfnPrecacheEvent(1, "events/decal_reset.sc");
|
||||
|
||||
/*Vector temp = g_vecZero;
|
||||
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc.tga");
|
||||
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_nw.tga");
|
||||
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_ne.tga");
|
||||
ENGINE_FORCE_UNMODIFIED(force_exactfile, (float *)&temp, (float *)&temp, "sprites/scope_arc_sw.tga");
|
||||
|
||||
|
||||
PRECACHE_GENERIC("sprites/scope_arc.tga");
|
||||
PRECACHE_GENERIC("sprites/scope_arc_nw.tga");
|
||||
PRECACHE_GENERIC("sprites/scope_arc_ne.tga");
|
||||
PRECACHE_GENERIC("sprites/scope_arc_sw.tga");
|
||||
|
||||
m_usResetDecals = g_engfuncs.pfnPrecacheEvent(1, "events/decal_reset.sc");*/
|
||||
}
|
||||
|
||||
/* <4a6e5> ../cstrike/dlls/client.cpp:4996 */
|
||||
|
@ -362,7 +362,7 @@ Activity CBaseMonster::__MAKE_VHOOK(GetDeathActivity)(void)
|
||||
}
|
||||
|
||||
// can we perform the prescribed death?
|
||||
if (LookupActivity(deathActivity) == ACTIVITY_NOT_AVAILABLE)
|
||||
if (LookupActivity(deathActivity) == ACT_INVALID)
|
||||
{
|
||||
// no! did we fail to perform a directional death?
|
||||
if (fTriedDirection)
|
||||
@ -384,7 +384,7 @@ Activity CBaseMonster::__MAKE_VHOOK(GetDeathActivity)(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (LookupActivity(deathActivity) == ACTIVITY_NOT_AVAILABLE)
|
||||
if (LookupActivity(deathActivity) == ACT_INVALID)
|
||||
{
|
||||
// if we're still invalid, simple is our only option.
|
||||
deathActivity = ACT_DIESIMPLE;
|
||||
@ -458,7 +458,7 @@ NOXREF Activity CBaseMonster::GetSmallFlinchActivity(void)
|
||||
}
|
||||
|
||||
// do we have a sequence for the ideal activity?
|
||||
if (LookupActivity(flinchActivity) == ACTIVITY_NOT_AVAILABLE)
|
||||
if (LookupActivity(flinchActivity) == ACT_INVALID)
|
||||
{
|
||||
flinchActivity = ACT_SMALL_FLINCH;
|
||||
}
|
||||
|
@ -38,8 +38,10 @@ BOOL CGameRules::__MAKE_VHOOK(CanHaveAmmo)(CBasePlayer *pPlayer, const char *psz
|
||||
/* <ad89d> ../cstrike/dlls/gamerules.cpp:59 */
|
||||
edict_t *CGameRules::__MAKE_VHOOK(GetPlayerSpawnSpot)(CBasePlayer *pPlayer)
|
||||
{
|
||||
// gat valid spawn point
|
||||
edict_t *pentSpawnSpot = EntSelectSpawnPoint(pPlayer);
|
||||
|
||||
// Move the player to the place it said.
|
||||
#ifndef PLAY_GAMEDLL
|
||||
pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector(0, 0, 1);
|
||||
#else
|
||||
|
@ -64,6 +64,9 @@
|
||||
#define MAX_MOTD_LENGTH 1536 // (MAX_MOTD_CHUNK * 4)
|
||||
|
||||
// custom enum
|
||||
#define WINNER_NONE 0
|
||||
#define WINNER_DRAW 1
|
||||
|
||||
enum
|
||||
{
|
||||
WINSTATUS_CTS = 1,
|
||||
@ -187,10 +190,7 @@ public:
|
||||
return FALSE;
|
||||
}
|
||||
virtual BOOL IsCoOp(void) = 0;
|
||||
virtual const char *GetGameDescription(void)
|
||||
{
|
||||
return "Counter-Strike";
|
||||
}
|
||||
virtual const char *GetGameDescription(void) { return "Counter-Strike"; } // this is the game name that gets seen in the server browser
|
||||
virtual BOOL ClientConnected(edict_t *pEntity, const char *pszName, const char *pszAddress, char *szRejectReason) = 0;
|
||||
virtual void InitHUD(CBasePlayer *pl) = 0;
|
||||
virtual void ClientDisconnected(edict_t *pClient) = 0;
|
||||
@ -473,6 +473,8 @@ public:
|
||||
virtual void CleanUpMap(void);
|
||||
|
||||
virtual void RestartRound(void);
|
||||
|
||||
// check if the scenario has been won/lost
|
||||
virtual void CheckWinConditions(void);
|
||||
virtual void RemoveGuns(void);
|
||||
virtual void GiveC4(void);
|
||||
|
@ -130,6 +130,7 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
|
||||
m_bJustBlew = true;
|
||||
mp->CheckWinConditions();
|
||||
|
||||
// Pull out of the wall a bit
|
||||
if (pTrace->flFraction != 1.0f)
|
||||
{
|
||||
pev->origin = pTrace->vecEndPos + (pTrace->vecPlaneNormal * (pev->dmg - 24) * 0.6);
|
||||
@ -177,6 +178,7 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
|
||||
WRITE_BYTE(17);
|
||||
MESSAGE_END();
|
||||
|
||||
// Sound! for everyone
|
||||
EMIT_SOUND(ENT(pev), CHAN_WEAPON, "weapons/c4_explode1.wav", VOL_NORM, 0.25);
|
||||
CSoundEnt::InsertSound(bits_SOUND_COMBAT, pev->origin, NORMAL_EXPLOSION_VOLUME, 3);
|
||||
|
||||
@ -198,14 +200,16 @@ void CGrenade::Explode2(TraceResult *pTrace, int bitsDamageType)
|
||||
}
|
||||
|
||||
// tell director about it
|
||||
// send director message, that something important happed here
|
||||
MESSAGE_BEGIN(MSG_SPEC, SVC_DIRECTOR);
|
||||
WRITE_BYTE(9); // command length in bytes
|
||||
WRITE_BYTE(DRC_CMD_EVENT); // explode event
|
||||
WRITE_BYTE(DRC_CMD_EVENT); // bomb explode
|
||||
WRITE_SHORT(ENTINDEX(edict())); // index number of primary entity
|
||||
WRITE_SHORT(0); // index number of secondary entity
|
||||
WRITE_LONG(15 | DRC_FLAG_FINAL); // eventflags (priority and flags)
|
||||
MESSAGE_END();
|
||||
|
||||
// Decal!
|
||||
if (RANDOM_FLOAT(0, 1) < 0.5)
|
||||
UTIL_DecalTrace(pTrace, DECAL_SCORCH1);
|
||||
else
|
||||
@ -984,6 +988,7 @@ void CGrenade::__MAKE_VHOOK(Use)(CBaseEntity *pActivator, CBaseEntity *pCaller,
|
||||
|
||||
CBasePlayer *player = GetClassPtr((CBasePlayer *)pActivator->pev);
|
||||
|
||||
// For CTs to defuse the c4
|
||||
if (player->m_iTeam != CT)
|
||||
{
|
||||
return;
|
||||
@ -991,16 +996,18 @@ void CGrenade::__MAKE_VHOOK(Use)(CBaseEntity *pActivator, CBaseEntity *pCaller,
|
||||
|
||||
if (m_bStartDefuse)
|
||||
{
|
||||
m_fNextDefuse = gpGlobals->time + 0.5;
|
||||
m_fNextDefuse = gpGlobals->time + 0.5f;
|
||||
return;
|
||||
}
|
||||
|
||||
// freeze the player in place while defusing
|
||||
SET_CLIENT_MAXSPEED(player->edict(), 1);
|
||||
|
||||
if (TheBots != NULL)
|
||||
{
|
||||
TheBots->OnEvent(EVENT_BOMB_DEFUSING, pActivator);
|
||||
}
|
||||
|
||||
if (g_pGameRules->IsCareer())
|
||||
{
|
||||
if (TheCareerTasks != NULL)
|
||||
@ -1011,14 +1018,12 @@ void CGrenade::__MAKE_VHOOK(Use)(CBaseEntity *pActivator, CBaseEntity *pCaller,
|
||||
|
||||
if (player->m_bHasDefuser)
|
||||
{
|
||||
UTIL_LogPrintf
|
||||
(
|
||||
"\"%s<%i><%s><CT>\" triggered \"Begin_Bomb_Defuse_With_Kit\"\n",
|
||||
UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Begin_Bomb_Defuse_With_Kit\"\n",
|
||||
STRING(player->pev->netname),
|
||||
GETPLAYERUSERID(player->edict()),
|
||||
GETPLAYERAUTHID(player->edict())
|
||||
);
|
||||
GETPLAYERAUTHID(player->edict()));
|
||||
|
||||
// TODO show messages on clients on event
|
||||
ClientPrint(player->pev, HUD_PRINTCENTER, "#Defusing_Bomb_With_Defuse_Kit");
|
||||
EMIT_SOUND(ENT(player->pev), CHAN_ITEM, "weapons/c4_disarm.wav", VOL_NORM, ATTN_NORM);
|
||||
|
||||
@ -1027,6 +1032,8 @@ void CGrenade::__MAKE_VHOOK(Use)(CBaseEntity *pActivator, CBaseEntity *pCaller,
|
||||
m_bStartDefuse = true;
|
||||
m_flDefuseCountDown = gpGlobals->time + 5;
|
||||
m_fNextDefuse = gpGlobals->time + 0.5;
|
||||
|
||||
// start the progress bar
|
||||
player->SetProgressBarTime(5);
|
||||
}
|
||||
else
|
||||
@ -1036,6 +1043,7 @@ void CGrenade::__MAKE_VHOOK(Use)(CBaseEntity *pActivator, CBaseEntity *pCaller,
|
||||
GETPLAYERUSERID(player->edict()),
|
||||
GETPLAYERAUTHID(player->edict()));
|
||||
|
||||
// TODO show messages on clients on event
|
||||
ClientPrint(player->pev, HUD_PRINTCENTER, "#Defusing_Bomb_Without_Defuse_Kit");
|
||||
EMIT_SOUND(ENT(player->pev), CHAN_ITEM, "weapons/c4_disarm.wav", VOL_NORM, ATTN_NORM);
|
||||
|
||||
@ -1044,6 +1052,8 @@ void CGrenade::__MAKE_VHOOK(Use)(CBaseEntity *pActivator, CBaseEntity *pCaller,
|
||||
m_bStartDefuse = true;
|
||||
m_flDefuseCountDown = gpGlobals->time + 10;
|
||||
m_fNextDefuse = gpGlobals->time + 0.5;
|
||||
|
||||
// start the progress bar
|
||||
player->SetProgressBarTime(10);
|
||||
}
|
||||
}
|
||||
@ -1208,14 +1218,17 @@ void CGrenade::C4Think(void)
|
||||
AnnounceFlashInterval(20);
|
||||
break;
|
||||
}
|
||||
|
||||
++m_iCurWave;
|
||||
}
|
||||
|
||||
if (gpGlobals->time >= m_flNextBeep)
|
||||
{
|
||||
m_flNextBeep = gpGlobals->time + 1.4;
|
||||
m_flNextBeep = gpGlobals->time + 1.4f;
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, m_sBeepName, VOL_NORM, m_fAttenu);
|
||||
|
||||
// let the bots hear the bomb beeping
|
||||
// BOTPORT: Emit beep events at same time as client effects
|
||||
if (TheBots != NULL)
|
||||
{
|
||||
TheBots->OnEvent(EVENT_BOMB_BEEP, this);
|
||||
@ -1238,6 +1251,7 @@ void CGrenade::C4Think(void)
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
// If the timer has expired ! blow this bomb up!
|
||||
if (gpGlobals->time >= m_flC4Blow)
|
||||
{
|
||||
if (TheBots != NULL)
|
||||
@ -1260,7 +1274,7 @@ void CGrenade::C4Think(void)
|
||||
}
|
||||
|
||||
CBasePlayer *pBombOwner = (CBasePlayer *)CBaseEntity::Instance(pev->owner);
|
||||
if (pBombOwner)
|
||||
if (pBombOwner != NULL)
|
||||
{
|
||||
pBombOwner->pev->frags += 3;
|
||||
}
|
||||
@ -1276,14 +1290,17 @@ void CGrenade::C4Think(void)
|
||||
SetThink(&CGrenade::Detonate2);
|
||||
}
|
||||
|
||||
if (m_bStartDefuse)
|
||||
// if the defusing process has started
|
||||
if (m_bStartDefuse && m_pBombDefuser != NULL)
|
||||
{
|
||||
CBasePlayer *pPlayer = (CBasePlayer *)((CBaseEntity *)m_pBombDefuser);
|
||||
CBasePlayer *pPlayer = (CBasePlayer *)m_pBombDefuser;
|
||||
|
||||
if (pPlayer != NULL && gpGlobals->time < m_flDefuseCountDown)
|
||||
// if the defusing process has not ended yet
|
||||
if (gpGlobals->time < m_flDefuseCountDown)
|
||||
{
|
||||
int iOnGround = ((m_pBombDefuser->pev->flags & FL_ONGROUND) == FL_ONGROUND);
|
||||
|
||||
// if the bomb defuser has stopped defusing the bomb
|
||||
if (gpGlobals->time > m_fNextDefuse || !iOnGround)
|
||||
{
|
||||
if (!iOnGround)
|
||||
@ -1291,92 +1308,95 @@ void CGrenade::C4Think(void)
|
||||
ClientPrint(m_pBombDefuser->pev, HUD_PRINTCENTER, "#C4_Defuse_Must_Be_On_Ground");
|
||||
}
|
||||
|
||||
// release the player from being frozen
|
||||
pPlayer->ResetMaxSpeed();
|
||||
pPlayer->m_bIsDefusing = false;
|
||||
pPlayer->SetProgressBarTime(0);
|
||||
|
||||
// cancel the progress bar
|
||||
pPlayer->SetProgressBarTime(0);
|
||||
m_pBombDefuser = NULL;
|
||||
m_bStartDefuse = false;
|
||||
m_flDefuseCountDown = 0;
|
||||
|
||||
// tell the bots someone has aborted defusing
|
||||
if (TheBots != NULL)
|
||||
{
|
||||
TheBots->OnEvent(EVENT_BOMB_DEFUSE_ABORTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if the defuse process has ended, kill the c4
|
||||
else if (m_pBombDefuser->pev->deadflag == DEAD_NO)
|
||||
{
|
||||
Broadcast("BOMBDEF");
|
||||
|
||||
if (TheBots != NULL)
|
||||
{
|
||||
TheBots->OnEvent(EVENT_BOMB_DEFUSED, (CBaseEntity *)m_pBombDefuser);
|
||||
}
|
||||
|
||||
MESSAGE_BEGIN(MSG_SPEC, SVC_DIRECTOR);
|
||||
WRITE_BYTE(9);
|
||||
WRITE_BYTE(DRC_CMD_EVENT);
|
||||
WRITE_SHORT(ENTINDEX(m_pBombDefuser->edict()));
|
||||
WRITE_SHORT(0);
|
||||
WRITE_LONG(15 | DRC_FLAG_FINAL | DRC_FLAG_FACEPLAYER | DRC_FLAG_DRAMATIC);
|
||||
MESSAGE_END();
|
||||
|
||||
UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Defused_The_Bomb\"\n",
|
||||
STRING(m_pBombDefuser->pev->netname),
|
||||
GETPLAYERUSERID(m_pBombDefuser->edict()),
|
||||
GETPLAYERAUTHID(m_pBombDefuser->edict()));
|
||||
|
||||
UTIL_EmitAmbientSound(ENT(pev), pev->origin, "weapons/c4_beep5.wav", 0, ATTN_NONE, SND_STOP, 0);
|
||||
EMIT_SOUND(ENT(m_pBombDefuser->pev), CHAN_WEAPON, "weapons/c4_disarmed.wav", VOL_NORM, ATTN_NORM);
|
||||
UTIL_Remove(this);
|
||||
|
||||
m_bJustBlew = true;
|
||||
|
||||
// release the player from being frozen
|
||||
pPlayer->ResetMaxSpeed();
|
||||
pPlayer->m_bIsDefusing = false;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgScenarioIcon);
|
||||
WRITE_BYTE(0);
|
||||
MESSAGE_END();
|
||||
|
||||
if (g_pGameRules->IsCareer() && !pPlayer->IsBot())
|
||||
{
|
||||
if (TheCareerTasks != NULL)
|
||||
{
|
||||
TheCareerTasks->HandleEvent(EVENT_BOMB_DEFUSED, pPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
g_pGameRules->m_bBombDefused = true;
|
||||
g_pGameRules->CheckWinConditions();
|
||||
|
||||
// give the defuser credit for defusing the bomb
|
||||
m_pBombDefuser->pev->frags += 3;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgBombPickup);
|
||||
MESSAGE_END();
|
||||
|
||||
g_pGameRules->m_bBombDropped = FALSE;
|
||||
m_pBombDefuser = NULL;
|
||||
m_bStartDefuse = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pPlayer != NULL && m_pBombDefuser->pev->deadflag == DEAD_NO)
|
||||
// if it gets here then the previouse defuser has taken off or been killed
|
||||
// release the player from being frozen
|
||||
pPlayer->ResetMaxSpeed();
|
||||
pPlayer->m_bIsDefusing = false;
|
||||
|
||||
m_bStartDefuse = false;
|
||||
m_pBombDefuser = NULL;
|
||||
|
||||
// tell the bots someone has aborted defusing
|
||||
if (TheBots != NULL)
|
||||
{
|
||||
Broadcast("BOMBDEF");
|
||||
|
||||
if (TheBots != NULL)
|
||||
{
|
||||
TheBots->OnEvent(EVENT_BOMB_DEFUSED, (CBaseEntity *)m_pBombDefuser);
|
||||
}
|
||||
|
||||
MESSAGE_BEGIN(MSG_SPEC, SVC_DIRECTOR);
|
||||
WRITE_BYTE(9);
|
||||
WRITE_BYTE(DRC_CMD_EVENT);
|
||||
WRITE_SHORT(ENTINDEX(m_pBombDefuser->edict()));
|
||||
WRITE_SHORT(0);
|
||||
WRITE_LONG(15 | DRC_FLAG_FINAL | DRC_FLAG_FACEPLAYER | DRC_FLAG_DRAMATIC);
|
||||
MESSAGE_END();
|
||||
|
||||
UTIL_LogPrintf("\"%s<%i><%s><CT>\" triggered \"Defused_The_Bomb\"\n",
|
||||
STRING(m_pBombDefuser->pev->netname),
|
||||
GETPLAYERUSERID(m_pBombDefuser->edict()),
|
||||
GETPLAYERAUTHID(m_pBombDefuser->edict()));
|
||||
|
||||
UTIL_EmitAmbientSound(ENT(pev), pev->origin, "weapons/c4_beep5.wav", 0, ATTN_NONE, SND_STOP, 0);
|
||||
EMIT_SOUND(ENT(m_pBombDefuser->pev), CHAN_WEAPON, "weapons/c4_disarmed.wav", VOL_NORM, ATTN_NORM);
|
||||
UTIL_Remove(this);
|
||||
|
||||
m_bJustBlew = true;
|
||||
|
||||
pPlayer->ResetMaxSpeed();
|
||||
pPlayer->m_bIsDefusing = false;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgScenarioIcon);
|
||||
WRITE_BYTE(0);
|
||||
MESSAGE_END();
|
||||
|
||||
if (g_pGameRules->IsCareer() && !pPlayer->IsBot())
|
||||
{
|
||||
if (TheCareerTasks != NULL)
|
||||
{
|
||||
TheCareerTasks->HandleEvent(EVENT_BOMB_DEFUSED, pPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
g_pGameRules->m_bBombDefused = true;
|
||||
g_pGameRules->CheckWinConditions();
|
||||
|
||||
m_pBombDefuser->pev->frags += 3;
|
||||
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgBombPickup);
|
||||
MESSAGE_END();
|
||||
|
||||
g_pGameRules->m_bBombDropped = FALSE;
|
||||
m_pBombDefuser = NULL;
|
||||
m_bStartDefuse = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pPlayer != NULL)
|
||||
{
|
||||
pPlayer->ResetMaxSpeed();
|
||||
pPlayer->m_bIsDefusing = false;
|
||||
}
|
||||
|
||||
m_bStartDefuse = false;
|
||||
m_pBombDefuser = NULL;
|
||||
|
||||
if (TheBots != NULL)
|
||||
{
|
||||
TheBots->OnEvent(EVENT_BOMB_DEFUSE_ABORTED);
|
||||
}
|
||||
TheBots->OnEvent(EVENT_BOMB_DEFUSE_ABORTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,17 +253,13 @@ void CHostage::IdleThink(void)
|
||||
|
||||
if (m_improv != NULL)
|
||||
{
|
||||
if (IsFollowingSomeone())
|
||||
{
|
||||
if (m_improv->IsFollowing())
|
||||
player = (CBasePlayer *)m_improv->GetFollowLeader();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player = GetClassPtr((CBasePlayer *)m_hTargetEnt->pev);
|
||||
}
|
||||
|
||||
if (!player || player->m_iTeam == CT)
|
||||
if (player == NULL || player->m_iTeam == CT)
|
||||
{
|
||||
if (!g_pGameRules->m_bMapHasRescueZone)
|
||||
{
|
||||
@ -924,18 +920,7 @@ void CHostage::DoFollow(void)
|
||||
}
|
||||
else if (pev->takedamage == DAMAGE_YES)
|
||||
{
|
||||
if (m_improv != NULL)
|
||||
{
|
||||
if (IsFollowingSomeone())
|
||||
{
|
||||
if (!m_bStuck && flDistToDest > 200)
|
||||
{
|
||||
m_bStuck = TRUE;
|
||||
m_flStuckTime = gpGlobals->time;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_hTargetEnt != NULL && m_State == FOLLOW)
|
||||
if (IsFollowingSomeone())
|
||||
{
|
||||
if (!m_bStuck && flDistToDest > 200)
|
||||
{
|
||||
@ -1498,7 +1483,6 @@ bool CHostageManager::IsNearbyHostageJumping(CHostageImprov *improv)
|
||||
{
|
||||
for (int i = 0; i < m_hostageCount; i++)
|
||||
{
|
||||
const float closeRange = 500.0f;
|
||||
const CHostageImprov *other = m_hostage[i]->m_improv;
|
||||
|
||||
if (other == NULL)
|
||||
@ -1506,7 +1490,8 @@ bool CHostageManager::IsNearbyHostageJumping(CHostageImprov *improv)
|
||||
|
||||
if (!other->IsAlive() || other == improv)
|
||||
continue;
|
||||
|
||||
|
||||
const float closeRange = 500.0f;
|
||||
if (!(improv->GetCentroid() - other->GetCentroid()).IsLengthGreaterThan(closeRange) && other->IsJumping())
|
||||
{
|
||||
return true;
|
||||
|
@ -95,13 +95,15 @@ extern int g_iHostageNumber;
|
||||
extern cvar_t cv_hostage_debug;
|
||||
extern cvar_t cv_hostage_stop;
|
||||
|
||||
// A Counter-Strike Hostage Simple
|
||||
|
||||
/* <4858e5> ../cstrike/dlls/hostage/hostage.h:32 */
|
||||
class CHostage: public CBaseMonster
|
||||
{
|
||||
public:
|
||||
virtual void Spawn(void);
|
||||
virtual void Precache(void);
|
||||
virtual int ObjectCaps(void);
|
||||
virtual int ObjectCaps(void); // make hostage "useable"
|
||||
virtual int Classify(void)
|
||||
{
|
||||
return CLASS_HUMAN_PASSIVE;
|
||||
@ -152,22 +154,34 @@ public:
|
||||
void Wiggle(void);
|
||||
void PreThink(void);
|
||||
|
||||
// queries
|
||||
bool IsFollowingSomeone(void)
|
||||
{
|
||||
return m_improv->IsFollowing();
|
||||
return IsFollowing();
|
||||
}
|
||||
CBaseEntity *GetLeader(void)
|
||||
CBaseEntity *GetLeader(void) // return our leader, or NULL
|
||||
{
|
||||
if (m_improv != NULL)
|
||||
{
|
||||
return m_improv->GetFollowLeader();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return m_hTargetEnt;
|
||||
}
|
||||
bool IsFollowing(const CBaseEntity *entity)
|
||||
bool IsFollowing(const CBaseEntity *entity = NULL)
|
||||
{
|
||||
return (entity == m_hTargetEnt && m_State == FOLLOW);
|
||||
if (m_improv != NULL)
|
||||
{
|
||||
return m_improv->IsFollowing();
|
||||
}
|
||||
|
||||
if (entity == NULL && m_hTargetEnt == NULL || (entity != NULL && m_hTargetEnt != entity))
|
||||
return false;
|
||||
|
||||
if (m_State != FOLLOW)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool IsValid(void)
|
||||
{
|
||||
@ -187,24 +201,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
enum state
|
||||
{
|
||||
FOLLOW = 0,
|
||||
STAND,
|
||||
DUCK,
|
||||
SCARED,
|
||||
IDLE,
|
||||
FOLLOWPATH,
|
||||
};
|
||||
|
||||
enum ModelType
|
||||
{
|
||||
REGULAR_GUY = 0,
|
||||
OLD_GUY,
|
||||
BLACK_GUY,
|
||||
GOOFY_GUY,
|
||||
};
|
||||
|
||||
int m_Activity;
|
||||
BOOL m_bTouched;
|
||||
BOOL m_bRescueMe;
|
||||
@ -214,7 +210,8 @@ public:
|
||||
int m_iModel;
|
||||
int m_iSkin;
|
||||
float m_flNextRadarTime;
|
||||
state m_State;
|
||||
enum state { FOLLOW, STAND, DUCK, SCARED, IDLE, FOLLOWPATH }
|
||||
m_State;
|
||||
Vector m_vStart;
|
||||
Vector m_vStartAngles;
|
||||
Vector m_vPathToFollow[20];
|
||||
@ -235,7 +232,9 @@ public:
|
||||
BOOL m_bStuck;
|
||||
float m_flStuckTime;
|
||||
CHostageImprov *m_improv;
|
||||
ModelType m_whichModel;
|
||||
|
||||
enum ModelType { REGULAR_GUY, OLD_GUY, BLACK_GUY, GOOFY_GUY }
|
||||
m_whichModel;
|
||||
|
||||
};/* size: 1988, cachelines: 32, members: 32 */
|
||||
|
||||
@ -294,6 +293,25 @@ public:
|
||||
bool IsNearbyHostageTalking(CHostageImprov *improv);
|
||||
bool IsNearbyHostageJumping(CHostageImprov *improv);
|
||||
void OnEvent(GameEventType event, CBaseEntity *entity, CBaseEntity *other);
|
||||
|
||||
// Iterate over all active hostages in the game, invoking functor on each.
|
||||
// If functor returns false, stop iteration and return false.
|
||||
template<typename Functor>
|
||||
inline bool ForEachHostage(Functor &func) const
|
||||
{
|
||||
for (int i = 0; i < m_hostageCount; i++)
|
||||
{
|
||||
CHostage *hostage = m_hostage[i];
|
||||
|
||||
if (hostage == NULL || hostage->pev->deadflag == DEAD_DEAD)
|
||||
continue;
|
||||
|
||||
if (func(hostage) == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
inline CHostage *GetClosestHostage(const Vector &pos, float *resultRange = NULL)
|
||||
{
|
||||
float range;
|
||||
@ -317,23 +335,6 @@ public:
|
||||
return close;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool ForEachHostage(T &func) const
|
||||
{
|
||||
for (int i = 0; i < m_hostageCount; i++)
|
||||
{
|
||||
CHostage *pHostage = m_hostage[ i ];
|
||||
|
||||
if (pHostage->pev->deadflag == DEAD_DEAD)
|
||||
continue;
|
||||
|
||||
if (func(pHostage) == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
CHostage *m_hostage[ MAX_HOSTAGES ];
|
||||
int m_hostageCount;
|
||||
@ -341,43 +342,18 @@ private:
|
||||
|
||||
};/* size: 5680, cachelines: 89, members: 3 */
|
||||
|
||||
|
||||
///* <470134> ../cstrike/dlls/hostage/hostage.h:293 */
|
||||
//inline void CHostageManager::ForEachHostage<KeepPersonalSpace>(KeepPersonalSpace &func)
|
||||
//{
|
||||
//// {
|
||||
//// int i; // 295
|
||||
//// }
|
||||
//}
|
||||
//
|
||||
///* <46fbe8> ../cstrike/dlls/hostage/hostage.h:293 */
|
||||
//inline void CHostageManager::ForEachHostage<CheckAhead>(CheckAhead &func)
|
||||
//{
|
||||
//// {
|
||||
//// int i; // 295
|
||||
//// }
|
||||
//}
|
||||
//
|
||||
///* <46fb04> ../cstrike/dlls/hostage/hostage.h:293 */
|
||||
//inline void CHostageManager::ForEachHostage<CheckWayFunctor>(CheckWayFunctor &func)
|
||||
//{
|
||||
//// {
|
||||
//// int i; // 295
|
||||
//// }
|
||||
//}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
// linked object
|
||||
C_DLLEXPORT void hostage_entity(entvars_t *pev);
|
||||
C_DLLEXPORT void monster_scientist(entvars_t *pev);
|
||||
|
||||
// refs
|
||||
extern void (CBaseEntity::*pCHostage__IdleThink)(void);
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
void Hostage_RegisterCVars(void);
|
||||
void InstallHostageManager(void);
|
||||
|
||||
// refs
|
||||
extern void (CBaseEntity::*pCHostage__IdleThink)(void);
|
||||
|
||||
#endif // HOSTAGE_H
|
||||
|
@ -275,7 +275,7 @@ void CHostageImprov::FaceOutwards(void)
|
||||
float farthestRange = 0.0f;
|
||||
int farthest = 0;
|
||||
|
||||
Vector corner[] =
|
||||
static Vector corner[] =
|
||||
{
|
||||
Vector(-1000, 1000, 0),
|
||||
Vector(1000, 1000, 0),
|
||||
@ -935,7 +935,7 @@ void CHostageImprov::UpdatePosition(float deltaT)
|
||||
|
||||
while (yaw < -180.0f)
|
||||
yaw += 360.0f;
|
||||
|
||||
|
||||
while (pitch > 180.0f)
|
||||
pitch -= 360.0f;
|
||||
|
||||
@ -1536,7 +1536,7 @@ CBasePlayer *CHostageImprov::GetClosestVisiblePlayer(int team)
|
||||
|
||||
for (int i = 0; i < m_visiblePlayerCount; i++)
|
||||
{
|
||||
CBasePlayer *player = (CBasePlayer *)((CBaseEntity *)m_visiblePlayer[i]);
|
||||
CBasePlayer *player = (CBasePlayer *)m_visiblePlayer[i];
|
||||
|
||||
if (player == NULL || (team > 0 && player->m_iTeam != team))
|
||||
continue;
|
||||
@ -1784,6 +1784,8 @@ void CHostageImprov::Wave(void)
|
||||
m_animateState.AddSequence(this, ACT_WAVE);
|
||||
}
|
||||
|
||||
// Invoked when an improv fails to reach a MoveTo goal
|
||||
|
||||
/* <474938> ../cstrike/dlls/hostage/hostage_improv.cpp:2375 */
|
||||
void CHostageImprov::__MAKE_VHOOK(OnMoveToFailure)(const Vector &goal, MoveToFailureType reason)
|
||||
{
|
||||
@ -1798,12 +1800,6 @@ void CHostageImprov::__MAKE_VHOOK(OnMoveToFailure)(const Vector &goal, MoveToFai
|
||||
/* <4763d7> ../cstrike/dlls/hostage/hostage_improv.cpp:2391 */
|
||||
void CHostageImprov::Wiggle(void)
|
||||
{
|
||||
Vector dir;
|
||||
Vector lat;
|
||||
|
||||
const float force = 15.0f;
|
||||
const float minStuckJumpTime = 0.5f;
|
||||
|
||||
// for wiggling
|
||||
if (m_wiggleTimer.IsElapsed())
|
||||
{
|
||||
@ -1811,45 +1807,34 @@ void CHostageImprov::Wiggle(void)
|
||||
m_wiggleTimer.Start(RANDOM_FLOAT(0.3, 0.5));
|
||||
}
|
||||
|
||||
lat.x = BotCOS(m_moveAngle);
|
||||
lat.y = BotSIN(m_moveAngle);
|
||||
lat.z = 0;
|
||||
const float force = 15.0f;
|
||||
Vector dir(BotCOS(m_moveAngle), BotSIN(m_moveAngle), 0.0f);
|
||||
Vector lat(-dir.y, dir.x, 0.0f);
|
||||
|
||||
switch (m_wiggleDirection)
|
||||
{
|
||||
case FORWARD:
|
||||
dir.x = lat.x;
|
||||
dir.y = lat.y;
|
||||
|
||||
ApplyForce(dir * force);
|
||||
break;
|
||||
case RIGHT:
|
||||
dir.x = -lat.y;
|
||||
dir.y = lat.x;
|
||||
|
||||
ApplyForce(dir * -force);
|
||||
break;
|
||||
case BACKWARD:
|
||||
dir.x = lat.x;
|
||||
dir.y = lat.y;
|
||||
|
||||
ApplyForce(dir * -force);
|
||||
break;
|
||||
case LEFT:
|
||||
dir.x = -lat.y;
|
||||
dir.y = lat.x;
|
||||
|
||||
ApplyForce(dir * force);
|
||||
ApplyForce(lat * force);
|
||||
break;
|
||||
case RIGHT:
|
||||
ApplyForce(lat * -force);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const float minStuckJumpTime = 0.5f;
|
||||
if (m_follower.GetStuckDuration() > minStuckJumpTime && m_wiggleJumpTimer.IsElapsed())
|
||||
{
|
||||
if (Jump())
|
||||
{
|
||||
m_wiggleJumpTimer.Start(RANDOM_FLOAT(0.75, 1.2));
|
||||
m_wiggleJumpTimer.Start(RANDOM_FLOAT(0.75f, 1.2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,21 +38,21 @@
|
||||
class CHostage;
|
||||
enum HostageChatterType;
|
||||
|
||||
// A Counter-Strike Hostage improved
|
||||
class CHostageImprov: public CImprov
|
||||
{
|
||||
public:
|
||||
CHostageImprov(CBaseEntity *entity);
|
||||
~CHostageImprov(void) {};
|
||||
|
||||
virtual void OnMoveToSuccess(const Vector &goal)
|
||||
{
|
||||
m_behavior.OnMoveToSuccess(goal);
|
||||
}
|
||||
// invoked when an improv reaches its MoveTo goal
|
||||
virtual void OnMoveToSuccess(const Vector &goal) { m_behavior.OnMoveToSuccess(goal); }
|
||||
|
||||
// invoked when an improv fails to reach a MoveTo goal
|
||||
virtual void OnMoveToFailure(const Vector &goal, MoveToFailureType reason);
|
||||
virtual void OnInjury(float amount)
|
||||
{
|
||||
m_behavior.OnInjury(amount);
|
||||
|
||||
m_lastInjuryTimer.Start();
|
||||
Frighten(TERRIFIED);
|
||||
}
|
||||
@ -63,122 +63,58 @@ public:
|
||||
virtual void FaceTo(const Vector &goal);
|
||||
virtual void ClearFaceTo(void);
|
||||
virtual bool IsAtMoveGoal(float error = 20.0f) const;
|
||||
virtual bool HasLookAt(void) const
|
||||
{
|
||||
return m_isLookingAt;
|
||||
}
|
||||
virtual bool HasFaceTo(void) const
|
||||
{
|
||||
return m_isFacingTo;
|
||||
}
|
||||
virtual bool HasLookAt(void) const { return m_isLookingAt; }
|
||||
virtual bool HasFaceTo(void) const { return m_isFacingTo; }
|
||||
virtual bool IsAtFaceGoal(void) const;
|
||||
virtual bool IsFriendInTheWay(const Vector &goalPos) const;
|
||||
virtual bool IsFriendInTheWay(CBaseEntity *myFriend, const Vector &goalPos) const;
|
||||
virtual void MoveForward(void)
|
||||
{
|
||||
m_moveFlags |= IN_FORWARD;
|
||||
}
|
||||
virtual void MoveBackward(void)
|
||||
{
|
||||
m_moveFlags |= IN_BACK;
|
||||
}
|
||||
virtual void StrafeLeft(void)
|
||||
{
|
||||
m_moveFlags |= IN_MOVELEFT;
|
||||
}
|
||||
virtual void StrafeRight(void)
|
||||
{
|
||||
m_moveFlags |= IN_MOVERIGHT;
|
||||
}
|
||||
virtual void MoveForward(void) { m_moveFlags |= IN_FORWARD; }
|
||||
virtual void MoveBackward(void) { m_moveFlags |= IN_BACK; }
|
||||
virtual void StrafeLeft(void) { m_moveFlags |= IN_MOVELEFT; }
|
||||
virtual void StrafeRight(void) { m_moveFlags |= IN_MOVERIGHT; }
|
||||
|
||||
#define HOSTAGE_MUST_JUMP true
|
||||
virtual bool Jump(void);
|
||||
|
||||
virtual void Crouch(void);
|
||||
virtual void StandUp(void);
|
||||
virtual void TrackPath(const Vector &pathGoal, float deltaT);
|
||||
virtual void TrackPath(const Vector &pathGoal, float deltaT); // move along path by following "pathGoal"
|
||||
virtual void StartLadder(const CNavLadder *ladder, NavTraverseType how, const Vector *approachPos, const Vector *departPos);
|
||||
virtual bool TraverseLadder(const CNavLadder *ladder, NavTraverseType how, const Vector *approachPos, const Vector *departPos, float deltaT);
|
||||
virtual bool GetSimpleGroundHeightWithFloor(const Vector *pos, float *height, Vector *normal = NULL);
|
||||
virtual void Run(void);
|
||||
virtual void Walk(void);
|
||||
virtual void Stop(void);
|
||||
virtual float GetMoveAngle(void) const
|
||||
{
|
||||
return m_moveAngle;
|
||||
}
|
||||
virtual float GetFaceAngle(void) const
|
||||
{
|
||||
return m_moveAngle;
|
||||
}
|
||||
virtual float GetMoveAngle(void) const { return m_moveAngle; }
|
||||
virtual float GetFaceAngle(void) const { return m_moveAngle; }
|
||||
virtual const Vector &GetFeet(void) const;
|
||||
virtual const Vector &GetCentroid(void) const;
|
||||
virtual const Vector &GetEyes(void) const;
|
||||
virtual bool IsRunning(void) const
|
||||
{
|
||||
return (m_moveType == Running);
|
||||
}
|
||||
virtual bool IsWalking(void) const
|
||||
{
|
||||
return (m_moveType == Walking);
|
||||
}
|
||||
virtual bool IsStopped(void) const
|
||||
{
|
||||
return (m_moveType == Stopped);
|
||||
}
|
||||
virtual bool IsCrouching(void) const
|
||||
{
|
||||
return m_isCrouching;
|
||||
}
|
||||
virtual bool IsJumping(void) const
|
||||
{
|
||||
return (m_jumpTimer.IsElapsed() == false);
|
||||
}
|
||||
virtual bool IsUsingLadder(void) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool IsRunning(void) const { return (m_moveType == Running); }
|
||||
virtual bool IsWalking(void) const { return (m_moveType == Walking); }
|
||||
virtual bool IsStopped(void) const { return (m_moveType == Stopped); }
|
||||
virtual bool IsCrouching(void) const { return m_isCrouching; }
|
||||
virtual bool IsJumping(void) const { return (m_jumpTimer.IsElapsed() == false); }
|
||||
virtual bool IsUsingLadder(void) const { return false; }
|
||||
virtual bool IsOnGround(void) const;
|
||||
virtual bool IsMoving(void) const;
|
||||
virtual bool CanRun(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool CanCrouch(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool CanJump(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool IsVisible(const Vector &pos, bool testFOV = false) const;
|
||||
virtual bool CanRun(void) const { return true; }
|
||||
virtual bool CanCrouch(void) const { return true; }
|
||||
virtual bool CanJump(void) const { return true; }
|
||||
virtual bool IsVisible(const Vector &pos, bool testFOV = false) const; // return true if hostage can see position
|
||||
virtual bool IsPlayerLookingAtMe(CBasePlayer *other, float cosTolerance = 0.95f) const;
|
||||
virtual CBasePlayer *IsAnyPlayerLookingAtMe(int team = 0, float cosTolerance = 0.95f) const;
|
||||
virtual CBasePlayer *GetClosestPlayerByTravelDistance(int team = 0, float *range = NULL) const;
|
||||
virtual CNavArea *GetLastKnownArea(void) const
|
||||
{
|
||||
return m_lastKnownArea;
|
||||
}
|
||||
virtual CNavArea *GetLastKnownArea(void) const { return m_lastKnownArea; }
|
||||
virtual void OnUpdate(float deltaT);
|
||||
virtual void OnUpkeep(float deltaT);
|
||||
virtual void OnReset(void);
|
||||
virtual void OnGameEvent(GameEventType event, CBaseEntity *entity = NULL, CBaseEntity *other = NULL);
|
||||
virtual void OnTouch(CBaseEntity *other);
|
||||
virtual void OnTouch(CBaseEntity *other); // in contact with "other"
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void OnMoveToSuccess_(const Vector &goal)
|
||||
{
|
||||
//if (m_behavior.IsState(NULL))
|
||||
// IImprovEvent::OnMoveToSuccess(goal);
|
||||
}
|
||||
void OnMoveToFailure_(const Vector &goal, MoveToFailureType reason);
|
||||
void OnInjury_(float amount)
|
||||
{
|
||||
//m_behavior.Update();
|
||||
//m_lastInjuryTimer.Start();
|
||||
}
|
||||
bool IsAlive_(void) const;
|
||||
void MoveTo_(const Vector &goal);
|
||||
void LookAt_(const Vector &target);
|
||||
@ -217,27 +153,13 @@ public:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
public:
|
||||
enum MoveType
|
||||
{
|
||||
Stopped = 0,
|
||||
Walking,
|
||||
Running,
|
||||
};
|
||||
|
||||
enum ScareType
|
||||
{
|
||||
NERVOUS = 0,
|
||||
SCARED,
|
||||
TERRIFIED,
|
||||
};
|
||||
enum MoveType { Stopped, Walking, Running };
|
||||
enum ScareType { NERVOUS, SCARED, TERRIFIED };
|
||||
|
||||
void FaceOutwards(void);
|
||||
bool IsFriendInTheWay(void) const;
|
||||
void SetKnownGoodPosition(const Vector &pos);
|
||||
const Vector &GetKnownGoodPosition(void) const
|
||||
{
|
||||
return m_knownGoodPos;
|
||||
}
|
||||
const Vector &GetKnownGoodPosition(void) const { return m_knownGoodPos; }
|
||||
void ResetToKnownGoodPosition(void);
|
||||
void ResetJump(void)
|
||||
{
|
||||
@ -253,7 +175,7 @@ public:
|
||||
m_hasJumpedIntoAir = true;
|
||||
}
|
||||
}
|
||||
void ApplyForce(Vector force);
|
||||
void ApplyForce(Vector force); // apply a force to the hostage
|
||||
#ifdef PLAY_GAMEDLL
|
||||
void ApplyForce2(float_precision x, float_precision y)
|
||||
{
|
||||
@ -261,62 +183,32 @@ public:
|
||||
m_vel.y += y;
|
||||
}
|
||||
#endif // PLAY_GAMEDLL
|
||||
const Vector GetActualVelocity(void) const
|
||||
{
|
||||
return m_actualVel;
|
||||
}
|
||||
void SetMoveLimit(MoveType limit)
|
||||
{
|
||||
m_moveLimit = limit;
|
||||
}
|
||||
MoveType GetMoveLimit(void) const
|
||||
{
|
||||
return m_moveLimit;
|
||||
}
|
||||
CNavPath *GetPath(void)
|
||||
{
|
||||
return &m_path;
|
||||
}
|
||||
const Vector GetActualVelocity(void) const { return m_actualVel; }
|
||||
void SetMoveLimit(MoveType limit) { m_moveLimit = limit; }
|
||||
MoveType GetMoveLimit(void) const { return m_moveLimit; }
|
||||
CNavPath *GetPath(void) { return &m_path; }
|
||||
CNavPathFollower *GetPathFollower(void);
|
||||
void Idle(void)
|
||||
{
|
||||
m_behavior.SetState(&m_idleState);
|
||||
}
|
||||
bool IsIdle(void) const
|
||||
{
|
||||
return m_behavior.IsState(&m_idleState);
|
||||
}
|
||||
void Follow(CBasePlayer *leader)
|
||||
{
|
||||
m_followState.SetLeader(leader);
|
||||
m_behavior.SetState(&m_followState);
|
||||
}
|
||||
bool IsFollowing(const CBaseEntity *leader = NULL) const
|
||||
{
|
||||
return m_behavior.IsState(&m_followState);
|
||||
}
|
||||
void Escape(void)
|
||||
{
|
||||
m_behavior.SetState(&m_escapeState);
|
||||
}
|
||||
bool IsEscaping(void) const
|
||||
{
|
||||
return m_behavior.IsState(&m_escapeState);
|
||||
}
|
||||
void Retreat(void)
|
||||
{
|
||||
m_behavior.SetState(&m_retreatState);
|
||||
}
|
||||
bool IsRetreating(void) const
|
||||
{
|
||||
return m_behavior.IsState(&m_retreatState);
|
||||
}
|
||||
|
||||
// hostage states
|
||||
// stand idle
|
||||
void Idle(void) { m_behavior.SetState(&m_idleState); }
|
||||
bool IsIdle(void) const { return m_behavior.IsState(&m_idleState); }
|
||||
|
||||
// begin following "leader"
|
||||
void Follow(CBasePlayer *leader) { m_followState.SetLeader(leader); m_behavior.SetState(&m_followState); }
|
||||
bool IsFollowing(const CBaseEntity *leader = NULL) const { return m_behavior.IsState(&m_followState); }
|
||||
|
||||
// Escape
|
||||
void Escape(void) { m_behavior.SetState(&m_escapeState); }
|
||||
bool IsEscaping(void) const { return m_behavior.IsState(&m_escapeState); }
|
||||
|
||||
// Retreat
|
||||
void Retreat(void) { m_behavior.SetState(&m_retreatState); }
|
||||
bool IsRetreating(void) const { return m_behavior.IsState(&m_retreatState); }
|
||||
|
||||
bool IsAtHome(void) const;
|
||||
bool CanSeeRescueZone(void) const;
|
||||
CBaseEntity *GetFollowLeader(void) const
|
||||
{
|
||||
return m_followState.GetLeader();
|
||||
}
|
||||
CBaseEntity *GetFollowLeader(void) const { return m_followState.GetLeader(); }
|
||||
CBasePlayer *GetClosestVisiblePlayer(int team);
|
||||
float GetTimeSinceLastSawPlayer(int team);
|
||||
float GetTimeSinceLastInjury(void);
|
||||
@ -324,25 +216,13 @@ public:
|
||||
bool IsTerroristNearby(void);
|
||||
void Frighten(ScareType scare);
|
||||
bool IsScared(void) const;
|
||||
ScareType GetScareIntensity(void) const
|
||||
{
|
||||
return m_scareIntensity;
|
||||
}
|
||||
bool IsIgnoringTerrorists(void) const
|
||||
{
|
||||
m_ignoreTerroristTimer.IsElapsed();
|
||||
}
|
||||
float GetAggression(void) const
|
||||
{
|
||||
return m_aggression;
|
||||
}
|
||||
ScareType GetScareIntensity(void) const { return m_scareIntensity; }
|
||||
bool IsIgnoringTerrorists(void) const { m_ignoreTerroristTimer.IsElapsed(); }
|
||||
float GetAggression(void) const { return m_aggression; }
|
||||
void Chatter(HostageChatterType sayType, bool mustSpeak = true);
|
||||
void DelayedChatter(float delayTime, HostageChatterType sayType, bool mustSpeak = false);
|
||||
NOXREF void UpdateDelayedChatter(void);
|
||||
bool IsTalking(void) const
|
||||
{
|
||||
return m_talkingTimer.IsElapsed();
|
||||
}
|
||||
bool IsTalking(void) const { return m_talkingTimer.IsElapsed(); }
|
||||
void UpdateGrenadeReactions(void);
|
||||
void Afraid(void);
|
||||
void Wave(void);
|
||||
@ -352,20 +232,14 @@ public:
|
||||
void Flinch(Activity activity);
|
||||
void UpdateIdleActivity(Activity activity, Activity fidget);
|
||||
void UpdateStationaryAnimation(void);
|
||||
CHostage *GetEntity(void) const
|
||||
{
|
||||
return m_hostage;
|
||||
}
|
||||
CHostage *GetEntity(void) const { return m_hostage; }
|
||||
void CheckForNearbyTerrorists(void);
|
||||
void UpdatePosition(float);
|
||||
void MoveTowards(const Vector &pos, float deltaT);
|
||||
bool FaceTowards(const Vector &target, float deltaT);
|
||||
bool FaceTowards(const Vector &target, float deltaT); // rotate body to face towards "target"
|
||||
float GetSpeed(void);
|
||||
void SetMoveAngle(float angle)
|
||||
{
|
||||
m_moveAngle = angle;
|
||||
}
|
||||
void Wiggle(void);
|
||||
void SetMoveAngle(float angle) { m_moveAngle = angle; }
|
||||
void Wiggle(void); // attempt to wiggle-out of begin stuck
|
||||
void ClearPath(void);
|
||||
|
||||
#define HOSTAGE_ONLY_JUMP_DOWN true
|
||||
@ -378,7 +252,7 @@ public:
|
||||
|
||||
private:
|
||||
CHostage *m_hostage;
|
||||
CNavArea *m_lastKnownArea;
|
||||
CNavArea *m_lastKnownArea; // last area we were in
|
||||
mutable Vector m_centroid;
|
||||
mutable Vector m_eye;
|
||||
HostageStateMachine m_behavior;
|
||||
@ -423,25 +297,27 @@ private:
|
||||
bool m_isLookingAt;
|
||||
Vector m_faceGoal;
|
||||
bool m_isFacingTo;
|
||||
CNavPath m_path;
|
||||
CNavPath m_path; // current path to follow
|
||||
CNavPathFollower m_follower;
|
||||
Vector m_lastPosition;
|
||||
MoveType m_moveType;
|
||||
MoveType m_moveLimit;
|
||||
bool m_isCrouching;
|
||||
bool m_isCrouching; // true if hostage is crouching
|
||||
CountdownTimer m_minCrouchTimer;
|
||||
float m_moveAngle;
|
||||
NavRelativeDirType m_wiggleDirection;
|
||||
CountdownTimer m_wiggleTimer;
|
||||
|
||||
CountdownTimer m_wiggleTimer; // for wiggling
|
||||
CountdownTimer m_wiggleJumpTimer;
|
||||
CountdownTimer m_inhibitObstacleAvoidance;
|
||||
CountdownTimer m_jumpTimer;
|
||||
CountdownTimer m_jumpTimer; // if zero, we can jump
|
||||
|
||||
bool m_hasJumped;
|
||||
bool m_hasJumpedIntoAir;
|
||||
Vector m_jumpTarget;
|
||||
CountdownTimer m_clearPathTimer;
|
||||
bool m_traversingLadder;
|
||||
EHANDLE m_visiblePlayer[32];
|
||||
EHANDLE m_visiblePlayer[ MAX_CLIENTS ];
|
||||
int m_visiblePlayerCount;
|
||||
CountdownTimer m_visionTimer;
|
||||
|
||||
@ -475,6 +351,9 @@ public:
|
||||
|
||||
}; /* size: 20, cachelines: 1, members: 3 */
|
||||
|
||||
// Functor used with NavAreaBuildPath() for building Hostage paths.
|
||||
// Once we hook up crouching and ladders, this can be removed and ShortestPathCost() can be used instead.
|
||||
|
||||
/* <46f426> ../cstrike/dlls/hostage/hostage_improv.h:400 */
|
||||
class HostagePathCost
|
||||
{
|
||||
@ -496,9 +375,12 @@ public:
|
||||
const float ladderCost = 10.0f;
|
||||
return ladder->m_length * ladderCost + fromArea->GetCostSoFar();
|
||||
}
|
||||
|
||||
dist = (*area->GetCenter() - *fromArea->GetCenter()).Length();
|
||||
float cost = fromArea->GetCostSoFar() + dist;
|
||||
else
|
||||
{
|
||||
dist = (*area->GetCenter() - *fromArea->GetCenter()).Length();
|
||||
}
|
||||
|
||||
float cost = dist + fromArea->GetCostSoFar();
|
||||
|
||||
// if this is a "crouch" area, add penalty
|
||||
if (area->GetAttributes() & NAV_CROUCH)
|
||||
@ -594,12 +476,8 @@ public:
|
||||
CheckAhead(const CHostageImprov *me)
|
||||
{
|
||||
m_me = me;
|
||||
|
||||
m_dir = Vector(BotCOS(me->GetMoveAngle()), BotSIN(me->GetMoveAngle()), 0.0f);
|
||||
m_isBlocked = false;
|
||||
|
||||
m_dir.x = BotCOS(me->GetMoveAngle());
|
||||
m_dir.y = BotSIN(me->GetMoveAngle());
|
||||
m_dir.z = 0;
|
||||
}
|
||||
/* <47046f> ../cstrike/dlls/hostage/hostage_improv.cpp:525 */
|
||||
bool operator()(CBaseEntity *entity)
|
||||
|
@ -79,24 +79,11 @@ public:
|
||||
virtual void OnEnter(CHostageImprov *improv);
|
||||
virtual void OnUpdate(CHostageImprov *improv);
|
||||
virtual void OnExit(CHostageImprov *improv);
|
||||
virtual const char *GetName(void) const
|
||||
{
|
||||
return "Idle";
|
||||
}
|
||||
virtual const char *GetName(void) const { return "Idle"; }
|
||||
virtual void UpdateStationaryAnimation(CHostageImprov *improv);
|
||||
virtual void OnMoveToSuccess(const Vector &goal)
|
||||
{
|
||||
m_moveState = MoveDone;
|
||||
}
|
||||
virtual void OnMoveToFailure(const Vector &goal, MoveToFailureType reason)
|
||||
{
|
||||
m_moveState = MoveFailed;
|
||||
}
|
||||
virtual void OnInjury(float amount = -1.0f)
|
||||
{
|
||||
m_fleeTimer.Invalidate();
|
||||
m_mustFlee = true;
|
||||
}
|
||||
virtual void OnMoveToSuccess(const Vector &goal) { m_moveState = MoveDone; }
|
||||
virtual void OnMoveToFailure(const Vector &goal, MoveToFailureType reason) { m_moveState = MoveFailed; }
|
||||
virtual void OnInjury(float amount = -1.0f) { m_fleeTimer.Invalidate(); m_mustFlee = true; }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
@ -137,10 +124,7 @@ public:
|
||||
virtual void OnEnter(CHostageImprov *improv);
|
||||
virtual void OnUpdate(CHostageImprov *improv);
|
||||
virtual void OnExit(CHostageImprov *improv);
|
||||
virtual const char *GetName(void) const
|
||||
{
|
||||
return "Escape:ToCover";
|
||||
}
|
||||
virtual const char *GetName(void) const { return "Escape:ToCover"; }
|
||||
virtual void OnMoveToFailure(const Vector &goal, MoveToFailureType reason);
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
@ -153,10 +137,7 @@ public:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
public:
|
||||
void SetRescueGoal(const Vector &rescueGoal)
|
||||
{
|
||||
m_rescueGoal = rescueGoal;
|
||||
}
|
||||
void SetRescueGoal(const Vector &rescueGoal) { m_rescueGoal = rescueGoal; }
|
||||
|
||||
private:
|
||||
Vector m_rescueGoal;
|
||||
@ -174,10 +155,7 @@ public:
|
||||
virtual void OnEnter(CHostageImprov *improv);
|
||||
virtual void OnUpdate(CHostageImprov *improv);
|
||||
virtual void OnExit(CHostageImprov *improv);
|
||||
virtual const char *GetName(void) const
|
||||
{
|
||||
return "Escape:LookAround";
|
||||
}
|
||||
virtual const char *GetName(void) const { return "Escape:LookAround"; }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
@ -201,14 +179,8 @@ public:
|
||||
virtual void OnEnter(CHostageImprov *improv);
|
||||
virtual void OnUpdate(CHostageImprov *improv);
|
||||
virtual void OnExit(CHostageImprov *improv);
|
||||
virtual const char *GetName(void) const
|
||||
{
|
||||
return "Escape";
|
||||
}
|
||||
virtual void OnMoveToFailure(const Vector &goal, MoveToFailureType reason)
|
||||
{
|
||||
m_behavior.OnMoveToFailure(goal, reason);
|
||||
}
|
||||
virtual const char *GetName(void) const { return "Escape"; }
|
||||
virtual void OnMoveToFailure(const Vector &goal, MoveToFailureType reason) { m_behavior.OnMoveToFailure(goal, reason); }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
@ -219,14 +191,8 @@ public:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
public:
|
||||
void ToCover(void)
|
||||
{
|
||||
m_behavior.SetState(&m_toCoverState);
|
||||
}
|
||||
void LookAround(void)
|
||||
{
|
||||
m_behavior.SetState(&m_lookAroundState);
|
||||
}
|
||||
void ToCover(void) { m_behavior.SetState(&m_toCoverState); }
|
||||
void LookAround(void) { m_behavior.SetState(&m_lookAroundState); }
|
||||
|
||||
private:
|
||||
HostageEscapeToCoverState m_toCoverState;
|
||||
@ -246,20 +212,13 @@ public:
|
||||
virtual void OnEnter(CHostageImprov *improv);
|
||||
virtual void OnUpdate(CHostageImprov *improv);
|
||||
virtual void OnExit(CHostageImprov *improv);
|
||||
virtual const char *GetName(void) const
|
||||
{
|
||||
return "Retreat";
|
||||
}
|
||||
virtual const char *GetName(void) const { return "Retreat"; }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
void OnEnter_(CHostageImprov *improv);
|
||||
void OnUpdate_(CHostageImprov *improv);
|
||||
void OnExit_(CHostageImprov *improv);
|
||||
const char *GetName_(void) const
|
||||
{
|
||||
return GetName();
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
@ -274,10 +233,7 @@ public:
|
||||
virtual void OnEnter(CHostageImprov *improv);
|
||||
virtual void OnUpdate(CHostageImprov *improv);
|
||||
virtual void OnExit(CHostageImprov *improv);
|
||||
virtual const char *GetName(void) const
|
||||
{
|
||||
return "Follow";
|
||||
}
|
||||
virtual const char *GetName(void) const { return "Follow"; }
|
||||
virtual void UpdateStationaryAnimation(CHostageImprov *improv);
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
@ -290,14 +246,8 @@ public:
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
public:
|
||||
void SetLeader(CBaseEntity *leader)
|
||||
{
|
||||
m_leader = leader;
|
||||
}
|
||||
CBaseEntity *GetLeader(void) const
|
||||
{
|
||||
return m_leader;
|
||||
}
|
||||
void SetLeader(CBaseEntity *leader) { m_leader = leader; }
|
||||
CBaseEntity *GetLeader(void) const { return m_leader; }
|
||||
|
||||
private:
|
||||
mutable EHANDLE m_leader;
|
||||
@ -321,10 +271,7 @@ public:
|
||||
virtual void OnEnter(CHostageImprov *improv);
|
||||
virtual void OnUpdate(CHostageImprov *improv);
|
||||
virtual void OnExit(CHostageImprov *improv);
|
||||
virtual const char *GetName(void) const
|
||||
{
|
||||
return "Animate";
|
||||
}
|
||||
virtual const char *GetName(void) const { return "Animate"; }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
@ -340,8 +287,7 @@ public:
|
||||
int seqID;
|
||||
float holdTime;
|
||||
float rate;
|
||||
|
||||
};/* size: 12, cachelines: 1, members: 3 */
|
||||
};
|
||||
|
||||
enum PerformanceType
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ void HostageFollowState::__MAKE_VHOOK(OnUpdate)(CHostageImprov *improv)
|
||||
bool makeWay = false;
|
||||
const float cosTolerance = 0.99f;
|
||||
|
||||
if (improv->IsPlayerLookingAtMe((CBasePlayer *)((CBaseEntity *)m_leader), cosTolerance))
|
||||
if (improv->IsPlayerLookingAtMe((CBasePlayer *)m_leader, cosTolerance))
|
||||
{
|
||||
if (!m_makeWayTimer.HasStarted())
|
||||
{
|
||||
|
@ -448,7 +448,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay(void)
|
||||
m_iAccountCT = 0;
|
||||
m_iAccountTerrorist = 0;
|
||||
m_iHostagesRescued = 0;
|
||||
m_iRoundWinStatus = 0;
|
||||
m_iRoundWinStatus = WINNER_NONE;
|
||||
m_iNumCTWins = 0;
|
||||
m_iNumTerroristWins = 0;
|
||||
m_pVIP = NULL;
|
||||
@ -949,7 +949,7 @@ void CHalfLifeMultiplay::QueueCareerRoundEndMenu(float tmDelay, int iWinStatus)
|
||||
{
|
||||
numHostagesInMap++;
|
||||
|
||||
CHostage *pHostage = reinterpret_cast<CHostage *>(hostage);
|
||||
CHostage *pHostage = static_cast<CHostage *>(hostage);
|
||||
|
||||
if (pHostage->pev->takedamage != DAMAGE_YES)
|
||||
{
|
||||
@ -958,17 +958,8 @@ void CHalfLifeMultiplay::QueueCareerRoundEndMenu(float tmDelay, int iWinStatus)
|
||||
|
||||
CBasePlayer *pLeader = NULL;
|
||||
|
||||
if (pHostage->m_improv != NULL)
|
||||
{
|
||||
if (pHostage->IsFollowingSomeone())
|
||||
{
|
||||
pLeader = reinterpret_cast<CBasePlayer *>(pHostage->GetLeader());
|
||||
}
|
||||
}
|
||||
else if (pHostage->m_hTargetEnt != NULL && pHostage->m_State == CHostage::FOLLOW)
|
||||
{
|
||||
pLeader = (CBasePlayer *)((CBaseEntity *)pHostage->m_hTargetEnt);
|
||||
}
|
||||
if (pHostage->IsFollowingSomeone())
|
||||
pLeader = static_cast<CBasePlayer *>(pHostage->GetLeader());
|
||||
|
||||
if (pLeader == NULL)
|
||||
{
|
||||
@ -1042,7 +1033,7 @@ void CHalfLifeMultiplay::__MAKE_VHOOK(CheckWinConditions)(void)
|
||||
#endif // REGAMEDLL_ADD
|
||||
|
||||
// If a winner has already been determined and game of started.. then get the heck out of here
|
||||
if (m_bFirstConnected && m_iRoundWinStatus != 0)
|
||||
if (m_bFirstConnected && m_iRoundWinStatus != WINNER_NONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -2091,7 +2082,7 @@ void CHalfLifeMultiplay::__MAKE_VHOOK(RestartRound)(void)
|
||||
m_iAccountTerrorist = m_iAccountCT = 0;
|
||||
m_iHostagesRescued = 0;
|
||||
m_iHostagesTouched = 0;
|
||||
m_iRoundWinStatus = 0;
|
||||
m_iRoundWinStatus = WINNER_NONE;
|
||||
m_bTargetBombed = m_bBombDefused = false;
|
||||
m_bLevelInitialized = false;
|
||||
m_bCompleteReset = false;
|
||||
@ -3000,7 +2991,7 @@ void CHalfLifeMultiplay::CheckRestartRound(void)
|
||||
bool CHalfLifeMultiplay::HasRoundTimeExpired(void)
|
||||
{
|
||||
// We haven't completed other objectives, so go for this!.
|
||||
if (TimeRemaining() > 0 || m_iRoundWinStatus != 0)
|
||||
if (TimeRemaining() > 0 || m_iRoundWinStatus != WINNER_NONE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -463,10 +463,7 @@ public:
|
||||
virtual void Precache(void);
|
||||
virtual int Save(CSave &save);
|
||||
virtual int Restore(CRestore &restore);
|
||||
virtual int ObjectCaps(void)
|
||||
{
|
||||
return (CBaseMonster::ObjectCaps() & ~FCAP_ACROSS_TRANSITION);
|
||||
}
|
||||
virtual int ObjectCaps(void) { return (CBaseMonster::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); }
|
||||
virtual int Classify(void);
|
||||
virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
||||
virtual int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType);
|
||||
@ -477,60 +474,30 @@ public:
|
||||
virtual BOOL AddPlayerItem(CBasePlayerItem *pItem);
|
||||
virtual BOOL RemovePlayerItem(CBasePlayerItem *pItem);
|
||||
virtual int GiveAmmo(int iAmount, char *szName, int iMax);
|
||||
virtual void StartSneaking(void)
|
||||
{
|
||||
m_tSneaking = gpGlobals->time - 1;
|
||||
}
|
||||
virtual void StopSneaking(void)
|
||||
{
|
||||
m_tSneaking = gpGlobals->time + 30;
|
||||
}
|
||||
virtual BOOL IsSneaking(void)
|
||||
{
|
||||
return m_tSneaking <= gpGlobals->time;
|
||||
}
|
||||
virtual BOOL IsAlive(void)
|
||||
{
|
||||
return (pev->deadflag == DEAD_NO && pev->health > 0.0f);
|
||||
}
|
||||
virtual BOOL IsPlayer(void)
|
||||
{
|
||||
return (pev->flags & FL_SPECTATOR) != FL_SPECTATOR;
|
||||
}
|
||||
virtual BOOL IsNetClient(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
virtual void StartSneaking(void) { m_tSneaking = gpGlobals->time - 1; }
|
||||
virtual void StopSneaking(void) { m_tSneaking = gpGlobals->time + 30; }
|
||||
virtual BOOL IsSneaking(void) { return m_tSneaking <= gpGlobals->time; }
|
||||
virtual BOOL IsAlive(void) { return (pev->deadflag == DEAD_NO && pev->health > 0.0f); }
|
||||
virtual BOOL IsPlayer(void) { return (pev->flags & FL_SPECTATOR) != FL_SPECTATOR; }
|
||||
virtual BOOL IsNetClient(void) { return TRUE; }
|
||||
virtual const char *TeamID(void);
|
||||
virtual BOOL FBecomeProne(void);
|
||||
virtual Vector BodyTarget(const Vector &posSrc)
|
||||
{
|
||||
return Center() + pev->view_ofs * RANDOM_FLOAT(0.5, 1.1);
|
||||
}
|
||||
virtual Vector BodyTarget(const Vector &posSrc) { return Center() + pev->view_ofs * RANDOM_FLOAT(0.5, 1.1); }
|
||||
virtual int Illumination(void);
|
||||
virtual BOOL ShouldFadeOnDeath(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
virtual BOOL ShouldFadeOnDeath(void) { return FALSE; }
|
||||
virtual void ResetMaxSpeed(void);
|
||||
virtual void Jump(void);
|
||||
virtual void Duck(void);
|
||||
virtual void PreThink(void);
|
||||
virtual void PostThink(void);
|
||||
virtual Vector GetGunPosition(void);
|
||||
virtual BOOL IsBot(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
virtual BOOL IsBot(void) { return FALSE; }
|
||||
virtual void UpdateClientData(void);
|
||||
virtual void ImpulseCommands(void);
|
||||
virtual void RoundRespawn(void);
|
||||
virtual Vector GetAutoaimVector(float flDelta);
|
||||
virtual void Blind(float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha);
|
||||
virtual void OnTouchingWeapon(CWeaponBox *pWeapon)
|
||||
{
|
||||
;
|
||||
}
|
||||
virtual void OnTouchingWeapon(CWeaponBox *pWeapon) { }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
@ -573,10 +540,7 @@ public:
|
||||
void Observer_SetMode(int iMode);
|
||||
void Observer_CheckTarget(void);
|
||||
void Observer_CheckProperties(void);
|
||||
int IsObserver(void)
|
||||
{
|
||||
return pev->iuser1;
|
||||
}
|
||||
int IsObserver(void) { return pev->iuser1; }
|
||||
NOXREF void PlantC4(void);
|
||||
void Radio(const char *msg_id, const char *msg_verbose = NULL, short pitch = 100, bool showIcon = true);
|
||||
CBasePlayer *GetNextRadioRecipient(CBasePlayer *pStartPlayer);
|
||||
@ -623,10 +587,7 @@ public:
|
||||
void UpdatePlayerSound(void);
|
||||
void DeathSound(void);
|
||||
void SetAnimation(PLAYER_ANIM playerAnim);
|
||||
NOXREF void SetWeaponAnimType(const char *szExtention)
|
||||
{
|
||||
Q_strcpy(m_szAnimExtention, szExtention);
|
||||
}
|
||||
NOXREF void SetWeaponAnimType(const char *szExtention) { Q_strcpy(m_szAnimExtention, szExtention); }
|
||||
void CheatImpulseCommands(int iImpulse);
|
||||
void StartDeathCam(void);
|
||||
void StartObserver(Vector vecPosition, Vector vecViewAngle);
|
||||
@ -685,10 +646,7 @@ public:
|
||||
void SendWeatherInfo(void);
|
||||
void UpdateShieldCrosshair(bool draw);
|
||||
bool HasShield(void);
|
||||
bool IsProtectedByShield(void)
|
||||
{
|
||||
return HasShield() && m_bShieldDrawn;
|
||||
}
|
||||
bool IsProtectedByShield(void) { return HasShield() && m_bShieldDrawn; }
|
||||
void RemoveShield(void);
|
||||
void DropShield(bool bDeploy = true);
|
||||
void GiveShield(bool bDeploy = true);
|
||||
@ -696,27 +654,17 @@ public:
|
||||
bool SelectSpawnSpot(const char *pEntClassName, CBaseEntity* &pSpot);
|
||||
bool IsReloading(void)
|
||||
{
|
||||
if (m_pActiveItem != NULL && ((CBasePlayerWeapon *)m_pActiveItem)->m_fInReload)
|
||||
CBasePlayerWeapon *weapon = static_cast<CBasePlayerWeapon *>(m_pActiveItem);
|
||||
|
||||
if (weapon != NULL && weapon->m_fInReload)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
bool IsBlind(void)
|
||||
{
|
||||
return (m_blindUntilTime > gpGlobals->time);
|
||||
}
|
||||
bool IsAutoFollowAllowed(void)
|
||||
{
|
||||
return (gpGlobals->time > m_allowAutoFollowTime);
|
||||
}
|
||||
void InhibitAutoFollow(float duration)
|
||||
{
|
||||
m_allowAutoFollowTime = duration;
|
||||
}
|
||||
void AllowAutoFollow(void)
|
||||
{
|
||||
m_allowAutoFollowTime = 0;
|
||||
}
|
||||
bool IsBlind(void) const { return (m_blindUntilTime > gpGlobals->time); }
|
||||
bool IsAutoFollowAllowed(void) const { return (gpGlobals->time > m_allowAutoFollowTime); }
|
||||
void InhibitAutoFollow(float duration) { m_allowAutoFollowTime = gpGlobals->time + duration; }
|
||||
void AllowAutoFollow(void) { m_allowAutoFollowTime = 0; }
|
||||
void ClearAutoBuyData(void);
|
||||
void AddAutoBuyData(const char *str);
|
||||
void AutoBuy(void);
|
||||
@ -744,15 +692,9 @@ public:
|
||||
void RebuyNightVision(void);
|
||||
void RebuyArmor(void);
|
||||
void UpdateLocation(bool forceUpdate = false);
|
||||
void SetObserverAutoDirector(bool val)
|
||||
{
|
||||
m_bObserverAutoDirector = val;
|
||||
}
|
||||
void SetObserverAutoDirector(bool val) { m_bObserverAutoDirector = val; }
|
||||
bool IsObservingPlayer(CBasePlayer *pPlayer);
|
||||
bool CanSwitchObserverModes(void)
|
||||
{
|
||||
return m_canSwitchObserverModes;
|
||||
}
|
||||
bool CanSwitchObserverModes(void) const { return m_canSwitchObserverModes; }
|
||||
NOXREF void Intense(void)
|
||||
{
|
||||
//m_musicState = INTENSE;
|
||||
|
@ -2271,7 +2271,7 @@ void CTriggerCamera::FollowTarget(void)
|
||||
if (m_hPlayer->IsAlive())
|
||||
{
|
||||
SET_VIEW(m_hPlayer->edict(), m_hPlayer->edict());
|
||||
((CBasePlayer *)((CBaseEntity *)m_hPlayer))->EnableControl(TRUE);
|
||||
((CBasePlayer *)m_hPlayer)->EnableControl(TRUE);
|
||||
}
|
||||
|
||||
SUB_UseTargets(this, USE_TOGGLE, 0);
|
||||
|
@ -701,7 +701,7 @@ void CCSTutor::ProcessShownDeathsForEvent(TutorMessageEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(m_playerDeathInfo); i++)
|
||||
for (int i = 0; i < ARRAYSIZE(m_playerDeathInfo); ++i)
|
||||
{
|
||||
if (m_playerDeathInfo[i].m_event == event)
|
||||
{
|
||||
@ -1071,7 +1071,7 @@ void CCSTutor::ClearEventList(void)
|
||||
/* <213289> ../cstrike/dlls/tutor_cs_tutor.cpp:1175 */
|
||||
void CCSTutor::DeleteEvent(TutorMessageEvent *event)
|
||||
{
|
||||
for (int i = 0; i < ARRAYSIZE(m_playerDeathInfo); i++)
|
||||
for (int i = 0; i < ARRAYSIZE(m_playerDeathInfo); ++i)
|
||||
{
|
||||
if (m_playerDeathInfo[i].m_event == event)
|
||||
{
|
||||
@ -1409,7 +1409,7 @@ void CCSTutor::HandleWeaponFired(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL && localPlayer->IsAlive())
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player != NULL && player == localPlayer)
|
||||
{
|
||||
@ -1425,7 +1425,7 @@ void CCSTutor::HandleWeaponFiredOnEmpty(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player != NULL && player->IsPlayer() && player == localPlayer)
|
||||
{
|
||||
@ -1449,7 +1449,7 @@ void CCSTutor::HandleWeaponFiredOnEmpty(CBaseEntity *entity, CBaseEntity *other)
|
||||
/* <213817> ../cstrike/dlls/tutor_cs_tutor.cpp:1654 */
|
||||
void CCSTutor::HandleWeaponReloaded(CBaseEntity *entity, CBaseEntity *other)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player != NULL && player->IsPlayer() && player == UTIL_GetLocalPlayer())
|
||||
{
|
||||
@ -1467,8 +1467,8 @@ void CCSTutor::HandlePlayerDied(CBaseEntity *entity, CBaseEntity *other)
|
||||
return;
|
||||
}
|
||||
|
||||
CBasePlayer *victim = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *attacker = reinterpret_cast<CBasePlayer *>(other);
|
||||
CBasePlayer *victim = static_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *attacker = static_cast<CBasePlayer *>(other);
|
||||
|
||||
if (victim != NULL && !victim->IsPlayer())
|
||||
{
|
||||
@ -1711,8 +1711,8 @@ void CCSTutor::HandlePlayerTookDamage(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *victim = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *attacker = reinterpret_cast<CBasePlayer *>(other);
|
||||
CBasePlayer *victim = static_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *attacker = static_cast<CBasePlayer *>(other);
|
||||
|
||||
if (victim != NULL && !victim->IsPlayer())
|
||||
{
|
||||
@ -1742,7 +1742,7 @@ void CCSTutor::HandlePlayerBlindedByFlashbang(CBaseEntity *entity, CBaseEntity *
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player != NULL && player->IsPlayer() && player == localPlayer)
|
||||
{
|
||||
@ -1754,7 +1754,7 @@ void CCSTutor::HandlePlayerBlindedByFlashbang(CBaseEntity *entity, CBaseEntity *
|
||||
/* <213ab7> ../cstrike/dlls/tutor_cs_tutor.cpp:2008 */
|
||||
void CCSTutor::HandlePlayerSpawned(CBaseEntity *entity, CBaseEntity *other)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player->IsPlayer() && player == UTIL_GetLocalPlayer())
|
||||
{
|
||||
@ -1767,7 +1767,7 @@ void CCSTutor::HandlePlayerSpawned(CBaseEntity *entity, CBaseEntity *other)
|
||||
/* <21868e> ../cstrike/dlls/tutor_cs_tutor.cpp:2033 */
|
||||
NOXREF void CCSTutor::HandleClientCorpseSpawned(CBaseEntity *entity, CBaseEntity *other)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player == NULL || !player->IsPlayer())
|
||||
{
|
||||
@ -1850,7 +1850,7 @@ void CCSTutor::HandleBombDefused(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *defuser = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *defuser = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (defuser != NULL && defuser->IsPlayer() && defuser == localPlayer)
|
||||
{
|
||||
@ -1881,7 +1881,7 @@ void CCSTutor::HandleBombDefusing(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player != NULL && player->IsPlayer() && player == localPlayer && !player->m_bHasDefuser)
|
||||
{
|
||||
@ -1962,7 +1962,7 @@ void CCSTutor::HandleBeingShotAt(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player != NULL && player->IsPlayer() && player == localPlayer && localPlayer->IsAlive())
|
||||
{
|
||||
@ -1978,7 +1978,7 @@ void CCSTutor::HandleHostageUsed(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *activator = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *activator = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (activator != NULL && activator->IsPlayer())
|
||||
{
|
||||
@ -2013,7 +2013,7 @@ void CCSTutor::HandleHostageRescued(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *rescuer = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *rescuer = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (rescuer != NULL && rescuer->IsPlayer())
|
||||
{
|
||||
@ -2060,7 +2060,7 @@ void CCSTutor::HandleHostageDamaged(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *attacker = reinterpret_cast<CBasePlayer *>(other);
|
||||
CBasePlayer *attacker = static_cast<CBasePlayer *>(other);
|
||||
|
||||
if (entity != NULL && attacker != NULL && attacker->IsPlayer() && localPlayer == attacker)
|
||||
{
|
||||
@ -2078,7 +2078,7 @@ void CCSTutor::HandleHostageKilled(CBaseEntity *entity, CBaseEntity *other)
|
||||
{
|
||||
CheckForAllHostagesDead();
|
||||
|
||||
CBasePlayer *attacker = reinterpret_cast<CBasePlayer *>(other);
|
||||
CBasePlayer *attacker = static_cast<CBasePlayer *>(other);
|
||||
|
||||
if (entity != NULL && attacker != NULL && attacker->IsPlayer())
|
||||
{
|
||||
@ -2141,7 +2141,7 @@ void CCSTutor::HandleDeathCameraStart(CBaseEntity *entity, CBaseEntity *other)
|
||||
|
||||
if (localPlayer != NULL)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player != NULL && player->IsPlayer() && player == localPlayer)
|
||||
{
|
||||
@ -2362,9 +2362,9 @@ void CCSTutor::GetNumPlayersAliveOnTeams(int &numT, int &numCT)
|
||||
numT = 0;
|
||||
numCT = 0;
|
||||
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
|
||||
|
||||
if (player == NULL || !player->IsAlive())
|
||||
{
|
||||
@ -2481,9 +2481,9 @@ void CCSTutor::CheckForBombViewable(void)
|
||||
{
|
||||
CBasePlayer *bombCarrier = NULL;
|
||||
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
|
||||
|
||||
if (player && player->m_bHasC4)
|
||||
{
|
||||
@ -2683,9 +2683,7 @@ void CCSTutor::CheckForHostageViewable(void)
|
||||
CBasePlayer *localPlayer = UTIL_GetLocalPlayer();
|
||||
|
||||
if (localPlayer == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CBaseEntity *hostageEntity = NULL;
|
||||
bool sawFirst = false;
|
||||
@ -2693,21 +2691,12 @@ void CCSTutor::CheckForHostageViewable(void)
|
||||
while ((hostageEntity = UTIL_FindEntityByClassname(hostageEntity, "hostage_entity")) != NULL)
|
||||
{
|
||||
bool validHostage = false;
|
||||
CHostage *hostage = reinterpret_cast<CHostage *>(hostageEntity);
|
||||
CHostage *hostage = static_cast<CHostage *>(hostageEntity);
|
||||
|
||||
if (hostage->pev->takedamage == DAMAGE_YES)
|
||||
{
|
||||
if (hostage->m_improv != NULL)
|
||||
{
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
{
|
||||
validHostage = true;
|
||||
}
|
||||
}
|
||||
else if (hostage->m_hTargetEnt == NULL || hostage->m_State != CHostage::FOLLOW)
|
||||
{
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
validHostage = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hostage->IsValid() && validHostage && IsEntityInViewOfPlayer(hostage, localPlayer) && !sawFirst)
|
||||
@ -2813,15 +2802,7 @@ bool CCSTutor::CheckForAllHostagesFollowingSomeone(void)
|
||||
{
|
||||
if (hostage->pev->takedamage == DAMAGE_YES)
|
||||
{
|
||||
if (hostage->m_improv != NULL)
|
||||
{
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
{
|
||||
foundUnusedOne = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (hostage->m_hTargetEnt == NULL || hostage->m_State != CHostage::FOLLOW)
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
{
|
||||
foundUnusedOne = true;
|
||||
break;
|
||||
@ -3098,7 +3079,7 @@ void CCSTutor::CheckExamineMessages(float time)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < TUTOR_NUM_MESSAGES; i++)
|
||||
for (int i = 0; i < TUTOR_NUM_MESSAGES; ++i)
|
||||
{
|
||||
//bool sawOne = false;
|
||||
|
||||
@ -3160,48 +3141,33 @@ void CCSTutor::CheckExamineMessages(float time)
|
||||
|
||||
if (i == YOU_SEE_FRIEND)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player->IsPlayer() && player->IsAlive() && player->m_iTeam == localPlayer->m_iTeam)
|
||||
{
|
||||
validEntity = true;
|
||||
}
|
||||
}
|
||||
else if (i == YOU_SEE_ENEMY)
|
||||
{
|
||||
CBasePlayer *player = reinterpret_cast<CBasePlayer *>(entity);
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(entity);
|
||||
|
||||
if (player->IsPlayer() && player->IsAlive() && player->m_iTeam == localPlayer->m_iTeam)
|
||||
{
|
||||
if ((player->m_iTeam != CT || localPlayer->m_iTeam == TERRORIST) && (player->m_iTeam != TERRORIST || localPlayer->m_iTeam == CT))
|
||||
{
|
||||
validEntity = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (i == YOU_SEE_HOSTAGE_CT_EXAMINE)
|
||||
{
|
||||
CHostage *hostage = reinterpret_cast<CHostage *>(entity);
|
||||
CHostage *hostage = static_cast<CHostage *>(entity);
|
||||
|
||||
if (entity->pev->takedamage == DAMAGE_YES)
|
||||
{
|
||||
if (hostage->m_improv != NULL)
|
||||
{
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
{
|
||||
validEntity = true;
|
||||
}
|
||||
}
|
||||
else if (hostage->m_hTargetEnt == NULL || hostage->m_State != CHostage::FOLLOW)
|
||||
{
|
||||
if (!hostage->IsFollowingSomeone())
|
||||
validEntity = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hostage->IsValid() || !validEntity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (validEntity)
|
||||
@ -3291,7 +3257,7 @@ bool CCSTutor::IsBombMap(void)
|
||||
/* <216d35> ../cstrike/dlls/tutor_cs_tutor.cpp:3781 */
|
||||
void CCSTutor::ResetPlayerDeathInfo(void)
|
||||
{
|
||||
for (int i = 0; i < ARRAYSIZE(m_playerDeathInfo); i++)
|
||||
for (int i = 0; i < ARRAYSIZE(m_playerDeathInfo); ++i)
|
||||
{
|
||||
m_playerDeathInfo[i].m_hasBeenShown = false;
|
||||
m_playerDeathInfo[i].m_event = NULL;
|
||||
@ -3309,9 +3275,9 @@ void CCSTutor::ConstructRecentDeathsList(TeamName team, char *buf, int buflen, T
|
||||
char scratch[32];
|
||||
buf[0] = '\0';
|
||||
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
||||
{
|
||||
CBasePlayer *pPlayer = reinterpret_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
|
||||
CBasePlayer *pPlayer = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
|
||||
|
||||
if (pPlayer == NULL)
|
||||
continue;
|
||||
@ -3334,7 +3300,7 @@ void CCSTutor::ConstructRecentDeathsList(TeamName team, char *buf, int buflen, T
|
||||
/* <216dc2> ../cstrike/dlls/tutor_cs_tutor.cpp:3853 */
|
||||
void CCSTutor::TransferDeathEvents(TutorMessageEvent *oldEvent, TutorMessageEvent *newEvent)
|
||||
{
|
||||
for (int i = 0; i < ARRAYSIZE(m_playerDeathInfo); i++)
|
||||
for (int i = 0; i < ARRAYSIZE(m_playerDeathInfo); ++i)
|
||||
{
|
||||
if (m_playerDeathInfo[i].m_event == oldEvent)
|
||||
{
|
||||
|
@ -587,7 +587,7 @@ void CBasePlayerItem::CheckRespawn(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Respawn- this item is already in the world, but it is
|
||||
// Respawn - this item is already in the world, but it is
|
||||
// invisible and intangible. Make it visible and tangible.
|
||||
|
||||
/* <1d1e09> ../cstrike/dlls/weapons.cpp:616 */
|
||||
@ -620,6 +620,9 @@ CBaseEntity *CBasePlayerItem::__MAKE_VHOOK(Respawn)(void)
|
||||
return pNewWeapon;
|
||||
}
|
||||
|
||||
// whats going on here is that if the player drops this weapon, they shouldn't take it back themselves
|
||||
// for a little while. But if they throw it at someone else, the other player should get it immediately.
|
||||
|
||||
/* <1d26f0> ../cstrike/dlls/weapons.cpp:642 */
|
||||
void CBasePlayerItem::DefaultTouch(CBaseEntity *pOther)
|
||||
{
|
||||
@ -629,7 +632,7 @@ void CBasePlayerItem::DefaultTouch(CBaseEntity *pOther)
|
||||
return;
|
||||
}
|
||||
|
||||
CBasePlayer *pPlayer = reinterpret_cast<CBasePlayer *>(pOther);
|
||||
CBasePlayer *pPlayer = static_cast<CBasePlayer *>(pOther);
|
||||
|
||||
if (pPlayer->m_bIsVIP
|
||||
&& m_iId != WEAPON_USP
|
||||
@ -789,6 +792,8 @@ void CBasePlayerWeapon::KickBack(float up_base, float lateral_base, float up_mod
|
||||
/* <1d242e> ../cstrike/dlls/weapons.cpp:792 */
|
||||
void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bIsGlock)
|
||||
{
|
||||
float nexttime = 0.1f;
|
||||
|
||||
m_iClip--;
|
||||
|
||||
if (m_iClip < 0)
|
||||
@ -831,16 +836,15 @@ void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bI
|
||||
|
||||
m_pPlayer->pev->effects |= EF_MUZZLEFLASH;
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
shotsFired++;
|
||||
|
||||
float nexttime = 0;
|
||||
shotsFired++;
|
||||
|
||||
if (shotsFired != 3)
|
||||
{
|
||||
nexttime = gpGlobals->time + 0.1f;
|
||||
shootTime = gpGlobals->time + nexttime;
|
||||
}
|
||||
|
||||
shootTime = nexttime;
|
||||
else
|
||||
shootTime = 0;
|
||||
}
|
||||
|
||||
/* <1d389e> ../cstrike/dlls/weapons.cpp:876 */
|
||||
@ -911,6 +915,8 @@ void CBasePlayerWeapon::__MAKE_VHOOK(ItemPostFrame)(void)
|
||||
FireRemaining(m_iFamasShotsFired, m_flFamasShoot, FALSE);
|
||||
}
|
||||
|
||||
// Return zoom level back to previous zoom level before we fired a shot.
|
||||
// This is used only for the AWP and Scout
|
||||
if (m_flNextPrimaryAttack <= UTIL_WeaponTimeBase())
|
||||
{
|
||||
if (m_pPlayer->m_bResumeZoom)
|
||||
@ -920,6 +926,7 @@ void CBasePlayerWeapon::__MAKE_VHOOK(ItemPostFrame)(void)
|
||||
|
||||
if (m_pPlayer->m_iFOV == m_pPlayer->m_iLastZoom)
|
||||
{
|
||||
// return the fade level in zoom.
|
||||
m_pPlayer->m_bResumeZoom = false;
|
||||
}
|
||||
}
|
||||
@ -978,6 +985,8 @@ void CBasePlayerWeapon::__MAKE_VHOOK(ItemPostFrame)(void)
|
||||
|
||||
m_pPlayer->TabulateAmmo();
|
||||
|
||||
// Can't shoot during the freeze period
|
||||
// Always allow firing in single player
|
||||
if ((m_pPlayer->m_bCanShoot && g_pGameRules->IsMultiplayer() && !g_pGameRules->IsFreezePeriod() && !m_pPlayer->m_bIsDefusing) || !g_pGameRules->IsMultiplayer())
|
||||
{
|
||||
PrimaryAttack();
|
||||
@ -985,6 +994,7 @@ void CBasePlayerWeapon::__MAKE_VHOOK(ItemPostFrame)(void)
|
||||
}
|
||||
else if ((m_pPlayer->pev->button & IN_RELOAD) && iMaxClip() != WEAPON_NOCLIP && !m_fInReload && m_flNextPrimaryAttack < UTIL_WeaponTimeBase())
|
||||
{
|
||||
// reload when reload is pressed, or if no buttons are down and weapon is empty.
|
||||
if (m_flFamasShoot == 0 && m_flGlock18Shoot == 0)
|
||||
{
|
||||
if (!(m_iWeaponState & WPNSTATE_SHIELD_DRAWN))
|
||||
@ -997,6 +1007,9 @@ void CBasePlayerWeapon::__MAKE_VHOOK(ItemPostFrame)(void)
|
||||
else if (!(usableButtons & (IN_ATTACK | IN_ATTACK2)))
|
||||
{
|
||||
// no fire buttons down
|
||||
|
||||
// The following code prevents the player from tapping the firebutton repeatedly
|
||||
// to simulate full auto and retaining the single shot accuracy of single fire
|
||||
if (m_bDelayFire)
|
||||
{
|
||||
m_bDelayFire = false;
|
||||
@ -1011,16 +1024,19 @@ void CBasePlayerWeapon::__MAKE_VHOOK(ItemPostFrame)(void)
|
||||
|
||||
m_fFireOnEmpty = FALSE;
|
||||
|
||||
if (m_iId != WEAPON_USP && m_iId != WEAPON_GLOCK18 && m_iId != WEAPON_P228 && m_iId != WEAPON_DEAGLE && m_iId != WEAPON_ELITE && m_iId != WEAPON_FIVESEVEN)
|
||||
// if it's a pistol then set the shots fired to 0 after the player releases a button
|
||||
if (IsSecondaryWeapon(m_iId))
|
||||
{
|
||||
m_iShotsFired = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_iShotsFired > 0 && m_flDecreaseShotsFired < gpGlobals->time)
|
||||
{
|
||||
m_flDecreaseShotsFired = gpGlobals->time + 0.0225f;
|
||||
m_iShotsFired--;
|
||||
m_flDecreaseShotsFired = gpGlobals->time + 0.0225;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_iShotsFired = 0;
|
||||
|
||||
if (!IsUseable() && m_flNextPrimaryAttack < UTIL_WeaponTimeBase())
|
||||
{
|
||||
|
@ -489,10 +489,7 @@ public:
|
||||
float GetNextAttackDelay(float delay);
|
||||
float GetNextAttackDelay2(float delay);
|
||||
bool HasSecondaryAttack(void);
|
||||
BOOL IsPistol(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
BOOL IsPistol(void) { return (m_iId == WEAPON_USP || m_iId == WEAPON_GLOCK18 || m_iId == WEAPON_P228 || m_iId == WEAPON_DEAGLE || m_iId == WEAPON_ELITE || m_iId == WEAPON_FIVESEVEN); }
|
||||
void SetPlayerShieldAnim(void);
|
||||
void ResetPlayerShieldAnim(void);
|
||||
bool ShieldSecondaryFire(int iUpAnim, int iDownAnim);
|
||||
@ -523,8 +520,8 @@ public:
|
||||
int m_iShotsFired;
|
||||
Vector m_vVecAiming;
|
||||
string_t model_name;
|
||||
float m_flGlock18Shoot;
|
||||
int m_iGlock18ShotsFired;
|
||||
float m_flGlock18Shoot; // time to shoot the remaining bullets of the glock18 burst fire
|
||||
int m_iGlock18ShotsFired; // used to keep track of the shots fired during the Glock18 burst fire mode.
|
||||
float m_flFamasShoot;
|
||||
int m_iFamasShotsFired;
|
||||
float m_fBurstSpread;
|
||||
@ -2224,7 +2221,7 @@ extern int giAmmoIndex;
|
||||
extern short g_sModelIndexRadio;
|
||||
extern MULTIDAMAGE gMultiDamage;
|
||||
|
||||
void FindHullIntersection(Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity);
|
||||
void FindHullIntersection(const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity);
|
||||
void AnnounceFlashInterval(float interval, float offset = 0);
|
||||
|
||||
int MaxAmmoCarry(int iszName);
|
||||
|
@ -7,41 +7,41 @@
|
||||
|
||||
AutoBuyInfoStruct g_autoBuyInfo[] =
|
||||
{
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_RIFLE), "galil", "weapon_galil" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_RIFLE), "ak47", "weapon_ak47" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SNIPERRIFLE), "scout", "weapon_scout" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_RIFLE), "sg552", "weapon_sg552" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SNIPERRIFLE), "awp", "weapon_awp" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SNIPERRIFLE), "g3sg1", "weapon_g3sg1" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_RIFLE), "famas", "weapon_famas" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_RIFLE), "m4a1", "weapon_m4a1" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_RIFLE), "aug", "weapon_aug" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SNIPERRIFLE), "sg550", "weapon_sg550" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_SECONDARY | AUTOBUYCLASS_PISTOL), "glock", "weapon_glock18" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_SECONDARY | AUTOBUYCLASS_PISTOL), "usp", "weapon_usp" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_SECONDARY | AUTOBUYCLASS_PISTOL), "p228", "weapon_p228" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_SECONDARY | AUTOBUYCLASS_PISTOL), "deagle", "weapon_deagle" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_SECONDARY | AUTOBUYCLASS_PISTOL), "elites", "weapon_elite" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_SECONDARY | AUTOBUYCLASS_PISTOL), "fn57", "weapon_fiveseven" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SHOTGUN), "m3", "weapon_m3" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SHOTGUN), "xm1014", "weapon_xm1014" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SMG), "mac10", "weapon_mac10" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SMG), "tmp", "weapon_tmp" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SMG), "mp5", "weapon_mp5navy" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SMG), "ump45", "weapon_ump45" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SMG), "p90", "weapon_p90" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_MACHINEGUN), "m249", "weapon_m249" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_AMMO), "primammo", "primammo" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_SECONDARY | AUTOBUYCLASS_AMMO), "secammo", "secammo" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_ARMOR), "vest", "item_kevlar" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_ARMOR), "vesthelm", "item_assaultsuit" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_GRENADE), "flash", "weapon_flashbang" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_GRENADE), "hegren", "weapon_hegrenade" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_GRENADE), "sgren", "weapon_smokegrenade"},
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_NIGHTVISION), "nvgs", "nvgs" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_DEFUSER), "defuser", "defuser" },
|
||||
{ (AutoBuyClassType)(AUTOBUYCLASS_PRIMARY | AUTOBUYCLASS_SHIELD), "shield", "shield" },
|
||||
{ (AutoBuyClassType)0, NULL, NULL }
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_RIFLE, "galil", "weapon_galil" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_RIFLE, "ak47", "weapon_ak47" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SNIPERRIFLE, "scout", "weapon_scout" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_RIFLE, "sg552", "weapon_sg552" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SNIPERRIFLE, "awp", "weapon_awp" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SNIPERRIFLE, "g3sg1", "weapon_g3sg1" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_RIFLE, "famas", "weapon_famas" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_RIFLE, "m4a1", "weapon_m4a1" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_RIFLE, "aug", "weapon_aug" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SNIPERRIFLE, "sg550", "weapon_sg550" },
|
||||
{ AUTOBUYCLASS_SECONDARY|AUTOBUYCLASS_PISTOL, "glock", "weapon_glock18" },
|
||||
{ AUTOBUYCLASS_SECONDARY|AUTOBUYCLASS_PISTOL, "usp", "weapon_usp" },
|
||||
{ AUTOBUYCLASS_SECONDARY|AUTOBUYCLASS_PISTOL, "p228", "weapon_p228" },
|
||||
{ AUTOBUYCLASS_SECONDARY|AUTOBUYCLASS_PISTOL, "deagle", "weapon_deagle" },
|
||||
{ AUTOBUYCLASS_SECONDARY|AUTOBUYCLASS_PISTOL, "elites", "weapon_elite" },
|
||||
{ AUTOBUYCLASS_SECONDARY|AUTOBUYCLASS_PISTOL, "fn57", "weapon_fiveseven" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SHOTGUN, "m3", "weapon_m3" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SHOTGUN, "xm1014", "weapon_xm1014" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SMG, "mac10", "weapon_mac10" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SMG, "tmp", "weapon_tmp" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SMG, "mp5", "weapon_mp5navy" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SMG, "ump45", "weapon_ump45" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SMG, "p90", "weapon_p90" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_MACHINEGUN, "m249", "weapon_m249" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_AMMO, "primammo", "primammo" },
|
||||
{ AUTOBUYCLASS_SECONDARY|AUTOBUYCLASS_AMMO, "secammo", "secammo" },
|
||||
{ AUTOBUYCLASS_ARMOR, "vest", "item_kevlar" },
|
||||
{ AUTOBUYCLASS_ARMOR, "vesthelm", "item_assaultsuit" },
|
||||
{ AUTOBUYCLASS_GRENADE, "flash", "weapon_flashbang" },
|
||||
{ AUTOBUYCLASS_GRENADE, "hegren", "weapon_hegrenade" },
|
||||
{ AUTOBUYCLASS_GRENADE, "sgren", "weapon_smokegrenade"},
|
||||
{ AUTOBUYCLASS_NIGHTVISION, "nvgs", "nvgs" },
|
||||
{ AUTOBUYCLASS_DEFUSER, "defuser", "defuser" },
|
||||
{ AUTOBUYCLASS_PRIMARY|AUTOBUYCLASS_SHIELD, "shield", "shield" },
|
||||
{ AUTOBUYCLASS_NONE, NULL, NULL }
|
||||
};
|
||||
|
||||
WeaponAliasInfo weaponAliasInfo[] =
|
||||
@ -225,12 +225,14 @@ WeaponInfoStruct weaponInfo[27];
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
// Given an alias, return the associated weapon ID
|
||||
|
||||
/* <22cd2a> ../cstrike/dlls/weapontype.cpp:208 */
|
||||
WeaponIdType AliasToWeaponID(const char *alias)
|
||||
{
|
||||
if (alias != NULL)
|
||||
{
|
||||
for (int i = 0; weaponAliasInfo[i].alias != NULL; i++)
|
||||
for (int i = 0; weaponAliasInfo[i].alias != NULL; ++i)
|
||||
{
|
||||
if (!Q_stricmp(weaponAliasInfo[i].alias, alias))
|
||||
return weaponAliasInfo[i].id;
|
||||
@ -259,6 +261,8 @@ const char *BuyAliasToWeaponID(const char *alias, WeaponIdType &id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Given a weapon ID, return its alias
|
||||
|
||||
/* <22cd03> ../cstrike/dlls/weapontype.cpp:246 */
|
||||
const char *WeaponIDToAlias(int id)
|
||||
{
|
||||
@ -292,6 +296,8 @@ WeaponClassType WeaponIDToWeaponClass(int id)
|
||||
return AliasToWeaponClass(WeaponIDToAlias(id));
|
||||
}
|
||||
|
||||
// Return true if given weapon ID is a primary weapon
|
||||
|
||||
/* <22cee3> ../cstrike/dlls/weapontype.cpp:285 */
|
||||
bool IsPrimaryWeapon(int id)
|
||||
{
|
||||
@ -324,6 +330,8 @@ bool IsPrimaryWeapon(int id)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if given weapon ID is a secondary weapon
|
||||
|
||||
/* <22cf19> ../cstrike/dlls/weapontype.cpp:318 */
|
||||
NOXREF bool IsSecondaryWeapon(int id)
|
||||
{
|
||||
|
@ -70,6 +70,7 @@ enum WeaponIdType
|
||||
|
||||
enum AutoBuyClassType
|
||||
{
|
||||
AUTOBUYCLASS_NONE = 0,
|
||||
AUTOBUYCLASS_PRIMARY = (1 << 0),
|
||||
AUTOBUYCLASS_SECONDARY = (1 << 1),
|
||||
AUTOBUYCLASS_AMMO = (1 << 2),
|
||||
|
@ -129,6 +129,7 @@ void CAWP::AWPFire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
|
||||
m_pPlayer->m_iFOV = DEFAULT_FOV;
|
||||
m_pPlayer->pev->fov = DEFAULT_FOV;
|
||||
}
|
||||
// If we are not zoomed in, the bullet diverts more.
|
||||
else
|
||||
{
|
||||
flSpread += 0.08;
|
||||
@ -224,7 +225,11 @@ void CAWP::__MAKE_VHOOK(WeaponIdle)(void)
|
||||
/* <23fa86> ../cstrike/dlls/wpn_shared/wpn_awp.cpp:283 */
|
||||
float CAWP::__MAKE_VHOOK(GetMaxSpeed)(void)
|
||||
{
|
||||
return m_pPlayer->m_iFOV == DEFAULT_FOV ? AWP_MAX_SPEED : AWP_MAX_SPEED_ZOOM;
|
||||
if (m_pPlayer->m_iFOV == DEFAULT_FOV)
|
||||
return AWP_MAX_SPEED;
|
||||
|
||||
// Slower speed when zoomed in.
|
||||
return AWP_MAX_SPEED_ZOOM;
|
||||
}
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
@ -79,7 +79,7 @@ BOOL CC4::__MAKE_VHOOK(Deploy)(void)
|
||||
void CC4::__MAKE_VHOOK(Holster)(int skiplocal)
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_bStartedArming = false;
|
||||
m_bStartedArming = false; // stop arming sequence
|
||||
|
||||
if (!m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
|
||||
{
|
||||
@ -98,15 +98,14 @@ void CC4::__MAKE_VHOOK(Holster)(int skiplocal)
|
||||
void CC4::__MAKE_VHOOK(PrimaryAttack)(void)
|
||||
{
|
||||
BOOL PlaceBomb;
|
||||
int inBombZone, onGround;
|
||||
|
||||
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
inBombZone = (m_pPlayer->m_signals.GetState() & SIGNAL_BOMB) == SIGNAL_BOMB;
|
||||
onGround = (m_pPlayer->pev->flags & FL_ONGROUND) == FL_ONGROUND;
|
||||
int inBombZone = (m_pPlayer->m_signals.GetState() & SIGNAL_BOMB) == SIGNAL_BOMB;
|
||||
int onGround = (m_pPlayer->pev->flags & FL_ONGROUND) == FL_ONGROUND;
|
||||
PlaceBomb = (onGround && inBombZone);
|
||||
|
||||
if (!m_bStartedArming)
|
||||
@ -121,7 +120,7 @@ void CC4::__MAKE_VHOOK(PrimaryAttack)(void)
|
||||
if (!onGround)
|
||||
{
|
||||
ClientPrint(m_pPlayer->pev, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground");
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(1);
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -129,8 +128,10 @@ void CC4::__MAKE_VHOOK(PrimaryAttack)(void)
|
||||
m_bBombPlacedAnimation = false;
|
||||
m_fArmedTime = gpGlobals->time + C4_ARMING_ON_TIME;
|
||||
|
||||
// player "arming bomb" animation
|
||||
SendWeaponAnim(C4_ARM, UseDecrement() != FALSE);
|
||||
|
||||
// freeze the player in place while planting
|
||||
SET_CLIENT_MAXSPEED(m_pPlayer->edict(), 1.0);
|
||||
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
@ -186,21 +187,24 @@ void CC4::__MAKE_VHOOK(PrimaryAttack)(void)
|
||||
TheCareerTasks->HandleEvent(EVENT_BOMB_PLANTED, m_pPlayer);
|
||||
}
|
||||
|
||||
UTIL_LogPrintf
|
||||
(
|
||||
"\"%s<%i><%s><TERRORIST>\" triggered \"Planted_The_Bomb\"\n",
|
||||
UTIL_LogPrintf("\"%s<%i><%s><TERRORIST>\" triggered \"Planted_The_Bomb\"\n",
|
||||
STRING(m_pPlayer->pev->netname),
|
||||
GETPLAYERUSERID(m_pPlayer->edict()),
|
||||
GETPLAYERAUTHID(m_pPlayer->edict())
|
||||
);
|
||||
GETPLAYERAUTHID(m_pPlayer->edict()));
|
||||
|
||||
g_pGameRules->m_bBombDropped = FALSE;
|
||||
|
||||
// Play the plant sound.
|
||||
EMIT_SOUND(edict(), CHAN_WEAPON, "weapons/c4_plant.wav", VOL_NORM, ATTN_NORM);
|
||||
|
||||
// hide the backpack in Terrorist's models.
|
||||
m_pPlayer->pev->body = 0;
|
||||
m_pPlayer->ResetMaxSpeed();
|
||||
m_pPlayer->SetBombIcon(FALSE);
|
||||
|
||||
// release the player from being frozen
|
||||
m_pPlayer->ResetMaxSpeed();
|
||||
|
||||
// No more c4!
|
||||
m_pPlayer->SetBombIcon(FALSE);
|
||||
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
|
||||
|
||||
if (!m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
|
||||
@ -214,9 +218,11 @@ void CC4::__MAKE_VHOOK(PrimaryAttack)(void)
|
||||
{
|
||||
if (m_fArmedTime - 0.75 <= gpGlobals->time && !m_bBombPlacedAnimation)
|
||||
{
|
||||
// call the c4 Placement animation
|
||||
m_bBombPlacedAnimation = true;
|
||||
|
||||
SendWeaponAnim(C4_DROP, UseDecrement() != FALSE);
|
||||
|
||||
// player "place" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_HOLDBOMB);
|
||||
}
|
||||
}
|
||||
@ -231,11 +237,17 @@ void CC4::__MAKE_VHOOK(PrimaryAttack)(void)
|
||||
m_bStartedArming = false;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(1.5);
|
||||
|
||||
// release the player from being frozen, we've somehow left the bomb zone
|
||||
m_pPlayer->ResetMaxSpeed();
|
||||
m_pPlayer->SetProgressBarTime(0);
|
||||
m_pPlayer->SetAnimation(PLAYER_HOLDBOMB);
|
||||
|
||||
SendWeaponAnim(m_bBombPlacedAnimation ? C4_DRAW : C4_IDLE1, UseDecrement() != FALSE);
|
||||
// this means the placement animation is canceled
|
||||
if (m_bBombPlacedAnimation)
|
||||
SendWeaponAnim(C4_DRAW, UseDecrement() != FALSE);
|
||||
else
|
||||
SendWeaponAnim(C4_IDLE1, UseDecrement() != FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -249,13 +261,20 @@ void CC4::__MAKE_VHOOK(WeaponIdle)(void)
|
||||
{
|
||||
if (m_bStartedArming)
|
||||
{
|
||||
// if the player releases the attack button cancel the arming sequence
|
||||
m_bStartedArming = false;
|
||||
|
||||
// release the player from being frozen
|
||||
m_pPlayer->ResetMaxSpeed();
|
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(1.0);
|
||||
m_pPlayer->SetProgressBarTime(0);
|
||||
|
||||
SendWeaponAnim(m_bBombPlacedAnimation ? C4_DRAW : C4_IDLE1, UseDecrement() != FALSE);
|
||||
// this means the placement animation is canceled
|
||||
if (m_bBombPlacedAnimation)
|
||||
SendWeaponAnim(C4_DRAW, UseDecrement() != FALSE);
|
||||
else
|
||||
SendWeaponAnim(C4_IDLE1, UseDecrement() != FALSE);
|
||||
}
|
||||
|
||||
if (m_flTimeWeaponIdle <= UTIL_WeaponTimeBase())
|
||||
|
@ -175,6 +175,7 @@ void CGLOCK18::GLOCK18Fire(float flSpread, float flCycleTime, BOOL bFireBurst)
|
||||
|
||||
if (m_flLastFire)
|
||||
{
|
||||
// Mark the time of this shot and determine the accuracy modifier based on the last shot fired...
|
||||
m_flAccuracy -= (0.325 - (gpGlobals->time - m_flLastFire)) * 0.275;
|
||||
|
||||
if (m_flAccuracy > 0.9)
|
||||
@ -208,10 +209,13 @@ void CGLOCK18::GLOCK18Fire(float flSpread, float flCycleTime, BOOL bFireBurst)
|
||||
m_iClip--;
|
||||
|
||||
m_pPlayer->pev->effects |= EF_MUZZLEFLASH;
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
|
||||
UTIL_MakeVectors(m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle);
|
||||
|
||||
// non-silenced
|
||||
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME;
|
||||
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;
|
||||
|
||||
@ -233,6 +237,7 @@ void CGLOCK18::GLOCK18Fire(float flSpread, float flCycleTime, BOOL bFireBurst)
|
||||
|
||||
if (!m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
|
||||
{
|
||||
// HEV suit - indicate out of ammo condition
|
||||
m_pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, FALSE);
|
||||
}
|
||||
|
||||
@ -240,6 +245,7 @@ void CGLOCK18::GLOCK18Fire(float flSpread, float flCycleTime, BOOL bFireBurst)
|
||||
|
||||
if (bFireBurst)
|
||||
{
|
||||
// Fire off the next two rounds
|
||||
m_iGlock18ShotsFired++;
|
||||
m_flGlock18Shoot = gpGlobals->time + 0.1;
|
||||
}
|
||||
@ -294,6 +300,7 @@ void CGLOCK18::__MAKE_VHOOK(WeaponIdle)(void)
|
||||
SendWeaponAnim(GLOCK18_SHIELD_IDLE, UseDecrement() != FALSE);
|
||||
}
|
||||
}
|
||||
// only idle if the slid isn't back
|
||||
else if (m_iClip)
|
||||
{
|
||||
flRand = RANDOM_FLOAT(0, 1);
|
||||
|
@ -93,35 +93,26 @@ NOXREF void CKnife::WeaponAnimation(int iAnimation)
|
||||
flag = 0;
|
||||
#endif // CLIENT_WEAPONS
|
||||
|
||||
PLAYBACK_EVENT_FULL
|
||||
(
|
||||
flag,
|
||||
m_pPlayer->edict(),
|
||||
m_usKnife,
|
||||
0,
|
||||
(float *)&g_vecZero,
|
||||
(float *)&g_vecZero,
|
||||
0,
|
||||
0,
|
||||
iAnimation,
|
||||
2, // param noxref
|
||||
3, // param noxref
|
||||
4 // param noxref
|
||||
);
|
||||
PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usKnife,
|
||||
0.0, (float *)&g_vecZero, (float *)&g_vecZero,
|
||||
0.0,
|
||||
0.0,
|
||||
iAnimation, 2, 3, 4);
|
||||
}
|
||||
|
||||
/* <26f852> ../cstrike/dlls/wpn_shared/wpn_knife.cpp:140 */
|
||||
void FindHullIntersection(Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity)
|
||||
void FindHullIntersection(const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity)
|
||||
{
|
||||
int i, j, k;
|
||||
float distance;
|
||||
float *minmaxs[2] = { mins, maxs };
|
||||
TraceResult tmpTrace;
|
||||
Vector vecHullEnd, vecEnd;
|
||||
Vector vecHullEnd = tr.vecEndPos;
|
||||
Vector vecEnd;
|
||||
|
||||
distance = 1e6f;
|
||||
|
||||
vecHullEnd = vecSrc + ((tr.vecEndPos - vecSrc) * 2);
|
||||
vecHullEnd = vecSrc + ((vecHullEnd - vecSrc) * 2);
|
||||
UTIL_TraceLine(vecSrc, vecHullEnd, dont_ignore_monsters, pEntity, &tmpTrace);
|
||||
|
||||
if (tmpTrace.flFraction < 1.0f)
|
||||
@ -130,11 +121,11 @@ void FindHullIntersection(Vector &vecSrc, TraceResult &tr, float *mins, float *m
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
for (j = 0; j < 2; j++)
|
||||
for (j = 0; j < 2; ++j)
|
||||
{
|
||||
for (k = 0; k < 2; k++)
|
||||
for (k = 0; k < 2; ++k)
|
||||
{
|
||||
vecEnd.x = vecHullEnd.x + minmaxs[i][0];
|
||||
vecEnd.y = vecHullEnd.y + minmaxs[j][1];
|
||||
@ -326,10 +317,10 @@ int CKnife::Swing(int fFirst)
|
||||
SendWeaponAnim(KNIFE_SHIELD_ATTACKHIT, UseDecrement() != FALSE);
|
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(1.0);
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.2;
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.2f;
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f;
|
||||
|
||||
// play wiff or swish sound
|
||||
if (RANDOM_LONG(0, 1))
|
||||
@ -355,17 +346,17 @@ int CKnife::Swing(int fFirst)
|
||||
}
|
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.4);
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim(KNIFE_SHIELD_ATTACKHIT, UseDecrement() != FALSE);
|
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(1.0);
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.2;
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.2f;
|
||||
}
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f;
|
||||
|
||||
// play thwack, smack, or dong sound
|
||||
float flVol = 1.0f;
|
||||
@ -378,7 +369,7 @@ int CKnife::Swing(int fFirst)
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
ClearMultiDamage();
|
||||
|
||||
if (m_flNextPrimaryAttack + 0.4 < UTIL_WeaponTimeBase())
|
||||
if (m_flNextPrimaryAttack + 0.4f < UTIL_WeaponTimeBase())
|
||||
pEntity->TraceAttack(m_pPlayer->pev, 20, gpGlobals->v_forward, &tr, (DMG_NEVERGIB | DMG_BULLET));
|
||||
else
|
||||
pEntity->TraceAttack(m_pPlayer->pev, 15, gpGlobals->v_forward, &tr, (DMG_NEVERGIB | DMG_BULLET));
|
||||
@ -429,7 +420,7 @@ int CKnife::Swing(int fFirst)
|
||||
m_trHit = tr;
|
||||
SetThink(&CKnife::Smack);
|
||||
|
||||
pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
|
||||
pev->nextthink = UTIL_WeaponTimeBase() + 0.2f;
|
||||
m_pPlayer->m_iWeaponVolume = (int)(flVol * KNIFE_WALLHIT_VOLUME);
|
||||
|
||||
ResetPlayerShieldAnim();
|
||||
|
@ -115,6 +115,7 @@ typedef struct incomingtransfer_s
|
||||
//#define Q_strtoull strtoull
|
||||
//#define Q_FileNameCmp FileNameCmp
|
||||
#define Q_vsnprintf _vsnprintf
|
||||
#define Q_vsnwprintf _vsnwprintf
|
||||
#else // Q_functions
|
||||
void Q_strcpy(char *dest, const char *src);
|
||||
int Q_strlen(const char *str);
|
||||
|
@ -11,6 +11,7 @@ float g_flBotCommandInterval = 1.0 / 30.0;
|
||||
// full AI only 10 times per second
|
||||
float g_flBotFullThinkInterval = 1.0 / 10.0;
|
||||
|
||||
// Nasty Hack. See client.cpp/ClientCommand()
|
||||
const char *BotArgs[4] = { NULL };
|
||||
bool UseBotArgs = false;
|
||||
|
||||
@ -25,14 +26,24 @@ bool UseBotArgs;
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
/* <48fed0> ../game_shared/bot/bot.cpp:28 */
|
||||
NOBODY CBot::CBot(void)
|
||||
CBot::CBot(void)
|
||||
{
|
||||
// CBasePlayer(CBasePlayer *const this); // 28
|
||||
// {
|
||||
// unsigned int nextID; // 34
|
||||
// }
|
||||
// the profile will be attached after this instance is constructed
|
||||
m_profile = NULL;
|
||||
|
||||
// assign this bot a unique ID
|
||||
static unsigned int nextID = 1;
|
||||
|
||||
// wraparound (highly unlikely)
|
||||
if (nextID == 0)
|
||||
++nextID;
|
||||
|
||||
m_id = nextID++;
|
||||
m_postureStackIndex = 0;
|
||||
}
|
||||
|
||||
// Prepare bot for action
|
||||
|
||||
/* <48f6ef> ../game_shared/bot/bot.cpp:50 */
|
||||
bool CBot::__MAKE_VHOOK(Initialize)(const BotProfile *profile)
|
||||
{
|
||||
@ -41,18 +52,40 @@ bool CBot::__MAKE_VHOOK(Initialize)(const BotProfile *profile)
|
||||
}
|
||||
|
||||
/* <48fbbd> ../game_shared/bot/bot.cpp:57 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(Spawn)(void)
|
||||
void CBot::__MAKE_VHOOK(Spawn)(void)
|
||||
{
|
||||
// ResetCommand(CBot *const this); // 80
|
||||
// Let CBasePlayer set some things up
|
||||
CBasePlayer::Spawn();
|
||||
|
||||
// Make sure everyone knows we are a bot
|
||||
pev->flags |= (FL_CLIENT | FL_FAKECLIENT);
|
||||
|
||||
// Bots use their own thinking mechanism
|
||||
SetThink(NULL);
|
||||
pev->nextthink = -1;
|
||||
|
||||
m_flNextBotThink = gpGlobals->time + g_flBotCommandInterval;
|
||||
m_flNextFullBotThink = gpGlobals->time + g_flBotFullThinkInterval;
|
||||
m_flPreviousCommandTime = gpGlobals->time;
|
||||
|
||||
m_isRunning = true;
|
||||
m_isCrouching = false;
|
||||
m_postureStackIndex = 0;
|
||||
|
||||
m_jumpTimestamp = 0.0f;
|
||||
|
||||
// Command interface variable initialization
|
||||
ResetCommand();
|
||||
|
||||
// Allow derived classes to setup at spawn time
|
||||
SpawnBot();
|
||||
}
|
||||
|
||||
/* <48fa37> ../game_shared/bot/bot.cpp:88 */
|
||||
NOBODY Vector CBot::__MAKE_VHOOK(GetAutoaimVector)(float flDelta)
|
||||
Vector CBot::__MAKE_VHOOK(GetAutoaimVector)(float flDelta)
|
||||
{
|
||||
// operator+(const Vector *const this,
|
||||
// const Vector &v); // 90
|
||||
// Vector(Vector *const this,
|
||||
// const Vector &v); // 92
|
||||
UTIL_MakeVectors(pev->v_angle + pev->punchangle);
|
||||
return gpGlobals->v_forward;
|
||||
}
|
||||
|
||||
/* <48ffa8> ../game_shared/bot/bot.cpp:97 */
|
||||
@ -76,77 +109,125 @@ void CBot::BotThink(void)
|
||||
}
|
||||
|
||||
/* <48f723> ../game_shared/bot/bot.cpp:119 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(MoveForward)(void)
|
||||
void CBot::__MAKE_VHOOK(MoveForward)(void)
|
||||
{
|
||||
// GetMoveSpeed(CBot *const this); // 121
|
||||
m_forwardSpeed = GetMoveSpeed();
|
||||
m_buttonFlags |= IN_FORWARD;
|
||||
|
||||
// make mutually exclusive
|
||||
m_buttonFlags &= ~IN_BACK;
|
||||
}
|
||||
|
||||
/* <48f761> ../game_shared/bot/bot.cpp:130 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(MoveBackward)(void)
|
||||
void CBot::__MAKE_VHOOK(MoveBackward)(void)
|
||||
{
|
||||
// GetMoveSpeed(CBot *const this); // 132
|
||||
m_forwardSpeed = -GetMoveSpeed();
|
||||
m_buttonFlags |= IN_BACK;
|
||||
|
||||
// make mutually exclusive
|
||||
m_buttonFlags &= ~IN_FORWARD;
|
||||
}
|
||||
|
||||
/* <48f79f> ../game_shared/bot/bot.cpp:140 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(StrafeLeft)(void)
|
||||
void CBot::__MAKE_VHOOK(StrafeLeft)(void)
|
||||
{
|
||||
// GetMoveSpeed(CBot *const this); // 142
|
||||
m_strafeSpeed = -GetMoveSpeed();
|
||||
m_buttonFlags |= IN_MOVELEFT;
|
||||
|
||||
// make mutually exclusive
|
||||
m_buttonFlags &= ~IN_MOVERIGHT;
|
||||
}
|
||||
|
||||
/* <48f7dd> ../game_shared/bot/bot.cpp:150 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(StrafeRight)(void)
|
||||
void CBot::__MAKE_VHOOK(StrafeRight)(void)
|
||||
{
|
||||
// GetMoveSpeed(CBot *const this); // 152
|
||||
m_strafeSpeed = GetMoveSpeed();
|
||||
m_buttonFlags |= IN_MOVERIGHT;
|
||||
|
||||
// make mutually exclusive
|
||||
m_buttonFlags &= ~IN_MOVELEFT;
|
||||
}
|
||||
|
||||
/* <48fe00> ../game_shared/bot/bot.cpp:160 */
|
||||
NOBODY bool CBot::__MAKE_VHOOK(Jump)(bool mustJump)
|
||||
bool CBot::__MAKE_VHOOK(Jump)(bool mustJump)
|
||||
{
|
||||
// {
|
||||
// float const sanityInterval; // 173
|
||||
// IsJumping(CBot *const this); // 162
|
||||
// {
|
||||
// float const minJumpInterval; // 167
|
||||
// }
|
||||
// }
|
||||
// Jump(CBot *const this,
|
||||
// bool mustJump); // 160
|
||||
if (IsJumping() || IsCrouching())
|
||||
return false;
|
||||
|
||||
if (!mustJump)
|
||||
{
|
||||
const float minJumpInterval = 0.9f; // 1.5f;
|
||||
if (gpGlobals->time - m_jumpTimestamp < minJumpInterval)
|
||||
return false;
|
||||
}
|
||||
|
||||
// still need sanity check for jumping frequency
|
||||
const float sanityInterval = 0.3f;
|
||||
if (gpGlobals->time - m_jumpTimestamp < sanityInterval)
|
||||
return false;
|
||||
|
||||
// jump
|
||||
m_buttonFlags |= IN_JUMP;
|
||||
m_jumpTimestamp = gpGlobals->time;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Zero any MoveForward(), Jump(), etc
|
||||
|
||||
/* <48f81b> ../game_shared/bot/bot.cpp:187 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(ClearMovement)(void)
|
||||
void CBot::__MAKE_VHOOK(ClearMovement)(void)
|
||||
{
|
||||
// ResetCommand(CBot *const this); // 189
|
||||
ResetCommand();
|
||||
}
|
||||
|
||||
// Returns true if we are in the midst of a jump
|
||||
|
||||
/* <48ffe7> ../game_shared/bot/bot.cpp:196 */
|
||||
NOBODY bool CBot::IsJumping(void)
|
||||
bool CBot::IsJumping(void)
|
||||
{
|
||||
// if long time after last jump, we can't be jumping
|
||||
if (gpGlobals->time - m_jumpTimestamp > 3.0f)
|
||||
return false;
|
||||
|
||||
// if we just jumped, we're still jumping
|
||||
if (gpGlobals->time - m_jumpTimestamp < 1.0f)
|
||||
return true;
|
||||
|
||||
// a little after our jump, we're jumping until we hit the ground
|
||||
if (pev->flags & FL_ONGROUND)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* <48f859> ../game_shared/bot/bot.cpp:214 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(Crouch)(void)
|
||||
void CBot::__MAKE_VHOOK(Crouch)(void)
|
||||
{
|
||||
m_isCrouching = true;
|
||||
}
|
||||
|
||||
/* <48f87f> ../game_shared/bot/bot.cpp:220 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(StandUp)(void)
|
||||
void CBot::__MAKE_VHOOK(StandUp)(void)
|
||||
{
|
||||
m_isCrouching = false;
|
||||
}
|
||||
|
||||
/* <48f8a5> ../game_shared/bot/bot.cpp:227 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(UseEnvironment)(void)
|
||||
void CBot::__MAKE_VHOOK(UseEnvironment)(void)
|
||||
{
|
||||
m_buttonFlags |= IN_USE;
|
||||
}
|
||||
|
||||
/* <48f8cb> ../game_shared/bot/bot.cpp:234 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(PrimaryAttack)(void)
|
||||
void CBot::__MAKE_VHOOK(PrimaryAttack)(void)
|
||||
{
|
||||
m_buttonFlags |= IN_ATTACK;
|
||||
}
|
||||
|
||||
/* <48f8f1> ../game_shared/bot/bot.cpp:240 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(ClearPrimaryAttack)(void)
|
||||
void CBot::__MAKE_VHOOK(ClearPrimaryAttack)(void)
|
||||
{
|
||||
m_buttonFlags &= ~IN_ATTACK;
|
||||
}
|
||||
|
||||
/* <48f917> ../game_shared/bot/bot.cpp:246 */
|
||||
@ -159,40 +240,68 @@ void CBot::__MAKE_VHOOK(TogglePrimaryAttack)(void)
|
||||
}
|
||||
|
||||
/* <48f93d> ../game_shared/bot/bot.cpp:260 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(SecondaryAttack)(void)
|
||||
void CBot::__MAKE_VHOOK(SecondaryAttack)(void)
|
||||
{
|
||||
m_buttonFlags |= IN_ATTACK2;
|
||||
}
|
||||
|
||||
/* <48f963> ../game_shared/bot/bot.cpp:266 */
|
||||
NOBODY void CBot::__MAKE_VHOOK(Reload)(void)
|
||||
void CBot::__MAKE_VHOOK(Reload)(void)
|
||||
{
|
||||
m_buttonFlags |= IN_RELOAD;
|
||||
}
|
||||
|
||||
// Returns ratio of ammo left to max ammo (1 = full clip, 0 = empty)
|
||||
|
||||
/* <490008> ../game_shared/bot/bot.cpp:275 */
|
||||
NOBODY float CBot::GetActiveWeaponAmmoRatio(void) const
|
||||
float CBot::GetActiveWeaponAmmoRatio(void) const
|
||||
{
|
||||
// {
|
||||
// class CBasePlayerWeapon *gun; // 277
|
||||
// iMaxClip(CBasePlayerItem *const this); // 286
|
||||
// }
|
||||
CBasePlayerWeapon *weapon = GetActiveWeapon();
|
||||
|
||||
if (!weapon)
|
||||
return 0.0f;
|
||||
|
||||
// weapons with no ammo are always full
|
||||
if (weapon->m_iClip < 0)
|
||||
return 1.0f;
|
||||
|
||||
return (float)weapon->m_iClip / (float)weapon->iMaxClip();
|
||||
}
|
||||
|
||||
// Return true if active weapon has an empty clip
|
||||
|
||||
/* <490058> ../game_shared/bot/bot.cpp:293 */
|
||||
NOBODY bool CBot::IsActiveWeaponClipEmpty(void) const
|
||||
bool CBot::IsActiveWeaponClipEmpty(void) const
|
||||
{
|
||||
// {
|
||||
// class CBasePlayerWeapon *gun; // 295
|
||||
// }
|
||||
CBasePlayerWeapon *weapon = GetActiveWeapon();
|
||||
|
||||
if (weapon != NULL && weapon->m_iClip == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if active weapon has no ammo at all
|
||||
|
||||
/* <490096> ../game_shared/bot/bot.cpp:307 */
|
||||
NOBODY bool CBot::IsActiveWeaponOutOfAmmo(void) const
|
||||
bool CBot::IsActiveWeaponOutOfAmmo(void) const
|
||||
{
|
||||
// {
|
||||
// class CBasePlayerWeapon *gun; // 309
|
||||
// }
|
||||
CBasePlayerWeapon *gun = GetActiveWeapon();
|
||||
|
||||
if (gun == NULL)
|
||||
return true;
|
||||
|
||||
if (gun->m_iClip < 0)
|
||||
return false;
|
||||
|
||||
if (gun->m_iClip == 0 && m_rgAmmo[ gun->m_iPrimaryAmmoType ] <= 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if looking thru weapon's scope
|
||||
|
||||
/* <4900d4> ../game_shared/bot/bot.cpp:327 */
|
||||
bool CBot::IsUsingScope(void) const
|
||||
{
|
||||
@ -252,6 +361,8 @@ byte CBot::ThrottledMsec(void) const
|
||||
return (byte)iNewMsec;
|
||||
}
|
||||
|
||||
// Do a "client command" - useful for invoking menu choices, etc.
|
||||
|
||||
/* <49016e> ../game_shared/bot/bot.cpp:389 */
|
||||
void CBot::ClientCommand(const char *cmd, const char *arg1, const char *arg2, const char *arg3)
|
||||
{
|
||||
@ -265,48 +376,94 @@ void CBot::ClientCommand(const char *cmd, const char *arg1, const char *arg2, co
|
||||
UseBotArgs = false;
|
||||
}
|
||||
|
||||
// Returns TRUE if given entity is our enemy
|
||||
|
||||
/* <4901ac> ../game_shared/bot/bot.cpp:410 */
|
||||
NOBODY bool CBot::IsEnemy(CBaseEntity *ent) const
|
||||
bool CBot::IsEnemy(CBaseEntity *ent) const
|
||||
{
|
||||
// {
|
||||
// class CBasePlayer *player; // 420
|
||||
// }
|
||||
// IsEnemy(const class CBot *const this,
|
||||
// class CBaseEntity *ent); // 410
|
||||
// only Players (real and AI) can be enemies
|
||||
if (!ent->IsPlayer())
|
||||
return false;
|
||||
|
||||
// corpses are no threat
|
||||
if (!ent->IsAlive())
|
||||
return false;
|
||||
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(ent);
|
||||
|
||||
// if they are on our team, they are our friends
|
||||
if (player->m_iTeam == m_iTeam)
|
||||
return false;
|
||||
|
||||
// yep, we hate 'em
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return number of enemies left alive
|
||||
|
||||
/* <49021a> ../game_shared/bot/bot.cpp:434 */
|
||||
NOBODY int CBot::GetEnemiesRemaining(void) const
|
||||
int CBot::GetEnemiesRemaining(void) const
|
||||
{
|
||||
// {
|
||||
// int count; // 436
|
||||
// {
|
||||
// int i; // 438
|
||||
// {
|
||||
// class CBaseEntity *player; // 440
|
||||
// FNullEnt(entvars_t *pev); // 445
|
||||
// IsEnemy(const class CBot *const this,
|
||||
// class CBaseEntity *ent); // 451
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
int count = 0;
|
||||
|
||||
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
||||
{
|
||||
CBaseEntity *player = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (player == NULL)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(player->pev))
|
||||
continue;
|
||||
|
||||
if (FStrEq(STRING(player->pev->netname), ""))
|
||||
continue;
|
||||
|
||||
if (!IsEnemy(player))
|
||||
continue;
|
||||
|
||||
if (!player->IsAlive())
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Return number of friends left alive
|
||||
|
||||
/* <490338> ../game_shared/bot/bot.cpp:467 */
|
||||
NOBODY int CBot::GetFriendsRemaining(void) const
|
||||
int CBot::GetFriendsRemaining(void) const
|
||||
{
|
||||
// {
|
||||
// int count; // 469
|
||||
// {
|
||||
// int i; // 471
|
||||
// {
|
||||
// class CBaseEntity *player; // 473
|
||||
// FNullEnt(entvars_t *pev); // 478
|
||||
// IsEnemy(const class CBot *const this,
|
||||
// class CBaseEntity *ent); // 484
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
int count = 0;
|
||||
|
||||
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
||||
{
|
||||
CBaseEntity *player = UTIL_PlayerByIndex(i);
|
||||
|
||||
if (player == NULL)
|
||||
continue;
|
||||
|
||||
if (FNullEnt(player->pev))
|
||||
continue;
|
||||
|
||||
if (FStrEq(STRING(player->pev->netname), ""))
|
||||
continue;
|
||||
|
||||
if (IsEnemy(player))
|
||||
continue;
|
||||
|
||||
if (!player->IsAlive())
|
||||
continue;
|
||||
|
||||
if (player == static_cast<CBaseEntity *>(const_cast<CBot *>(this)))
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* <490489> ../game_shared/bot/bot.cpp:503 */
|
||||
@ -332,6 +489,7 @@ bool CBot::IsLocalPlayerWatchingMe(void) const
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -417,7 +575,7 @@ bool ActiveGrenade::IsValid(void) const
|
||||
}
|
||||
|
||||
/* <490710> ../game_shared/bot/bot.cpp:622 */
|
||||
NOXREF const Vector *ActiveGrenade::GetPosition(void) const
|
||||
const Vector *ActiveGrenade::GetPosition(void) const
|
||||
{
|
||||
return &m_entity->pev->origin;
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ extern bool UseBotArgs;
|
||||
|
||||
class BotProfile;
|
||||
|
||||
extern bool AreBotsAllowed();
|
||||
|
||||
/* <36c175> ../game_shared/bot/bot.h:36 */
|
||||
template <class T>
|
||||
T *CreateBot(const BotProfile *profile)
|
||||
@ -88,7 +90,7 @@ public:
|
||||
// constructor initializes all values to zero
|
||||
CBot(void);
|
||||
|
||||
NOBODY virtual void Spawn(void);
|
||||
virtual void Spawn(void);
|
||||
|
||||
// invoked when injured by something
|
||||
virtual int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
|
||||
@ -100,15 +102,12 @@ public:
|
||||
{
|
||||
CBasePlayer::Killed(pevAttacker, iGib);
|
||||
}
|
||||
NOBODY virtual void Think(void) {};
|
||||
virtual BOOL IsBot(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
NOBODY virtual Vector GetAutoaimVector(float flDelta);
|
||||
virtual void Think(void) {};
|
||||
virtual BOOL IsBot(void) { return true; }
|
||||
virtual Vector GetAutoaimVector(float flDelta);
|
||||
// invoked when in contact with a CWeaponBox
|
||||
NOBODY virtual void OnTouchingWeapon(CWeaponBox *box) {}
|
||||
NOBODY virtual bool Initialize(const BotProfile *profile);
|
||||
virtual void OnTouchingWeapon(CWeaponBox *box) {}
|
||||
virtual bool Initialize(const BotProfile *profile);
|
||||
|
||||
virtual void SpawnBot(void) = 0;
|
||||
|
||||
@ -118,28 +117,29 @@ public:
|
||||
// heavyweight algorithms, invoked less often
|
||||
virtual void Update(void) = 0;
|
||||
|
||||
NOBODY virtual void Run(void);
|
||||
NOBODY virtual void Walk(void);
|
||||
NOBODY virtual void Crouch(void);
|
||||
NOBODY virtual void StandUp(void);
|
||||
NOBODY virtual void MoveForward(void);
|
||||
NOBODY virtual void MoveBackward(void);
|
||||
NOBODY virtual void StrafeLeft(void);
|
||||
NOBODY virtual void StrafeRight(void);
|
||||
virtual void Run(void);
|
||||
virtual void Walk(void);
|
||||
virtual void Crouch(void);
|
||||
virtual void StandUp(void);
|
||||
virtual void MoveForward(void);
|
||||
virtual void MoveBackward(void);
|
||||
virtual void StrafeLeft(void);
|
||||
virtual void StrafeRight(void);
|
||||
|
||||
// returns true if jump was started
|
||||
NOBODY virtual bool Jump(bool mustJump = false);
|
||||
#define MUST_JUMP true
|
||||
virtual bool Jump(bool mustJump = false);
|
||||
|
||||
// zero any MoveForward(), Jump(), etc
|
||||
NOBODY virtual void ClearMovement(void);
|
||||
virtual void ClearMovement(void);
|
||||
|
||||
// Weapon interface
|
||||
NOBODY virtual void UseEnvironment(void);
|
||||
NOBODY virtual void PrimaryAttack(void);
|
||||
NOBODY virtual void ClearPrimaryAttack(void);
|
||||
virtual void UseEnvironment(void);
|
||||
virtual void PrimaryAttack(void);
|
||||
virtual void ClearPrimaryAttack(void);
|
||||
virtual void TogglePrimaryAttack(void);
|
||||
NOBODY virtual void SecondaryAttack(void);
|
||||
NOBODY virtual void Reload(void);
|
||||
virtual void SecondaryAttack(void);
|
||||
virtual void Reload(void);
|
||||
|
||||
// invoked when event occurs in the game (some events have NULL entities)
|
||||
virtual void OnEvent(GameEventType event, CBaseEntity *entity = NULL, CBaseEntity *other = NULL) {};
|
||||
@ -150,7 +150,7 @@ public:
|
||||
// return true if we can see any part of the player
|
||||
virtual bool IsVisible(CBasePlayer *player, bool testFOV = false, unsigned char *visParts = NULL) const = 0;
|
||||
|
||||
enum VisiblePartType
|
||||
enum VisiblePartType:uint8
|
||||
{
|
||||
NONE = 0x00,
|
||||
CHEST = 0x01,
|
||||
@ -164,12 +164,12 @@ public:
|
||||
virtual bool IsEnemyPartVisible(VisiblePartType part) const = 0;
|
||||
|
||||
// return true if player is facing towards us
|
||||
NOBODY virtual bool IsPlayerFacingMe(CBasePlayer *other) const;
|
||||
virtual bool IsPlayerFacingMe(CBasePlayer *other) const;
|
||||
|
||||
// returns true if other player is pointing right at us
|
||||
NOBODY virtual bool IsPlayerLookingAtMe(CBasePlayer *other) const;
|
||||
virtual bool IsPlayerLookingAtMe(CBasePlayer *other) const;
|
||||
virtual void ExecuteCommand(void);
|
||||
NOBODY virtual void SetModel(const char *modelName);
|
||||
virtual void SetModel(const char *modelName);
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
@ -189,45 +189,36 @@ public:
|
||||
void ClearPrimaryAttack_(void);
|
||||
void TogglePrimaryAttack_(void);
|
||||
void SecondaryAttack_(void);
|
||||
bool IsPlayerFacingMe_(CBasePlayer *other) const;
|
||||
bool IsPlayerLookingAtMe_(CBasePlayer *other) const;
|
||||
void Reload_(void);
|
||||
void ExecuteCommand_(void);
|
||||
void SetModel_(const char *modelName);
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
public:
|
||||
unsigned int GetID(void) const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
bool IsRunning(void) const
|
||||
{
|
||||
return m_isRunning;
|
||||
}
|
||||
bool IsCrouching(void) const
|
||||
{
|
||||
return m_isCrouching;
|
||||
}
|
||||
unsigned int GetID(void) const { return m_id; }
|
||||
bool IsRunning(void) const { return m_isRunning; }
|
||||
bool IsCrouching(void) const { return m_isCrouching; }
|
||||
|
||||
// push the current posture context onto the top of the stack
|
||||
void PushPostureContext(void);
|
||||
|
||||
// restore the posture context to the next context on the stack
|
||||
void PopPostureContext(void);
|
||||
NOBODY bool IsJumping(void);
|
||||
bool IsJumping(void);
|
||||
|
||||
// return time last jump began
|
||||
float GetJumpTimestamp(void) const
|
||||
{
|
||||
return m_jumpTimestamp;
|
||||
}
|
||||
float GetJumpTimestamp(void) const { return m_jumpTimestamp; }
|
||||
// returns ratio of ammo left to max ammo (1 = full clip, 0 = empty)
|
||||
NOBODY float GetActiveWeaponAmmoRatio(void) const;
|
||||
float GetActiveWeaponAmmoRatio(void) const;
|
||||
|
||||
// return true if active weapon has any empty clip
|
||||
NOBODY bool IsActiveWeaponClipEmpty(void) const;
|
||||
bool IsActiveWeaponClipEmpty(void) const;
|
||||
|
||||
// return true if active weapon has no ammo at all
|
||||
NOBODY bool IsActiveWeaponOutOfAmmo(void) const;
|
||||
bool IsActiveWeaponOutOfAmmo(void) const;
|
||||
|
||||
// is the weapon in the middle of a reload
|
||||
bool IsActiveWeaponReloading(void) const;
|
||||
@ -242,13 +233,13 @@ public:
|
||||
bool IsUsingScope(void) const;
|
||||
|
||||
// returns TRUE if given entity is our enemy
|
||||
NOBODY bool IsEnemy(CBaseEntity *ent) const;
|
||||
bool IsEnemy(CBaseEntity *ent) const;
|
||||
|
||||
// return number of enemies left alive
|
||||
NOBODY int GetEnemiesRemaining(void) const;
|
||||
int GetEnemiesRemaining(void) const;
|
||||
|
||||
// return number of friends left alive
|
||||
NOBODY int GetFriendsRemaining(void) const;
|
||||
int GetFriendsRemaining(void) const;
|
||||
|
||||
// return true if local player is observing this bot
|
||||
bool IsLocalPlayerWatchingMe(void) const;
|
||||
@ -260,18 +251,13 @@ public:
|
||||
void PrintIfWatched(char *format,...) const;
|
||||
|
||||
void BotThink(void);
|
||||
bool IsNetClient(void) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool IsNetClient(void) const { return false; }
|
||||
int Save(CSave &save) const;
|
||||
int Restore(CRestore &restor) const;
|
||||
|
||||
// return our personality profile
|
||||
const BotProfile *GetProfile(void) const
|
||||
{
|
||||
return m_profile;
|
||||
}
|
||||
const BotProfile *GetProfile(void) const { return m_profile; }
|
||||
|
||||
#ifndef HOOK_GAMEDLL
|
||||
protected:
|
||||
#endif // HOOK_GAMEDLL
|
||||
@ -280,8 +266,8 @@ protected:
|
||||
|
||||
// the "personality" profile of this bot
|
||||
const BotProfile *m_profile;
|
||||
private:
|
||||
|
||||
private:
|
||||
void ResetCommand(void);
|
||||
byte ThrottledMsec(void) const;
|
||||
|
||||
@ -329,7 +315,7 @@ private:
|
||||
};/* size: 2564, cachelines: 41, members: 15 */
|
||||
|
||||
/* <48f61d> ../game_shared/bot/bot.h:253 */
|
||||
inline void CBot::SetModel(const char *modelName)
|
||||
inline void CBot::__MAKE_VHOOK(SetModel)(const char *modelName)
|
||||
{
|
||||
SET_CLIENT_KEY_VALUE(entindex(), GET_INFO_BUFFER(edict()), "model", (char *)modelName);
|
||||
}
|
||||
@ -364,11 +350,11 @@ inline CBasePlayerWeapon *CBot::GetActiveWeapon(void) const
|
||||
/* <5c4d70> ../game_shared/bot/bot.h:287 */
|
||||
inline bool CBot::IsActiveWeaponReloading(void) const
|
||||
{
|
||||
CBasePlayerWeapon *gun = GetActiveWeapon();
|
||||
if (gun == NULL)
|
||||
CBasePlayerWeapon *weapon = GetActiveWeapon();
|
||||
if (weapon == NULL)
|
||||
return false;
|
||||
|
||||
return (gun->m_fInReload || gun->m_fInSpecialReload) != 0;
|
||||
return (weapon->m_fInReload || weapon->m_fInSpecialReload) != 0;
|
||||
}
|
||||
|
||||
/* <3c5c5c> ../game_shared/bot/bot.h:297 */
|
||||
@ -392,6 +378,7 @@ inline void CBot::PushPostureContext(void)
|
||||
PrintIfWatched("PushPostureContext() overflow error!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_postureStack[m_postureStackIndex].isRunning = m_isRunning;
|
||||
m_postureStack[m_postureStackIndex].isCrouching = m_isCrouching;
|
||||
++m_postureStackIndex;
|
||||
@ -416,7 +403,7 @@ inline void CBot::PopPostureContext(void)
|
||||
}
|
||||
|
||||
/* <48fae3> ../game_shared/bot/bot.h:340 */
|
||||
inline bool CBot::IsPlayerFacingMe(CBasePlayer *other) const
|
||||
inline bool CBot::__MAKE_VHOOK(IsPlayerFacingMe)(CBasePlayer *other) const
|
||||
{
|
||||
Vector toOther = other->pev->origin - pev->origin;
|
||||
UTIL_MakeVectors(other->pev->v_angle + other->pev->punchangle);
|
||||
@ -424,11 +411,12 @@ inline bool CBot::IsPlayerFacingMe(CBasePlayer *other) const
|
||||
|
||||
if (otherDir.x * toOther.x + otherDir.y * toOther.y < 0.0f)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* <48fbfc> ../game_shared/bot/bot.h:355 */
|
||||
inline bool CBot::IsPlayerLookingAtMe(CBasePlayer *other) const
|
||||
inline bool CBot::__MAKE_VHOOK(IsPlayerLookingAtMe)(CBasePlayer *other) const
|
||||
{
|
||||
Vector toOther = other->pev->origin - pev->origin;
|
||||
toOther.NormalizeInPlace();
|
||||
@ -443,6 +431,7 @@ inline bool CBot::IsPlayerLookingAtMe(CBasePlayer *other) const
|
||||
if (IsVisible(&vec))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -451,6 +440,21 @@ inline bool CBot::IsPlayerLookingAtMe(CBasePlayer *other) const
|
||||
typedef bool (CBot::*IS_VISIBLE_VECTOR)(const Vector *, bool) const;
|
||||
typedef bool (CBot::*IS_VISIBLE_CBASE_PLAYER)(CBasePlayer *, bool, unsigned char *) const;
|
||||
|
||||
inline bool CBot::IsPlayerFacingMe(CBasePlayer *other) const
|
||||
{
|
||||
return IsPlayerFacingMe_(other);
|
||||
}
|
||||
|
||||
inline bool CBot::IsPlayerLookingAtMe(CBasePlayer *other) const
|
||||
{
|
||||
return IsPlayerLookingAtMe_(other);
|
||||
}
|
||||
|
||||
inline void CBot::SetModel(const char *modelName)
|
||||
{
|
||||
SetModel_(modelName);
|
||||
}
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
#endif // BOT_H
|
||||
|
@ -32,11 +32,15 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// We'll define our own version of this, because everyone else does.
|
||||
// This needs to stay in sync with MAX_CLIENTS, but there's no header with the #define.
|
||||
#define BOT_MAX_CLIENTS 32
|
||||
|
||||
// version number is MAJOR.MINOR
|
||||
#define BOT_VERSION_MAJOR 1
|
||||
#define BOT_VERSION_MINOR 50
|
||||
|
||||
// Difficulty levels
|
||||
enum BotDifficultyType
|
||||
{
|
||||
BOT_EASY = 0,
|
||||
@ -47,22 +51,12 @@ enum BotDifficultyType
|
||||
NUM_DIFFICULTY_LEVELS
|
||||
};
|
||||
|
||||
#ifdef DEFINE_DIFFICULTY_NAMES
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
char *BotDifficultyName[] =
|
||||
{
|
||||
"EASY",
|
||||
"NORMAL",
|
||||
"HARD",
|
||||
"EXPERT",
|
||||
#define BotDifficultyName (*pBotDifficultyName)
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
#else
|
||||
|
||||
extern char *BotDifficultyName[];
|
||||
|
||||
#endif // DEFINE_DIFFICULTY_NAMES
|
||||
extern char *BotDifficultyName[5];
|
||||
|
||||
#endif // BOT_CONSTANTS_H
|
||||
|
@ -8,45 +8,74 @@
|
||||
|
||||
BotProfileManager *TheBotProfiles = NULL;
|
||||
|
||||
char *BotDifficultyName[] =
|
||||
{
|
||||
"EASY", "NORMAL", "HARD", "EXPERT", NULL
|
||||
};
|
||||
|
||||
#else // HOOK_GAMEDLL
|
||||
|
||||
BotProfileManager *TheBotProfiles;
|
||||
char *BotDifficultyName[5];
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
// Generates a filename-decorated skin name
|
||||
|
||||
/* <4a693f> ../game_shared/bot/bot_profile.cpp:52 */
|
||||
NOBODY const char *GetDecoratedSkinName(const char *name, const char *filename)
|
||||
const char *GetDecoratedSkinName(const char *name, const char *filename)
|
||||
{
|
||||
// {
|
||||
// int const BufLen; // 57
|
||||
// char buf; // 59
|
||||
// }
|
||||
const int BufLen = MAX_PATH + 64;
|
||||
static char buf[BufLen];
|
||||
Q_snprintf(buf, BufLen, "%s/%s", filename, name);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* <4a7a99> ../game_shared/bot/bot_profile.cpp:65 */
|
||||
NOBODY const char *BotProfile::GetWeaponPreferenceAsString(int i) const
|
||||
const char *BotProfile::GetWeaponPreferenceAsString(int i) const
|
||||
{
|
||||
if (i < 0 || i >= m_weaponPreferenceCount)
|
||||
return NULL;
|
||||
|
||||
return WeaponIDToAlias(m_weaponPreference[i]);
|
||||
}
|
||||
|
||||
// Return true if this profile has a primary weapon preference
|
||||
|
||||
/* <4a7acd> ../game_shared/bot/bot_profile.cpp:78 */
|
||||
NOBODY bool BotProfile::HasPrimaryPreference(void) const
|
||||
bool BotProfile::HasPrimaryPreference(void) const
|
||||
{
|
||||
// {
|
||||
// int i; // 80
|
||||
// {
|
||||
// int weaponClass; // 82
|
||||
// }
|
||||
// }
|
||||
for (int i = 0; i < m_weaponPreferenceCount; ++i)
|
||||
{
|
||||
int weaponClass = AliasToWeaponClass(WeaponIDToAlias(m_weaponPreference[i]));
|
||||
|
||||
if (weaponClass == WEAPONCLASS_SUBMACHINEGUN ||
|
||||
weaponClass == WEAPONCLASS_SHOTGUN ||
|
||||
weaponClass == WEAPONCLASS_MACHINEGUN ||
|
||||
weaponClass == WEAPONCLASS_RIFLE ||
|
||||
weaponClass == WEAPONCLASS_SNIPERRIFLE)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if this profile has a pistol weapon preference
|
||||
|
||||
/* <4a7b22> ../game_shared/bot/bot_profile.cpp:99 */
|
||||
NOBODY bool BotProfile::HasPistolPreference(void) const
|
||||
bool BotProfile::HasPistolPreference(void) const
|
||||
{
|
||||
// {
|
||||
// int i; // 101
|
||||
// }
|
||||
for (int i = 0; i < m_weaponPreferenceCount; ++i)
|
||||
{
|
||||
if (AliasToWeaponClass(WeaponIDToAlias(m_weaponPreference[i])) == WEAPONCLASS_PISTOL)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if this profile is valid for the specified team
|
||||
|
||||
/* <4a7b5e> ../game_shared/bot/bot_profile.cpp:112 */
|
||||
bool BotProfile::IsValidForTeam(BotProfileTeamType team) const
|
||||
{
|
||||
@ -54,132 +83,462 @@ bool BotProfile::IsValidForTeam(BotProfileTeamType team) const
|
||||
}
|
||||
|
||||
/* <4a7bb2> ../game_shared/bot/bot_profile.cpp:122 */
|
||||
NOBODY BotProfileManager::BotProfileManager(void)
|
||||
BotProfileManager::BotProfileManager(void)
|
||||
{
|
||||
// list(list<BotProfile*, std::allocator<BotProfile*>> *const this); // 122
|
||||
// vector(vector<char*, std::allocator<char*>> *const this); // 122
|
||||
// {
|
||||
// int i; // 125
|
||||
// }
|
||||
m_nextSkin = 0;
|
||||
for (int i = 0; i < NumCustomSkins; ++i)
|
||||
{
|
||||
m_skins[i] = NULL;
|
||||
m_skinFilenames[i] = NULL;
|
||||
m_skinModelnames[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the bot profile database
|
||||
|
||||
/* <4a8acb> ../game_shared/bot/bot_profile.cpp:137 */
|
||||
NOBODY void BotProfileManager::Init(const char *filename, unsigned int *checksum)
|
||||
void BotProfileManager::Init(const char *filename, unsigned int *checksum)
|
||||
{
|
||||
// {
|
||||
// int dataLength; // 139
|
||||
// char *dataPointer; // 140
|
||||
// const char *dataFile; // 141
|
||||
// BotProfileList templateList; // 159
|
||||
// class BotProfile defaultProfile; // 161
|
||||
// ComputeSimpleChecksum(const unsigned char *dataPointer,
|
||||
// int dataLength); // 155
|
||||
// BotProfile(BotProfile *const this); // 161
|
||||
// list(list<BotProfile*, std::allocator<BotProfile*>> *const this); // 159
|
||||
// {
|
||||
// char *token; // 172
|
||||
// bool isDefault; // 174
|
||||
// bool isTemplate; // 175
|
||||
// bool isCustomSkin; // 176
|
||||
// class BotProfile *profile; // 270
|
||||
// bool isFirstWeaponPref; // 348
|
||||
// {
|
||||
// int const BufLen; // 180
|
||||
// char skinName; // 181
|
||||
// const char *decoratedName; // 236
|
||||
// bool skinExists; // 237
|
||||
// GetDecoratedSkinName(const char *name,
|
||||
// const char *filename); // 236
|
||||
// GetCustomSkinIndex(BotProfileManager *const this,
|
||||
// const char *name,
|
||||
// const char *filename); // 237
|
||||
// CloneString(const char *str); // 241
|
||||
// CloneString(const char *str); // 244
|
||||
// }
|
||||
// {
|
||||
// const class BotProfile *inherit; // 287
|
||||
// {
|
||||
// char *c; // 292
|
||||
// strchr(char *__s,
|
||||
// int __c); // 292
|
||||
// {
|
||||
// iterator iter; // 297
|
||||
// operator++(_List_iterator<BotProfile*> *const this); // 297
|
||||
// }
|
||||
// Inherit(BotProfile *const this,
|
||||
// const class BotProfile *parent,
|
||||
// const class BotProfile *baseline); // 314
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// char attributeName; // 366
|
||||
// {
|
||||
// char *c; // 474
|
||||
// strchr(char *__s,
|
||||
// int __c); // 474
|
||||
// {
|
||||
// int i; // 478
|
||||
// }
|
||||
// }
|
||||
// atof(const char *__nptr); // 464
|
||||
// atof(const char *__nptr); // 453
|
||||
// atoi(const char *__nptr); // 424
|
||||
// atoi(const char *__nptr); // 420
|
||||
// atof(const char *__nptr); // 416
|
||||
// atoi(const char *__nptr); // 407
|
||||
// GetCustomSkinIndex(BotProfileManager *const this,
|
||||
// const char *name,
|
||||
// const char *filename); // 411
|
||||
// atof(const char *__nptr); // 403
|
||||
// atof(const char *__nptr); // 399
|
||||
// }
|
||||
// BotProfile(BotProfile *const this); // 278
|
||||
// CloneString(const char *str); // 334
|
||||
// push_back(list<BotProfile*, std::allocator<BotProfile*>> *const this,
|
||||
// const value_type &__x); // 514
|
||||
// push_back(list<BotProfile*, std::allocator<BotProfile*>> *const this,
|
||||
// const value_type &__x); // 519
|
||||
// }
|
||||
// ~list(list<BotProfile*, std::allocator<BotProfile*>> *const this,
|
||||
// int const __in_chrg); // 159
|
||||
// {
|
||||
// iterator iter; // 527
|
||||
// operator++(_List_iterator<BotProfile*> *const this); // 527
|
||||
// }
|
||||
// ~list(list<BotProfile*, std::allocator<BotProfile*>> *const this,
|
||||
// int const __in_chrg); // 159
|
||||
// }
|
||||
int dataLength;
|
||||
char *dataPointer = (char *)LOAD_FILE_FOR_ME(const_cast<char *>(filename), &dataLength);
|
||||
const char *dataFile = dataPointer;
|
||||
|
||||
if (dataFile == NULL)
|
||||
{
|
||||
if (UTIL_IsGame("czero"))
|
||||
{
|
||||
CONSOLE_ECHO("WARNING: Cannot access bot profile database '%s'\n", filename);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// compute simple checksum
|
||||
if (checksum)
|
||||
{
|
||||
*checksum = ComputeSimpleChecksum((const unsigned char *)dataPointer, dataLength);
|
||||
}
|
||||
|
||||
// keep list of templates used for inheritance
|
||||
BotProfileList templateList;
|
||||
BotProfile defaultProfile;
|
||||
|
||||
// Parse the BotProfile.db into BotProfile instances
|
||||
while (true)
|
||||
{
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
break;
|
||||
|
||||
char *token = SharedGetToken();
|
||||
|
||||
bool isDefault = (!Q_stricmp(token, "Default"));
|
||||
bool isTemplate = (!Q_stricmp(token, "Template"));
|
||||
bool isCustomSkin = (!Q_stricmp(token, "Skin"));
|
||||
|
||||
if (isCustomSkin)
|
||||
{
|
||||
const int BufLen = 64;
|
||||
char skinName[BufLen];
|
||||
|
||||
// get skin name
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected skin name\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
token = SharedGetToken();
|
||||
Q_snprintf(skinName, BufLen, "%s", token);
|
||||
|
||||
// get attribute name
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected 'Model'\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
token = SharedGetToken();
|
||||
if (Q_stricmp("Model", token))
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected 'Model'\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
// eat '='
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected '='\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
token = SharedGetToken();
|
||||
if (Q_strcmp("=", token))
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected '='\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
// get attribute value
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected attribute value\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
token = SharedGetToken();
|
||||
|
||||
const char *decoratedName = GetDecoratedSkinName(skinName, filename);
|
||||
bool skinExists = GetCustomSkinIndex(decoratedName) > 0;
|
||||
if (m_nextSkin < NumCustomSkins && !skinExists)
|
||||
{
|
||||
// decorate the name
|
||||
m_skins[ m_nextSkin ] = CloneString(decoratedName);
|
||||
|
||||
// construct the model filename
|
||||
m_skinModelnames[ m_nextSkin ] = CloneString(token);
|
||||
m_skinFilenames[ m_nextSkin ] = new char[ Q_strlen(token) * 2 + Q_strlen("models/player//.mdl") + 1 ];
|
||||
Q_sprintf(m_skinFilenames[ m_nextSkin ], "models/player/%s/%s.mdl", token, token);
|
||||
++m_nextSkin;
|
||||
}
|
||||
|
||||
// eat 'End'
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
token = SharedGetToken();
|
||||
if (Q_strcmp("End", token))
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
// it's just a custom skin - no need to do inheritance on a bot profile, etc.
|
||||
continue;
|
||||
}
|
||||
|
||||
// encountered a new profile
|
||||
BotProfile *profile;
|
||||
if (isDefault)
|
||||
{
|
||||
profile = &defaultProfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
profile = new BotProfile;
|
||||
// always inherit from Default
|
||||
*profile = defaultProfile;
|
||||
}
|
||||
|
||||
// do inheritance in order of appearance
|
||||
if (!isTemplate && !isDefault)
|
||||
{
|
||||
const BotProfile *inherit = NULL;
|
||||
|
||||
// template names are separated by "+"
|
||||
while (true)
|
||||
{
|
||||
char *c = Q_strchr(token, '+');
|
||||
if (c)
|
||||
*c = '\000';
|
||||
|
||||
// find the given template name
|
||||
for (BotProfileList::iterator iter = templateList.begin(); iter != templateList.end(); ++iter)
|
||||
{
|
||||
if (!Q_stricmp((*iter)->GetName(), token))
|
||||
{
|
||||
inherit = *iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inherit == NULL)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing '%s' - invalid template reference '%s'\n", filename, token);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
// inherit the data
|
||||
profile->Inherit(inherit, &defaultProfile);
|
||||
|
||||
if (c == NULL)
|
||||
break;
|
||||
|
||||
token = c + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// get name of this profile
|
||||
if (!isDefault)
|
||||
{
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing '%s' - expected name\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
profile->m_name = CloneString(SharedGetToken());
|
||||
|
||||
// HACK HACK
|
||||
// Until we have a generalized means of storing bot preferences, we're going to hardcode the bot's
|
||||
// preference towards silencers based on his name.
|
||||
if (profile->m_name[0] % 2)
|
||||
{
|
||||
profile->m_prefersSilencer = true;
|
||||
}
|
||||
}
|
||||
|
||||
// read attributes for this profile
|
||||
bool isFirstWeaponPref = true;
|
||||
while (true)
|
||||
{
|
||||
// get next token
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected 'End'\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
token = SharedGetToken();
|
||||
|
||||
// check for End delimiter
|
||||
if (!Q_stricmp(token, "End"))
|
||||
break;
|
||||
|
||||
// found attribute name - keep it
|
||||
char attributeName[64];
|
||||
Q_strcpy(attributeName, token);
|
||||
|
||||
// eat '='
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected '='\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
token = SharedGetToken();
|
||||
if (Q_strcmp("=", token))
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected '='\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
// get attribute value
|
||||
dataFile = SharedParse(dataFile);
|
||||
if (!dataFile)
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - expected attribute value\n", filename);
|
||||
FREE_FILE(dataPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
token = SharedGetToken();
|
||||
|
||||
// store value in appropriate attribute
|
||||
if (!Q_stricmp("Aggression", attributeName))
|
||||
{
|
||||
profile->m_aggression = Q_atof(token) / 100.0f;
|
||||
}
|
||||
else if (!Q_stricmp("Skill", attributeName))
|
||||
{
|
||||
profile->m_skill = Q_atof(token) / 100.0f;
|
||||
}
|
||||
else if (!Q_stricmp("Skin", attributeName))
|
||||
{
|
||||
profile->m_skin = Q_atoi(token);
|
||||
|
||||
if (profile->m_skin == 0)
|
||||
{
|
||||
// Q_atoi() failed - try to look up a custom skin by name
|
||||
profile->m_skin = GetCustomSkinIndex(token, filename);
|
||||
}
|
||||
}
|
||||
else if (!Q_stricmp("Teamwork", attributeName))
|
||||
{
|
||||
profile->m_teamwork = Q_atof(token) / 100.0f;
|
||||
}
|
||||
else if (!Q_stricmp("Cost", attributeName))
|
||||
{
|
||||
profile->m_cost = Q_atoi(token);
|
||||
}
|
||||
else if (!Q_stricmp("VoicePitch", attributeName))
|
||||
{
|
||||
profile->m_voicePitch = Q_atoi(token);
|
||||
}
|
||||
else if (!Q_stricmp("VoiceBank", attributeName))
|
||||
{
|
||||
profile->m_voiceBank = FindVoiceBankIndex(token);
|
||||
}
|
||||
else if (!Q_stricmp("WeaponPreference", attributeName))
|
||||
{
|
||||
// weapon preferences override parent prefs
|
||||
if (isFirstWeaponPref)
|
||||
{
|
||||
isFirstWeaponPref = false;
|
||||
profile->m_weaponPreferenceCount = 0;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(token, "none"))
|
||||
{
|
||||
profile->m_weaponPreferenceCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (profile->m_weaponPreferenceCount < BotProfile::MAX_WEAPON_PREFS)
|
||||
{
|
||||
profile->m_weaponPreference[ profile->m_weaponPreferenceCount++ ] = AliasToWeaponID(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!Q_stricmp("ReactionTime", attributeName))
|
||||
{
|
||||
profile->m_reactionTime = Q_atof(token);
|
||||
|
||||
#ifndef GAMEUI_EXPORTS
|
||||
// subtract off latency due to "think" update rate.
|
||||
// In GameUI, we don't really care.
|
||||
profile->m_reactionTime -= g_flBotFullThinkInterval;
|
||||
#endif // GAMEUI_EXPORTS
|
||||
|
||||
}
|
||||
else if (!Q_stricmp("AttackDelay", attributeName))
|
||||
{
|
||||
profile->m_attackDelay = Q_atof(token);
|
||||
}
|
||||
else if (!Q_stricmp("Difficulty", attributeName))
|
||||
{
|
||||
// override inheritance
|
||||
profile->m_difficultyFlags = 0;
|
||||
|
||||
// parse bit flags
|
||||
while (true)
|
||||
{
|
||||
char *c = Q_strchr(token, '+');
|
||||
if (c)
|
||||
*c = '\000';
|
||||
|
||||
for (int i = 0; i < NUM_DIFFICULTY_LEVELS; ++i)
|
||||
{
|
||||
if (!Q_stricmp(BotDifficultyName[i], token))
|
||||
profile->m_difficultyFlags |= (1 << i);
|
||||
}
|
||||
|
||||
if (c == NULL)
|
||||
break;
|
||||
|
||||
token = c + 1;
|
||||
}
|
||||
}
|
||||
else if (!Q_stricmp("Team", attributeName))
|
||||
{
|
||||
if (!Q_stricmp(token, "T"))
|
||||
{
|
||||
profile->m_teams = BOT_TEAM_T;
|
||||
}
|
||||
else if (!Q_stricmp(token, "CT"))
|
||||
{
|
||||
profile->m_teams = BOT_TEAM_CT;
|
||||
}
|
||||
else
|
||||
{
|
||||
profile->m_teams = BOT_TEAM_ANY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CONSOLE_ECHO("Error parsing %s - unknown attribute '%s'\n", filename, attributeName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDefault)
|
||||
{
|
||||
if (isTemplate)
|
||||
{
|
||||
// add to template list
|
||||
templateList.push_back(profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// add profile to the master list
|
||||
m_profileList.push_back(profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FREE_FILE(dataPointer);
|
||||
|
||||
// free the templates
|
||||
for (BotProfileList::iterator iter = templateList.begin(); iter != templateList.end(); ++iter)
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
/* <4a7dfd> ../game_shared/bot/bot_profile.cpp:532 */
|
||||
NOBODY BotProfileManager::~BotProfileManager(void)
|
||||
BotProfileManager::~BotProfileManager(void)
|
||||
{
|
||||
// {
|
||||
// iterator it; // 536
|
||||
// begin(vector<char*, std::allocator<char*>> *const this); // 537
|
||||
// end(vector<char*, std::allocator<char*>> *const this); // 537
|
||||
// operator++(__normal_iterator<char**, std::vector<char*, std::allocator<char*>> > *const this); // 537
|
||||
// clear(vector<char*, std::allocator<char*>> *const this); // 541
|
||||
// }
|
||||
// ~vector(vector<char*, std::allocator<char*>> *const this,
|
||||
// int const __in_chrg); // 532
|
||||
// ~list(list<BotProfile*, std::allocator<BotProfile*>> *const this,
|
||||
// int const __in_chrg); // 532
|
||||
Reset();
|
||||
|
||||
for (VoiceBankList::iterator it = m_voiceBanks.begin(); it != m_voiceBanks.end(); ++it)
|
||||
delete[] *it;
|
||||
|
||||
m_voiceBanks.clear();
|
||||
}
|
||||
|
||||
// Free all bot profiles
|
||||
|
||||
/* <4a7c76> ../game_shared/bot/bot_profile.cpp:548 */
|
||||
NOBODY void BotProfileManager::Reset(void)
|
||||
void BotProfileManager::Reset(void)
|
||||
{
|
||||
// clear(list<BotProfile*, std::allocator<BotProfile*>> *const this); // 553
|
||||
// {
|
||||
// iterator iter; // 550
|
||||
// operator++(_List_iterator<BotProfile*> *const this); // 550
|
||||
// }
|
||||
// {
|
||||
// int i; // 555
|
||||
// }
|
||||
for (BotProfileList::iterator iter = m_profileList.begin(); iter != m_profileList.end(); ++iter)
|
||||
delete *iter;
|
||||
|
||||
m_profileList.clear();
|
||||
|
||||
for (int i = 0; i < NumCustomSkins; ++i)
|
||||
{
|
||||
if (m_skins[i])
|
||||
{
|
||||
delete[] m_skins[i];
|
||||
m_skins[i] = NULL;
|
||||
}
|
||||
if (m_skinFilenames[i])
|
||||
{
|
||||
delete[] m_skinFilenames[i];
|
||||
m_skinFilenames[i] = NULL;
|
||||
}
|
||||
if (m_skinModelnames[i])
|
||||
{
|
||||
delete[] m_skinModelnames[i];
|
||||
m_skinModelnames[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns custom skin name at a particular index
|
||||
|
||||
/* <4a7fdf> ../game_shared/bot/bot_profile.cpp:579 */
|
||||
const char *BotProfileManager::GetCustomSkin(int index)
|
||||
{
|
||||
@ -191,6 +550,8 @@ const char *BotProfileManager::GetCustomSkin(int index)
|
||||
return m_skins[ index - FirstCustomSkin ];
|
||||
}
|
||||
|
||||
// Returns custom skin filename at a particular index
|
||||
|
||||
/* <4a8019> ../game_shared/bot/bot_profile.cpp:593 */
|
||||
const char *BotProfileManager::GetCustomSkinFname(int index)
|
||||
{
|
||||
@ -202,6 +563,8 @@ const char *BotProfileManager::GetCustomSkinFname(int index)
|
||||
return m_skinFilenames[ index - FirstCustomSkin ];
|
||||
}
|
||||
|
||||
// Returns custom skin modelname at a particular index
|
||||
|
||||
/* <4a8053> ../game_shared/bot/bot_profile.cpp:607 */
|
||||
const char *BotProfileManager::GetCustomSkinModelname(int index)
|
||||
{
|
||||
@ -213,37 +576,55 @@ const char *BotProfileManager::GetCustomSkinModelname(int index)
|
||||
return m_skinModelnames[ index - FirstCustomSkin ];
|
||||
}
|
||||
|
||||
// Looks up a custom skin index by filename-decorated name (will decorate the name if filename is given)
|
||||
|
||||
/* <4a80db> ../game_shared/bot/bot_profile.cpp:621 */
|
||||
NOBODY int BotProfileManager::GetCustomSkinIndex(const char *name, const char *filename)
|
||||
int BotProfileManager::GetCustomSkinIndex(const char *name, const char *filename)
|
||||
{
|
||||
// {
|
||||
// const char *skinName; // 623
|
||||
// GetDecoratedSkinName(const char *name,
|
||||
// const char *filename); // 626
|
||||
// {
|
||||
// int i; // 629
|
||||
// }
|
||||
// }
|
||||
const char *skinName = name;
|
||||
if (filename)
|
||||
{
|
||||
skinName = GetDecoratedSkinName(name, filename);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NumCustomSkins; ++i)
|
||||
{
|
||||
if (m_skins[i])
|
||||
{
|
||||
if (!Q_stricmp(skinName, m_skins[i]))
|
||||
{
|
||||
return FirstCustomSkin + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return index of the (custom) bot phrase db, inserting it if needed
|
||||
|
||||
/* <4a8916> ../game_shared/bot/bot_profile.cpp:647 */
|
||||
NOBODY int BotProfileManager::FindVoiceBankIndex(const char *filename)
|
||||
int BotProfileManager::FindVoiceBankIndex(const char *filename)
|
||||
{
|
||||
// {
|
||||
// int index; // 649
|
||||
// const_iterator it; // 651
|
||||
// begin(vector<char*, std::allocator<char*>> *const this); // 652
|
||||
// end(vector<char*, std::allocator<char*>> *const this); // 652
|
||||
// operator++(__normal_iterator<char* const*, std::vector<char*, std::allocator<char*>> > *const this); // 652
|
||||
// CloneString(const char *str); // 660
|
||||
// push_back(vector<char*, std::allocator<char*>> *const this,
|
||||
// const value_type &__x); // 660
|
||||
// }
|
||||
int index = 0;
|
||||
for (VoiceBankList::const_iterator it = m_voiceBanks.begin(); it != m_voiceBanks.end(); ++it, ++index)
|
||||
{
|
||||
if (!Q_stricmp(filename, *it))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
m_voiceBanks.push_back(CloneString(filename));
|
||||
return index;
|
||||
}
|
||||
|
||||
// Return random unused profile that matches the given difficulty level
|
||||
|
||||
/* <4a8177> ../game_shared/bot/bot_profile.cpp:669 */
|
||||
const BotProfile *BotProfileManager::GetRandomProfile(BotDifficultyType difficulty, BotProfileTeamType team) const
|
||||
{
|
||||
#ifdef RANDOM_LONG
|
||||
BotProfileList::const_iterator iter;
|
||||
|
||||
// count up valid profiles
|
||||
@ -274,4 +655,8 @@ const BotProfile *BotProfileManager::GetRandomProfile(BotDifficultyType difficul
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#else
|
||||
// we don't need random profiles when we're not in the game dll
|
||||
return NULL;
|
||||
#endif // RANDOM_LONG
|
||||
}
|
||||
|
@ -83,71 +83,27 @@ public:
|
||||
m_voiceBank = 0;
|
||||
m_prefersSilencer = false;
|
||||
}
|
||||
|
||||
const char *GetName(void) const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
float GetAggression(void) const
|
||||
{
|
||||
return m_aggression;
|
||||
}
|
||||
float GetSkill(void) const
|
||||
{
|
||||
return m_skill;
|
||||
}
|
||||
float GetTeamwork(void) const
|
||||
{
|
||||
return m_teamwork;
|
||||
}
|
||||
int GetWeaponPreference(int i)
|
||||
{
|
||||
return m_weaponPreference[i];
|
||||
}
|
||||
NOBODY const char *GetWeaponPreferenceAsString(int i) const;
|
||||
int GetWeaponPreferenceCount(void) const
|
||||
{
|
||||
return m_weaponPreferenceCount;
|
||||
}
|
||||
|
||||
NOBODY bool HasPrimaryPreference(void) const;
|
||||
NOBODY bool HasPistolPreference(void) const;
|
||||
|
||||
int GetCost(void) const
|
||||
{
|
||||
return m_cost;
|
||||
}
|
||||
int GetSkin(void) const
|
||||
{
|
||||
return m_skin;
|
||||
}
|
||||
NOBODY bool IsDifficulty(BotDifficultyType diff) const;
|
||||
int GetVoicePitch(void) const
|
||||
{
|
||||
return m_voicePitch;
|
||||
}
|
||||
float GetReactionTime(void) const
|
||||
{
|
||||
return m_reactionTime;
|
||||
}
|
||||
float GetAttackDelay(void) const
|
||||
{
|
||||
return m_attackDelay;
|
||||
}
|
||||
int GetVoiceBank(void) const
|
||||
{
|
||||
return m_voiceBank;
|
||||
}
|
||||
const char *GetName(void) const { return m_name; }
|
||||
float GetAggression(void) const { return m_aggression; }
|
||||
float GetSkill(void) const { return m_skill; }
|
||||
float GetTeamwork(void) const { return m_teamwork; }
|
||||
int GetWeaponPreference(int i) const { return m_weaponPreference[i]; }
|
||||
const char *GetWeaponPreferenceAsString(int i) const;
|
||||
int GetWeaponPreferenceCount(void) const { return m_weaponPreferenceCount; }
|
||||
bool HasPrimaryPreference(void) const;
|
||||
bool HasPistolPreference(void) const;
|
||||
int GetCost(void) const { return m_cost; }
|
||||
int GetSkin(void) const { return m_skin; }
|
||||
bool IsDifficulty(BotDifficultyType diff) const;
|
||||
int GetVoicePitch(void) const { return m_voicePitch; }
|
||||
float GetReactionTime(void) const { return m_reactionTime; }
|
||||
float GetAttackDelay(void) const { return m_attackDelay; }
|
||||
int GetVoiceBank(void) const { return m_voiceBank; }
|
||||
bool IsValidForTeam(BotProfileTeamType team) const;
|
||||
bool PrefersSilencer(void) const
|
||||
{
|
||||
return m_prefersSilencer;
|
||||
}
|
||||
// TODO: it func private
|
||||
NOBODY void Inherit(const BotProfile *parent, const BotProfile *baseline);
|
||||
bool PrefersSilencer(void) const { return m_prefersSilencer; }
|
||||
|
||||
private:
|
||||
|
||||
void Inherit(const BotProfile *parent, const BotProfile *baseline);
|
||||
friend class BotProfileManager;
|
||||
|
||||
char *m_name;
|
||||
@ -223,7 +179,7 @@ inline void BotProfile::Inherit(const BotProfile *parent, const BotProfile *base
|
||||
m_voiceBank = parent->m_voiceBank;
|
||||
}
|
||||
|
||||
typedef std::list<BotProfile *> BotProfileList;
|
||||
typedef std::STD_LIST<BotProfile *> BotProfileList;
|
||||
|
||||
/* <36a051> ../game_shared/bot/bot_profile.h:180 */
|
||||
class BotProfileManager
|
||||
@ -238,8 +194,10 @@ public:
|
||||
const BotProfile *GetProfile(const char *name, BotProfileTeamType team) const
|
||||
{
|
||||
for (BotProfileList::const_iterator iter = m_profileList.begin(); iter != m_profileList.end(); ++iter)
|
||||
{
|
||||
if (!Q_stricmp(name, (*iter)->GetName()) && (*iter)->IsValidForTeam(team))
|
||||
return *iter;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -254,7 +212,7 @@ public:
|
||||
const char *GetCustomSkinFname(int index);
|
||||
int GetCustomSkinIndex(const char *name, const char *filename = NULL);
|
||||
|
||||
typedef std::vector<char *> VoiceBankList;
|
||||
typedef std::STD_VECTOR<char *> VoiceBankList;
|
||||
|
||||
const VoiceBankList *GetVoiceBanks() const
|
||||
{
|
||||
@ -263,11 +221,6 @@ public:
|
||||
int FindVoiceBankIndex(const char *filename);
|
||||
|
||||
protected:
|
||||
|
||||
#if defined(_WIN32) && defined(HOOK_GAMEDLL)
|
||||
int unknown_padding1;
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
BotProfileList m_profileList;
|
||||
VoiceBankList m_voiceBanks;
|
||||
|
||||
|
@ -144,7 +144,7 @@ int UTIL_HumansInGame(bool ignoreSpectators)
|
||||
}
|
||||
|
||||
/* <4ad507> ../game_shared/bot/bot_util.cpp:174 */
|
||||
NOBODY int UTIL_HumansOnTeam(int teamID, bool isAlive)
|
||||
int UTIL_HumansOnTeam(int teamID, bool isAlive)
|
||||
{
|
||||
int iCount = 0;
|
||||
for (int iIndex = 1; iIndex <= gpGlobals->maxClients; ++iIndex)
|
||||
@ -178,7 +178,7 @@ NOBODY int UTIL_HumansOnTeam(int teamID, bool isAlive)
|
||||
}
|
||||
|
||||
/* <4ad5db> ../game_shared/bot/bot_util.cpp:210 */
|
||||
NOBODY int UTIL_BotsInGame(void)
|
||||
int UTIL_BotsInGame(void)
|
||||
{
|
||||
int iCount = 0;
|
||||
|
||||
@ -265,7 +265,7 @@ bool UTIL_KickBotFromTeam(TeamName kickTeam)
|
||||
}
|
||||
|
||||
/* <4ad7ad> ../game_shared/bot/bot_util.cpp:305 */
|
||||
NOBODY bool UTIL_IsTeamAllBots(int team)
|
||||
bool UTIL_IsTeamAllBots(int team)
|
||||
{
|
||||
int botCount = 0;
|
||||
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
||||
@ -330,7 +330,7 @@ NOBODY bool UTIL_IsTeamAllBots(int team)
|
||||
// If 'distance' is non-NULL, the distance to the closest player is returned in it.
|
||||
|
||||
/* <4ad86a> ../game_shared/bot/bot_util.cpp:343 */
|
||||
NOBODY /*extern*/ CBasePlayer *UTIL_GetClosestPlayer(const Vector *pos, int team, float *distance)
|
||||
/*extern*/ CBasePlayer *UTIL_GetClosestPlayer(const Vector *pos, int team, float *distance)
|
||||
{
|
||||
CBasePlayer *closePlayer = NULL;
|
||||
float closeDistSq = 1.0e12f; // 999999999999.9f
|
||||
@ -388,7 +388,7 @@ void UTIL_ConstructBotNetName(char *name, int nameLength, const BotProfile *prof
|
||||
}
|
||||
|
||||
/* <4adb6c> ../game_shared/bot/bot_util.cpp:440 */
|
||||
NOBODY bool UTIL_IsVisibleToTeam(const Vector &spot, int team, float maxRange)
|
||||
bool UTIL_IsVisibleToTeam(const Vector &spot, int team, float maxRange)
|
||||
{
|
||||
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
||||
{
|
||||
@ -432,26 +432,26 @@ CBasePlayer *UTIL_GetLocalPlayer(void)
|
||||
}
|
||||
|
||||
/* <4adcab> ../game_shared/bot/bot_util.cpp:491 */
|
||||
NOBODY Vector UTIL_ComputeOrigin(entvars_t *pevVars)
|
||||
NOXREF Vector UTIL_ComputeOrigin(entvars_t *pevVars)
|
||||
{
|
||||
if ((pevVars->origin.x == 0.0) && (pevVars->origin.y == 0.0) && (pevVars->origin.z == 0.0))
|
||||
return (pevVars->absmax + pevVars->absmin) *0.5;
|
||||
if (pevVars->origin.x == 0.0f && pevVars->origin.y == 0.0f && pevVars->origin.z == 0.0f)
|
||||
return (pevVars->absmax + pevVars->absmin) * 0.5f;
|
||||
else
|
||||
return pevVars->origin;
|
||||
}
|
||||
|
||||
NOBODY Vector UTIL_ComputeOrigin(CBaseEntity *pEntity)
|
||||
NOXREF Vector UTIL_ComputeOrigin(CBaseEntity *pEntity)
|
||||
{
|
||||
return UTIL_ComputeOrigin(pEntity->pev);
|
||||
}
|
||||
|
||||
NOBODY Vector UTIL_ComputeOrigin(edict_t *pentEdict)
|
||||
NOXREF Vector UTIL_ComputeOrigin(edict_t *pentEdict)
|
||||
{
|
||||
return UTIL_ComputeOrigin(VARS(pentEdict));
|
||||
}
|
||||
|
||||
/* <4adf8a> ../game_shared/bot/bot_util.cpp:513 */
|
||||
NOBODY void UTIL_DrawBeamFromEnt(int iIndex, Vector vecEnd, int iLifetime, byte bRed, byte bGreen, byte bBlue)
|
||||
NOXREF void UTIL_DrawBeamFromEnt(int iIndex, Vector vecEnd, int iLifetime, byte bRed, byte bGreen, byte bBlue)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, vecEnd);
|
||||
WRITE_BYTE(TE_BEAMENTPOINT);
|
||||
@ -474,7 +474,7 @@ NOBODY void UTIL_DrawBeamFromEnt(int iIndex, Vector vecEnd, int iLifetime, byte
|
||||
}
|
||||
|
||||
/* <4ae02e> ../game_shared/bot/bot_util.cpp:537 */
|
||||
NOBODY void UTIL_DrawBeamPoints(Vector vecStart, Vector vecEnd, int iLifetime, byte bRed, byte bGreen, byte bBlue)
|
||||
void UTIL_DrawBeamPoints(Vector vecStart, Vector vecEnd, int iLifetime, byte bRed, byte bGreen, byte bBlue)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, vecStart);
|
||||
WRITE_BYTE(TE_BEAMPOINTS);
|
||||
@ -585,8 +585,8 @@ bool IsGameEventAudible(GameEventType event, CBaseEntity *entity, CBaseEntity *o
|
||||
|
||||
switch (event)
|
||||
{
|
||||
/// TODO: Check weapon type (knives are pretty quiet)
|
||||
/// TODO: Use actual volume, account for silencers, etc.
|
||||
// TODO: Check weapon type (knives are pretty quiet)
|
||||
// TODO: Use actual volume, account for silencers, etc.
|
||||
case EVENT_WEAPON_FIRED:
|
||||
{
|
||||
if (player->m_pActiveItem == NULL)
|
||||
|
@ -45,10 +45,7 @@ class BotProfile;
|
||||
|
||||
enum PriorityType
|
||||
{
|
||||
PRIORITY_LOW,
|
||||
PRIORITY_MEDIUM,
|
||||
PRIORITY_HIGH,
|
||||
PRIORITY_UNINTERRUPTABLE
|
||||
PRIORITY_LOW, PRIORITY_MEDIUM, PRIORITY_HIGH, PRIORITY_UNINTERRUPTABLE
|
||||
};
|
||||
|
||||
// Simple class for tracking intervals of game time
|
||||
@ -97,7 +94,8 @@ public:
|
||||
{
|
||||
return (gpGlobals->time - m_timestamp > duration) ? true : false;
|
||||
}
|
||||
/*private:*/
|
||||
|
||||
private:
|
||||
float m_timestamp;
|
||||
|
||||
};/* size: 4, cachelines: 1, members: 1 */
|
||||
@ -179,12 +177,14 @@ inline bool IsIntersecting2D(const Vector &startA, const Vector &endA, const Vec
|
||||
// parallel
|
||||
return false;
|
||||
}
|
||||
|
||||
float numS = (startA.y - startB.y) * (endB.x - startB.x) - (startA.x - startB.x) * (endB.y - startB.y);
|
||||
if (numS == 0.0f)
|
||||
{
|
||||
// coincident
|
||||
return true;
|
||||
}
|
||||
|
||||
float numT = (startA.y - startB.y) * (endA.x - startA.x) - (startA.x - startB.x) * (endA.y - startA.y);
|
||||
float s = numS / denom;
|
||||
if (s < 0.0f || s > 1.0f)
|
||||
@ -192,6 +192,7 @@ inline bool IsIntersecting2D(const Vector &startA, const Vector &endA, const Vec
|
||||
// intersection is not within line segment of startA to endA
|
||||
return false;
|
||||
}
|
||||
|
||||
float t = numT / denom;
|
||||
if (t < 0.0f || t > 1.0f)
|
||||
{
|
||||
@ -214,7 +215,7 @@ inline bool IsIntersecting2D(const Vector &startA, const Vector &endA, const Vec
|
||||
template <typename Functor>
|
||||
bool ForEachPlayer(Functor &func)
|
||||
{
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
for (int i = 1; i <= gpGlobals->maxClients; ++i)
|
||||
{
|
||||
CBasePlayer *player = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(i));
|
||||
if (!IsEntityValid((CBaseEntity *)player))
|
||||
@ -247,38 +248,106 @@ inline bool IsZombieGame(void)
|
||||
#define s_iBeamSprite (*ps_iBeamSprite)
|
||||
#define cosTable (*pcosTable)
|
||||
|
||||
#define cv_bot_traceview (*pcv_bot_traceview)
|
||||
#define cv_bot_stop (*pcv_bot_stop)
|
||||
#define cv_bot_show_nav (*pcv_bot_show_nav)
|
||||
#define cv_bot_show_danger (*pcv_bot_show_danger)
|
||||
#define cv_bot_nav_edit (*pcv_bot_nav_edit)
|
||||
#define cv_bot_nav_zdraw (*pcv_bot_nav_zdraw)
|
||||
#define cv_bot_walk (*pcv_bot_walk)
|
||||
#define cv_bot_difficulty (*pcv_bot_difficulty)
|
||||
#define cv_bot_debug (*pcv_bot_debug)
|
||||
#define cv_bot_quicksave (*pcv_bot_quicksave)
|
||||
#define cv_bot_quota (*pcv_bot_quota)
|
||||
#define cv_bot_quota_match (*pcv_bot_quota_match)
|
||||
#define cv_bot_prefix (*pcv_bot_prefix)
|
||||
#define cv_bot_allow_rogues (*pcv_bot_allow_rogues)
|
||||
#define cv_bot_allow_pistols (*pcv_bot_allow_pistols)
|
||||
#define cv_bot_allow_shotguns (*pcv_bot_allow_shotguns)
|
||||
#define cv_bot_allow_sub_machine_guns (*pcv_bot_allow_sub_machine_guns)
|
||||
#define cv_bot_allow_rifles (*pcv_bot_allow_rifles)
|
||||
#define cv_bot_allow_machine_guns (*pcv_bot_allow_machine_guns)
|
||||
#define cv_bot_allow_grenades (*pcv_bot_allow_grenades)
|
||||
#define cv_bot_allow_snipers (*pcv_bot_allow_snipers)
|
||||
#define cv_bot_allow_shield (*pcv_bot_allow_shield)
|
||||
#define cv_bot_join_team (*pcv_bot_join_team)
|
||||
#define cv_bot_join_after_player (*pcv_bot_join_after_player)
|
||||
#define cv_bot_auto_vacate (*pcv_bot_auto_vacate)
|
||||
#define cv_bot_zombie (*pcv_bot_zombie)
|
||||
#define cv_bot_defer_to_human (*pcv_bot_defer_to_human)
|
||||
#define cv_bot_chatter (*pcv_bot_chatter)
|
||||
#define cv_bot_profile_db (*pcv_bot_profile_db)
|
||||
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
extern short s_iBeamSprite;
|
||||
extern float cosTable[COS_TABLE_SIZE];
|
||||
|
||||
extern cvar_t cv_bot_traceview;
|
||||
extern cvar_t cv_bot_stop;
|
||||
extern cvar_t cv_bot_show_nav;
|
||||
extern cvar_t cv_bot_show_danger;
|
||||
extern cvar_t cv_bot_nav_edit;
|
||||
extern cvar_t cv_bot_nav_zdraw;
|
||||
extern cvar_t cv_bot_walk;
|
||||
extern cvar_t cv_bot_difficulty;
|
||||
extern cvar_t cv_bot_debug;
|
||||
extern cvar_t cv_bot_quicksave;
|
||||
extern cvar_t cv_bot_quota;
|
||||
extern cvar_t cv_bot_quota_match;
|
||||
extern cvar_t cv_bot_prefix;
|
||||
extern cvar_t cv_bot_allow_rogues;
|
||||
extern cvar_t cv_bot_allow_pistols;
|
||||
extern cvar_t cv_bot_allow_shotguns;
|
||||
extern cvar_t cv_bot_allow_sub_machine_guns;
|
||||
extern cvar_t cv_bot_allow_rifles;
|
||||
extern cvar_t cv_bot_allow_machine_guns;
|
||||
extern cvar_t cv_bot_allow_grenades;
|
||||
extern cvar_t cv_bot_allow_snipers;
|
||||
extern cvar_t cv_bot_allow_shield;
|
||||
extern cvar_t cv_bot_join_team;
|
||||
extern cvar_t cv_bot_join_after_player;
|
||||
extern cvar_t cv_bot_auto_vacate;
|
||||
extern cvar_t cv_bot_zombie;
|
||||
extern cvar_t cv_bot_defer_to_human;
|
||||
extern cvar_t cv_bot_chatter;
|
||||
extern cvar_t cv_bot_profile_db;
|
||||
|
||||
#define IS_ALIVE true
|
||||
int UTIL_HumansOnTeam(int teamID, bool isAlive = false);
|
||||
|
||||
#define IGNORE_SPECTATORS true
|
||||
int UTIL_HumansInGame(bool ignoreSpectators = false);
|
||||
|
||||
bool UTIL_IsNameTaken(const char *name, bool ignoreHumans = false);
|
||||
int UTIL_ClientsInGame(void);
|
||||
int UTIL_ActivePlayersInGame(void);
|
||||
int UTIL_HumansInGame(bool ignoreSpectators);
|
||||
NOBODY int UTIL_HumansOnTeam(int teamID, bool isAlive = false);
|
||||
NOBODY int UTIL_BotsInGame(void);
|
||||
int UTIL_BotsInGame(void);
|
||||
bool UTIL_KickBotFromTeam(TeamName kickTeam);
|
||||
NOBODY bool UTIL_IsTeamAllBots(int team);
|
||||
bool UTIL_IsTeamAllBots(int team);
|
||||
CBasePlayer *UTIL_GetClosestPlayer(const Vector *pos, float *distance = NULL);
|
||||
NOBODY CBasePlayer *UTIL_GetClosestPlayer(const Vector *pos, int team, float *distance = NULL);
|
||||
CBasePlayer *UTIL_GetClosestPlayer(const Vector *pos, int team, float *distance = NULL);
|
||||
const char *UTIL_GetBotPrefix();
|
||||
void UTIL_ConstructBotNetName(char *name, int nameLength, const BotProfile *profile);
|
||||
NOBODY bool UTIL_IsVisibleToTeam(const Vector &spot, int team, float maxRange = -1.0f);
|
||||
bool UTIL_IsVisibleToTeam(const Vector &spot, int team, float maxRange = -1.0f);
|
||||
CBasePlayer *UTIL_GetLocalPlayer(void);
|
||||
NOBODY Vector UTIL_ComputeOrigin(entvars_t *pevVars);
|
||||
NOBODY Vector UTIL_ComputeOrigin(CBaseEntity *pEntity);
|
||||
NOBODY Vector UTIL_ComputeOrigin(edict_t *pentEdict);
|
||||
NOBODY void UTIL_DrawBeamFromEnt(int iIndex, Vector vecEnd, int iLifetime, byte bRed, byte bGreen, byte bBlue);
|
||||
NOBODY void UTIL_DrawBeamPoints(Vector vecStart, Vector vecEnd, int iLifetime, byte bRed, byte bGreen, byte bBlue);
|
||||
NOXREF Vector UTIL_ComputeOrigin(entvars_t *pevVars);
|
||||
NOXREF Vector UTIL_ComputeOrigin(CBaseEntity *pEntity);
|
||||
NOXREF Vector UTIL_ComputeOrigin(edict_t *pentEdict);
|
||||
NOXREF void UTIL_DrawBeamFromEnt(int iIndex, Vector vecEnd, int iLifetime, byte bRed, byte bGreen, byte bBlue);
|
||||
void UTIL_DrawBeamPoints(Vector vecStart, Vector vecEnd, int iLifetime, byte bRed, byte bGreen, byte bBlue);
|
||||
|
||||
// Echos text to the console, and prints it on the client's screen. This is NOT tied to the developer cvar.
|
||||
// If you are adding debugging output in cstrike, use UTIL_DPrintf() (debug.h) instead.
|
||||
void CONSOLE_ECHO(char *pszMsg, ...);
|
||||
void CONSOLE_ECHO_LOGGED(char *pszMsg, ...);
|
||||
|
||||
void BotPrecache(void);
|
||||
void InitBotTrig(void);
|
||||
float BotCOS(float angle);
|
||||
float BotSIN(float angle);
|
||||
bool IsGameEventAudible(enum GameEventType event, CBaseEntity *entity, CBaseEntity *other, float *range, PriorityType *priority, bool *isHostile);
|
||||
NOBODY void HintMessageToAllPlayers(const char *message);
|
||||
void HintMessageToAllPlayers(const char *message);
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
#pragma warning(disable : 4530)
|
||||
|
||||
// to help identify nav files
|
||||
#define NAV_MAGIC_NUMBER 0xFEEDFACE
|
||||
#define NAV_MAGIC_NUMBER 0xFEEDFACE
|
||||
|
||||
// A place is a named group of navigation areas
|
||||
typedef unsigned int Place;
|
||||
@ -47,6 +47,7 @@ typedef unsigned int Place;
|
||||
|
||||
#define WALK_THRU_DOORS 0x01
|
||||
#define WALK_THRU_BREAKABLES 0x02
|
||||
#define WALK_THRU_EVERYTHING (WALK_THRU_DOORS | WALK_THRU_BREAKABLES)
|
||||
|
||||
//class CNavArea;
|
||||
//class CNavNode;
|
||||
@ -141,24 +142,13 @@ struct Extent
|
||||
Vector lo;
|
||||
Vector hi;
|
||||
|
||||
UNTESTED float SizeX(void) const
|
||||
{
|
||||
return hi.x - lo.x;
|
||||
}
|
||||
UNTESTED float SizeY(void) const
|
||||
{
|
||||
return hi.y - lo.y;
|
||||
}
|
||||
UNTESTED float SizeZ(void) const
|
||||
{
|
||||
return hi.z - lo.z;
|
||||
}
|
||||
UNTESTED float Area(void) const
|
||||
{
|
||||
return SizeX() * SizeY();
|
||||
}
|
||||
float SizeX(void) const { return hi.x - lo.x; }
|
||||
float SizeY(void) const { return hi.y - lo.y;}
|
||||
float SizeZ(void) const { return hi.z - lo.z; }
|
||||
float Area(void) const { return SizeX() * SizeY(); }
|
||||
|
||||
// return true if 'pos' is inside of this extent
|
||||
UNTESTED bool Contains(const Vector *pos) const
|
||||
bool Contains(const Vector *pos) const
|
||||
{
|
||||
return (pos->x >= lo.x && pos->x <= hi.x &&
|
||||
pos->y >= lo.y && pos->y <= hi.y &&
|
||||
@ -236,12 +226,12 @@ inline void AddDirectionVector(Vector *v, NavDirType dir, float amount)
|
||||
case NORTH:
|
||||
v->y -= amount;
|
||||
return;
|
||||
case EAST:
|
||||
v->x += amount;
|
||||
return;
|
||||
case SOUTH:
|
||||
v->y += amount;
|
||||
return;
|
||||
case EAST:
|
||||
v->x += amount;
|
||||
return;
|
||||
case WEST:
|
||||
v->x -= amount;
|
||||
return;
|
||||
@ -267,7 +257,7 @@ inline float DirectionToAngle(NavDirType dir)
|
||||
}
|
||||
|
||||
/* <3d8335> ../game_shared/bot/nav.h:202 */
|
||||
inline NavDirType AngleToDirection(float angle)
|
||||
inline NavDirType AngleToDirection(float_precision angle)
|
||||
{
|
||||
while (angle < 0.0f)
|
||||
angle += 360.0f;
|
||||
@ -327,6 +317,13 @@ inline void SnapToGrid(float *value)
|
||||
*value = c * GenerationStepSize;
|
||||
}
|
||||
|
||||
// custom
|
||||
inline float SnapToGrid(float v)
|
||||
{
|
||||
int c = v / GenerationStepSize;
|
||||
return c;
|
||||
}
|
||||
|
||||
/* <14ea2f> ../game_shared/bot/nav.h:251 */
|
||||
inline float_precision NormalizeAngle(float_precision angle)
|
||||
{
|
||||
@ -368,7 +365,7 @@ inline float AngleDifference(float a, float b)
|
||||
/* <38cac9> ../game_shared/bot/nav.h:288 */
|
||||
inline bool AnglesAreEqual(float a, float b, float tolerance = 5.0f)
|
||||
{
|
||||
if (abs(AngleDifference(a, b)) < tolerance)
|
||||
if (abs(int64(AngleDifference(a, b))) < tolerance)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -3631,7 +3631,7 @@ int CNavArea::GetPlayerCount(int teamID, CBasePlayer *ignore) const
|
||||
if (!player->IsAlive())
|
||||
continue;
|
||||
|
||||
if (teamID == 0 || player->m_iTeam == teamID)
|
||||
if (teamID == UNASSIGNED || player->m_iTeam == teamID)
|
||||
if (Contains(&player->pev->origin))
|
||||
++count;
|
||||
}
|
||||
@ -3697,7 +3697,7 @@ void CNavArea::DrawConnectedAreas(void)
|
||||
if (player == NULL)
|
||||
return;
|
||||
|
||||
CCSBotManager *ctrl = static_cast<CCSBotManager *>(TheBots);
|
||||
CCSBotManager *ctrl = TheCSBots();
|
||||
const float maxRange = 500.0f;
|
||||
|
||||
// draw self
|
||||
@ -3868,10 +3868,9 @@ public:
|
||||
{
|
||||
m_initialPlace = area->GetPlace();
|
||||
}
|
||||
|
||||
bool operator()(CNavArea *area)
|
||||
{
|
||||
CCSBotManager *ctrl = static_cast<CCSBotManager *>(TheBots);
|
||||
CCSBotManager *ctrl = TheCSBots();
|
||||
|
||||
if (area->GetPlace() != m_initialPlace)
|
||||
return false;
|
||||
@ -3891,8 +3890,7 @@ private:
|
||||
/* <4d76ef> ../game_shared/bot/nav_area.cpp:4002 */
|
||||
void EditNavAreas(NavEditCmdType cmd)
|
||||
{
|
||||
CCSBotManager *ctrl = static_cast<CCSBotManager *>(TheBots);
|
||||
|
||||
CCSBotManager *ctrl = TheCSBots();
|
||||
CBasePlayer *player = UTIL_GetLocalPlayer();
|
||||
if (player == NULL)
|
||||
return;
|
||||
@ -3912,7 +3910,6 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
lastDrawTimestamp = drawTimestamp;
|
||||
}
|
||||
|
||||
|
||||
const float maxRange = 1000.0f;
|
||||
int beamTime = 1;
|
||||
|
||||
@ -4034,7 +4031,7 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
// find the area the player is pointing at
|
||||
CNavArea *area = TheNavAreaGrid.GetNearestNavArea(&result.vecEndPos);
|
||||
|
||||
if (area)
|
||||
if (area != NULL)
|
||||
{
|
||||
// if area changed, print its ID
|
||||
if (area != lastSelectedArea)
|
||||
@ -4048,10 +4045,10 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
if (area->GetPlace())
|
||||
{
|
||||
const char *name = TheBotPhrases->IDToName(area->GetPlace());
|
||||
if (name)
|
||||
strcpy(locName, name);
|
||||
if (name != NULL)
|
||||
Q_strcpy(locName, name);
|
||||
else
|
||||
strcpy(locName, "ERROR");
|
||||
Q_strcpy(locName, "ERROR");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4064,14 +4061,14 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(attrib, "%s%s%s%s",
|
||||
Q_sprintf(attrib, "%s%s%s%s",
|
||||
(area->GetAttributes() & NAV_CROUCH) ? "CROUCH " : "",
|
||||
(area->GetAttributes() & NAV_JUMP) ? "JUMP " : "",
|
||||
(area->GetAttributes() & NAV_PRECISE) ? "PRECISE " : "",
|
||||
(area->GetAttributes() & NAV_NO_JUMP) ? "NO_JUMP " : "");
|
||||
}
|
||||
|
||||
sprintf(buffer, "Area #%d %s %s\n", area->GetID(), locName, attrib);
|
||||
Q_sprintf(buffer, "Area #%d %s %s\n", area->GetID(), locName, attrib);
|
||||
UTIL_SayTextAll(buffer, player);
|
||||
|
||||
// do "place painting"
|
||||
@ -4255,7 +4252,7 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
connected += markedArea->GetAdjacentCount(WEST);
|
||||
|
||||
char buffer[80];
|
||||
sprintf(buffer, "Marked Area is connected to %d other Areas\n", connected);
|
||||
Q_sprintf(buffer, "Marked Area is connected to %d other Areas\n", connected);
|
||||
UTIL_SayTextAll(buffer, player);
|
||||
}
|
||||
break;
|
||||
@ -4302,7 +4299,7 @@ void EditNavAreas(NavEditCmdType cmd)
|
||||
}
|
||||
|
||||
char buffer[80];
|
||||
sprintf(buffer, "Marked Area is connected to %d other Areas - there are %d total unnamed areas\n", connected, totalUnnamedAreas);
|
||||
Q_sprintf(buffer, "Marked Area is connected to %d other Areas - there are %d total unnamed areas\n", connected, totalUnnamedAreas);
|
||||
UTIL_SayTextAll(buffer, player);
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,6 @@ enum LadderDirectionType
|
||||
NUM_LADDER_DIRECTIONS
|
||||
};
|
||||
|
||||
|
||||
/* <4c2fda> ../game_shared/bot/nav_area.h:63 */
|
||||
class CNavLadder
|
||||
{
|
||||
@ -232,10 +231,12 @@ public:
|
||||
}
|
||||
static void ChangeMasterMarker(void)
|
||||
{
|
||||
IMPL(m_masterMarker)++;
|
||||
++IMPL(m_masterMarker);
|
||||
}
|
||||
|
||||
#ifndef HOOK_GAMEDLL
|
||||
private:
|
||||
#endif // HOOK_GAMEDLL
|
||||
friend void DestroyHidingSpots(void);
|
||||
|
||||
Vector m_pos;
|
||||
@ -243,9 +244,6 @@ private:
|
||||
unsigned int m_marker;
|
||||
unsigned char m_flags;
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
public:
|
||||
#endif // HOOK_GAMEDLL
|
||||
static unsigned int IMPL(m_nextID);
|
||||
static unsigned int IMPL(m_masterMarker);
|
||||
|
||||
@ -303,77 +301,45 @@ public:
|
||||
void Load(SteamFile *file, unsigned int version);
|
||||
NavErrorType PostLoad(void);
|
||||
|
||||
unsigned int GetID(void) const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
void SetAttributes(unsigned char bits)
|
||||
{
|
||||
m_attributeFlags = bits;
|
||||
}
|
||||
unsigned char GetAttributes(void) const
|
||||
{
|
||||
return m_attributeFlags;
|
||||
}
|
||||
void SetPlace(Place place) // set place descriptor
|
||||
{
|
||||
m_place = place;
|
||||
}
|
||||
Place GetPlace(void) const // get place descriptor
|
||||
{
|
||||
return m_place;
|
||||
}
|
||||
unsigned int GetID(void) const { return m_id; }
|
||||
void SetAttributes(unsigned char bits) { m_attributeFlags = bits; }
|
||||
unsigned char GetAttributes(void) const { return m_attributeFlags; }
|
||||
void SetPlace(Place place) { m_place = place; } // set place descriptor
|
||||
Place GetPlace(void) const { return m_place; } // get place descriptor
|
||||
|
||||
bool IsOverlapping(const Vector *pos) const; // return true if 'pos' is within 2D extents of area
|
||||
bool IsOverlapping(const CNavArea *area) const; // return true if 'area' overlaps our 2D extents
|
||||
bool IsOverlappingX(const CNavArea *area) const; // return true if 'area' overlaps our X extent
|
||||
bool IsOverlappingY(const CNavArea *area) const; // return true if 'area' overlaps our Y extent
|
||||
int GetPlayerCount(int teamID = 0, CBasePlayer *ignore = NULL) const; // return number of players with given teamID in this area (teamID == 0 means any/all)
|
||||
float GetZ(const Vector *pos) const; // return Z of area at (x,y) of 'pos'
|
||||
float GetZ(float x, float y) const; // return Z of area at (x,y) of 'pos'
|
||||
bool Contains(const Vector *pos) const; // return true if given point is on or above this area, but no others
|
||||
bool IsCoplanar(const CNavArea *area) const; // return true if this area and given area are approximately co-planar
|
||||
void GetClosestPointOnArea(const Vector *pos, Vector *close) const; // return closest point to 'pos' on this area - returned point in 'close'
|
||||
float GetDistanceSquaredToPoint(const Vector *pos) const; // return shortest distance between point and this area
|
||||
bool IsDegenerate(void) const; // return true if this area is badly formed
|
||||
bool IsEdge(NavDirType dir) const; // return true if there are no bi-directional links on the given side
|
||||
int GetAdjacentCount(NavDirType dir) const // return number of connected areas in given direction
|
||||
{
|
||||
return m_connect[dir].size();
|
||||
}
|
||||
CNavArea *GetAdjacentArea(NavDirType dir, int i) const; // return the i'th adjacent area in the given direction
|
||||
bool IsOverlapping(const Vector *pos) const; // return true if 'pos' is within 2D extents of area
|
||||
bool IsOverlapping(const CNavArea *area) const; // return true if 'area' overlaps our 2D extents
|
||||
bool IsOverlappingX(const CNavArea *area) const; // return true if 'area' overlaps our X extent
|
||||
bool IsOverlappingY(const CNavArea *area) const; // return true if 'area' overlaps our Y extent
|
||||
int GetPlayerCount(int teamID = 0, CBasePlayer *ignore = NULL) const; // return number of players with given teamID in this area (teamID == 0 means any/all)
|
||||
float GetZ(const Vector *pos) const; // return Z of area at (x,y) of 'pos'
|
||||
float GetZ(float x, float y) const; // return Z of area at (x,y) of 'pos'
|
||||
bool Contains(const Vector *pos) const; // return true if given point is on or above this area, but no others
|
||||
bool IsCoplanar(const CNavArea *area) const; // return true if this area and given area are approximately co-planar
|
||||
void GetClosestPointOnArea(const Vector *pos, Vector *close) const; // return closest point to 'pos' on this area - returned point in 'close'
|
||||
float GetDistanceSquaredToPoint(const Vector *pos) const; // return shortest distance between point and this area
|
||||
bool IsDegenerate(void) const; // return true if this area is badly formed
|
||||
bool IsEdge(NavDirType dir) const; // return true if there are no bi-directional links on the given side
|
||||
int GetAdjacentCount(NavDirType dir) const { return m_connect[dir].size(); } // return number of connected areas in given direction
|
||||
CNavArea *GetAdjacentArea(NavDirType dir, int i) const; // return the i'th adjacent area in the given direction
|
||||
CNavArea *GetRandomAdjacentArea(NavDirType dir) const;
|
||||
const NavConnectList *GetAdjacentList(NavDirType dir) const
|
||||
{
|
||||
return &m_connect[dir];
|
||||
}
|
||||
bool IsConnected(const CNavArea *area, NavDirType dir) const; // return true if given area is connected in given direction
|
||||
float ComputeHeightChange(const CNavArea *area); // compute change in height from this area to given area
|
||||
const NavConnectList *GetAdjacentList(NavDirType dir) const { return &m_connect[dir]; }
|
||||
bool IsConnected(const CNavArea *area, NavDirType dir) const; // return true if given area is connected in given direction
|
||||
float ComputeHeightChange(const CNavArea *area); // compute change in height from this area to given area
|
||||
|
||||
const NavLadderList *GetLadderList(LadderDirectionType dir) const
|
||||
{
|
||||
return &m_ladder[dir];
|
||||
}
|
||||
const NavLadderList *GetLadderList(LadderDirectionType dir) const { return &m_ladder[dir]; }
|
||||
|
||||
void ComputePortal(const CNavArea *to, NavDirType dir, Vector *center, float *halfWidth) const; // compute portal to adjacent area
|
||||
void ComputeClosestPointInPortal(const CNavArea *to, NavDirType dir, const Vector *fromPos, Vector *closePos) const; // compute closest point within the "portal" between to adjacent areas
|
||||
NavDirType ComputeDirection(Vector *point) const; // return direction from this area to the given point
|
||||
|
||||
// for hunting algorithm
|
||||
void SetClearedTimestamp(int teamID) // set this area's "clear" timestamp to now
|
||||
{
|
||||
m_clearedTimestamp[teamID] = gpGlobals->time;
|
||||
}
|
||||
float GetClearedTimestamp(int teamID) // get time this area was marked "clear"
|
||||
{
|
||||
return m_clearedTimestamp[teamID];
|
||||
}
|
||||
void SetClearedTimestamp(int teamID) { m_clearedTimestamp[teamID] = gpGlobals->time; } // set this area's "clear" timestamp to now
|
||||
float GetClearedTimestamp(int teamID) { return m_clearedTimestamp[teamID]; } // get time this area was marked "clear"
|
||||
|
||||
// hiding spots
|
||||
const HidingSpotList *GetHidingSpotList(void) const
|
||||
{
|
||||
return &m_hidingSpotList;
|
||||
}
|
||||
const HidingSpotList *GetHidingSpotList(void) const { return &m_hidingSpotList; }
|
||||
|
||||
void ComputeHidingSpots(void); // analyze local area neighborhood to find "hiding spots" in this area - for map learning
|
||||
void ComputeSniperSpots(void); // analyze local area neighborhood to find "sniper spots" in this area - for map learning
|
||||
|
||||
@ -383,22 +349,12 @@ public:
|
||||
// danger
|
||||
void IncreaseDanger(int teamID, float amount); // increase the danger of this area for the given team
|
||||
float GetDanger(int teamID); // return the danger of this area (decays over time)
|
||||
float GetSizeX(void) const
|
||||
{
|
||||
return m_extent.hi.x - m_extent.lo.x;
|
||||
}
|
||||
float GetSizeY(void) const
|
||||
{
|
||||
return m_extent.hi.y - m_extent.lo.y;
|
||||
}
|
||||
const Extent *GetExtent(void) const
|
||||
{
|
||||
return &m_extent;
|
||||
}
|
||||
const Vector *GetCenter(void) const
|
||||
{
|
||||
return &m_center;
|
||||
}
|
||||
|
||||
float GetSizeX(void) const { return m_extent.hi.x - m_extent.lo.x; }
|
||||
float GetSizeY(void) const { return m_extent.hi.y - m_extent.lo.y; }
|
||||
|
||||
const Extent *GetExtent(void) const { return &m_extent; }
|
||||
const Vector *GetCenter(void) const { return &m_center; }
|
||||
const Vector *GetCorner(NavCornerType corner) const;
|
||||
|
||||
// approach areas
|
||||
@ -411,44 +367,22 @@ public:
|
||||
NavTraverseType hereToNextHow;
|
||||
};
|
||||
|
||||
const ApproachInfo *GetApproachInfo(int i) const
|
||||
{
|
||||
return &m_approach[i];
|
||||
}
|
||||
int GetApproachInfoCount(void) const
|
||||
{
|
||||
return m_approachCount;
|
||||
}
|
||||
void ComputeApproachAreas(void); // determine the set of "approach areas" - for map learning
|
||||
const ApproachInfo *GetApproachInfo(int i) const { return &m_approach[i]; }
|
||||
int GetApproachInfoCount(void) const { return m_approachCount; }
|
||||
void ComputeApproachAreas(void); // determine the set of "approach areas" - for map learning
|
||||
|
||||
// A* pathfinding algorithm
|
||||
static void MakeNewMarker(void)
|
||||
{
|
||||
IMPL(m_masterMarker)++;
|
||||
++IMPL(m_masterMarker);
|
||||
if (IMPL(m_masterMarker) == 0)
|
||||
IMPL(m_masterMarker) = 1;
|
||||
}
|
||||
void Mark(void)
|
||||
{
|
||||
m_marker = IMPL(m_masterMarker);
|
||||
}
|
||||
BOOL IsMarked(void) const
|
||||
{
|
||||
return (m_marker == IMPL(m_masterMarker)) ? true : false;
|
||||
}
|
||||
void SetParent(CNavArea *parent, NavTraverseType how = NUM_TRAVERSE_TYPES)
|
||||
{
|
||||
m_parent = parent;
|
||||
m_parentHow = how;
|
||||
}
|
||||
CNavArea *GetParent(void) const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
NavTraverseType GetParentHow(void) const
|
||||
{
|
||||
return m_parentHow;
|
||||
}
|
||||
void Mark(void) { m_marker = IMPL(m_masterMarker); }
|
||||
BOOL IsMarked(void) const { return (m_marker == IMPL(m_masterMarker)) ? true : false; }
|
||||
void SetParent(CNavArea *parent, NavTraverseType how = NUM_TRAVERSE_TYPES) { m_parent = parent; m_parentHow = how; }
|
||||
CNavArea *GetParent(void) const { return m_parent; }
|
||||
NavTraverseType GetParentHow(void) const { return m_parentHow; }
|
||||
|
||||
bool IsOpen(void) const; // true if on "open list"
|
||||
void AddToOpenList(void); // add to open list in decreasing value order
|
||||
@ -463,22 +397,10 @@ public:
|
||||
|
||||
static void ClearSearchLists(void); // clears the open and closed lists for a new search
|
||||
|
||||
void SetTotalCost(float value)
|
||||
{
|
||||
m_totalCost = value;
|
||||
}
|
||||
float GetTotalCost(void) const
|
||||
{
|
||||
return m_totalCost;
|
||||
}
|
||||
void SetCostSoFar(float value)
|
||||
{
|
||||
m_costSoFar = value;
|
||||
}
|
||||
float GetCostSoFar(void) const
|
||||
{
|
||||
return m_costSoFar;
|
||||
}
|
||||
void SetTotalCost(float value) { m_totalCost = value; }
|
||||
float GetTotalCost(void) const { return m_totalCost; }
|
||||
void SetCostSoFar(float value) { m_costSoFar = value; }
|
||||
float GetCostSoFar(void) const { return m_costSoFar; }
|
||||
|
||||
// editing
|
||||
void Draw(byte red, byte green, byte blue, int duration = 50); // draw area for debugging & editing
|
||||
@ -490,18 +412,10 @@ public:
|
||||
void RaiseCorner(NavCornerType corner, int amount); // raise/lower a corner (or all corners if corner == NUM_CORNERS)
|
||||
|
||||
// ladders
|
||||
void AddLadderUp(CNavLadder *ladder)
|
||||
{
|
||||
m_ladder[LADDER_UP].push_back(ladder);
|
||||
}
|
||||
void AddLadderDown(CNavLadder *ladder)
|
||||
{
|
||||
m_ladder[LADDER_DOWN].push_back(ladder);
|
||||
}
|
||||
void AddLadderUp(CNavLadder *ladder) { m_ladder[LADDER_UP].push_back(ladder); }
|
||||
void AddLadderDown(CNavLadder *ladder) { m_ladder[LADDER_DOWN].push_back(ladder); }
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
public:
|
||||
#else
|
||||
#ifndef HOOK_GAMEDLL
|
||||
private:
|
||||
#endif // HOOK_GAMEDLL
|
||||
friend void ConnectGeneratedAreas(void);
|
||||
@ -602,6 +516,7 @@ inline CNavArea *CNavArea::GetAdjacentArea(NavDirType dir, int i) const
|
||||
return (*iter).area;
|
||||
--i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1151,7 +1066,7 @@ void SearchSurroundingAreas(CNavArea *startArea, const Vector *startPos, Functor
|
||||
|
||||
// check up ladders
|
||||
const NavLadderList *ladderList = area->GetLadderList(LADDER_UP);
|
||||
if (ladderList)
|
||||
if (ladderList != NULL)
|
||||
{
|
||||
for (ladderIt = ladderList->begin(); ladderIt != ladderList->end(); ++ladderIt)
|
||||
{
|
||||
@ -1172,7 +1087,7 @@ void SearchSurroundingAreas(CNavArea *startArea, const Vector *startPos, Functor
|
||||
|
||||
// check down ladders
|
||||
ladderList = area->GetLadderList(LADDER_DOWN);
|
||||
if (ladderList)
|
||||
if (ladderList != NULL)
|
||||
{
|
||||
for (ladderIt = ladderList->begin(); ladderIt != ladderList->end(); ++ladderIt)
|
||||
{
|
||||
@ -1185,23 +1100,26 @@ void SearchSurroundingAreas(CNavArea *startArea, const Vector *startPos, Functor
|
||||
}
|
||||
|
||||
// Apply the functor to all navigation areas
|
||||
// If functor returns false, stop processing and return false.
|
||||
|
||||
/* <4c4137> ../game_shared/bot/nav_area.h:1109 */
|
||||
template <typename Functor>
|
||||
void ForAllAreas(Functor &func)
|
||||
bool ForAllAreas(Functor &func)
|
||||
{
|
||||
NavAreaList::iterator iter;
|
||||
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
|
||||
{
|
||||
CNavArea *area = *iter;
|
||||
func(area);
|
||||
if (func(area) == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fuctor that returns lowest cost for farthest away areas
|
||||
// For use with FindMinimumCostArea()
|
||||
|
||||
class FarAwayFunctor NOXREF
|
||||
NOXREF class FarAwayFunctor
|
||||
{
|
||||
public:
|
||||
float operator()(CNavArea *area, CNavArea *fromArea, const CNavLadder *ladder)
|
||||
@ -1209,7 +1127,7 @@ public:
|
||||
if (area == fromArea)
|
||||
return 9999999.9f;
|
||||
|
||||
return 1.0f/(*fromArea->GetCenter() - *area->GetCenter()).Length();
|
||||
return 1.0f / (*fromArea->GetCenter() - *area->GetCenter()).Length();
|
||||
}
|
||||
};
|
||||
|
||||
@ -1275,9 +1193,11 @@ CNavArea *FindMinimumCostArea(CNavArea *startArea, CostFunctor &costFunc)
|
||||
{
|
||||
// replace most expensive cost if this is cheaper
|
||||
int expensive = 0;
|
||||
for (int i = 1; i < NUM_CHEAP_AREAS; i++)
|
||||
for (int i = 1; i < NUM_CHEAP_AREAS; ++i)
|
||||
{
|
||||
if (cheapAreaSet[i].cost > cheapAreaSet[expensive].cost)
|
||||
expensive = i;
|
||||
}
|
||||
|
||||
if (cheapAreaSet[expensive].cost > cost)
|
||||
{
|
||||
@ -1299,8 +1219,10 @@ CNavArea *FindMinimumCostArea(CNavArea *startArea, CostFunctor &costFunc)
|
||||
|
||||
NavAreaList::iterator iter;
|
||||
for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
|
||||
{
|
||||
if (which-- == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return *iter;
|
||||
}
|
||||
@ -1386,9 +1308,4 @@ void BuildLadders(void);
|
||||
void MarkJumpAreas(void);
|
||||
void GenerateNavigationAreaMesh(void);
|
||||
|
||||
//refs
|
||||
extern float (*pGetZ__Vector)(const Vector *pos);
|
||||
extern CNavArea *(*pGetNearestNavArea)(const Vector *pos, bool anyZ);
|
||||
extern CNavArea *(*pGetNavArea)(const Vector *pos, float beneathLimit);
|
||||
|
||||
#endif // NAV_AREA_H
|
||||
|
@ -16,15 +16,21 @@ char s_shared_quote;
|
||||
#endif // HOOK_GAMEDLL
|
||||
|
||||
/* <2d4a66> ../game_shared/shared_util.cpp:50 */
|
||||
NOBODY uchar32 *SharedWVarArgs(uchar32 *format, ...)
|
||||
NOXREF wchar_t *SharedWVarArgs(wchar_t *format, ...)
|
||||
{
|
||||
// {
|
||||
// va_list argptr; // 52
|
||||
// intconst BufLen; // 53
|
||||
// intconst NumBuffers; // 54
|
||||
// wchar_t string; // 55
|
||||
// int curstring; // 56
|
||||
// }
|
||||
va_list argptr;
|
||||
const int BufLen = 1024;
|
||||
const int NumBuffers = 4;
|
||||
static wchar_t string[NumBuffers][BufLen];
|
||||
static int curstring = 0;
|
||||
|
||||
curstring = (curstring + 1) % NumBuffers;
|
||||
|
||||
va_start(argptr, format);
|
||||
Q_vsnwprintf(string[curstring], BufLen, format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
return string[curstring];
|
||||
}
|
||||
|
||||
/* <2d4b0a> ../game_shared/shared_util.cpp:68 */
|
||||
@ -59,27 +65,39 @@ char *BufPrintf(char *buf, int &len, const char *fmt, ...)
|
||||
len -= Q_strlen(buf);
|
||||
return buf + Q_strlen(buf);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* <2d4c0d> ../game_shared/shared_util.cpp:106 */
|
||||
NOBODY uchar32 *BufWPrintf(uchar32 *buf, int &len, const uchar32 *fmt, ...)
|
||||
wchar_t *BufWPrintf(wchar_t *buf, int &len, const wchar_t *fmt, ...)
|
||||
{
|
||||
// {
|
||||
// va_list argptr; // 111
|
||||
// }
|
||||
if (len <= 0)
|
||||
return NULL;
|
||||
|
||||
va_list argptr;
|
||||
|
||||
va_start(argptr, fmt);
|
||||
Q_vsnwprintf(buf, len, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
len -= wcslen(buf);
|
||||
return buf + wcslen(buf);
|
||||
}
|
||||
|
||||
/* <2d4c7e> ../game_shared/shared_util.cpp:122 */
|
||||
NOBODY const uchar32 *NumAsWString(int val)
|
||||
NOXREF const wchar_t *NumAsWString(int val)
|
||||
{
|
||||
// {
|
||||
// intconst BufLen; // 124
|
||||
// intconst NumBuffers; // 125
|
||||
// wchar_t string; // 126
|
||||
// int curstring; // 127
|
||||
// int len; // 131
|
||||
// }
|
||||
const int BufLen = 16;
|
||||
const int NumBuffers = 4;
|
||||
static wchar_t string[NumBuffers][BufLen];
|
||||
static int curstring = 0;
|
||||
|
||||
curstring = (curstring + 1) % NumBuffers;
|
||||
|
||||
int len = BufLen;
|
||||
BufWPrintf(string[curstring], len, L"%d", val);
|
||||
return string[curstring];
|
||||
}
|
||||
|
||||
/* <2d4d11> ../game_shared/shared_util.cpp:137 */
|
||||
@ -118,22 +136,99 @@ NOXREF void SharedSetQuoteChar(char c)
|
||||
// Parse a token out of a string
|
||||
|
||||
/* <2d4de7> ../game_shared/shared_util.cpp:173 */
|
||||
NOBODY const char *SharedParse(const char *data)
|
||||
const char *SharedParse(const char *data)
|
||||
{
|
||||
//
|
||||
//skipwhite: // 185
|
||||
// {
|
||||
// int c; // 175
|
||||
// int len; // 176
|
||||
// }
|
||||
int c;
|
||||
int len;
|
||||
|
||||
len = 0;
|
||||
s_shared_token[0] = '\0';
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
// skip whitespace
|
||||
skipwhite:
|
||||
while ((c = *data) <= ' ')
|
||||
{
|
||||
if (c == 0)
|
||||
{
|
||||
// end of file;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data++;
|
||||
}
|
||||
|
||||
// skip // comments
|
||||
if (c == '/' && data[1] == '/')
|
||||
{
|
||||
while (*data && *data != '\n')
|
||||
data++;
|
||||
|
||||
goto skipwhite;
|
||||
}
|
||||
|
||||
// handle quoted strings specially
|
||||
if (c == s_shared_quote)
|
||||
{
|
||||
data++;
|
||||
|
||||
while (true)
|
||||
{
|
||||
c = *data++;
|
||||
if (c == s_shared_quote || !c)
|
||||
{
|
||||
s_shared_token[len] = '\0';
|
||||
return data;
|
||||
}
|
||||
|
||||
s_shared_token[len] = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
// parse single characters
|
||||
if (c == '{' || c == '}'|| c == ')'|| c == '(' || c == '\'' || c == ',')
|
||||
{
|
||||
s_shared_token[len] = c;
|
||||
len++;
|
||||
s_shared_token[len] = '\0';
|
||||
return data + 1;
|
||||
}
|
||||
|
||||
// parse a regular word
|
||||
do
|
||||
{
|
||||
s_shared_token[len] = c;
|
||||
data++;
|
||||
len++;
|
||||
c = *data;
|
||||
|
||||
if (c == '{' || c == '}'|| c == ')'|| c == '(' || c == '\'' || c == ',')
|
||||
break;
|
||||
|
||||
} while (c > 32);
|
||||
|
||||
s_shared_token[len] = '\0';
|
||||
return data;
|
||||
}
|
||||
|
||||
// Returns true if additional data is waiting to be processed on this line
|
||||
|
||||
/* <2d4e40> ../game_shared/shared_util.cpp:247 */
|
||||
NOBODY bool SharedTokenWaiting(const char *buffer)
|
||||
NOXREF bool SharedTokenWaiting(const char *buffer)
|
||||
{
|
||||
// {
|
||||
// const char *p; // 249
|
||||
// }
|
||||
const char *p;
|
||||
|
||||
p = buffer;
|
||||
while (*p && *p!='\n')
|
||||
{
|
||||
if (!isspace(*p) || isalnum(*p))
|
||||
return true;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -32,6 +32,11 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef HOOK_GAMEDLL
|
||||
|
||||
#define s_shared_token (*ps_shared_token)
|
||||
@ -42,16 +47,18 @@
|
||||
extern char s_shared_token[ 1500 ];
|
||||
extern char s_shared_quote;
|
||||
|
||||
NOBODY uchar32 *SharedWVarArgs(uchar32 *format, ...);
|
||||
NOXREF wchar_t *SharedWVarArgs(wchar_t *format, ...);
|
||||
char *SharedVarArgs(char *format, ...);
|
||||
char *BufPrintf(char *buf, int &len, const char *fmt, ...);
|
||||
NOBODY uchar32 *BufWPrintf(uchar32 *buf, int &len, const uchar32 *fmt, ...);
|
||||
NOBODY const uchar32 *NumAsWString(int val);
|
||||
NOXREF wchar_t *BufWPrintf(wchar_t *buf, int &len, const wchar_t *fmt, ...);
|
||||
NOXREF const wchar_t *NumAsWString(int val);
|
||||
const char *NumAsString(int val);
|
||||
char *SharedGetToken(void);
|
||||
NOXREF void SharedSetQuoteChar(char c);
|
||||
NOBODY const char *SharedParse(const char *data);
|
||||
NOBODY bool SharedTokenWaiting(const char *buffer);
|
||||
const char *SharedParse(const char *data);
|
||||
NOXREF bool SharedTokenWaiting(const char *buffer);
|
||||
|
||||
// Simple utility function to allocate memory and duplicate a string
|
||||
|
||||
/* <db469> ../game_shared/shared_util.h:46 */
|
||||
inline char *CloneString(const char *str)
|
||||
@ -62,20 +69,26 @@ inline char *CloneString(const char *str)
|
||||
cloneStr[0] = '\0';
|
||||
return cloneStr;
|
||||
}
|
||||
|
||||
char *cloneStr = new char [Q_strlen(str) + 1];
|
||||
Q_strcpy(cloneStr, str);
|
||||
return cloneStr;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Simple utility function to allocate memory and duplicate a wide string
|
||||
|
||||
inline wchar_t *CloneWString(const wchar_t *str)
|
||||
{
|
||||
if (!str)
|
||||
{
|
||||
wchar_t *cloneStr = new wchar_t[1];
|
||||
cloneStr[0] = L'\0';
|
||||
return cloneStr;
|
||||
}
|
||||
|
||||
wchar_t *cloneStr = new wchar_t [wcslen(str) + 1];
|
||||
wcscpy(cloneStr, str);
|
||||
return cloneStr;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#endif // SHARED_UTIL
|
||||
|
@ -131,7 +131,7 @@ bool CVoiceGameMgr::ClientCommand(CBasePlayer *pPlayer, const char *cmd)
|
||||
bool bBan = Q_stricmp(cmd, "vban") == 0;
|
||||
if (bBan && CMD_ARGC() >= 2)
|
||||
{
|
||||
for (int i = 1; i < CMD_ARGC(); i++)
|
||||
for (int i = 1; i < CMD_ARGC(); ++i)
|
||||
{
|
||||
uint32 mask = 0;
|
||||
sscanf(CMD_ARGV(i), "%x", &mask);
|
||||
@ -145,6 +145,8 @@ bool CVoiceGameMgr::ClientCommand(CBasePlayer *pPlayer, const char *cmd)
|
||||
VoiceServerDebug("CVoiceGameMgr::ClientCommand: invalid index (%d)\n", i);
|
||||
}
|
||||
|
||||
// Force it to update the masks now.
|
||||
//UpdateMasks();
|
||||
return true;
|
||||
}
|
||||
else if (Q_stricmp(cmd, "VModEnable") == 0 && CMD_ARGC() >= 2)
|
||||
@ -153,7 +155,7 @@ bool CVoiceGameMgr::ClientCommand(CBasePlayer *pPlayer, const char *cmd)
|
||||
|
||||
g_PlayerModEnable[ playerClientIndex ] = !!Q_atoi(CMD_ARGV(1));
|
||||
g_bWantModEnable[ playerClientIndex ] = false;
|
||||
|
||||
//UpdateMasks();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -167,7 +169,7 @@ void CVoiceGameMgr::UpdateMasks(void)
|
||||
|
||||
bool bAllTalk = !!(sv_alltalk.value);
|
||||
|
||||
for (int iClient = 0; iClient < m_nMaxPlayers; iClient++)
|
||||
for (int iClient = 0; iClient < m_nMaxPlayers; ++iClient)
|
||||
{
|
||||
CBaseEntity *pEnt = UTIL_PlayerByIndex(iClient + 1);
|
||||
|
||||
@ -191,7 +193,7 @@ void CVoiceGameMgr::UpdateMasks(void)
|
||||
if (g_PlayerModEnable[ iClient ])
|
||||
{
|
||||
// Build a mask of who they can hear based on the game rules.
|
||||
for (int iOtherClient = 0; iOtherClient < m_nMaxPlayers; iOtherClient++)
|
||||
for (int iOtherClient = 0; iOtherClient < m_nMaxPlayers; ++iOtherClient)
|
||||
{
|
||||
CBaseEntity *pEnt = UTIL_PlayerByIndex(iOtherClient + 1);
|
||||
|
||||
@ -209,7 +211,7 @@ void CVoiceGameMgr::UpdateMasks(void)
|
||||
g_SentBanMasks[ iClient ] = g_BanMasks[ iClient ];
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, m_msgPlayerVoiceMask, NULL, pPlayer->pev);
|
||||
for (int dw = 0; dw < VOICE_MAX_PLAYERS_DW; dw++)
|
||||
for (int dw = 0; dw < VOICE_MAX_PLAYERS_DW; ++dw)
|
||||
{
|
||||
WRITE_LONG(gameRulesMask.GetDWord(dw));
|
||||
WRITE_LONG(g_BanMasks[ iClient ].GetDWord(dw));
|
||||
@ -218,7 +220,7 @@ void CVoiceGameMgr::UpdateMasks(void)
|
||||
}
|
||||
|
||||
// Tell the engine.
|
||||
for (int iOtherClient = 0; iOtherClient < m_nMaxPlayers; iOtherClient++)
|
||||
for (int iOtherClient = 0; iOtherClient < m_nMaxPlayers; ++iOtherClient)
|
||||
{
|
||||
bool bCanHear = gameRulesMask[ iOtherClient ] && !g_BanMasks[ iClient ][ iOtherClient ];
|
||||
SET_CLIENT_LISTENING(iClient + 1, iOtherClient + 1, bCanHear);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "iterator"
|
||||
#include "xutility"
|
||||
#include "memory"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -142,14 +143,14 @@ public:
|
||||
{erase(begin(), end());
|
||||
insert(begin(), _N, _X); }
|
||||
iterator insert(iterator _P, const _Ty& _X = _Ty())
|
||||
{size_type _O = _P - begin();
|
||||
{size_type _O = size_type(_P - begin());
|
||||
insert(_P, 1, _X);
|
||||
return (begin() + _O); }
|
||||
void insert(iterator _P, size_type _M, const _Ty& _X)
|
||||
{if (_End - _Last < _M)
|
||||
{if (size_type(_End - _Last) < _M)
|
||||
{size_type _N = size() + (_M < size() ? size() : _M);
|
||||
iterator_ _S = allocator.allocate(_N, (void *)0);
|
||||
iterator_ _Q = _Ucopy(_First, _P, _S);
|
||||
iterator _S = allocator.allocate(_N, (void *)0);
|
||||
iterator _Q = _Ucopy(_First, _P, _S);
|
||||
_Ufill(_Q, _M, _X);
|
||||
_Ucopy(_P, _Last, _Q + _M);
|
||||
__Destroy(_First, _Last);
|
||||
@ -157,7 +158,7 @@ public:
|
||||
_End = _S + _N;
|
||||
_Last = _S + size() + _M;
|
||||
_First = _S; }
|
||||
else if (_Last - _P < _M)
|
||||
else if (size_type(_Last - _P) < _M)
|
||||
{_Ucopy(_P, _Last, _P + _M);
|
||||
_Ufill(_Last, _M - (_Last - _P), _X);
|
||||
fill_(_P, _Last, _X);
|
||||
@ -172,8 +173,8 @@ public:
|
||||
__Distance(_F, _L, _M);
|
||||
if (_End - _Last < _M)
|
||||
{size_type _N = size() + (_M < size() ? size() : _M);
|
||||
iterator_ _S = allocator.allocate(_N, (void *)0);
|
||||
iterator_ _Q = _Ucopy(_First, _P, _S);
|
||||
iterator _S = allocator.allocate(_N, (void *)0);
|
||||
iterator _Q = _Ucopy(_First, _P, _S);
|
||||
_Q = _Ucopy(_F, _L, _Q);
|
||||
_Ucopy(_P, _Last, _Q);
|
||||
__Destroy(_First, _Last);
|
||||
@ -197,7 +198,7 @@ public:
|
||||
--_Last;
|
||||
return (_P); }
|
||||
iterator erase(iterator _F, iterator _L)
|
||||
{iterator_ _S = copy_(_L, end(), _F);
|
||||
{iterator _S = copy_(_L, end(), _F);
|
||||
__Destroy(_S, end());
|
||||
_Last = _S;
|
||||
return (_F); }
|
||||
|
@ -838,6 +838,7 @@
|
||||
<ClInclude Include="..\extra\IDA structures\goldsource.h" />
|
||||
<ClInclude Include="..\game_shared\bitvec.h" />
|
||||
<ClInclude Include="..\game_shared\bot\bot.h" />
|
||||
<ClInclude Include="..\game_shared\bot\bot_constants.h" />
|
||||
<ClInclude Include="..\game_shared\bot\bot_manager.h" />
|
||||
<ClInclude Include="..\game_shared\bot\bot_profile.h" />
|
||||
<ClInclude Include="..\game_shared\bot\bot_util.h" />
|
||||
@ -1168,7 +1169,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>CSTRIKE;REGAMEDLL_SELF;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;DEDICATED;_CRT_SECURE_NO_WARNINGS;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>CSTRIKE;REGAMEDLL_ADD;REGAMEDLL_FIXES;REGAMEDLL_SELF;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;DEDICATED;_CRT_SECURE_NO_WARNINGS;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
@ -1204,7 +1205,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>REGAMEDLL_SELF;PLAY_GAMEDLL;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;DEDICATED;_CRT_SECURE_NO_WARNINGS;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>CSTRIKE;REGAMEDLL_SELF;PLAY_GAMEDLL;REGAMEDLL_CHECKS;CLIENT_WEAPONS;USE_BREAKPAD_HANDLER;DEDICATED;_CRT_SECURE_NO_WARNINGS;_DEBUG;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<AdditionalOptions>/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
|
@ -1136,6 +1136,9 @@
|
||||
<ClInclude Include="..\public\tier0\platform.h">
|
||||
<Filter>public\tier0</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\game_shared\bot\bot_constants.h">
|
||||
<Filter>game_shared\bot</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\linux\appversion.sh">
|
||||
|
@ -43,4 +43,9 @@ char *_strdup_mhook_(const char *s)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int __cdecl _rand_mhook_()
|
||||
{
|
||||
return CRegamedllPlatformHolder::get()->rand();
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
@ -12,6 +12,7 @@ void _free_mhook_(void *p);
|
||||
void *_calloc_mhook_(size_t n, size_t s);
|
||||
void *__nh_malloc_mhook_(size_t n);
|
||||
char *_strdup_mhook_(const char *s);
|
||||
int __cdecl _rand_mhook_();
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
|
@ -62,6 +62,8 @@ TEST(StructOffsets, ReversingChecks, 5000)
|
||||
REPEAT_SIZEOF_PRINT(CCareerTaskManager);
|
||||
REPEAT_SIZEOF_PRINT(CCareerTask);
|
||||
REPEAT_SIZEOF_PRINT(CPreventDefuseTask);
|
||||
|
||||
REPEAT_SIZEOF_PRINT(BotStatement);
|
||||
|
||||
// offset the members
|
||||
REPEAT_OFFSETOF_PRINT(CBaseEntity, pev);
|
||||
@ -99,7 +101,8 @@ TEST(StructOffsets, ReversingChecks, 5000)
|
||||
//CHECK_CLASS_SIZE(CBotManager, 12u, 12);
|
||||
CHECK_CLASS_SIZE(CCSBot, 11404, 11424);
|
||||
//CHECK_CLASS_SIZE(CCSBotManager, 740, 0x2E0u);//0x2E4u | 0x2E0u
|
||||
|
||||
|
||||
CHECK_CLASS_SIZE(BotStatement, 0x70u, 0x70u);
|
||||
//CHECK_CLASS_SIZE(HostageStateMachine, 0x10, 0x10);
|
||||
//CHECK_CLASS_SIZE(HostageFollowState, 0x4C, 0x4C);
|
||||
//CHECK_CLASS_SIZE(CCSBot, 0x2CA0, 0x2CA0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user