Bots are now able to destroy random breakables around him, without touching them.
Added cvars descriptions and yapb.cfg generation. Finally fixed bomb-defuse problems. Fixed unaligned access in bot compression/decompression. Fixed low-fps aim code falure.
This commit is contained in:
parent
ef1faabfe6
commit
91c4d9ce1f
21 changed files with 523 additions and 293 deletions
|
|
@ -73,6 +73,7 @@ private:
|
|||
int cmdNodeMenu ();
|
||||
int cmdMenu ();
|
||||
int cmdList ();
|
||||
int cmdCvars ();
|
||||
int cmdNode ();
|
||||
int cmdNodeOn ();
|
||||
int cmdNodeOff ();
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ namespace detail {
|
|||
|
||||
// basic dictionary
|
||||
template <class K, class V, class H = StringHash <K>, size_t HashSize = 36> class Dictionary final : public DenyCopying {
|
||||
private:
|
||||
using DictBucket = detail::DictionaryBucket <K, V>;
|
||||
|
||||
public:
|
||||
enum : size_t {
|
||||
InvalidIndex = static_cast <size_t> (-1)
|
||||
|
|
@ -73,7 +76,7 @@ public:
|
|||
|
||||
private:
|
||||
Array <detail::DictionaryList *> m_table;
|
||||
Array <detail::DictionaryBucket <K, V>> m_buckets;
|
||||
Array <DictBucket> m_buckets;
|
||||
H m_hasher;
|
||||
|
||||
private:
|
||||
|
|
@ -226,19 +229,19 @@ public:
|
|||
|
||||
// for range-based loops
|
||||
public:
|
||||
detail::DictionaryBucket <K, V> *begin () {
|
||||
DictBucket *begin () {
|
||||
return m_buckets.begin ();
|
||||
}
|
||||
|
||||
detail::DictionaryBucket <K, V> *begin () const {
|
||||
DictBucket *begin () const {
|
||||
return m_buckets.begin ();
|
||||
}
|
||||
|
||||
detail::DictionaryBucket <K, V> *end () {
|
||||
DictBucket *end () {
|
||||
return m_buckets.end ();
|
||||
}
|
||||
|
||||
detail::DictionaryBucket <K, V> *end () const {
|
||||
DictBucket *end () const {
|
||||
return m_buckets.end ();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -90,11 +90,11 @@ public:
|
|||
return fprintf (m_handle, fmt, cr::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
bool puts (const String &buffer) {
|
||||
bool puts (const char *buffer) {
|
||||
if (!*this) {
|
||||
return 0;
|
||||
}
|
||||
if (fputs (buffer.chars (), m_handle) < 0) {
|
||||
if (fputs (buffer, m_handle) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ public:
|
|||
|
||||
public:
|
||||
bool patch (void *address, void *replacement) {
|
||||
if (plat.isArm) {
|
||||
return false;
|
||||
}
|
||||
uint8 *ptr = reinterpret_cast <uint8 *> (address);
|
||||
|
||||
while (*reinterpret_cast <uint16 *> (ptr) == 0x25ff) {
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@ CR_NAMESPACE_BEGIN
|
|||
# define CR_ARCH_X86
|
||||
#endif
|
||||
|
||||
#if defined(__arm__)
|
||||
# define CR_ARCH_ARM
|
||||
# if defined(__aarch64__)
|
||||
# define CR_ARCH_ARM64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (defined(CR_ARCH_X86) || defined(CR_ARCH_X64)) && !defined(CR_DEBUG)
|
||||
# define CR_HAS_SSE2
|
||||
#endif
|
||||
|
|
@ -85,6 +92,7 @@ struct Platform : public Singleton <Platform> {
|
|||
bool isAndroid = false;
|
||||
bool isAndroidHardFP = false;
|
||||
bool isX64 = false;
|
||||
bool isArm = false;
|
||||
|
||||
Platform () {
|
||||
#if defined(CR_WINDOWS)
|
||||
|
|
@ -94,22 +102,27 @@ struct Platform : public Singleton <Platform> {
|
|||
#if defined(CR_ANDROID)
|
||||
isAndroid = true;
|
||||
|
||||
# if defined (CR_ANDROID_HARD_FP)
|
||||
# if defined (CR_ANDROID_HARD_FP)
|
||||
isAndroidHardFP = true;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(CR_LINUX)
|
||||
isLinux = true;
|
||||
#endif
|
||||
|
||||
#if defined (CR_OSX)
|
||||
#if defined(CR_OSX)
|
||||
isOSX = true;
|
||||
#endif
|
||||
|
||||
#if defined (CR_ARCH_X64)
|
||||
#if defined(CR_ARCH_X64) || defined(CR_ARCH_ARM64)
|
||||
isX64 = true;
|
||||
#endif
|
||||
|
||||
#if defined(CR_ARCH_ARM)
|
||||
isArm = true;
|
||||
isAndroid = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// helper platform-dependant functions
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public:
|
|||
for (auto &htb : m_hashTable) {
|
||||
htb = EmptyHash;
|
||||
}
|
||||
uint8 *op = out;
|
||||
auto op = out;
|
||||
|
||||
int32 anchor = 0;
|
||||
int32 cur = 0;
|
||||
|
|
@ -99,9 +99,9 @@ public:
|
|||
}
|
||||
|
||||
if (bestLength >= MinMatch && bestLength < maxMatch && (cur - anchor) != 6) {
|
||||
const int32 next = cur + 1;
|
||||
const int32 target = bestLength + 1;
|
||||
const int32 limit = cr::max <int32> (next - WindowSize, EmptyHash);
|
||||
const auto next = cur + 1;
|
||||
const auto target = bestLength + 1;
|
||||
const auto limit = cr::max <int32> (next - WindowSize, EmptyHash);
|
||||
|
||||
int32 chainLength = MaxChain;
|
||||
int32 lookup = m_hashTable[hash32 (&in[next])];
|
||||
|
|
@ -128,11 +128,11 @@ public:
|
|||
}
|
||||
|
||||
if (bestLength >= MinMatch) {
|
||||
const int32 length = bestLength - MinMatch;
|
||||
const int32 token = ((dist >> 12) & 16) + cr::min <int32> (length, 15);
|
||||
const auto length = bestLength - MinMatch;
|
||||
const auto token = ((dist >> 12) & 16) + cr::min <int32> (length, 15);
|
||||
|
||||
if (anchor != cur) {
|
||||
const int32 run = cur - anchor;
|
||||
const auto run = cur - anchor;
|
||||
|
||||
if (run >= 7) {
|
||||
add (op, (7 << 5) + token);
|
||||
|
|
@ -155,7 +155,7 @@ public:
|
|||
op += 2;
|
||||
|
||||
while (bestLength-- != 0) {
|
||||
const uint32 hash = hash32 (&in[cur]);
|
||||
const auto hash = hash32 (&in[cur]);
|
||||
|
||||
m_prevTable[cur & WindowMask] = m_hashTable[hash];
|
||||
m_hashTable[hash] = cur++;
|
||||
|
|
@ -163,7 +163,7 @@ public:
|
|||
anchor = cur;
|
||||
}
|
||||
else {
|
||||
const uint32 hash = hash32 (&in[cur]);
|
||||
const auto hash = hash32 (&in[cur]);
|
||||
|
||||
m_prevTable[cur & WindowMask] = m_hashTable[hash];
|
||||
m_hashTable[hash] = cur++;
|
||||
|
|
@ -171,7 +171,7 @@ public:
|
|||
}
|
||||
|
||||
if (anchor != cur) {
|
||||
const int32 run = cur - anchor;
|
||||
const auto run = cur - anchor;
|
||||
|
||||
if (run >= 7) {
|
||||
add (op, 7 << 5);
|
||||
|
|
@ -187,17 +187,17 @@ public:
|
|||
}
|
||||
|
||||
int32 uncompress (uint8 *in, int32 inputLength, uint8 *out, int32 outLength) {
|
||||
uint8 *op = out;
|
||||
uint8 *ip = in;
|
||||
auto op = out;
|
||||
auto ip = in;
|
||||
|
||||
const uint8 *opEnd = op + outLength;
|
||||
const uint8 *ipEnd = ip + inputLength;
|
||||
const auto opEnd = op + outLength;
|
||||
const auto ipEnd = ip + inputLength;
|
||||
|
||||
while (ip < ipEnd) {
|
||||
const int32 token = *ip++;
|
||||
const auto token = *ip++;
|
||||
|
||||
if (token >= 32) {
|
||||
int32 run = token >> 5;
|
||||
auto run = token >> 5;
|
||||
|
||||
if (run == 7) {
|
||||
run += decode (ip);
|
||||
|
|
@ -215,7 +215,7 @@ public:
|
|||
break;
|
||||
}
|
||||
}
|
||||
int32 length = (token & 15) + MinMatch;
|
||||
auto length = (token & 15) + MinMatch;
|
||||
|
||||
if (length == (15 + MinMatch)) {
|
||||
length += decode (ip);
|
||||
|
|
@ -224,10 +224,10 @@ public:
|
|||
if ((opEnd - op) < length) {
|
||||
return UncompressFailure;
|
||||
}
|
||||
const int32 dist = ((token & 16) << 12) + load16 (ip);
|
||||
const auto dist = ((token & 16) << 12) + load16 (ip);
|
||||
ip += 2;
|
||||
|
||||
uint8 *cp = op - dist;
|
||||
auto cp = op - dist;
|
||||
|
||||
if ((op - out) < dist) {
|
||||
return UncompressFailure;
|
||||
|
|
@ -237,8 +237,7 @@ public:
|
|||
copy (op, cp, length);
|
||||
op += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
for (int32 i = 0; i < 4; ++i) {
|
||||
*op++ = *cp++;
|
||||
}
|
||||
|
|
@ -252,27 +251,33 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
inline uint16 load16 (void *ptr) {
|
||||
return *reinterpret_cast <const uint16 *> (ptr);
|
||||
uint16 load16 (void *ptr) {
|
||||
uint16 ret;
|
||||
memcpy (&ret, ptr, sizeof (uint16));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline uint32 load32 (void *ptr) {
|
||||
return *reinterpret_cast <const uint32 *> (ptr);
|
||||
uint32 load32 (void *ptr) {
|
||||
uint32 ret;
|
||||
memcpy (&ret, ptr, sizeof (uint32));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void store16 (void *ptr, int32 val) {
|
||||
*reinterpret_cast <uint16 *> (ptr) = static_cast <uint16> (val);
|
||||
void store16 (void *ptr, int32 val) {
|
||||
memcpy (ptr, &val, sizeof (uint16));
|
||||
}
|
||||
|
||||
inline void copy64 (void *dst, void *src) {
|
||||
*reinterpret_cast <uint64 *> (dst) = *reinterpret_cast <const uint64 *> (src);
|
||||
void copy64 (void *dst, void *src) {
|
||||
memcpy (dst, src, sizeof (uint64));
|
||||
}
|
||||
|
||||
inline uint32 hash32 (void *ptr) {
|
||||
return (load32 (ptr) * 0x9E3779B9) >> (32 - HashBits);
|
||||
uint32 hash32 (void *ptr) {
|
||||
return (load32 (ptr) * 0x9e3779b9) >> (32 - HashBits);
|
||||
}
|
||||
|
||||
inline void copy (uint8 *dst, uint8 *src, int32 count) {
|
||||
void copy (uint8 *dst, uint8 *src, int32 count) {
|
||||
copy64 (dst, src);
|
||||
|
||||
for (int32 i = 8; i < count; i += 8) {
|
||||
|
|
@ -280,11 +285,11 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
inline void add (uint8 *&dst, int32 val) {
|
||||
void add (uint8 *&dst, int32 val) {
|
||||
*dst++ = static_cast <uint8> (val);
|
||||
}
|
||||
|
||||
inline void encode (uint8 *&ptr, uint32 val) {
|
||||
void encode (uint8 *&ptr, uint32 val) {
|
||||
while (val >= 128) {
|
||||
val -= 128;
|
||||
|
||||
|
|
@ -294,7 +299,7 @@ private:
|
|||
*ptr++ = static_cast <uint8> (val);
|
||||
}
|
||||
|
||||
inline uint32 decode (uint8 *&ptr) {
|
||||
uint32 decode (uint8 *&ptr) {
|
||||
uint32 val = 0;
|
||||
|
||||
for (int32 i = 0; i <= 21; i += 7) {
|
||||
|
|
@ -309,6 +314,4 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
CR_NAMESPACE_END
|
||||
|
|
@ -74,6 +74,9 @@ struct VarPair {
|
|||
bool missing;
|
||||
const char *regval;
|
||||
class ConVar *self;
|
||||
String info;
|
||||
float initial, min, max;
|
||||
bool bounded;
|
||||
};
|
||||
|
||||
// entity prototype
|
||||
|
|
@ -95,6 +98,7 @@ private:
|
|||
edict_t *m_startEntity;
|
||||
edict_t *m_localEntity;
|
||||
|
||||
Array <edict_t *> m_breakables;
|
||||
SmallArray <VarPair> m_cvars;
|
||||
SharedLibrary m_gameLib;
|
||||
|
||||
|
|
@ -137,10 +141,10 @@ public:
|
|||
const char *getMapName ();
|
||||
|
||||
// get the "any" entity origin
|
||||
Vector getAbsPos (edict_t *ent);
|
||||
Vector getEntityWorldOrigin (edict_t *ent);
|
||||
|
||||
// registers a server command
|
||||
void registerEngineCommand (const char *command, void func_ ());
|
||||
void registerEngineCommand (const char *command, void func ());
|
||||
|
||||
// play's sound to client
|
||||
void playSound (edict_t *ent, const char *sound);
|
||||
|
|
@ -149,7 +153,10 @@ public:
|
|||
void prepareBotArgs (edict_t *ent, String str);
|
||||
|
||||
// adds cvar to registration stack
|
||||
void addNewCvar (const char *variable, const char *value, Var varType, bool regMissing, const char *regVal, class ConVar *self);
|
||||
void addNewCvar (const char *name, const char *value, const char *info, bool bounded, float min, float max, Var varType, bool missingAction, const char *regval, class ConVar *self);
|
||||
|
||||
// check the cvar bounds
|
||||
void checkCvarsBounds ();
|
||||
|
||||
// sends local registration stack for engine registration
|
||||
void registerCvars (bool gameVars = false);
|
||||
|
|
@ -175,6 +182,9 @@ public:
|
|||
// search entities in sphere
|
||||
void searchEntities (const Vector &position, const float radius, EntitySearch functor);
|
||||
|
||||
// this function is checking that pointed by ent pointer obstacle, can be destroyed
|
||||
bool isShootableBreakable (edict_t *ent);
|
||||
|
||||
// public inlines
|
||||
public:
|
||||
// get the current time on server
|
||||
|
|
@ -294,6 +304,21 @@ public:
|
|||
return m_gameLib;
|
||||
}
|
||||
|
||||
// get registered cvars list
|
||||
const SmallArray <VarPair> &getCvars () {
|
||||
return m_cvars;
|
||||
}
|
||||
|
||||
// check if map has breakables
|
||||
const Array <edict_t *> &getBreakables () {
|
||||
return m_breakables;
|
||||
}
|
||||
|
||||
// map has breakables ?
|
||||
bool hasBreakables () const {
|
||||
return !m_breakables.empty ();
|
||||
}
|
||||
|
||||
// helper to sending the client message
|
||||
void sendClientMessage (bool console, edict_t *ent, const char *message);
|
||||
|
||||
|
|
@ -332,33 +357,41 @@ public:
|
|||
};
|
||||
|
||||
// simplify access for console variables
|
||||
class ConVar final {
|
||||
class ConVar final : public DenyCopying {
|
||||
public:
|
||||
cvar_t *eptr;
|
||||
cvar_t *ptr;
|
||||
|
||||
public:
|
||||
ConVar (const char *name, const char *initval, Var type = Var::NoServer, bool regMissing = false, const char *regVal = nullptr) : eptr (nullptr) {
|
||||
Game::get ().addNewCvar (name, initval, type, regMissing, regVal, this);
|
||||
ConVar () = delete;
|
||||
~ConVar () = default;
|
||||
|
||||
public:
|
||||
ConVar (const char *name, const char *initval, Var type = Var::NoServer, bool regMissing = false, const char *regVal = nullptr) : ptr (nullptr) {
|
||||
Game::get ().addNewCvar (name, initval, "", false, 0.0f, 0.0f, type, regMissing, regVal, this);
|
||||
}
|
||||
|
||||
ConVar (const char *name, const char *initval, const char *info, bool bounded = true, float min = 0.0f, float max = 1.0f, Var type = Var::NoServer, bool regMissing = false, const char *regVal = nullptr) : ptr (nullptr) {
|
||||
Game::get ().addNewCvar (name, initval, info, bounded, min, max, type, regMissing, regVal, this);
|
||||
}
|
||||
|
||||
bool bool_ () const {
|
||||
return eptr->value > 0.0f;
|
||||
return ptr->value > 0.0f;
|
||||
}
|
||||
|
||||
int int_ () const {
|
||||
return static_cast <int> (eptr->value);
|
||||
return static_cast <int> (ptr->value);
|
||||
}
|
||||
|
||||
float float_ () const {
|
||||
return eptr->value;
|
||||
return ptr->value;
|
||||
}
|
||||
|
||||
const char *str () const {
|
||||
return eptr->string;
|
||||
return ptr->string;
|
||||
}
|
||||
|
||||
void set (float val) {
|
||||
engfuncs.pfnCVarSetFloat (eptr->name, val);
|
||||
engfuncs.pfnCVarSetFloat (ptr->name, val);
|
||||
}
|
||||
|
||||
void set (int val) {
|
||||
|
|
@ -366,7 +399,7 @@ public:
|
|||
}
|
||||
|
||||
void set (const char *val) {
|
||||
engfuncs.pfnCvar_DirectSet (eptr, const_cast <char *> (val));
|
||||
engfuncs.pfnCvar_DirectSet (ptr, const_cast <char *> (val));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -541,7 +574,7 @@ public:
|
|||
};
|
||||
|
||||
// for android
|
||||
#if defined (CR_ANDROID)
|
||||
#if defined (CR_ANDROID) && defined(CR_ARCH_ARM)
|
||||
extern "C" void player (entvars_t *pev);
|
||||
#endif
|
||||
|
||||
|
|
@ -588,7 +621,7 @@ public:
|
|||
|
||||
public:
|
||||
void initialize () {
|
||||
if (plat.isAndroid) {
|
||||
if (plat.isArm) {
|
||||
return;
|
||||
}
|
||||
m_dlsym.patch (reinterpret_cast <void *> (&LookupSymbol), reinterpret_cast <void *> (&DynamicEntityLink::replacement));
|
||||
|
|
@ -596,7 +629,7 @@ public:
|
|||
}
|
||||
|
||||
EntityFunction getPlayerFunction () {
|
||||
#if defined (CR_ANDROID)
|
||||
#if defined (CR_ANDROID) && defined(CR_ARCH_ARM)
|
||||
return player;
|
||||
#else
|
||||
return reinterpret_cast <EntityFunction> (search (Game::get ().lib ().handle (), "player"));
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ private:
|
|||
|
||||
Vector m_learnVelocity;
|
||||
Vector m_learnPosition;
|
||||
Vector m_bombPos;
|
||||
Vector m_bombOrigin;
|
||||
Vector m_lastNode;
|
||||
|
||||
IntArray m_terrorPoints;
|
||||
|
|
@ -344,7 +344,7 @@ public:
|
|||
void initBuckets ();
|
||||
void addToBucket (const Vector &pos, int index);
|
||||
void eraseFromBucket (const Vector &pos, int index);
|
||||
void setBombPos (bool reset = false, const Vector &pos = nullptr);
|
||||
void setBombOrigin (bool reset = false, const Vector &pos = nullptr);
|
||||
void updateGlobalPractice ();
|
||||
void unassignPath (int from, int to);
|
||||
void setDangerValue (int team, int start, int goal, int value);
|
||||
|
|
@ -393,8 +393,8 @@ public:
|
|||
m_autoPathDistance = distance;
|
||||
}
|
||||
|
||||
const Vector &getBombPos () const {
|
||||
return m_bombPos;
|
||||
const Vector &getBombOrigin () const {
|
||||
return m_bombOrigin;
|
||||
}
|
||||
|
||||
// access paths
|
||||
|
|
|
|||
|
|
@ -118,11 +118,11 @@ public:
|
|||
bool kickRandom (bool decQuota = true, Team fromTeam = Team::Unassigned);
|
||||
|
||||
public:
|
||||
Array <edict_t *> &searchActiveGrenades () {
|
||||
const Array <edict_t *> &searchActiveGrenades () {
|
||||
return m_activeGrenades;
|
||||
}
|
||||
|
||||
Array <edict_t *> &searchIntrestingEntities () {
|
||||
const Array <edict_t *> &searchIntrestingEntities () {
|
||||
return m_intrestingEntities;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -268,13 +268,13 @@ CR_DECLARE_SCOPED_ENUM (Weapon,
|
|||
// buy counts
|
||||
CR_DECLARE_SCOPED_ENUM (BuyState,
|
||||
PrimaryWeapon = 0,
|
||||
ArmorVestHelm ,
|
||||
SecondaryWeapon,
|
||||
Grenades,
|
||||
DefusalKit,
|
||||
Ammo,
|
||||
NightVision,
|
||||
Done
|
||||
ArmorVestHelm,
|
||||
SecondaryWeapon,
|
||||
Grenades,
|
||||
DefusalKit,
|
||||
Ammo,
|
||||
NightVision,
|
||||
Done
|
||||
)
|
||||
|
||||
// economics limits
|
||||
|
|
@ -284,7 +284,7 @@ CR_DECLARE_SCOPED_ENUM (EcoLimit,
|
|||
SmgTEGreater,
|
||||
ShotgunGreater,
|
||||
ShotgunLess,
|
||||
HeavyGreater ,
|
||||
HeavyGreater,
|
||||
HeavyLess,
|
||||
ProstockNormal,
|
||||
ProstockRusher,
|
||||
|
|
@ -513,11 +513,17 @@ public:
|
|||
{ }
|
||||
};
|
||||
|
||||
// clients noise
|
||||
struct ClientNoise {
|
||||
Vector pos;
|
||||
float dist;
|
||||
float last;
|
||||
};
|
||||
|
||||
// array of clients struct
|
||||
struct Client {
|
||||
edict_t *ent; // pointer to actual edict
|
||||
Vector origin; // position in the world
|
||||
Vector sound; // position sound was played
|
||||
int team; // bot team
|
||||
int team2; // real bot team in free for all mode (csdm)
|
||||
int flags; // client flags
|
||||
|
|
@ -526,9 +532,8 @@ struct Client {
|
|||
int ping; // when bot latency is enabled, client ping stored here
|
||||
int iconFlags[kGameMaxPlayers]; // flag holding chatter icons
|
||||
float iconTimestamp[kGameMaxPlayers]; // timers for chatter icons
|
||||
float hearingDistance; // distance this sound is heared
|
||||
float timeSoundLasting; // time sound is played/heared
|
||||
bool pingUpdate; // update ping ?
|
||||
ClientNoise noise;
|
||||
};
|
||||
|
||||
// define chatting collection structure
|
||||
|
|
@ -733,7 +738,6 @@ private:
|
|||
bool isOccupiedNode (int index);
|
||||
bool seesItem (const Vector &dest, const char *itemName);
|
||||
bool lastEnemyShootable ();
|
||||
bool isShootableBreakable (edict_t *ent);
|
||||
bool rateGroundWeapon (edict_t *ent);
|
||||
bool reactOnEnemy ();
|
||||
bool selectBestNextNode ();
|
||||
|
|
@ -975,6 +979,7 @@ public:
|
|||
void showChaterIcon (bool show);
|
||||
void clearSearchNodes ();
|
||||
void checkBreakable (edict_t *touch);
|
||||
void checkBreablesAround ();
|
||||
void startTask (Task id, float desire, int data, float time, bool resume);
|
||||
void clearTask (Task id);
|
||||
void filterTasks ();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue