fixed bomb defuse check doesn't verify pressing IN_USE button of client

fixed potential crash bug in IsPointOccupied
processing global refactoring
This commit is contained in:
jeefo 2016-03-01 22:52:17 +03:00
commit d5a8b3642b
18 changed files with 717 additions and 739 deletions

2
.gitignore vendored
View file

@ -28,6 +28,7 @@ $RECYCLE.BIN/
# Icon must ends with two \r. # Icon must ends with two \r.
Icon Icon
# Thumbnails # Thumbnails
._* ._*
@ -54,3 +55,4 @@ Icon
*.vspx *.vspx
project/yapb.vcxproj.user project/yapb.vcxproj.user
*.psess *.psess
*.opendb

View file

@ -361,6 +361,15 @@ enum LiftState
LIFT_LEAVING LIFT_LEAVING
}; };
// wayponit auto-downloader
enum WaypointDownloadError
{
WDE_SOCKET_ERROR,
WDE_CONNECT_ERROR,
WDE_NOTFOUND_ERROR,
WDE_NOERROR
};
// game start messages for counter-strike... // game start messages for counter-strike...
enum GameStartMessage enum GameStartMessage
{ {
@ -376,6 +385,7 @@ enum GameStartMessage
// netmessage functions // netmessage functions
enum NetworkMessage enum NetworkMessage
{ {
NETMSG_UNDEFINED = 0,
NETMSG_VGUI = 1, NETMSG_VGUI = 1,
NETMSG_SHOWMENU = 2, NETMSG_SHOWMENU = 2,
NETMSG_WEAPONLIST = 3, NETMSG_WEAPONLIST = 3,
@ -395,7 +405,7 @@ enum NetworkMessage
NETMSG_SAYTEXT = 18, NETMSG_SAYTEXT = 18,
NETMSG_BOTVOICE = 19, NETMSG_BOTVOICE = 19,
NETMSG_RESETHUD = 20, NETMSG_RESETHUD = 20,
NETMSG_UNDEFINED = 0 NETMSG_NUM = 21
}; };
// sensing states // sensing states
@ -1226,7 +1236,7 @@ public:
}; };
// manager class // manager class
class BotManager : public Singleton <BotManager> class BotManager
{ {
private: private:
Array <CreateQueue> m_creationTab; // bot creation tab Array <CreateQueue> m_creationTab; // bot creation tab
@ -1322,7 +1332,7 @@ public:
}; };
// texts localizer // texts localizer
class Localizer : public Singleton <Localizer> class Localizer
{ {
public: public:
Array <LanguageItem> m_langTab; Array <LanguageItem> m_langTab;
@ -1336,13 +1346,13 @@ public:
}; };
// netmessage handler class // netmessage handler class
class NetworkMsg : public Singleton <NetworkMsg> class NetworkMsg
{ {
private: private:
Bot *m_bot; Bot *m_bot;
int m_state; int m_state;
int m_message; int m_message;
int m_registerdMessages[NETMSG_RESETHUD + 1]; int m_registerdMessages[NETMSG_NUM];
public: public:
NetworkMsg (void); NetworkMsg (void);
@ -1360,7 +1370,7 @@ public:
}; };
// waypoint operation class // waypoint operation class
class Waypoint : public Singleton <Waypoint> class Waypoint
{ {
friend class Bot; friend class Bot;
@ -1468,6 +1478,7 @@ public:
{ {
return m_foundBombOrigin; return m_foundBombOrigin;
} }
const char *GetDataDir (void);
void SetBombPosition (bool shouldReset = false); void SetBombPosition (bool shouldReset = false);
String CheckSubfolderFile (void); String CheckSubfolderFile (void);
@ -1482,141 +1493,41 @@ public:
return GetPath (index); return GetPath (index);
} }
};
// wayponit auto-downloader
enum WaypointDownloadError
{
WDE_SOCKET_ERROR,
WDE_CONNECT_ERROR,
WDE_NOTFOUND_ERROR,
WDE_NOERROR
};
class WaypointDownloader
{
public:
// free's socket handle // free's socket handle
void FreeSocket (int sock); void CloseSocketHandle (int sock);
// do actually downloading of waypoint file // do actually downloading of waypoint file
WaypointDownloadError DoDownload (void); WaypointDownloadError RequestWaypoint (void);
}; };
enum VarType #include <engine.h>
{
VT_NORMAL = 0,
VT_READONLY,
VT_PASSWORD,
VT_NOSERVER,
VT_NOREGISTER
};
class ConVarWrapper : public Singleton <ConVarWrapper> // expose bot super-globals
{ extern NetworkMsg netmsg;
private: extern Localizer locale;
struct VarPair extern Waypoint waypoints;
{ extern BotManager bots;
VarType type; extern Engine engine;
cvar_t reg;
class ConVar *self;
};
Array <VarPair> m_regs;
public:
void RegisterVariable (const char *variable, const char *value, VarType varType, ConVar *self);
void PushRegisteredConVarsToEngine (bool gameVars = false);
};
// expose bot globals
#define netmsg NetworkMsg::GetReference ()
#define locale Localizer::GetReference ()
#define convars ConVarWrapper::GetReference ()
#define waypoints Waypoint::GetReference ()
#define bots BotManager::GetReference ()
// simplify access for console variables
class ConVar
{
public:
cvar_t *m_eptr;
public:
ConVar (const char *name, const char *initval, VarType type = VT_NOSERVER)
{
m_eptr = NULL;
convars.RegisterVariable (name, initval, type, this);
}
inline bool GetBool(void)
{
return m_eptr->value > 0.0f;
}
inline int GetInt (void)
{
return static_cast <int> (m_eptr->value);
}
inline int GetFlags (void)
{
return m_eptr->flags;
}
inline float GetFloat (void)
{
return m_eptr->value;
}
inline const char *GetString (void)
{
return m_eptr->string;
}
inline const char *GetName (void)
{
return m_eptr->name;
}
inline void SetFloat (float val)
{
g_engfuncs.pfnCVarSetFloat (m_eptr->name, val);
}
inline void SetInt (int val)
{
SetFloat (static_cast <float> (val));
}
inline void SetString (const char *val)
{
g_engfuncs.pfnCVarSetString (m_eptr->name, val);
}
};
// prototypes of bot functions... // prototypes of bot functions...
extern int GetWeaponReturn (bool isString, const char *weaponAlias, int weaponIndex = -1); extern int GetWeaponReturn (bool isString, const char *weaponAlias, int weaponIndex = -1);
extern int GetWeaponPenetrationPower (int id);
extern int GenerateBuildNumber (void);
extern float GetShootingConeDeviation (edict_t *ent, Vector *position); extern float GetShootingConeDeviation (edict_t *ent, Vector *position);
extern bool IsVisible (const Vector &origin, edict_t *ent); extern bool IsVisible (const Vector &origin, edict_t *ent);
extern bool IsAlive (edict_t *ent); extern bool IsAlive (edict_t *ent);
extern bool IsInViewCone (const Vector &origin, edict_t *ent); extern bool IsInViewCone (const Vector &origin, edict_t *ent);
extern int GetWeaponPenetrationPower (int id);
extern bool IsValidBot (edict_t *ent); extern bool IsValidBot (edict_t *ent);
extern bool IsValidPlayer (edict_t *ent); extern bool IsValidPlayer (edict_t *ent);
extern bool IsPlayerVIP (edict_t *ent); extern bool IsPlayerVIP (edict_t *ent);
extern bool OpenConfig (const char *fileName, const char *errorIfNotExists, File *outFile, bool languageDependant = false); extern bool OpenConfig (const char *fileName, const char *errorIfNotExists, File *outFile, bool languageDependant = false);
extern bool FindNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false); extern bool FindNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false);
extern const char *GetField (const char *string, int fieldId, bool endLine = false);
extern const char *FormatBuffer (const char *format, ...);
extern uint16 GenerateBuildNumber (void);
extern void FreeLibraryMemory (void); extern void FreeLibraryMemory (void);
extern void RoundInit (void); extern void RoundInit (void);
extern void FakeClientCommand (edict_t *fakeClient, const char *format, ...);
extern void strtrim (char *string);
extern void CreatePath (char *path);
extern void CheckWelcomeMessage (void); extern void CheckWelcomeMessage (void);
extern void DetectCSVersion (void); extern void DetectCSVersion (void);
extern void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...); extern void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...);
@ -1624,7 +1535,8 @@ extern void DisplayMenuToClient (edict_t *ent, MenuText *menu);
extern void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex); extern void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex);
extern void SoundAttachToClients (edict_t *ent, const char *sample, float volume); extern void SoundAttachToClients (edict_t *ent, const char *sample, float volume);
extern void SoundSimulateUpdate (int playerIndex); extern void SoundSimulateUpdate (int playerIndex);
extern const char *GetWaypointDir (void);
extern const char *FormatBuffer (const char *format, ...);
// very global convars // very global convars
extern ConVar yb_jasonmode; extern ConVar yb_jasonmode;
@ -1632,7 +1544,6 @@ extern ConVar yb_communication_type;
extern ConVar yb_csdm_mode; extern ConVar yb_csdm_mode;
extern ConVar yb_ignore_enemies; extern ConVar yb_ignore_enemies;
#include <engine.h>
#include <globals.h> #include <globals.h>
#include <compress.h> #include <compress.h>
#include <resource.h> #include <resource.h>

View file

@ -21,6 +21,10 @@
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#ifdef _WIN32
#include <direct.h>
#endif
// //
// Title: Utility Classes Header // Title: Utility Classes Header
// //
@ -3296,6 +3300,56 @@ public:
return Split (sep); return Split (sep);
} }
public:
//
// Function: TrimExternalBuffer
// Trims string from both sides.
//
// Returns:
// None
//
static inline void TrimExternalBuffer (char *string)
{
char *ptr = string;
int length = 0, toggleFlag = 0, increment = 0;
int i = 0;
while (*ptr++)
length++;
for (i = length - 1; i >= 0; i--)
{
if (!isspace (string[i]))
break;
else
{
string[i] = 0;
length--;
}
}
for (i = 0; i < length; i++)
{
if (isspace (string[i]) && !toggleFlag)
{
increment++;
if (increment + i < length)
string[i] = string[increment + i];
}
else
{
if (!toggleFlag)
toggleFlag = 1;
if (increment)
string[i] = string[increment + i];
}
}
string[length] = 0;
}
}; };
// //
@ -3615,6 +3669,29 @@ public:
} }
return false; return false;
} }
static inline void CreatePath (char *path)
{
for (char *ofs = path + 1; *ofs; ofs++)
{
if (*ofs == '/')
{
// create the directory
*ofs = 0;
#ifdef _WIN32
_mkdir (path);
#else
mkdir (path, 0777);
#endif
*ofs = '/';
}
}
#ifdef _WIN32
_mkdir (path);
#else
mkdir (path, 0777);
#endif
}
}; };
// //

View file

@ -28,12 +28,44 @@ enum TraceIgnore
TRACE_IGNORE_EVERYTHING = TRACE_IGNORE_GLASS | TRACE_IGNORE_MONSTERS TRACE_IGNORE_EVERYTHING = TRACE_IGNORE_GLASS | TRACE_IGNORE_MONSTERS
}; };
// variable type
enum VarType
{
VT_NORMAL = 0,
VT_READONLY,
VT_PASSWORD,
VT_NOSERVER,
VT_NOREGISTER
};
// need since we don't want to use Singleton on engine class
class ConVarWrapper : public Singleton <ConVarWrapper>
{
private:
struct VarPair
{
VarType type;
cvar_t reg;
class ConVar *self;
};
Array <VarPair> m_regs;
public:
void RegisterVariable (const char *variable, const char *value, VarType varType, ConVar *self);
void PushRegisteredConVarsToEngine (bool gameVars = false);
};
// provides utility functions to not call original engine (less call-cost) // provides utility functions to not call original engine (less call-cost)
class Engine class Engine
{ {
private: private:
short m_drawModels[DRAW_NUM]; short m_drawModels[DRAW_NUM];
// bot client command
bool m_isBotCommand;
char m_arguments[256];
int m_argumentCount;
// public functions // public functions
public: public:
@ -85,21 +117,72 @@ public:
// play's sound to client // play's sound to client
void EmitSound (edict_t *ent, const char *sound); void EmitSound (edict_t *ent, const char *sound);
// sends bot command
void IssueBotCommand (edict_t *ent, const char *fmt, ...);
// public inlines // public inlines
public: public:
// get the current time on server // get the current time on server
static inline float Time (void) inline float Time (void)
{ {
return g_pGlobals->time; return g_pGlobals->time;
} }
// get "maxplayers" limit on server // get "maxplayers" limit on server
static inline int MaxClients (void) inline int MaxClients (void)
{ {
return g_pGlobals->maxClients; return g_pGlobals->maxClients;
} }
// get the fakeclient command interface
inline bool IsBotCommand (void)
{
return m_isBotCommand;
}
// gets custom engine args for client command
inline const char *GetOverrideArgs (void)
{
if (strncmp ("say ", m_arguments, 4) == 0)
return &m_arguments[4];
else if (strncmp ("say_team ", m_arguments, 9) == 0)
return &m_arguments[9];
return m_arguments;
}
// gets custom engine argv for client command
inline const char *GetOverrideArgv (int num)
{
return ExtractSingleField (m_arguments, num, false);
}
// gets custom engine argc for client command
inline int GetOverrideArgc (void)
{
return m_argumentCount;
}
// static utility functions
public:
static const char *ExtractSingleField (const char *string, int id, bool terminate);
}; };
// provides quick access to engine instance // simplify access for console variables
extern Engine engine; class ConVar
{
public:
cvar_t *m_eptr;
public:
ConVar (const char *name, const char *initval, VarType type = VT_NOSERVER);
inline bool GetBool (void) { return m_eptr->value > 0.0f; }
inline int GetInt (void) { return static_cast <int> (m_eptr->value); }
inline float GetFloat (void) { return m_eptr->value; }
inline const char *GetString (void) { return m_eptr->string; }
inline void SetFloat (float val) { m_eptr->value = val; }
inline void SetInt (int val) { SetFloat (static_cast <float> (val)); }
inline void SetString (const char *val) { g_engfuncs.pfnCVarSetString (m_eptr->name, val); }
};

View file

@ -20,7 +20,6 @@ extern bool g_autoWaypoint;
extern bool g_botsCanPause; extern bool g_botsCanPause;
extern bool g_editNoclip; extern bool g_editNoclip;
extern bool g_isMetamod; extern bool g_isMetamod;
extern bool g_isFakeCommand;
extern bool g_sendAudioFinished; extern bool g_sendAudioFinished;
extern bool g_isCommencing; extern bool g_isCommencing;
extern bool g_leaderChoosen[2]; extern bool g_leaderChoosen[2];
@ -39,7 +38,6 @@ extern float g_lastRadioTime[2];
extern int g_mapType; extern int g_mapType;
extern int g_numWaypoints; extern int g_numWaypoints;
extern int g_gameFlags; extern int g_gameFlags;
extern int g_fakeArgc;
extern int g_highestDamageCT; extern int g_highestDamageCT;
extern int g_highestDamageT; extern int g_highestDamageT;
@ -55,8 +53,6 @@ extern int g_lastRadio[2];
extern int g_storeAddbotVars[4]; extern int g_storeAddbotVars[4];
extern int *g_weaponPrefs[]; extern int *g_weaponPrefs[];
extern char g_fakeArgv[256];
extern Array <Array <String> > g_chatFactory; extern Array <Array <String> > g_chatFactory;
extern Array <Array <ChatterItem> > g_chatterFactory; extern Array <Array <ChatterItem> > g_chatterFactory;
extern Array <BotName> g_botNames; extern Array <BotName> g_botNames;
@ -105,7 +101,7 @@ static inline int EntOffsetOfEntity(const edict_t *ent)
return (char *) ent - (char *) g_worldEntity; return (char *) ent - (char *) g_worldEntity;
} }
static inline bool IsEntityNull (const edict_t *ent) static inline bool IsNullEntity (const edict_t *ent)
{ {
return !ent || !EntOffsetOfEntity (ent); return !ent || !EntOffsetOfEntity (ent);
} }

View file

@ -16,6 +16,7 @@ OBJECTS = $(SRC_DIR)/basecode.cpp \
$(SRC_DIR)/chatlib.cpp \ $(SRC_DIR)/chatlib.cpp \
$(SRC_DIR)/combat.cpp \ $(SRC_DIR)/combat.cpp \
$(SRC_DIR)/globals.cpp \ $(SRC_DIR)/globals.cpp \
$(SRC_DIR)/engine.cpp \
$(SRC_DIR)/interface.cpp \ $(SRC_DIR)/interface.cpp \
$(SRC_DIR)/navigate.cpp \ $(SRC_DIR)/navigate.cpp \
$(SRC_DIR)/netmsg.cpp \ $(SRC_DIR)/netmsg.cpp \

View file

@ -22,6 +22,7 @@ LOCAL_SRC_FILES := \
chatlib.cpp \ chatlib.cpp \
combat.cpp \ combat.cpp \
globals.cpp \ globals.cpp \
engine.cpp \
interface.cpp \ interface.cpp \
navigate.cpp \ navigate.cpp \
netmsg.cpp \ netmsg.cpp \

View file

@ -281,7 +281,7 @@ void Bot::AvoidGrenades (void)
return; return;
// check if old pointers to grenade is invalid // check if old pointers to grenade is invalid
if (IsEntityNull (m_avoidGrenade)) if (IsNullEntity (m_avoidGrenade))
{ {
m_avoidGrenade = NULL; m_avoidGrenade = NULL;
m_needAvoidGrenade = 0; m_needAvoidGrenade = 0;
@ -318,7 +318,7 @@ void Bot::AvoidGrenades (void)
} }
else if (strcmp (STRING (ent->v.model) + 9, "hegrenade.mdl") == 0) else if (strcmp (STRING (ent->v.model) + 9, "hegrenade.mdl") == 0)
{ {
if (!IsEntityNull (m_avoidGrenade)) if (!IsNullEntity (m_avoidGrenade))
return; return;
if (GetTeam (ent->v.owner) == m_team && ent->v.owner != GetEntity ()) if (GetTeam (ent->v.owner) == m_team && ent->v.owner != GetEntity ())
@ -469,7 +469,7 @@ void Bot::VerifyBreakable (edict_t *touch)
m_breakableEntity = FindBreakable (); m_breakableEntity = FindBreakable ();
if (IsEntityNull (m_breakableEntity)) if (IsNullEntity (m_breakableEntity))
return; return;
m_campButtons = pev->button & IN_DUCK; m_campButtons = pev->button & IN_DUCK;
@ -572,12 +572,12 @@ void Bot::FindItem (void)
const float searchRadius = 340.0f; const float searchRadius = 340.0f;
if (!IsEntityNull (m_pickupItem)) if (!IsNullEntity (m_pickupItem))
{ {
bool itemExists = false; bool itemExists = false;
pickupItem = m_pickupItem; pickupItem = m_pickupItem;
while (!IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, searchRadius))) while (!IsNullEntity (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, searchRadius)))
{ {
if ((ent->v.effects & EF_NODRAW) || IsValidPlayer (ent->v.owner)) if ((ent->v.effects & EF_NODRAW) || IsValidPlayer (ent->v.owner))
continue; // someone owns this weapon or it hasn't re spawned yet continue; // someone owns this weapon or it hasn't re spawned yet
@ -612,7 +612,7 @@ void Bot::FindItem (void)
m_pickupItem = NULL; m_pickupItem = NULL;
m_pickupType = PICKUP_NONE; m_pickupType = PICKUP_NONE;
while (!IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, searchRadius))) while (!IsNullEntity (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, searchRadius)))
{ {
bool allowPickup = false; // assume can't use it until known otherwise bool allowPickup = false; // assume can't use it until known otherwise
@ -772,7 +772,7 @@ void Bot::FindItem (void)
{ {
if (pickupType == PICKUP_HOSTAGE) if (pickupType == PICKUP_HOSTAGE)
{ {
if (IsEntityNull (ent) || ent->v.health <= 0) if (IsNullEntity (ent) || ent->v.health <= 0)
allowPickup = false; // never pickup dead hostage allowPickup = false; // never pickup dead hostage
else for (int i = 0; i < engine.MaxClients (); i++) else for (int i = 0; i < engine.MaxClients (); i++)
{ {
@ -866,7 +866,7 @@ void Bot::FindItem (void)
} }
} // end of the while loop } // end of the while loop
if (!IsEntityNull (pickupItem)) if (!IsNullEntity (pickupItem))
{ {
for (int i = 0; i < engine.MaxClients (); i++) for (int i = 0; i < engine.MaxClients (); i++)
{ {
@ -1248,20 +1248,20 @@ void Bot::CheckMessageQueue (void)
if ((m_radioSelect != Radio_ReportingIn && g_radioInsteadVoice) || yb_communication_type.GetInt () != 2 || g_chatterFactory[m_radioSelect].IsEmpty () || (g_gameFlags & GAME_LEGACY)) if ((m_radioSelect != Radio_ReportingIn && g_radioInsteadVoice) || yb_communication_type.GetInt () != 2 || g_chatterFactory[m_radioSelect].IsEmpty () || (g_gameFlags & GAME_LEGACY))
{ {
if (m_radioSelect < Radio_GoGoGo) if (m_radioSelect < Radio_GoGoGo)
FakeClientCommand (GetEntity (), "radio1"); engine.IssueBotCommand (GetEntity (), "radio1");
else if (m_radioSelect < Radio_Affirmative) else if (m_radioSelect < Radio_Affirmative)
{ {
m_radioSelect -= Radio_GoGoGo - 1; m_radioSelect -= Radio_GoGoGo - 1;
FakeClientCommand (GetEntity (), "radio2"); engine.IssueBotCommand (GetEntity (), "radio2");
} }
else else
{ {
m_radioSelect -= Radio_Affirmative - 1; m_radioSelect -= Radio_Affirmative - 1;
FakeClientCommand (GetEntity (), "radio3"); engine.IssueBotCommand (GetEntity (), "radio3");
} }
// select correct menu item for this radio message // select correct menu item for this radio message
FakeClientCommand (GetEntity (), "menuselect %d", m_radioSelect); engine.IssueBotCommand (GetEntity (), "menuselect %d", m_radioSelect);
} }
else if (m_radioSelect != -1 && m_radioSelect != Radio_ReportingIn) else if (m_radioSelect != -1 && m_radioSelect != Radio_ReportingIn)
InstantChatterMessage (m_radioSelect); InstantChatterMessage (m_radioSelect);
@ -1561,16 +1561,16 @@ void Bot::PurchaseWeapons (void)
if (selectedWeapon != NULL) if (selectedWeapon != NULL)
{ {
FakeClientCommand (GetEntity (), "buy;menuselect %d", selectedWeapon->buyGroup); engine.IssueBotCommand (GetEntity (), "buy;menuselect %d", selectedWeapon->buyGroup);
if (isOldGame) if (isOldGame)
FakeClientCommand(GetEntity (), "menuselect %d", selectedWeapon->buySelect); engine.IssueBotCommand(GetEntity (), "menuselect %d", selectedWeapon->buySelect);
else // SteamCS buy menu is different from the old one else // SteamCS buy menu is different from the old one
{ {
if (m_team == TERRORIST) if (m_team == TERRORIST)
FakeClientCommand(GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT); engine.IssueBotCommand(GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT);
else else
FakeClientCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT); engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT);
} }
} }
} }
@ -1590,9 +1590,9 @@ void Bot::PurchaseWeapons (void)
{ {
// if bot is rich, buy kevlar + helmet, else buy a single kevlar // if bot is rich, buy kevlar + helmet, else buy a single kevlar
if (m_moneyAmount > 1500 && !IsRestricted (WEAPON_ARMORHELM)) if (m_moneyAmount > 1500 && !IsRestricted (WEAPON_ARMORHELM))
FakeClientCommand (GetEntity (), "buyequip;menuselect 2"); engine.IssueBotCommand (GetEntity (), "buyequip;menuselect 2");
else if (!IsRestricted (WEAPON_ARMOR)) else if (!IsRestricted (WEAPON_ARMOR))
FakeClientCommand (GetEntity (), "buyequip;menuselect 1"); engine.IssueBotCommand (GetEntity (), "buyequip;menuselect 1");
} }
break; break;
@ -1649,17 +1649,17 @@ void Bot::PurchaseWeapons (void)
if (selectedWeapon != NULL) if (selectedWeapon != NULL)
{ {
FakeClientCommand (GetEntity (), "buy;menuselect %d", selectedWeapon->buyGroup); engine.IssueBotCommand (GetEntity (), "buy;menuselect %d", selectedWeapon->buyGroup);
if (isOldGame) if (isOldGame)
FakeClientCommand (GetEntity (), "menuselect %d", selectedWeapon->buySelect); engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->buySelect);
else // steam cs buy menu is different from old one else // steam cs buy menu is different from old one
{ {
if (GetTeam (GetEntity ()) == TERRORIST) if (GetTeam (GetEntity ()) == TERRORIST)
FakeClientCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT); engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT);
else else
FakeClientCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT); engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT);
} }
} }
} }
@ -1669,22 +1669,22 @@ void Bot::PurchaseWeapons (void)
if (Random.Long (1, 100) < g_grenadeBuyPrecent[0] && m_moneyAmount >= 400 && !IsRestricted (WEAPON_EXPLOSIVE)) if (Random.Long (1, 100) < g_grenadeBuyPrecent[0] && m_moneyAmount >= 400 && !IsRestricted (WEAPON_EXPLOSIVE))
{ {
// buy a he grenade // buy a he grenade
FakeClientCommand (GetEntity (), "buyequip"); engine.IssueBotCommand (GetEntity (), "buyequip");
FakeClientCommand (GetEntity (), "menuselect 4"); engine.IssueBotCommand (GetEntity (), "menuselect 4");
} }
if (Random.Long (1, 100) < g_grenadeBuyPrecent[1] && m_moneyAmount >= 300 && teamEcoValid && !IsRestricted (WEAPON_FLASHBANG)) if (Random.Long (1, 100) < g_grenadeBuyPrecent[1] && m_moneyAmount >= 300 && teamEcoValid && !IsRestricted (WEAPON_FLASHBANG))
{ {
// buy a concussion grenade, i.e., 'flashbang' // buy a concussion grenade, i.e., 'flashbang'
FakeClientCommand (GetEntity (), "buyequip"); engine.IssueBotCommand (GetEntity (), "buyequip");
FakeClientCommand (GetEntity (), "menuselect 3"); engine.IssueBotCommand (GetEntity (), "menuselect 3");
} }
if (Random.Long (1, 100) < g_grenadeBuyPrecent[2] && m_moneyAmount >= 400 && teamEcoValid && !IsRestricted (WEAPON_SMOKE)) if (Random.Long (1, 100) < g_grenadeBuyPrecent[2] && m_moneyAmount >= 400 && teamEcoValid && !IsRestricted (WEAPON_SMOKE))
{ {
// buy a smoke grenade // buy a smoke grenade
FakeClientCommand (GetEntity (), "buyequip"); engine.IssueBotCommand (GetEntity (), "buyequip");
FakeClientCommand (GetEntity (), "menuselect 5"); engine.IssueBotCommand (GetEntity (), "menuselect 5");
} }
break; break;
@ -1692,22 +1692,22 @@ void Bot::PurchaseWeapons (void)
if ((g_mapType & MAP_DE) && m_team == CT && Random.Long (1, 100) < 80 && m_moneyAmount > 200 && !IsRestricted (WEAPON_DEFUSER)) if ((g_mapType & MAP_DE) && m_team == CT && Random.Long (1, 100) < 80 && m_moneyAmount > 200 && !IsRestricted (WEAPON_DEFUSER))
{ {
if (isOldGame) if (isOldGame)
FakeClientCommand (GetEntity (), "buyequip;menuselect 6"); engine.IssueBotCommand (GetEntity (), "buyequip;menuselect 6");
else else
FakeClientCommand (GetEntity (), "defuser"); // use alias in SteamCS engine.IssueBotCommand (GetEntity (), "defuser"); // use alias in SteamCS
} }
break; break;
case BUYSTATE_AMMO: // buy enough primary & secondary ammo (do not check for money here) case BUYSTATE_AMMO: // buy enough primary & secondary ammo (do not check for money here)
for (int i = 0; i <= 5; i++) for (int i = 0; i <= 5; i++)
FakeClientCommand (GetEntity (), "buyammo%d", Random.Long (1, 2)); // simulate human engine.IssueBotCommand (GetEntity (), "buyammo%d", Random.Long (1, 2)); // simulate human
// buy enough secondary ammo // buy enough secondary ammo
if (HasPrimaryWeapon ()) if (HasPrimaryWeapon ())
FakeClientCommand (GetEntity (), "buy;menuselect 7"); engine.IssueBotCommand (GetEntity (), "buy;menuselect 7");
// buy enough primary ammo // buy enough primary ammo
FakeClientCommand (GetEntity (), "buy;menuselect 6"); engine.IssueBotCommand (GetEntity (), "buy;menuselect 6");
// try to reload secondary weapon // try to reload secondary weapon
if (m_reloadState != RELOAD_PRIMARY) if (m_reloadState != RELOAD_PRIMARY)
@ -1860,7 +1860,7 @@ void Bot::SetConditions (void)
} }
// did bot just kill an enemy? // did bot just kill an enemy?
if (!IsEntityNull (m_lastVictim)) if (!IsNullEntity (m_lastVictim))
{ {
if (GetTeam (m_lastVictim) != m_team) if (GetTeam (m_lastVictim) != m_team)
{ {
@ -1927,7 +1927,7 @@ void Bot::SetConditions (void)
} }
// check if our current enemy is still valid // check if our current enemy is still valid
if (!IsEntityNull (m_lastEnemy)) if (!IsNullEntity (m_lastEnemy))
{ {
if (!IsAlive (m_lastEnemy) && m_shootAtDeadTime < engine.Time ()) if (!IsAlive (m_lastEnemy) && m_shootAtDeadTime < engine.Time ())
{ {
@ -1950,7 +1950,7 @@ void Bot::SetConditions (void)
else if (m_heardSoundTime < engine.Time ()) else if (m_heardSoundTime < engine.Time ())
m_states &= ~STATE_HEARING_ENEMY; m_states &= ~STATE_HEARING_ENEMY;
if (IsEntityNull (m_enemy) && !IsEntityNull (m_lastEnemy) && !m_lastEnemyOrigin.IsZero ()) if (IsNullEntity (m_enemy) && !IsNullEntity (m_lastEnemy) && !m_lastEnemyOrigin.IsZero ())
{ {
m_aimFlags |= AIM_PREDICT_PATH; m_aimFlags |= AIM_PREDICT_PATH;
@ -1960,7 +1960,7 @@ void Bot::SetConditions (void)
CheckGrenadeThrow (); CheckGrenadeThrow ();
// check if there are items needing to be used/collected // check if there are items needing to be used/collected
if (m_itemCheckTime < engine.Time () || !IsEntityNull (m_pickupItem)) if (m_itemCheckTime < engine.Time () || !IsNullEntity (m_pickupItem))
{ {
m_itemCheckTime = engine.Time () + 0.4f; m_itemCheckTime = engine.Time () + 0.4f;
FindItem (); FindItem ();
@ -1993,7 +1993,7 @@ void Bot::ApplyTaskFilters (void)
} }
// bot found some item to use? // bot found some item to use?
if (!IsEntityNull (m_pickupItem) && GetTaskId () != TASK_ESCAPEFROMBOMB) if (!IsNullEntity (m_pickupItem) && GetTaskId () != TASK_ESCAPEFROMBOMB)
{ {
m_states |= STATE_PICKUP_ITEM; m_states |= STATE_PICKUP_ITEM;
@ -2053,7 +2053,7 @@ void Bot::ApplyTaskFilters (void)
// if half of the round is over, allow hunting // if half of the round is over, allow hunting
// FIXME: it probably should be also team/map dependant // FIXME: it probably should be also team/map dependant
if (GetTaskId () != TASK_ESCAPEFROMBOMB && IsEntityNull (m_enemy) && g_timeRoundMid < engine.Time () && !m_isUsingGrenade && m_currentWaypointIndex != waypoints.FindNearest (m_lastEnemyOrigin) && m_personality != PERSONALITY_CAREFUL) if (GetTaskId () != TASK_ESCAPEFROMBOMB && IsNullEntity (m_enemy) && g_timeRoundMid < engine.Time () && !m_isUsingGrenade && m_currentWaypointIndex != waypoints.FindNearest (m_lastEnemyOrigin) && m_personality != PERSONALITY_CAREFUL)
{ {
float desireLevel = 4096.0f - ((1.0f - tempAgression) * distance); float desireLevel = 4096.0f - ((1.0f - tempAgression) * distance);
@ -2242,7 +2242,7 @@ void Bot::TaskComplete (void)
bool Bot::EnemyIsThreat (void) bool Bot::EnemyIsThreat (void)
{ {
if (IsEntityNull (m_enemy) || GetTaskId () == TASK_SEEKCOVER) if (IsNullEntity (m_enemy) || GetTaskId () == TASK_SEEKCOVER)
return false; return false;
// if bot is camping, he should be firing anyway and not leaving his position // if bot is camping, he should be firing anyway and not leaving his position
@ -2290,7 +2290,7 @@ bool Bot::ReactOnEnemy (void)
bool Bot::LastEnemyShootable (void) bool Bot::LastEnemyShootable (void)
{ {
// don't allow shooting through walls // don't allow shooting through walls
if (!(m_aimFlags & AIM_LAST_ENEMY) || m_lastEnemyOrigin.IsZero () || IsEntityNull (m_lastEnemy)) if (!(m_aimFlags & AIM_LAST_ENEMY) || m_lastEnemyOrigin.IsZero () || IsNullEntity (m_lastEnemy))
return false; return false;
return GetShootingConeDeviation (GetEntity (), &m_lastEnemyOrigin) >= 0.90f && IsShootableThruObstacle (m_lastEnemyOrigin); return GetShootingConeDeviation (GetEntity (), &m_lastEnemyOrigin) >= 0.90f && IsShootableThruObstacle (m_lastEnemyOrigin);
@ -2319,7 +2319,7 @@ void Bot::CheckRadioCommands (void)
// check if line of sight to object is not blocked (i.e. visible) // check if line of sight to object is not blocked (i.e. visible)
if ((EntityIsVisible (m_radioEntity->v.origin)) || (m_radioOrder == Radio_StickTogether)) if ((EntityIsVisible (m_radioEntity->v.origin)) || (m_radioOrder == Radio_StickTogether))
{ {
if (IsEntityNull (m_targetEntity) && IsEntityNull (m_enemy) && Random.Long (0, 100) < (m_personality == PERSONALITY_CAREFUL ? 80 : 20)) if (IsNullEntity (m_targetEntity) && IsNullEntity (m_enemy) && Random.Long (0, 100) < (m_personality == PERSONALITY_CAREFUL ? 80 : 20))
{ {
int numFollowers = 0; int numFollowers = 0;
@ -2384,7 +2384,7 @@ void Bot::CheckRadioCommands (void)
break; break;
case Radio_HoldPosition: case Radio_HoldPosition:
if (!IsEntityNull (m_targetEntity)) if (!IsNullEntity (m_targetEntity))
{ {
if (m_targetEntity == m_radioEntity) if (m_targetEntity == m_radioEntity)
{ {
@ -2403,9 +2403,9 @@ void Bot::CheckRadioCommands (void)
break; break;
case Radio_TakingFire: case Radio_TakingFire:
if (IsEntityNull (m_targetEntity)) if (IsNullEntity (m_targetEntity))
{ {
if (IsEntityNull (m_enemy) && m_seeEnemyTime + 4.0f < engine.Time ()) if (IsNullEntity (m_enemy) && m_seeEnemyTime + 4.0f < engine.Time ())
{ {
// decrease fear levels to lower probability of bot seeking cover again // decrease fear levels to lower probability of bot seeking cover again
m_fearLevel -= 0.2f; m_fearLevel -= 0.2f;
@ -2434,7 +2434,7 @@ void Bot::CheckRadioCommands (void)
case Radio_NeedBackup: case Radio_NeedBackup:
case Chatter_ScaredEmotion: case Chatter_ScaredEmotion:
case Chatter_Pinned_Down: case Chatter_Pinned_Down:
if (((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 2048.0f || !m_moveToC4) && Random.Long (0, 100) > 50 && m_seeEnemyTime + 4.0f < engine.Time ()) if (((IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 2048.0f || !m_moveToC4) && Random.Long (0, 100) > 50 && m_seeEnemyTime + 4.0f < engine.Time ())
{ {
m_fearLevel -= 0.1f; m_fearLevel -= 0.1f;
@ -2466,7 +2466,7 @@ void Bot::CheckRadioCommands (void)
if (m_fearLevel < 0.0f) if (m_fearLevel < 0.0f)
m_fearLevel = 0.0f; m_fearLevel = 0.0f;
} }
else if ((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 2048.0f) else if ((IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 2048.0f)
{ {
TaskID taskID = GetTaskId (); TaskID taskID = GetTaskId ();
@ -2490,7 +2490,7 @@ void Bot::CheckRadioCommands (void)
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0f, true); PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0f, true);
} }
} }
else if (!IsEntityNull (m_doubleJumpEntity)) else if (!IsNullEntity (m_doubleJumpEntity))
{ {
RadioMessage (Radio_Affirmative); RadioMessage (Radio_Affirmative);
ResetDoubleJumpState (); ResetDoubleJumpState ();
@ -2501,7 +2501,7 @@ void Bot::CheckRadioCommands (void)
break; break;
case Radio_ShesGonnaBlow: case Radio_ShesGonnaBlow:
if (IsEntityNull (m_enemy) && distance < 2048.0f && g_bombPlanted && m_team == TERRORIST) if (IsNullEntity (m_enemy) && distance < 2048.0f && g_bombPlanted && m_team == TERRORIST)
{ {
RadioMessage (Radio_Affirmative); RadioMessage (Radio_Affirmative);
@ -2530,7 +2530,7 @@ void Bot::CheckRadioCommands (void)
break; break;
case Radio_StormTheFront: case Radio_StormTheFront:
if (((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) && Random.Long (0, 100) > 50) if (((IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) && Random.Long (0, 100) > 50)
{ {
RadioMessage (Radio_Affirmative); RadioMessage (Radio_Affirmative);
@ -2561,7 +2561,7 @@ void Bot::CheckRadioCommands (void)
break; break;
case Radio_Fallback: case Radio_Fallback:
if ((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) if ((IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f)
{ {
m_fearLevel += 0.5f; m_fearLevel += 0.5f;
@ -2667,7 +2667,7 @@ void Bot::CheckRadioCommands (void)
break; break;
case Radio_GetInPosition: case Radio_GetInPosition:
if ((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) if ((IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f)
{ {
RadioMessage (Radio_Affirmative); RadioMessage (Radio_Affirmative);
@ -2960,7 +2960,7 @@ void Bot::ThinkDelayed (void)
// no movement allowed in // no movement allowed in
if (m_voteKickIndex != m_lastVoteKick && yb_tkpunish.GetBool ()) // we got a teamkiller? vote him away... if (m_voteKickIndex != m_lastVoteKick && yb_tkpunish.GetBool ()) // we got a teamkiller? vote him away...
{ {
FakeClientCommand (GetEntity (), "vote %d", m_voteKickIndex); engine.IssueBotCommand (GetEntity (), "vote %d", m_voteKickIndex);
m_lastVoteKick = m_voteKickIndex; m_lastVoteKick = m_voteKickIndex;
// if bot tk punishment is enabled slay the tk // if bot tk punishment is enabled slay the tk
@ -2974,7 +2974,7 @@ void Bot::ThinkDelayed (void)
} }
else if (m_voteMap != 0) // host wants the bots to vote for a map? else if (m_voteMap != 0) // host wants the bots to vote for a map?
{ {
FakeClientCommand (GetEntity (), "votemap %d", m_voteMap); engine.IssueBotCommand (GetEntity (), "votemap %d", m_voteMap);
m_voteMap = 0; m_voteMap = 0;
} }
extern ConVar yb_chat; extern ConVar yb_chat;
@ -3048,7 +3048,7 @@ void Bot::PeriodicThink (void)
CheckSpawnTimeConditions (); CheckSpawnTimeConditions ();
// clear enemy far away // clear enemy far away
if (!m_lastEnemyOrigin.IsZero () && !IsEntityNull (m_lastEnemy) && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0f) if (!m_lastEnemyOrigin.IsZero () && !IsNullEntity (m_lastEnemy) && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0f)
{ {
m_lastEnemy = NULL; m_lastEnemy = NULL;
m_lastEnemyOrigin.Zero (); m_lastEnemyOrigin.Zero ();
@ -3068,7 +3068,7 @@ void Bot::RunTask_Normal (void)
} }
// bots rushing with knife, when have no enemy (thanks for idea to nicebot project) // bots rushing with knife, when have no enemy (thanks for idea to nicebot project)
if (m_currentWeapon == WEAPON_KNIFE && (IsEntityNull (m_lastEnemy) || !IsAlive (m_lastEnemy)) && IsEntityNull (m_enemy) && m_knifeAttackTime < engine.Time () && !HasShield () && GetNearbyFriendsNearPosition (pev->origin, 96) == 0) if (m_currentWeapon == WEAPON_KNIFE && (IsNullEntity (m_lastEnemy) || !IsAlive (m_lastEnemy)) && IsNullEntity (m_enemy) && m_knifeAttackTime < engine.Time () && !HasShield () && GetNearbyFriendsNearPosition (pev->origin, 96) == 0)
{ {
if (Random.Long (0, 100) < 40) if (Random.Long (0, 100) < 40)
pev->button |= IN_ATTACK; pev->button |= IN_ATTACK;
@ -3098,7 +3098,7 @@ void Bot::RunTask_Normal (void)
m_prevGoalIndex = -1; m_prevGoalIndex = -1;
// spray logo sometimes if allowed to do so // spray logo sometimes if allowed to do so
if (m_timeLogoSpray < engine.Time () && yb_spraypaints.GetBool () && Random.Long (1, 100) < 60 && m_moveSpeed > GetWalkSpeed () && IsEntityNull (m_pickupItem)) if (m_timeLogoSpray < engine.Time () && yb_spraypaints.GetBool () && Random.Long (1, 100) < 60 && m_moveSpeed > GetWalkSpeed () && IsNullEntity (m_pickupItem))
{ {
if (!((g_mapType & MAP_DE) && g_bombPlanted && m_team == CT)) if (!((g_mapType & MAP_DE) && g_bombPlanted && m_team == CT))
PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, engine.Time () + 1.0f, false); PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, engine.Time () + 1.0f, false);
@ -3324,7 +3324,7 @@ void Bot::RunTask_HuntEnemy (void)
m_checkTerrain = true; m_checkTerrain = true;
// if we've got new enemy... // if we've got new enemy...
if (!IsEntityNull (m_enemy) || IsEntityNull (m_lastEnemy)) if (!IsNullEntity (m_enemy) || IsNullEntity (m_lastEnemy))
{ {
// forget about it... // forget about it...
TaskComplete (); TaskComplete ();
@ -3390,7 +3390,7 @@ void Bot::RunTask_SeekCover (void)
{ {
m_aimFlags |= AIM_NAVPOINT; m_aimFlags |= AIM_NAVPOINT;
if (IsEntityNull (m_lastEnemy) || !IsAlive (m_lastEnemy)) if (IsNullEntity (m_lastEnemy) || !IsAlive (m_lastEnemy))
{ {
TaskComplete (); TaskComplete ();
m_prevGoalIndex = -1; m_prevGoalIndex = -1;
@ -3478,7 +3478,7 @@ void Bot::RunTask_Attack (void)
m_moveToGoal = false; m_moveToGoal = false;
m_checkTerrain = false; m_checkTerrain = false;
if (!IsEntityNull (m_enemy)) if (!IsNullEntity (m_enemy))
{ {
IgnoreCollisionShortly (); IgnoreCollisionShortly ();
@ -3702,7 +3702,7 @@ void Bot::RunTask_Hide (void)
m_campButtons = 0; m_campButtons = 0;
m_prevGoalIndex = -1; m_prevGoalIndex = -1;
if (!IsEntityNull (m_enemy)) if (!IsNullEntity (m_enemy))
CombatFight (); CombatFight ();
return; return;
@ -3986,7 +3986,7 @@ void Bot::RunTask_DefuseBomb (void)
void Bot::RunTask_FollowUser (void) void Bot::RunTask_FollowUser (void)
{ {
if (IsEntityNull (m_targetEntity) || !IsAlive (m_targetEntity)) if (IsNullEntity (m_targetEntity) || !IsAlive (m_targetEntity))
{ {
m_targetEntity = NULL; m_targetEntity = NULL;
TaskComplete (); TaskComplete ();
@ -4001,7 +4001,7 @@ void Bot::RunTask_FollowUser (void)
TraceResult tr; TraceResult tr;
engine.TestLine (m_targetEntity->v.origin + m_targetEntity->v.view_ofs, g_pGlobals->v_forward * 500.0f, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); engine.TestLine (m_targetEntity->v.origin + m_targetEntity->v.view_ofs, g_pGlobals->v_forward * 500.0f, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr);
if (!IsEntityNull (tr.pHit) && IsValidPlayer (tr.pHit) && GetTeam (tr.pHit) != m_team) if (!IsNullEntity (tr.pHit) && IsValidPlayer (tr.pHit) && GetTeam (tr.pHit) != m_team)
{ {
m_targetEntity = NULL; m_targetEntity = NULL;
m_lastEnemy = tr.pHit; m_lastEnemy = tr.pHit;
@ -4096,7 +4096,7 @@ void Bot::RunTask_Throw_HE (void)
m_moveSpeed = 0.0f; m_moveSpeed = 0.0f;
m_moveToGoal = false; m_moveToGoal = false;
} }
else if (!(m_states & STATE_SUSPECT_ENEMY) && !IsEntityNull (m_enemy)) else if (!(m_states & STATE_SUSPECT_ENEMY) && !IsNullEntity (m_enemy))
dest = m_enemy->v.origin + m_enemy->v.velocity.Get2D () * 0.5f; dest = m_enemy->v.origin + m_enemy->v.velocity.Get2D () * 0.5f;
m_isUsingGrenade = true; m_isUsingGrenade = true;
@ -4131,7 +4131,7 @@ void Bot::RunTask_Throw_HE (void)
{ {
edict_t *ent = NULL; edict_t *ent = NULL;
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade")))
{ {
if (ent->v.owner == GetEntity () && strcmp (STRING (ent->v.model) + 9, "hegrenade.mdl") == 0) if (ent->v.owner == GetEntity () && strcmp (STRING (ent->v.model) + 9, "hegrenade.mdl") == 0)
{ {
@ -4148,7 +4148,7 @@ void Bot::RunTask_Throw_HE (void)
} }
} }
if (IsEntityNull (ent)) if (IsNullEntity (ent))
{ {
if (m_currentWeapon != WEAPON_EXPLOSIVE) if (m_currentWeapon != WEAPON_EXPLOSIVE)
{ {
@ -4172,7 +4172,7 @@ void Bot::RunTask_Throw_FL (void)
m_strafeSpeed = 0.0f; m_strafeSpeed = 0.0f;
m_moveSpeed = 0.0f; m_moveSpeed = 0.0f;
} }
else if (!(m_states & STATE_SUSPECT_ENEMY) && !IsEntityNull (m_enemy)) else if (!(m_states & STATE_SUSPECT_ENEMY) && !IsNullEntity (m_enemy))
dest = m_enemy->v.origin + m_enemy->v.velocity.Get2D () * 0.5; dest = m_enemy->v.origin + m_enemy->v.velocity.Get2D () * 0.5;
m_isUsingGrenade = true; m_isUsingGrenade = true;
@ -4196,7 +4196,7 @@ void Bot::RunTask_Throw_FL (void)
else else
{ {
edict_t *ent = NULL; edict_t *ent = NULL;
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade")))
{ {
if (ent->v.owner == GetEntity () && strcmp (STRING (ent->v.model) + 9, "flashbang.mdl") == 0) if (ent->v.owner == GetEntity () && strcmp (STRING (ent->v.model) + 9, "flashbang.mdl") == 0)
{ {
@ -4212,7 +4212,7 @@ void Bot::RunTask_Throw_FL (void)
} }
} }
if (IsEntityNull (ent)) if (IsNullEntity (ent))
{ {
if (m_currentWeapon != WEAPON_FLASHBANG) if (m_currentWeapon != WEAPON_FLASHBANG)
{ {
@ -4244,7 +4244,7 @@ void Bot::RunTask_Throw_SG (void)
Vector src = m_lastEnemyOrigin - pev->velocity; Vector src = m_lastEnemyOrigin - pev->velocity;
// predict where the enemy is in 0.5 secs // predict where the enemy is in 0.5 secs
if (!IsEntityNull (m_enemy)) if (!IsNullEntity (m_enemy))
src = src + m_enemy->v.velocity * 0.5f; src = src + m_enemy->v.velocity * 0.5f;
m_grenade = (src - EyePosition ()).Normalize (); m_grenade = (src - EyePosition ()).Normalize ();
@ -4274,7 +4274,7 @@ void Bot::RunTask_Throw_SG (void)
void Bot::RunTask_DoubleJump (void) void Bot::RunTask_DoubleJump (void)
{ {
if (IsEntityNull (m_doubleJumpEntity) || !IsAlive (m_doubleJumpEntity) || (m_aimFlags & AIM_ENEMY) || (m_travelStartIndex != -1 && GetTask ()->time + (waypoints.GetTravelTime (pev->maxspeed, waypoints.GetPath (m_travelStartIndex)->origin, m_doubleJumpOrigin) + 11.0) < engine.Time ())) if (IsNullEntity (m_doubleJumpEntity) || !IsAlive (m_doubleJumpEntity) || (m_aimFlags & AIM_ENEMY) || (m_travelStartIndex != -1 && GetTask ()->time + (waypoints.GetTravelTime (pev->maxspeed, waypoints.GetPath (m_travelStartIndex)->origin, m_doubleJumpOrigin) + 11.0) < engine.Time ()))
{ {
ResetDoubleJumpState (); ResetDoubleJumpState ();
return; return;
@ -4404,7 +4404,7 @@ void Bot::RunTask_ShootBreakable (void)
m_aimFlags |= AIM_OVERRIDE; m_aimFlags |= AIM_OVERRIDE;
// Breakable destroyed? // Breakable destroyed?
if (IsEntityNull (FindBreakable ())) if (IsNullEntity (FindBreakable ()))
{ {
TaskComplete (); TaskComplete ();
return; return;
@ -4438,7 +4438,7 @@ void Bot::RunTask_ShootBreakable (void)
void Bot::RunTask_PickupItem () void Bot::RunTask_PickupItem ()
{ {
if (IsEntityNull (m_pickupItem)) if (IsNullEntity (m_pickupItem))
{ {
m_pickupItem = NULL; m_pickupItem = NULL;
TaskComplete (); TaskComplete ();
@ -4487,10 +4487,10 @@ void Bot::RunTask_PickupItem ()
if (weaponID > 0) if (weaponID > 0)
{ {
SelectWeaponbyNumber (weaponID); SelectWeaponbyNumber (weaponID);
FakeClientCommand (GetEntity (), "drop"); engine.IssueBotCommand (GetEntity (), "drop");
if (HasShield ()) // If we have the shield... if (HasShield ()) // If we have the shield...
FakeClientCommand (GetEntity (), "drop"); // discard both shield and pistol engine.IssueBotCommand (GetEntity (), "drop"); // discard both shield and pistol
} }
EquipInBuyzone (BUYSTATE_PRIMARY_WEAPON); EquipInBuyzone (BUYSTATE_PRIMARY_WEAPON);
} }
@ -4502,7 +4502,7 @@ void Bot::RunTask_PickupItem ()
if ((weaponID > 6) || HasShield ()) if ((weaponID > 6) || HasShield ())
{ {
SelectWeaponbyNumber (weaponID); SelectWeaponbyNumber (weaponID);
FakeClientCommand (GetEntity (), "drop"); engine.IssueBotCommand (GetEntity (), "drop");
} }
EquipInBuyzone (BUYSTATE_PRIMARY_WEAPON); EquipInBuyzone (BUYSTATE_PRIMARY_WEAPON);
} }
@ -4526,7 +4526,7 @@ void Bot::RunTask_PickupItem ()
if (weaponID > 6) if (weaponID > 6)
{ {
SelectWeaponbyNumber (weaponID); SelectWeaponbyNumber (weaponID);
FakeClientCommand (GetEntity (), "drop"); engine.IssueBotCommand (GetEntity (), "drop");
} }
} }
break; break;
@ -4578,7 +4578,7 @@ void Bot::RunTask_PickupItem ()
for (int i = 0; i < MAX_HOSTAGES; i++) for (int i = 0; i < MAX_HOSTAGES; i++)
{ {
if (IsEntityNull (m_hostages[i])) // store pointer to hostage so other bots don't steal from this one or bot tries to reuse it if (IsNullEntity (m_hostages[i])) // store pointer to hostage so other bots don't steal from this one or bot tries to reuse it
{ {
m_hostages[i] = m_pickupItem; m_hostages[i] = m_pickupItem;
m_pickupItem = NULL; m_pickupItem = NULL;
@ -4604,7 +4604,7 @@ void Bot::RunTask_PickupItem ()
case PICKUP_BUTTON: case PICKUP_BUTTON:
m_aimFlags |= AIM_ENTITY; m_aimFlags |= AIM_ENTITY;
if (IsEntityNull (m_pickupItem) || m_buttonPushTime < engine.Time ()) // it's safer... if (IsNullEntity (m_pickupItem) || m_buttonPushTime < engine.Time ()) // it's safer...
{ {
TaskComplete (); TaskComplete ();
m_pickupType = PICKUP_NONE; m_pickupType = PICKUP_NONE;
@ -4762,14 +4762,14 @@ void Bot::CheckSpawnTimeConditions (void)
if (yb_jasonmode.GetBool ()) if (yb_jasonmode.GetBool ())
{ {
SelectPistol (); SelectPistol ();
FakeClientCommand (GetEntity (), "drop"); engine.IssueBotCommand (GetEntity (), "drop");
} }
else else
SelectWeaponByName ("weapon_knife"); SelectWeaponByName ("weapon_knife");
} }
m_checkKnifeSwitch = false; m_checkKnifeSwitch = false;
if (Random.Long (0, 100) < yb_user_follow_percent.GetInt () && IsEntityNull (m_targetEntity) && !m_isLeader && !m_hasC4) if (Random.Long (0, 100) < yb_user_follow_percent.GetInt () && IsNullEntity (m_targetEntity) && !m_isLeader && !m_hasC4)
AttachToUser (); AttachToUser ();
} }
@ -4847,7 +4847,7 @@ void Bot::BotAI (void)
// some stuff required by by chatter engine // some stuff required by by chatter engine
if (yb_communication_type.GetInt () == 2) if (yb_communication_type.GetInt () == 2)
{ {
if ((m_states & STATE_SEEING_ENEMY) && !IsEntityNull (m_enemy)) if ((m_states & STATE_SEEING_ENEMY) && !IsNullEntity (m_enemy))
{ {
int hasFriendNearby = GetNearbyFriendsNearPosition (pev->origin, 512.0f); int hasFriendNearby = GetNearbyFriendsNearPosition (pev->origin, 512.0f);
@ -4950,12 +4950,12 @@ void Bot::BotAI (void)
} }
// time to reach waypoint // time to reach waypoint
if (m_navTimeset + GetEstimatedReachTime () < engine.Time () && IsEntityNull (m_enemy)) if (m_navTimeset + GetEstimatedReachTime () < engine.Time () && IsNullEntity (m_enemy))
{ {
GetValidWaypoint (); GetValidWaypoint ();
// clear these pointers, bot mingh be stuck getting to them // clear these pointers, bot mingh be stuck getting to them
if (!IsEntityNull (m_pickupItem) && !m_hasProgressBar) if (!IsNullEntity (m_pickupItem) && !m_hasProgressBar)
m_itemIgnore = m_pickupItem; m_itemIgnore = m_pickupItem;
m_pickupItem = NULL; m_pickupItem = NULL;
@ -4993,7 +4993,7 @@ void Bot::BotAI (void)
} }
// display some debugging thingy to host entity // display some debugging thingy to host entity
if (!IsEntityNull (g_hostEntity) && yb_debug.GetInt () >= 1) if (!IsNullEntity (g_hostEntity) && yb_debug.GetInt () >= 1)
DisplayDebugOverlay (); DisplayDebugOverlay ();
// save the previous speed (for checking if stuck) // save the previous speed (for checking if stuck)
@ -5121,9 +5121,9 @@ void Bot::DisplayDebugOverlay (void)
char enemyName[80], weaponName[80], aimFlags[64], botType[32]; char enemyName[80], weaponName[80], aimFlags[64], botType[32];
if (!IsEntityNull (m_enemy)) if (!IsNullEntity (m_enemy))
strncpy (enemyName, STRING (m_enemy->v.netname), SIZEOF_CHAR (enemyName)); strncpy (enemyName, STRING (m_enemy->v.netname), SIZEOF_CHAR (enemyName));
else if (!IsEntityNull (m_lastEnemy)) else if (!IsNullEntity (m_lastEnemy))
{ {
strcpy (enemyName, " (L)"); strcpy (enemyName, " (L)");
strncat (enemyName, STRING (m_lastEnemy->v.netname), SIZEOF_CHAR (enemyName)); strncat (enemyName, STRING (m_lastEnemy->v.netname), SIZEOF_CHAR (enemyName));
@ -5134,7 +5134,7 @@ void Bot::DisplayDebugOverlay (void)
char pickupName[80]; char pickupName[80];
memset (pickupName, 0, sizeof (pickupName)); memset (pickupName, 0, sizeof (pickupName));
if (!IsEntityNull (m_pickupItem)) if (!IsNullEntity (m_pickupItem))
strncpy (pickupName, STRING (m_pickupItem->v.classname), SIZEOF_CHAR (pickupName)); strncpy (pickupName, STRING (m_pickupItem->v.classname), SIZEOF_CHAR (pickupName));
else else
strcpy (pickupName, " (null)"); strcpy (pickupName, " (null)");
@ -5255,7 +5255,7 @@ bool Bot::HasHostage (void)
{ {
for (int i = 0; i < MAX_HOSTAGES; i++) for (int i = 0; i < MAX_HOSTAGES; i++)
{ {
if (!IsEntityNull (m_hostages[i])) if (!IsNullEntity (m_hostages[i]))
{ {
// don't care about dead hostages // don't care about dead hostages
if (m_hostages[i]->v.health <= 0.0f || (pev->origin - m_hostages[i]->v.origin).GetLength () > 600.0f) if (m_hostages[i]->v.health <= 0.0f || (pev->origin - m_hostages[i]->v.origin).GetLength () > 600.0f)
@ -5321,7 +5321,7 @@ void Bot::TakeDamage (edict_t *inflictor, int damage, int armor, int bits)
} }
RemoveCertainTask (TASK_CAMP); RemoveCertainTask (TASK_CAMP);
if (IsEntityNull (m_enemy) && m_team != GetTeam (inflictor)) if (IsNullEntity (m_enemy) && m_team != GetTeam (inflictor))
{ {
m_lastEnemy = inflictor; m_lastEnemy = inflictor;
m_lastEnemyOrigin = inflictor->v.origin; m_lastEnemyOrigin = inflictor->v.origin;
@ -5559,12 +5559,12 @@ void Bot::DiscardWeaponForUser (edict_t *user, bool discardC4)
if (discardC4) if (discardC4)
{ {
SelectWeaponByName ("weapon_c4"); SelectWeaponByName ("weapon_c4");
FakeClientCommand (GetEntity (), "drop"); engine.IssueBotCommand (GetEntity (), "drop");
} }
else else
{ {
SelectBestWeapon (); SelectBestWeapon ();
FakeClientCommand (GetEntity (), "drop"); engine.IssueBotCommand (GetEntity (), "drop");
} }
m_pickupItem = NULL; m_pickupItem = NULL;
@ -5612,7 +5612,7 @@ void Bot::DebugMsg (const char *format, ...)
bool playMessage = false; bool playMessage = false;
if (level == 3 && !IsEntityNull (g_hostEntity) && g_hostEntity->v.iuser2 == IndexOfEntity (GetEntity ())) if (level == 3 && !IsNullEntity (g_hostEntity) && g_hostEntity->v.iuser2 == IndexOfEntity (GetEntity ()))
playMessage = true; playMessage = true;
else if (level != 3) else if (level != 3)
playMessage = true; playMessage = true;
@ -5973,7 +5973,7 @@ void Bot::ReactOnSound (void)
m_heardSoundTime = engine.Time (); m_heardSoundTime = engine.Time ();
m_states |= STATE_HEARING_ENEMY; m_states |= STATE_HEARING_ENEMY;
if ((Random.Long (0, 100) < 15) && IsEntityNull (m_enemy) && IsEntityNull (m_lastEnemy) && m_seeEnemyTime + 7.0f < engine.Time ()) if ((Random.Long (0, 100) < 15) && IsNullEntity (m_enemy) && IsNullEntity (m_lastEnemy) && m_seeEnemyTime + 7.0f < engine.Time ())
ChatterMessage (Chatter_HeardEnemy); ChatterMessage (Chatter_HeardEnemy);
// didn't bot already have an enemy ? take this one... // didn't bot already have an enemy ? take this one...
@ -6058,7 +6058,6 @@ bool Bot::IsBombDefusing (const Vector &bombOrigin)
{ {
// this function finds if somebody currently defusing the bomb. // this function finds if somebody currently defusing the bomb.
// @todo: need to check progress bar for non-bots clients.
bool defusingInProgress = false; bool defusingInProgress = false;
for (int i = 0; i < engine.MaxClients (); i++) for (int i = 0; i < engine.MaxClients (); i++)
@ -6076,12 +6075,13 @@ bool Bot::IsBombDefusing (const Vector &bombOrigin)
defusingInProgress = true; defusingInProgress = true;
break; break;
} }
Client *client = &g_clients[i];
// take in account peoples too // take in account peoples too
if (defusingInProgress || !(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team != m_team || IsValidBot (g_clients[i].ent)) if (defusingInProgress || !(client->flags & CF_USED) || !(client->flags & CF_ALIVE) || client->team != m_team || IsValidBot (g_clients[i].ent))
continue; continue;
if ((g_clients[i].ent->v.origin - bombOrigin).GetLength () < 140.0f) if ((client->ent->v.origin - bombOrigin).GetLength () < 140.0f && ((client->ent->v.button | client->ent->v.oldbuttons) & IN_USE))
{ {
defusingInProgress = true; defusingInProgress = true;
break; break;

View file

@ -47,7 +47,7 @@ void StripTags (char *buffer)
// have we stripped too much (all the stuff)? // have we stripped too much (all the stuff)?
if (buffer[0] != '\0') if (buffer[0] != '\0')
{ {
strtrim (buffer); // if so, string is just a tag String::TrimExternalBuffer (buffer); // if so, string is just a tag
int tagLength = 0; int tagLength = 0;
@ -81,7 +81,7 @@ void StripTags (char *buffer)
} }
} }
} }
strtrim (buffer); // to finish, strip eventual blanks after and before the tag marks String::TrimExternalBuffer (buffer); // to finish, strip eventual blanks after and before the tag marks
} }
char *HumanizeName (char *name) char *HumanizeName (char *name)
@ -95,7 +95,7 @@ char *HumanizeName (char *name)
if (Random.Long (1, 100) < 80) if (Random.Long (1, 100) < 80)
StripTags (outputName); StripTags (outputName);
else else
strtrim (outputName); String::TrimExternalBuffer (outputName);
// sometimes switch name to lower characters // sometimes switch name to lower characters
// note: since we're using russian names written in english, we reduce this shit to 6 percent // note: since we're using russian names written in english, we reduce this shit to 6 percent
@ -156,7 +156,7 @@ void Bot::PrepareChatMessage (char *text)
if (!yb_chat.GetBool () || IsNullString (text)) if (!yb_chat.GetBool () || IsNullString (text))
return; return;
#define ASSIGN_TALK_ENTITY() if (!IsEntityNull (talkEntity)) strncat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))), SIZEOF_CHAR (m_tempStrings)) #define ASSIGN_TALK_ENTITY() if (!IsNullEntity (talkEntity)) strncat (m_tempStrings, HumanizeName (const_cast <char *> (STRING (talkEntity->v.netname))), SIZEOF_CHAR (m_tempStrings))
memset (&m_tempStrings, 0, sizeof (m_tempStrings)); memset (&m_tempStrings, 0, sizeof (m_tempStrings));
@ -232,7 +232,7 @@ void Bot::PrepareChatMessage (char *text)
if (i < engine.MaxClients ()) if (i < engine.MaxClients ())
{ {
if (!IsEntityNull (pev->dmg_inflictor) && m_team == GetTeam (pev->dmg_inflictor)) if (!IsNullEntity (pev->dmg_inflictor) && m_team == GetTeam (pev->dmg_inflictor))
talkEntity = pev->dmg_inflictor; talkEntity = pev->dmg_inflictor;
else else
talkEntity = g_clients[i].ent; talkEntity = g_clients[i].ent;
@ -426,7 +426,7 @@ void Bot::SayText (const char *text)
if (IsNullString (text)) if (IsNullString (text))
return; return;
FakeClientCommand (GetEntity (), "say \"%s\"", text); engine.IssueBotCommand (GetEntity (), "say \"%s\"", text);
} }
void Bot::TeamSayText (const char *text) void Bot::TeamSayText (const char *text)
@ -436,5 +436,5 @@ void Bot::TeamSayText (const char *text)
if (IsNullString (text)) if (IsNullString (text))
return; return;
FakeClientCommand (GetEntity (), "say_team \"%s\"", text); engine.IssueBotCommand (GetEntity (), "say_team \"%s\"", text);
} }

View file

@ -48,7 +48,7 @@ int Bot::GetNearbyEnemiesNearPosition(const Vector &origin, float radius)
bool Bot::IsEnemyHiddenByRendering (edict_t *enemy) bool Bot::IsEnemyHiddenByRendering (edict_t *enemy)
{ {
if (IsEntityNull (enemy) || !yb_check_enemy_rendering.GetBool ()) if (IsNullEntity (enemy) || !yb_check_enemy_rendering.GetBool ())
return false; return false;
entvars_t &v = enemy->v; entvars_t &v = enemy->v;
@ -183,7 +183,7 @@ bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart)
bool Bot::IsEnemyViewable (edict_t *player) bool Bot::IsEnemyViewable (edict_t *player)
{ {
if (IsEntityNull (player)) if (IsNullEntity (player))
return false; return false;
bool forceTrueIfVisible = false; bool forceTrueIfVisible = false;
@ -218,7 +218,7 @@ bool Bot::LookupEnemy (void)
if (m_seeEnemyTime + 3.0f < engine.Time ()) if (m_seeEnemyTime + 3.0f < engine.Time ())
m_states &= ~STATE_SUSPECT_ENEMY; m_states &= ~STATE_SUSPECT_ENEMY;
if (!IsEntityNull (m_enemy) && m_enemyUpdateTime > engine.Time ()) if (!IsNullEntity (m_enemy) && m_enemyUpdateTime > engine.Time ())
{ {
player = m_enemy; player = m_enemy;
@ -228,7 +228,7 @@ bool Bot::LookupEnemy (void)
} }
// the old enemy is no longer visible or // the old enemy is no longer visible or
if (IsEntityNull (newEnemy)) if (IsNullEntity (newEnemy))
{ {
m_enemyUpdateTime = engine.Time () + 0.5f; m_enemyUpdateTime = engine.Time () + 0.5f;
@ -289,7 +289,7 @@ bool Bot::LookupEnemy (void)
} }
} }
if (IsEntityNull (newEnemy) && !IsEntityNull (shieldEnemy)) if (IsNullEntity (newEnemy) && !IsNullEntity (shieldEnemy))
newEnemy = shieldEnemy; newEnemy = shieldEnemy;
} }
@ -314,7 +314,7 @@ bool Bot::LookupEnemy (void)
} }
else else
{ {
if (m_seeEnemyTime + 3.0 < engine.Time () && (m_hasC4 || HasHostage () || !IsEntityNull (m_targetEntity))) if (m_seeEnemyTime + 3.0 < engine.Time () && (m_hasC4 || HasHostage () || !IsNullEntity (m_targetEntity)))
RadioMessage (Radio_EnemySpotted); RadioMessage (Radio_EnemySpotted);
m_targetEntity = NULL; // stop following when we see an enemy... m_targetEntity = NULL; // stop following when we see an enemy...
@ -345,7 +345,7 @@ bool Bot::LookupEnemy (void)
Bot *friendBot = bots.GetBot (g_clients[j].ent); Bot *friendBot = bots.GetBot (g_clients[j].ent);
if (friendBot != NULL && friendBot->m_seeEnemyTime + 2.0f < engine.Time () && IsEntityNull (friendBot->m_lastEnemy) && IsVisible (pev->origin, ENT (friendBot->pev)) && friendBot->IsInViewCone (pev->origin)) if (friendBot != NULL && friendBot->m_seeEnemyTime + 2.0f < engine.Time () && IsNullEntity (friendBot->m_lastEnemy) && IsVisible (pev->origin, ENT (friendBot->pev)) && friendBot->IsInViewCone (pev->origin))
{ {
friendBot->m_lastEnemy = newEnemy; friendBot->m_lastEnemy = newEnemy;
friendBot->m_lastEnemyOrigin = m_lastEnemyOrigin; friendBot->m_lastEnemyOrigin = m_lastEnemyOrigin;
@ -357,7 +357,7 @@ bool Bot::LookupEnemy (void)
return true; return true;
} }
} }
else if (!IsEntityNull (m_enemy)) else if (!IsNullEntity (m_enemy))
{ {
newEnemy = m_enemy; newEnemy = m_enemy;
m_lastEnemy = newEnemy; m_lastEnemy = newEnemy;
@ -406,7 +406,7 @@ bool Bot::LookupEnemy (void)
} }
// check if bots should reload... // check if bots should reload...
if ((m_aimFlags <= AIM_PREDICT_PATH && m_seeEnemyTime + 3.0f < engine.Time () && !(m_states & (STATE_SEEING_ENEMY | STATE_HEARING_ENEMY)) && IsEntityNull (m_lastEnemy) && IsEntityNull (m_enemy) && GetTaskId () != TASK_SHOOTBREAKABLE && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB) || g_roundEnded) if ((m_aimFlags <= AIM_PREDICT_PATH && m_seeEnemyTime + 3.0f < engine.Time () && !(m_states & (STATE_SEEING_ENEMY | STATE_HEARING_ENEMY)) && IsNullEntity (m_lastEnemy) && IsNullEntity (m_enemy) && GetTaskId () != TASK_SHOOTBREAKABLE && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB) || g_roundEnded)
{ {
if (!m_reloadState) if (!m_reloadState)
m_reloadState = RELOAD_PRIMARY; m_reloadState = RELOAD_PRIMARY;
@ -560,7 +560,7 @@ bool Bot::IsFriendInLineOfFire (float distance)
engine.TestLine (EyePosition (), EyePosition () + 10000.0f * pev->v_angle, TRACE_IGNORE_NONE, GetEntity (), &tr); engine.TestLine (EyePosition (), EyePosition () + 10000.0f * pev->v_angle, TRACE_IGNORE_NONE, GetEntity (), &tr);
// check if we hit something // check if we hit something
if (!IsEntityNull (tr.pHit) && tr.pHit != g_worldEntity) if (!IsNullEntity (tr.pHit) && tr.pHit != g_worldEntity)
{ {
int playerIndex = IndexOfEntity (tr.pHit) - 1; int playerIndex = IndexOfEntity (tr.pHit) - 1;
@ -731,7 +731,7 @@ void Bot::FireWeapon (void)
} }
// or if friend in line of fire, stop this too but do not update shoot time // or if friend in line of fire, stop this too but do not update shoot time
if (!IsEntityNull (m_enemy)) if (!IsNullEntity (m_enemy))
{ {
if (IsFriendInLineOfFire (distance)) if (IsFriendInLineOfFire (distance))
{ {
@ -753,7 +753,7 @@ void Bot::FireWeapon (void)
goto WeaponSelectEnd; goto WeaponSelectEnd;
// use knife if near and good difficulty (l33t dude!) // use knife if near and good difficulty (l33t dude!)
if (m_difficulty >= 3 && pev->health > 80.0f && !IsEntityNull (enemy) && pev->health >= enemy->v.health && distance < 100.0f && !IsOnLadder () && !IsGroupOfEnemies (pev->origin)) if (m_difficulty >= 3 && pev->health > 80.0f && !IsNullEntity (enemy) && pev->health >= enemy->v.health && distance < 100.0f && !IsOnLadder () && !IsGroupOfEnemies (pev->origin))
goto WeaponSelectEnd; goto WeaponSelectEnd;
// loop through all the weapons until terminator is found... // loop through all the weapons until terminator is found...
@ -844,7 +844,7 @@ WeaponSelectEnd:
{ {
if (distance >= 750.0f && !IsShieldDrawn ()) if (distance >= 750.0f && !IsShieldDrawn ())
pev->button |= IN_ATTACK2; // draw the shield pev->button |= IN_ATTACK2; // draw the shield
else if (IsShieldDrawn () || (!IsEntityNull (m_enemy) && ((m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable(m_enemy)))) else if (IsShieldDrawn () || (!IsNullEntity (m_enemy) && ((m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable(m_enemy))))
pev->button |= IN_ATTACK2; // draw out the shield pev->button |= IN_ATTACK2; // draw out the shield
m_shieldCheckTime = engine.Time () + 1.0f; m_shieldCheckTime = engine.Time () + 1.0f;
@ -863,7 +863,7 @@ WeaponSelectEnd:
m_zoomCheckTime = engine.Time (); m_zoomCheckTime = engine.Time ();
if (!IsEntityNull (m_enemy) && (m_states & STATE_SEEING_ENEMY)) if (!IsNullEntity (m_enemy) && (m_states & STATE_SEEING_ENEMY))
{ {
m_moveSpeed = 0.0f; m_moveSpeed = 0.0f;
m_strafeSpeed = 0.0f; m_strafeSpeed = 0.0f;
@ -1011,7 +1011,7 @@ void Bot::FocusEnemy (void)
void Bot::CombatFight (void) void Bot::CombatFight (void)
{ {
// no enemy? no need to do strafing // no enemy? no need to do strafing
if (IsEntityNull (m_enemy)) if (IsNullEntity (m_enemy))
return; return;
float distance = (m_lookAt - EyePosition ()).GetLength2D (); // how far away is the enemy scum? float distance = (m_lookAt - EyePosition ()).GetLength2D (); // how far away is the enemy scum?
@ -1223,7 +1223,7 @@ bool Bot::IsEnemyProtectedByShield (edict_t *enemy)
{ {
// this function returns true, if enemy protected by the shield // this function returns true, if enemy protected by the shield
if (IsEntityNull (enemy) || IsShieldDrawn ()) if (IsNullEntity (enemy) || IsShieldDrawn ())
return false; return false;
// check if enemy has shield and this shield is drawn // check if enemy has shield and this shield is drawn
@ -1408,12 +1408,12 @@ int Bot::GetHighestWeapon (void)
void Bot::SelectWeaponByName (const char *name) void Bot::SelectWeaponByName (const char *name)
{ {
FakeClientCommand (GetEntity (), name); engine.IssueBotCommand (GetEntity (), name);
} }
void Bot::SelectWeaponbyNumber (int num) void Bot::SelectWeaponbyNumber (int num)
{ {
FakeClientCommand (GetEntity (), g_weaponSelect[num].weaponName); engine.IssueBotCommand (GetEntity (), g_weaponSelect[num].weaponName);
} }
void Bot::AttachToUser (void) void Bot::AttachToUser (void)

View file

@ -11,10 +11,14 @@
void Engine::Precache (void) void Engine::Precache (void)
{ {
// this function precaches needed models for DrawLine // this function precaches needed models and initialize class variables
m_drawModels[DRAW_SIMPLE] = PRECACHE_MODEL (ENGINE_STR ("sprites/laserbeam.spr")); m_drawModels[DRAW_SIMPLE] = PRECACHE_MODEL (ENGINE_STR ("sprites/laserbeam.spr"));
m_drawModels[DRAW_ARROW] = PRECACHE_MODEL (ENGINE_STR ("sprites/arrow1.spr")); m_drawModels[DRAW_ARROW] = PRECACHE_MODEL (ENGINE_STR ("sprites/arrow1.spr"));
m_isBotCommand = false;
m_argumentCount = 0;
m_arguments[0] = { 0, };
} }
void Engine::Printf (const char *fmt, ...) void Engine::Printf (const char *fmt, ...)
@ -22,10 +26,10 @@ void Engine::Printf (const char *fmt, ...)
// this function outputs string into server console // this function outputs string into server console
va_list ap; va_list ap;
char string[1024]; static char string[1024];
va_start (ap, fmt); va_start (ap, fmt);
vsprintf (string, locale.TranslateInput (fmt), ap); vsnprintf (string, SIZEOF_CHAR (string), locale.TranslateInput (fmt), ap);
va_end (ap); va_end (ap);
g_engfuncs.pfnServerPrint (string); g_engfuncs.pfnServerPrint (string);
@ -35,10 +39,10 @@ void Engine::Printf (const char *fmt, ...)
void Engine::ChatPrintf (const char *fmt, ...) void Engine::ChatPrintf (const char *fmt, ...)
{ {
va_list ap; va_list ap;
char string[512]; static char string[1024];
va_start (ap, fmt); va_start (ap, fmt);
vsprintf (string, locale.TranslateInput (fmt), ap); vsnprintf (string, SIZEOF_CHAR (string), locale.TranslateInput (fmt), ap);
va_end (ap); va_end (ap);
if (IsDedicatedServer ()) if (IsDedicatedServer ())
@ -57,10 +61,10 @@ void Engine::ChatPrintf (const char *fmt, ...)
void Engine::CenterPrintf (const char *fmt, ...) void Engine::CenterPrintf (const char *fmt, ...)
{ {
va_list ap; va_list ap;
char string[512]; static char string[1024];
va_start (ap, fmt); va_start (ap, fmt);
vsprintf (string, locale.TranslateInput (fmt), ap); vsnprintf (string, SIZEOF_CHAR (string), locale.TranslateInput (fmt), ap);
va_end (ap); va_end (ap);
if (IsDedicatedServer ()) if (IsDedicatedServer ())
@ -79,13 +83,13 @@ void Engine::CenterPrintf (const char *fmt, ...)
void Engine::ClientPrintf (edict_t *ent, const char *fmt, ...) void Engine::ClientPrintf (edict_t *ent, const char *fmt, ...)
{ {
va_list ap; va_list ap;
char string[2048]; static char string[1024];
va_start (ap, fmt); va_start (ap, fmt);
vsprintf (string, locale.TranslateInput (fmt), ap); vsnprintf (string, SIZEOF_CHAR (string), locale.TranslateInput (fmt), ap);
va_end (ap); va_end (ap);
if (IsEntityNull (ent) || ent == g_hostEntity) if (IsNullEntity (ent) || ent == g_hostEntity)
{ {
engine.Printf (string); engine.Printf (string);
return; return;
@ -167,7 +171,9 @@ void Engine::TestHull (const Vector &start, const Vector &end, int ignoreFlags,
float Engine::GetWaveLength (const char *fileName) float Engine::GetWaveLength (const char *fileName)
{ {
extern ConVar yb_chatter_path; extern ConVar yb_chatter_path;
File fp (FormatBuffer ("%s/%s/%s.wav", GetModName (), yb_chatter_path.GetString (), fileName), "rb"); const char *filePath = FormatBuffer ("%s/%s/%s.wav", GetModName (), yb_chatter_path.GetString (), fileName);
File fp (filePath, "rb");
// we're got valid handle? // we're got valid handle?
if (!fp.IsValid ()) if (!fp.IsValid ())
@ -177,7 +183,7 @@ float Engine::GetWaveLength (const char *fileName)
if (g_engfuncs.pfnGetApproxWavePlayLen != NULL) if (g_engfuncs.pfnGetApproxWavePlayLen != NULL)
{ {
fp.Close (); fp.Close ();
return g_engfuncs.pfnGetApproxWavePlayLen (fileName) / 1000.0f; return g_engfuncs.pfnGetApproxWavePlayLen (filePath) / 1000.0f;
} }
// else fuck with manual search // else fuck with manual search
@ -202,20 +208,20 @@ float Engine::GetWaveLength (const char *fileName)
if (fp.Read (&waveHdr, sizeof (WavHeader)) == 0) if (fp.Read (&waveHdr, sizeof (WavHeader)) == 0)
{ {
AddLogEntry (true, LL_ERROR, "Wave File %s - has wrong or unsupported format", fileName); AddLogEntry (true, LL_ERROR, "Wave File %s - has wrong or unsupported format", filePath);
return 0.0f; return 0.0f;
} }
if (strncmp (waveHdr.chunkID, "WAVE", 4) != 0) if (strncmp (waveHdr.chunkID, "WAVE", 4) != 0)
{ {
AddLogEntry (true, LL_ERROR, "Wave File %s - has wrong wave chunk id", fileName); AddLogEntry (true, LL_ERROR, "Wave File %s - has wrong wave chunk id", filePath);
return 0.0f; return 0.0f;
} }
fp.Close (); fp.Close ();
if (waveHdr.dataChunkLength == 0) if (waveHdr.dataChunkLength == 0)
{ {
AddLogEntry (true, LL_ERROR, "Wave File %s - has zero length!", fileName); AddLogEntry (true, LL_ERROR, "Wave File %s - has zero length!", filePath);
return 0.0f; return 0.0f;
} }
return static_cast <float> (waveHdr.dataChunkLength) / static_cast <float> (waveHdr.bytesPerSecond); return static_cast <float> (waveHdr.dataChunkLength) / static_cast <float> (waveHdr.bytesPerSecond);
@ -261,7 +267,7 @@ Vector Engine::GetAbsOrigin (edict_t *ent)
// this expanded function returns the vector origin of a bounded entity, assuming that any // this expanded function returns the vector origin of a bounded entity, assuming that any
// entity that has a bounding box has its center at the center of the bounding box itself. // entity that has a bounding box has its center at the center of the bounding box itself.
if (IsEntityNull (ent)) if (IsNullEntity (ent))
return Vector::GetZero (); return Vector::GetZero ();
if (ent->v.origin.IsZero ()) if (ent->v.origin.IsZero ())
@ -285,6 +291,140 @@ void Engine::EmitSound (edict_t *ent, const char *sound)
g_engfuncs.pfnEmitSound (ent, CHAN_WEAPON, sound, 1.0f, ATTN_NORM, 0, 100.0f); g_engfuncs.pfnEmitSound (ent, CHAN_WEAPON, sound, 1.0f, ATTN_NORM, 0, 100.0f);
} }
void Engine::IssueBotCommand (edict_t *ent, const char *fmt, ...)
{
// the purpose of this function is to provide fakeclients (bots) with the same client
// command-scripting advantages (putting multiple commands in one line between semicolons)
// as real players. It is an improved version of botman's FakeClientCommand, in which you
// supply directly the whole string as if you were typing it in the bot's "console". It
// is supposed to work exactly like the pfnClientCommand (server-sided client command).
if (IsNullEntity (ent))
return;
va_list ap;
static char string[256];
va_start (ap, fmt);
vsnprintf (string, SIZEOF_CHAR (string), fmt, ap);
va_end (ap);
if (IsNullString (string))
return;
m_arguments[0] = { 0, };
m_argumentCount = 0;
m_isBotCommand = true;
int i, pos = 0;
int length = strlen (string);
while (pos < length)
{
int start = pos;
int stop = pos;
while (pos < length && string[pos] != ';')
pos++;
if (string[pos - 1] == '\n')
stop = pos - 2;
else
stop = pos - 1;
for (i = start; i <= stop; i++)
m_arguments[i - start] = string[i];
m_arguments[i - start] = 0;
pos++;
int index = 0;
m_argumentCount = 0;
while (index < i - start)
{
while (index < i - start && m_arguments[index] == ' ')
index++;
if (m_arguments[index] == '"')
{
index++;
while (index < i - start && m_arguments[index] != '"')
index++;
index++;
}
else
while (index < i - start && m_arguments[index] != ' ')
index++;
m_argumentCount++;
}
MDLL_ClientCommand (ent);
}
m_isBotCommand = false;
m_arguments[0] = { 0, };
m_argumentCount = 0;
}
const char *Engine::ExtractSingleField (const char *string, int id, bool terminate)
{
// this function gets and returns a particuliar field in a string where several strings are concatenated
static char field[256];
field[0] = { 0, };
int pos = 0, count = 0, start = 0, stop = 0;
int length = strlen (string);
while (pos < length && count <= id)
{
while (pos < length && (string[pos] == ' ' || string[pos] == '\t'))
pos++;
if (string[pos] == '"')
{
pos++;
start = pos;
while (pos < length && string[pos] != '"')
pos++;
stop = pos - 1;
pos++;
}
else
{
start = pos;
while (pos < length && string[pos] != ' ' && string[pos] != '\t')
pos++;
stop = pos - 1;
}
if (count == id)
{
int i = start;
for (; i <= stop; i++)
field[i - start] = string[i];
field[i - start] = 0;
break;
}
count++; // we have parsed one field more
}
if (terminate)
field[strlen (field) - 1] = 0;
String::TrimExternalBuffer (field);
return field;
}
void Engine::IssueCmd (const char *fmt, ...) void Engine::IssueCmd (const char *fmt, ...)
{ {
// this function asks the engine to execute a server command // this function asks the engine to execute a server command
@ -294,15 +434,68 @@ void Engine::IssueCmd (const char *fmt, ...)
// concatenate all the arguments in one string // concatenate all the arguments in one string
va_start (ap, fmt); va_start (ap, fmt);
vsprintf (string, fmt, ap); vsnprintf (string, SIZEOF_CHAR (string), fmt, ap);
va_end (ap); va_end (ap);
strcat (string, "\n"); strcat (string, "\n");
g_engfuncs.pfnServerCommand (string); g_engfuncs.pfnServerCommand (string);
g_engfuncs.pfnServerExecute ();
} }
void ConVarWrapper::RegisterVariable (const char *variable, const char *value, VarType varType, ConVar *self)
{
// this function adds globally defined variable to registration stack
// expose singleton VarPair newVariable;
Engine engine; memset (&newVariable, 0, sizeof (VarPair));
newVariable.reg.name = const_cast <char *> (variable);
newVariable.reg.string = const_cast <char *> (value);
int engineFlags = FCVAR_EXTDLL;
if (varType == VT_NORMAL)
engineFlags |= FCVAR_SERVER;
else if (varType == VT_READONLY)
engineFlags |= FCVAR_SERVER | FCVAR_SPONLY | FCVAR_PRINTABLEONLY;
else if (varType == VT_PASSWORD)
engineFlags |= FCVAR_PROTECTED;
newVariable.reg.flags = engineFlags;
newVariable.self = self;
newVariable.type = varType;
m_regs.Push (newVariable);
}
void ConVarWrapper::PushRegisteredConVarsToEngine (bool gameVars)
{
// this function pushes all added global variables to engine registration
FOR_EACH_AE (m_regs, i)
{
VarPair *ptr = &m_regs[i];
if (ptr->type != VT_NOREGISTER)
{
ptr->self->m_eptr = g_engfuncs.pfnCVarGetPointer (ptr->reg.name);
if (ptr->self->m_eptr == NULL)
{
g_engfuncs.pfnCVarRegister (&ptr->reg);
ptr->self->m_eptr = g_engfuncs.pfnCVarGetPointer (ptr->reg.name);
}
}
else if (gameVars && ptr->type == VT_NOREGISTER)
{
ptr->self->m_eptr = g_engfuncs.pfnCVarGetPointer (ptr->reg.name);
// ensure game cvar exists
InternalAssert (ptr->self->m_eptr != NULL);
}
}
}
ConVar::ConVar (const char *name, const char *initval, VarType type) : m_eptr (NULL)
{
ConVarWrapper::GetReference ().RegisterVariable (name, initval, type, this);
}

View file

@ -9,6 +9,13 @@
#include <core.h> #include <core.h>
// forward for super-globals
NetworkMsg netmsg;
Localizer locale;
Waypoint waypoints;
BotManager bots;
Engine engine;
bool g_canSayBombPlanted = true; bool g_canSayBombPlanted = true;
bool g_isMetamod = false; bool g_isMetamod = false;
bool g_radioInsteadVoice = false; bool g_radioInsteadVoice = false;
@ -19,7 +26,6 @@ bool g_bombPlanted = false;
bool g_bombSayString = false; bool g_bombSayString = false;
bool g_isCommencing = false; bool g_isCommencing = false;
bool g_editNoclip = false; bool g_editNoclip = false;
bool g_isFakeCommand = false;
bool g_waypointOn = false; bool g_waypointOn = false;
bool g_waypointsChanged = true; bool g_waypointsChanged = true;
bool g_autoWaypoint = false; bool g_autoWaypoint = false;
@ -39,7 +45,6 @@ float g_autoPathDistance = 250.0f;
int g_lastRadio[2]; int g_lastRadio[2];
int g_storeAddbotVars[4]; int g_storeAddbotVars[4];
int g_radioSelect[32]; int g_radioSelect[32];
int g_fakeArgc = 0;
int g_gameFlags = 0; int g_gameFlags = 0;
int g_numWaypoints = 0; int g_numWaypoints = 0;
int g_mapType = 0; int g_mapType = 0;
@ -48,7 +53,6 @@ int g_highestDamageCT = 1;
int g_highestDamageT = 1; int g_highestDamageT = 1;
int g_highestKills = 1; int g_highestKills = 1;
char g_fakeArgv[256];
Array <Array <String> > g_chatFactory; Array <Array <String> > g_chatFactory;
Array <Array <ChatterItem> > g_chatterFactory; Array <Array <ChatterItem> > g_chatterFactory;

View file

@ -205,7 +205,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
// waypoint manimupulation (really obsolete, can be edited through menu) (supported only on listen server) // waypoint manimupulation (really obsolete, can be edited through menu) (supported only on listen server)
else if (stricmp (arg0, "waypoint") == 0 || stricmp (arg0, "wp") == 0 || stricmp (arg0, "wpt") == 0) else if (stricmp (arg0, "waypoint") == 0 || stricmp (arg0, "wp") == 0 || stricmp (arg0, "wpt") == 0)
{ {
if (engine.IsDedicatedServer () || IsEntityNull (g_hostEntity)) if (engine.IsDedicatedServer () || IsNullEntity (g_hostEntity))
return 2; return 2;
// enables or disable waypoint displaying // enables or disable waypoint displaying
@ -250,11 +250,11 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
if (stricmp (arg2, "on") == 0) if (stricmp (arg2, "on") == 0)
{ {
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start"))) while (!IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start")))
spawnEntity->v.effects &= ~EF_NODRAW; spawnEntity->v.effects &= ~EF_NODRAW;
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch"))) while (!IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch")))
spawnEntity->v.effects &= ~EF_NODRAW; spawnEntity->v.effects &= ~EF_NODRAW;
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start"))) while (!IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start")))
spawnEntity->v.effects &= ~EF_NODRAW; spawnEntity->v.effects &= ~EF_NODRAW;
engine.IssueCmd ("mp_roundtime 9"); // reset round time to maximum engine.IssueCmd ("mp_roundtime 9"); // reset round time to maximum
@ -263,11 +263,11 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
} }
else if (stricmp (arg2, "off") == 0) else if (stricmp (arg2, "off") == 0)
{ {
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start"))) while (!IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start")))
spawnEntity->v.effects |= EF_NODRAW; spawnEntity->v.effects |= EF_NODRAW;
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch"))) while (!IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch")))
spawnEntity->v.effects |= EF_NODRAW; spawnEntity->v.effects |= EF_NODRAW;
while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start"))) while (!IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start")))
spawnEntity->v.effects |= EF_NODRAW; spawnEntity->v.effects |= EF_NODRAW;
} }
} }
@ -373,7 +373,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
// path waypoint editing system (supported only on listen server) // path waypoint editing system (supported only on listen server)
else if (stricmp (arg0, "pathwaypoint") == 0 || stricmp (arg0, "path") == 0 || stricmp (arg0, "pwp") == 0) else if (stricmp (arg0, "pathwaypoint") == 0 || stricmp (arg0, "path") == 0 || stricmp (arg0, "pwp") == 0)
{ {
if (engine.IsDedicatedServer () || IsEntityNull (g_hostEntity)) if (engine.IsDedicatedServer () || IsNullEntity (g_hostEntity))
return 2; return 2;
// opens path creation menu // opens path creation menu
@ -404,7 +404,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
// automatic waypoint handling (supported only on listen server) // automatic waypoint handling (supported only on listen server)
else if (stricmp (arg0, "autowaypoint") == 0 || stricmp (arg0, "autowp") == 0) else if (stricmp (arg0, "autowaypoint") == 0 || stricmp (arg0, "autowp") == 0)
{ {
if (engine.IsDedicatedServer () || IsEntityNull (g_hostEntity)) if (engine.IsDedicatedServer () || IsNullEntity (g_hostEntity))
return 2; return 2;
// enable autowaypointing // enable autowaypointing
@ -425,7 +425,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c
// experience system handling (supported only on listen server) // experience system handling (supported only on listen server)
else if (stricmp (arg0, "experience") == 0 || stricmp (arg0, "exp") == 0) else if (stricmp (arg0, "experience") == 0 || stricmp (arg0, "exp") == 0)
{ {
if (engine.IsDedicatedServer () || IsEntityNull (g_hostEntity)) if (engine.IsDedicatedServer () || IsNullEntity (g_hostEntity))
return 2; return 2;
// write experience table (and visibility table) to hard disk // write experience table (and visibility table) to hard disk
@ -506,7 +506,7 @@ void InitConfig (void)
if (pair.GetElementNumber () > 1) if (pair.GetElementNumber () > 1)
strncpy (line, pair[0].Trim ().GetBuffer (), SIZEOF_CHAR (line)); strncpy (line, pair[0].Trim ().GetBuffer (), SIZEOF_CHAR (line));
strtrim (line); String::TrimExternalBuffer (line);
line[32] = 0; line[32] = 0;
BotName item; BotName item;
@ -532,7 +532,7 @@ void InitConfig (void)
while (fp.GetBuffer (line, 255)) while (fp.GetBuffer (line, 255))
{ {
SKIP_COMMENTS (); SKIP_COMMENTS ();
strncpy (section, GetField (line, 0, 1), SIZEOF_CHAR (section)); strncpy (section, Engine::ExtractSingleField (line, 0, 1), SIZEOF_CHAR (section));
if (strcmp (section, "[KILLED]") == 0) if (strcmp (section, "[KILLED]") == 0)
{ {
@ -578,7 +578,7 @@ void InitConfig (void)
if (chatType != 3) if (chatType != 3)
line[79] = 0; line[79] = 0;
strtrim (line); String::TrimExternalBuffer (line);
switch (chatType) switch (chatType)
{ {
@ -850,7 +850,7 @@ void InitConfig (void)
if (!IsNullString (buffer)) if (!IsNullString (buffer))
{ {
strtrim (buffer); String::TrimExternalBuffer (buffer);
temp.translated = _strdup (buffer); temp.translated = _strdup (buffer);
buffer[0] = 0x0; buffer[0] = 0x0;
} }
@ -860,7 +860,7 @@ void InitConfig (void)
} }
else if (strncmp (line, "[TRANSLATED]", 12) == 0) else if (strncmp (line, "[TRANSLATED]", 12) == 0)
{ {
strtrim (buffer); String::TrimExternalBuffer (buffer);
temp.original = _strdup (buffer); temp.original = _strdup (buffer);
buffer[0] = 0x0; buffer[0] = 0x0;
@ -977,7 +977,7 @@ void Touch (edict_t *pentTouched, edict_t *pentOther)
// the two entities both have velocities, for example two players colliding, this function // the two entities both have velocities, for example two players colliding, this function
// is called twice, once for each entity moving. // is called twice, once for each entity moving.
if (!IsEntityNull (pentOther) && (pentOther->v.flags & FL_FAKECLIENT)) if (!IsNullEntity (pentOther) && (pentOther->v.flags & FL_FAKECLIENT))
{ {
Bot *bot = bots.GetBot (pentOther); Bot *bot = bots.GetBot (pentOther);
@ -1002,9 +1002,10 @@ int Spawn (edict_t *ent)
if (strcmp (entityClassname, "worldspawn") == 0) if (strcmp (entityClassname, "worldspawn") == 0)
{ {
engine.Precache ();
g_worldEntity = ent; // save the world entity for future use g_worldEntity = ent; // save the world entity for future use
convars.PushRegisteredConVarsToEngine (true); ConVarWrapper::GetReference ().PushRegisteredConVarsToEngine (true);
PRECACHE_SOUND (ENGINE_STR ("weapons/xbow_hit1.wav")); // waypoint add PRECACHE_SOUND (ENGINE_STR ("weapons/xbow_hit1.wav")); // waypoint add
PRECACHE_SOUND (ENGINE_STR ("weapons/mine_activate.wav")); // waypoint delete PRECACHE_SOUND (ENGINE_STR ("weapons/mine_activate.wav")); // waypoint delete
@ -1013,14 +1014,11 @@ int Spawn (edict_t *ent)
PRECACHE_SOUND (ENGINE_STR ("common/wpn_moveselect.wav")); // path add/delete cancel PRECACHE_SOUND (ENGINE_STR ("common/wpn_moveselect.wav")); // path add/delete cancel
PRECACHE_SOUND (ENGINE_STR ("common/wpn_denyselect.wav")); // path add/delete error PRECACHE_SOUND (ENGINE_STR ("common/wpn_denyselect.wav")); // path add/delete error
engine.Precache ();
g_roundEnded = true; g_roundEnded = true;
RoundInit (); RoundInit ();
g_mapType = NULL; // reset map type as worldspawn is the first entity spawned g_mapType = NULL; // reset map type as worldspawn is the first entity spawned
// detect official csbots here, as they causing crash in linkent code when active for some reason // detect official csbots here, as they causing crash in linkent code when active for some reason
if (!(g_gameFlags & GAME_LEGACY) && g_engfuncs.pfnCVarGetPointer ("bot_stop") != NULL) if (!(g_gameFlags & GAME_LEGACY) && g_engfuncs.pfnCVarGetPointer ("bot_stop") != NULL)
g_gameFlags |= GAME_OFFICIAL_CSBOT; g_gameFlags |= GAME_OFFICIAL_CSBOT;
@ -1231,7 +1229,7 @@ void ClientCommand (edict_t *ent)
static int fillServerTeam = 5; static int fillServerTeam = 5;
static bool fillCommand = false; static bool fillCommand = false;
if (!g_isFakeCommand && (ent == g_hostEntity || (g_clients[IndexOfEntity (ent) - 1].flags & CF_ADMIN))) if (!engine.IsBotCommand () && (ent == g_hostEntity || (g_clients[IndexOfEntity (ent) - 1].flags & CF_ADMIN)))
{ {
if (stricmp (command, "yapb") == 0 || stricmp (command, "yb") == 0) if (stricmp (command, "yapb") == 0 || stricmp (command, "yb") == 0)
{ {
@ -2011,7 +2009,7 @@ void ClientCommand (edict_t *ent)
} }
} }
if (!g_isFakeCommand && (stricmp (command, "say") == 0 || stricmp (command, "say_team") == 0)) if (!engine.IsBotCommand () && (stricmp (command, "say") == 0 || stricmp (command, "say_team") == 0))
{ {
Bot *bot = NULL; Bot *bot = NULL;
@ -2168,7 +2166,7 @@ void StartFrame (void)
{ {
edict_t *player = EntityOfIndex (i + 1); edict_t *player = EntityOfIndex (i + 1);
if (!IsEntityNull (player) && (player->v.flags & FL_CLIENT)) if (!IsNullEntity (player) && (player->v.flags & FL_CLIENT))
{ {
g_clients[i].ent = player; g_clients[i].ent = player;
g_clients[i].flags |= CF_USED; g_clients[i].flags |= CF_USED;
@ -2195,7 +2193,7 @@ void StartFrame (void)
} }
} }
if (!engine.IsDedicatedServer () && !IsEntityNull (g_hostEntity)) if (!engine.IsDedicatedServer () && !IsNullEntity (g_hostEntity))
{ {
if (g_waypointOn) if (g_waypointOn)
waypoints.Think (); waypoints.Think ();
@ -2211,7 +2209,7 @@ void StartFrame (void)
edict_t *player = EntityOfIndex (i + 1); edict_t *player = EntityOfIndex (i + 1);
// code below is executed only on dedicated server // code below is executed only on dedicated server
if (engine.IsDedicatedServer () && !IsEntityNull (player) && (player->v.flags & FL_CLIENT) && !(player->v.flags & FL_FAKECLIENT)) if (engine.IsDedicatedServer () && !IsNullEntity (player) && (player->v.flags & FL_CLIENT) && !(player->v.flags & FL_FAKECLIENT))
{ {
if (g_clients[i].flags & CF_ADMIN) if (g_clients[i].flags & CF_ADMIN)
{ {
@ -2379,8 +2377,7 @@ void pfnClientCommand (edict_t *ent, char *format, ...)
// make the server crash. Since hordes of uncautious, not to say stupid, programmers don't // make the server crash. Since hordes of uncautious, not to say stupid, programmers don't
// even imagine some players on their servers could be bots, this check is performed less than // even imagine some players on their servers could be bots, this check is performed less than
// sometimes actually by their side, that's why we strongly recommend to check it here too. In // sometimes actually by their side, that's why we strongly recommend to check it here too. In
// case it's a bot asking for a client command, we handle it like we do for bot commands, ie // case it's a bot asking for a client command, we handle it like we do for bot commands
// using FakeClientCommand().
va_list ap; va_list ap;
char buffer[1024]; char buffer[1024];
@ -2440,7 +2437,7 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed
netmsg.HandleMessageIfRequired (msgType, NETMSG_WEAPONLIST); netmsg.HandleMessageIfRequired (msgType, NETMSG_WEAPONLIST);
if (!IsEntityNull (ed)) if (!IsNullEntity (ed))
{ {
int index = bots.GetIndex (ed); int index = bots.GetIndex (ed);
@ -2609,13 +2606,13 @@ int pfnCmd_Argc (void)
// DLL for a command we are holding here. Of course, real clients commands are still retrieved // DLL for a command we are holding here. Of course, real clients commands are still retrieved
// the normal way, by asking the engine. // the normal way, by asking the engine.
// is this a bot issuing that client command ? // is this a bot issuing that client command?
if (g_isFakeCommand) if (engine.IsBotCommand ())
{ {
if (g_isMetamod) if (g_isMetamod)
RETURN_META_VALUE (MRES_SUPERCEDE, g_fakeArgc); RETURN_META_VALUE (MRES_SUPERCEDE, engine.GetOverrideArgc ());
return g_fakeArgc; // if so, then return the argument count we know return engine.GetOverrideArgc (); // if so, then return the argument count we know
} }
if (g_isMetamod) if (g_isMetamod)
@ -2634,28 +2631,12 @@ const char *pfnCmd_Args (void)
// normal way, by asking the engine. // normal way, by asking the engine.
// is this a bot issuing that client command? // is this a bot issuing that client command?
if (g_isFakeCommand) if (engine.IsBotCommand ())
{
// is it a "say" or "say_team" client command?
if (strncmp ("say ", g_fakeArgv, 4) == 0)
{ {
if (g_isMetamod) if (g_isMetamod)
RETURN_META_VALUE (MRES_SUPERCEDE, &g_fakeArgv[4]); RETURN_META_VALUE (MRES_SUPERCEDE, engine.GetOverrideArgs ());
return &g_fakeArgv[4]; // skip the "say" bot client command return engine.GetOverrideArgs (); // else return the whole bot client command string we know
}
else if (strncmp ("say_team ", g_fakeArgv, 9) == 0)
{
if (g_isMetamod)
RETURN_META_VALUE (MRES_SUPERCEDE, &g_fakeArgv[9]);
return &g_fakeArgv[9]; // skip the "say_team" bot client command
}
if (g_isMetamod)
RETURN_META_VALUE (MRES_SUPERCEDE, g_fakeArgv);
return g_fakeArgv; // else return the whole bot client command string we know
} }
if (g_isMetamod) if (g_isMetamod)
@ -2673,13 +2654,13 @@ const char *pfnCmd_Argv (int argc)
// DLL for a command we are holding here. Of course, real clients commands are still retrieved // DLL for a command we are holding here. Of course, real clients commands are still retrieved
// the normal way, by asking the engine. // the normal way, by asking the engine.
// is this a bot issuing that client command ? // is this a bot issuing that client command?
if (g_isFakeCommand) if (engine.IsBotCommand ())
{ {
if (g_isMetamod) if (g_isMetamod)
RETURN_META_VALUE (MRES_SUPERCEDE, GetField (g_fakeArgv, argc)); RETURN_META_VALUE (MRES_SUPERCEDE, engine.GetOverrideArgv (argc));
return GetField (g_fakeArgv, argc); // if so, then return the wanted argument we know return engine.GetOverrideArgv (argc); // if so, then return the wanted argument we know
} }
if (g_isMetamod) if (g_isMetamod)
RETURN_META_VALUE (MRES_IGNORED, NULL); RETURN_META_VALUE (MRES_IGNORED, NULL);
@ -3062,7 +3043,7 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t
g_pGlobals = pGlobals; g_pGlobals = pGlobals;
// register our cvars // register our cvars
convars.PushRegisteredConVarsToEngine (); ConVarWrapper::GetReference ().PushRegisteredConVarsToEngine ();
#ifdef PLATFORM_ANDROID #ifdef PLATFORM_ANDROID
g_gameFlags |= (GAME_LEGACY | GAME_XASH | GAME_MOBILITY); g_gameFlags |= (GAME_LEGACY | GAME_XASH | GAME_MOBILITY);
@ -3181,59 +3162,6 @@ DLL_ENTRYPOINT
DLL_RETENTRY; // the return data type is OS specific too DLL_RETENTRY; // the return data type is OS specific too
} }
void ConVarWrapper::RegisterVariable (const char *variable, const char *value, VarType varType, ConVar *self)
{
VarPair newVariable;
memset (&newVariable, 0, sizeof (VarPair));
newVariable.reg.name = const_cast <char *> (variable);
newVariable.reg.string = const_cast <char *> (value);
int engineFlags = FCVAR_EXTDLL;
if (varType == VT_NORMAL)
engineFlags |= FCVAR_SERVER;
else if (varType == VT_READONLY)
engineFlags |= FCVAR_SERVER | FCVAR_SPONLY | FCVAR_PRINTABLEONLY;
else if (varType == VT_PASSWORD)
engineFlags |= FCVAR_PROTECTED;
newVariable.reg.flags = engineFlags;
newVariable.self = self;
newVariable.type = varType;
m_regs.Push (newVariable);
}
void ConVarWrapper::PushRegisteredConVarsToEngine (bool gameVars)
{
FOR_EACH_AE (m_regs, i)
{
VarPair *ptr = &m_regs[i];
if (ptr == NULL)
break;
if (ptr->type != VT_NOREGISTER)
{
ptr->self->m_eptr = g_engfuncs.pfnCVarGetPointer (ptr->reg.name);
if (ptr->self->m_eptr == NULL)
{
g_engfuncs.pfnCVarRegister (&ptr->reg);
ptr->self->m_eptr = g_engfuncs.pfnCVarGetPointer (ptr->reg.name);
}
}
else if (gameVars && ptr->type == VT_NOREGISTER)
{
ptr->self->m_eptr = g_engfuncs.pfnCVarGetPointer (ptr->reg.name);
// ensure game cvar exists
InternalAssert (ptr->self->m_eptr != NULL);
}
}
}
static void LinkEntity_Helper (EntityPtr_t &entAddress, const char *name, entvars_t *pev) static void LinkEntity_Helper (EntityPtr_t &entAddress, const char *name, entvars_t *pev)
{ {
// here we're see an ugliest hack :) // here we're see an ugliest hack :)

View file

@ -66,13 +66,13 @@ void BotManager::CreateKillerEntity (void)
void BotManager::DestroyKillerEntity (void) void BotManager::DestroyKillerEntity (void)
{ {
if (!IsEntityNull (m_killerEntity)) if (!IsNullEntity (m_killerEntity))
g_engfuncs.pfnRemoveEntity (m_killerEntity); g_engfuncs.pfnRemoveEntity (m_killerEntity);
} }
void BotManager::TouchWithKillerEntity (Bot *bot) void BotManager::TouchWithKillerEntity (Bot *bot)
{ {
if (IsEntityNull (m_killerEntity)) if (IsNullEntity (m_killerEntity))
{ {
MDLL_ClientKill (bot->GetEntity ()); MDLL_ClientKill (bot->GetEntity ());
return; return;
@ -194,7 +194,7 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality,
strcpy (outputName, prefixedName); strcpy (outputName, prefixedName);
} }
if (IsEntityNull ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName)))) if (IsNullEntity ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName))))
{ {
engine.CenterPrintf ("Maximum players reached (%d/%d). Unable to create Bot.", engine.MaxClients (), engine.MaxClients ()); engine.CenterPrintf ("Maximum players reached (%d/%d). Unable to create Bot.", engine.MaxClients (), engine.MaxClients ());
return 2; return 2;
@ -217,7 +217,7 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality,
int BotManager::GetIndex (edict_t *ent) int BotManager::GetIndex (edict_t *ent)
{ {
// this function returns index of bot (using own bot array) // this function returns index of bot (using own bot array)
if (IsEntityNull (ent)) if (IsNullEntity (ent))
return -1; return -1;
int index = IndexOfEntity (ent) - 1; int index = IndexOfEntity (ent) - 1;
@ -421,7 +421,7 @@ void BotManager::MaintainBotQuota (void)
m_creationTab.RemoveAll (); // maximum players reached, so set quota to maximum players m_creationTab.RemoveAll (); // maximum players reached, so set quota to maximum players
yb_quota.SetInt (GetBotsNum ()); yb_quota.SetInt (GetBotsNum ());
} }
m_maintainTime = engine.Time () + 0.45f; m_maintainTime = engine.Time () + 0.20f;
} }
// now keep bot number up to date // now keep bot number up to date
@ -505,7 +505,6 @@ void BotManager::FillServer (int selection, int personality, int difficulty, int
AddBot ("", difficulty, personality, selection, -1); AddBot ("", difficulty, personality, selection, -1);
yb_quota.SetInt (toAdd); yb_quota.SetInt (toAdd);
engine.CenterPrintf ("Fill Server with %s bots...", &teamDesc[selection][0]); engine.CenterPrintf ("Fill Server with %s bots...", &teamDesc[selection][0]);
} }
@ -565,7 +564,7 @@ void BotManager::RemoveMenu (edict_t *ent, int selection)
for (int i = ((selection - 1) * 8); i < selection * 8; i++) for (int i = ((selection - 1) * 8); i < selection * 8; i++)
{ {
if ((m_bots[i] != NULL) && !IsEntityNull (m_bots[i]->GetEntity ())) if ((m_bots[i] != NULL) && !IsNullEntity (m_bots[i]->GetEntity ()))
{ {
validSlots |= 1 << (i - ((selection - 1) * 8)); validSlots |= 1 << (i - ((selection - 1) * 8));
sprintf (buffer, "%s %1.1d. %s%s\n", buffer, i - ((selection - 1) * 8) + 1, STRING (m_bots[i]->pev->netname), GetTeam (m_bots[i]->GetEntity ()) == CT ? " \\y(CT)\\w" : " \\r(T)\\w"); sprintf (buffer, "%s %1.1d. %s%s\n", buffer, i - ((selection - 1) * 8) + 1, STRING (m_bots[i]->pev->netname), GetTeam (m_bots[i]->GetEntity ()) == CT ? " \\y(CT)\\w" : " \\r(T)\\w");
@ -798,7 +797,7 @@ void BotManager::CheckTeamEconomics (int team, bool setTrue)
extern ConVar yb_economics_rounds; extern ConVar yb_economics_rounds;
if (!yb_economics_rounds.GetBool () || setTrue) if (setTrue || !yb_economics_rounds.GetBool ())
{ {
m_economicsGood[team] = true; m_economicsGood[team] = true;
return; // don't check economics while economics disable return; // don't check economics while economics disable
@ -1287,7 +1286,7 @@ void Bot::StartGame (void)
#ifdef XASH_CSDM #ifdef XASH_CSDM
m_wantedTeam = Random.Long (1, 2); m_wantedTeam = Random.Long (1, 2);
FakeClientCommand (GetEntity (), "jointeam %d", m_wantedTeam); engine.IssueBotCommand (GetEntity (), "jointeam %d", m_wantedTeam);
SET_CLIENT_KEYVALUE (GetIndex (), GET_INFOKEYBUFFER (GetEntity ()), "model", m_wantedTeam == 2 ? "Counter-Terrorists" : "Terrorists"); SET_CLIENT_KEYVALUE (GetIndex (), GET_INFOKEYBUFFER (GetEntity ()), "model", m_wantedTeam == 2 ? "Counter-Terrorists" : "Terrorists");
@ -1314,7 +1313,7 @@ void Bot::StartGame (void)
m_wantedTeam = 5; m_wantedTeam = 5;
// select the team the bot wishes to join... // select the team the bot wishes to join...
FakeClientCommand (GetEntity (), "menuselect %d", m_wantedTeam); engine.IssueBotCommand (GetEntity (), "menuselect %d", m_wantedTeam);
} }
else if (m_startAction == GSM_CLASS_SELECT) else if (m_startAction == GSM_CLASS_SELECT)
{ {
@ -1332,7 +1331,7 @@ void Bot::StartGame (void)
} }
// select the class the bot wishes to use... // select the class the bot wishes to use...
FakeClientCommand (GetEntity (), "menuselect %d", m_wantedClass); engine.IssueBotCommand (GetEntity (), "menuselect %d", m_wantedClass);
// bot has now joined the game (doesn't need to be started) // bot has now joined the game (doesn't need to be started)
m_notStarted = false; m_notStarted = false;
@ -1405,7 +1404,7 @@ void BotManager::CalculatePingOffsets (void)
void BotManager::SendPingDataOffsets (edict_t *to) void BotManager::SendPingDataOffsets (edict_t *to)
{ {
if ((g_gameFlags & GAME_LEGACY) || yb_latency_display.GetInt () != 2 || IsEntityNull (to)) if ((g_gameFlags & GAME_LEGACY) || yb_latency_display.GetInt () != 2 || IsNullEntity (to))
return; return;
if (!(to->v.flags & FL_CLIENT) && !(((to->v.button & IN_SCORE) || !(to->v.oldbuttons & IN_SCORE)))) if (!(to->v.flags & FL_CLIENT) && !(((to->v.button & IN_SCORE) || !(to->v.oldbuttons & IN_SCORE))))
@ -1483,7 +1482,7 @@ void BotManager::UpdateActiveGrenades (void)
m_activeGrenades.RemoveAll (); m_activeGrenades.RemoveAll ();
// search the map for any type of grenade // search the map for any type of grenade
while (!IsEntityNull (grenade = FIND_ENTITY_BY_CLASSNAME (grenade, "grenade"))) while (!IsNullEntity (grenade = FIND_ENTITY_BY_CLASSNAME (grenade, "grenade")))
{ {
// do not count c4 as a grenade // do not count c4 as a grenade
if (strcmp (STRING (grenade->v.model) + 9, "c4.mdl") == 0) if (strcmp (STRING (grenade->v.model) + 9, "c4.mdl") == 0)

View file

@ -18,7 +18,7 @@ int Bot::FindGoal (void)
{ {
edict_t *pent = NULL; edict_t *pent = NULL;
while (!IsEntityNull (pent = FIND_ENTITY_BY_STRING (pent, "classname", "weaponbox"))) while (!IsNullEntity (pent = FIND_ENTITY_BY_STRING (pent, "classname", "weaponbox")))
{ {
if (strcmp (STRING (pent->v.model), "models/w_backpack.mdl") == 0) if (strcmp (STRING (pent->v.model), "models/w_backpack.mdl") == 0)
{ {
@ -734,7 +734,7 @@ bool Bot::DoWaypointNav (void)
engine.TestLine (m_currentPath->origin, m_currentPath->origin + Vector (0.0f, 0.0f, -50.0f), TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); engine.TestLine (m_currentPath->origin, m_currentPath->origin + Vector (0.0f, 0.0f, -50.0f), TRACE_IGNORE_EVERYTHING, GetEntity (), &tr);
// if trace result shows us that it is a lift // if trace result shows us that it is a lift
if (!IsEntityNull (tr.pHit) && m_navNode != NULL && (strcmp (STRING (tr.pHit->v.classname), "func_door") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_plat") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_train") == 0) && !liftClosedDoorExists) if (!IsNullEntity (tr.pHit) && m_navNode != NULL && (strcmp (STRING (tr.pHit->v.classname), "func_door") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_plat") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_train") == 0) && !liftClosedDoorExists)
{ {
if ((m_liftState == LIFT_NO_NEARBY || m_liftState == LIFT_WAITING_FOR || m_liftState == LIFT_LOOKING_BUTTON_OUTSIDE) && tr.pHit->v.velocity.z == 0.0f) if ((m_liftState == LIFT_NO_NEARBY || m_liftState == LIFT_WAITING_FOR || m_liftState == LIFT_LOOKING_BUTTON_OUTSIDE) && tr.pHit->v.velocity.z == 0.0f)
{ {
@ -760,7 +760,7 @@ bool Bot::DoWaypointNav (void)
{ {
engine.TestLine (m_currentPath->origin, waypoints.GetPath (m_navNode->next->index)->origin, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); engine.TestLine (m_currentPath->origin, waypoints.GetPath (m_navNode->next->index)->origin, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr);
if (!IsEntityNull (tr.pHit) && (strcmp (STRING (tr.pHit->v.classname), "func_door") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_plat") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_train") == 0)) if (!IsNullEntity (tr.pHit) && (strcmp (STRING (tr.pHit->v.classname), "func_door") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_plat") == 0 || strcmp (STRING (tr.pHit->v.classname), "func_train") == 0))
m_liftEntity = tr.pHit; m_liftEntity = tr.pHit;
} }
m_liftState = LIFT_LOOKING_BUTTON_OUTSIDE; m_liftState = LIFT_LOOKING_BUTTON_OUTSIDE;
@ -875,7 +875,7 @@ bool Bot::DoWaypointNav (void)
edict_t *button = FindNearestButton (STRING (m_liftEntity->v.targetname)); edict_t *button = FindNearestButton (STRING (m_liftEntity->v.targetname));
// got a valid button entity ? // got a valid button entity ?
if (!IsEntityNull (button) && pev->groundentity == m_liftEntity && m_buttonPushTime + 1.0f < engine.Time () && m_liftEntity->v.velocity.z == 0.0f && IsOnFloor ()) if (!IsNullEntity (button) && pev->groundentity == m_liftEntity && m_buttonPushTime + 1.0f < engine.Time () && m_liftEntity->v.velocity.z == 0.0f && IsOnFloor ())
{ {
m_pickupItem = button; m_pickupItem = button;
m_pickupType = PICKUP_BUTTON; m_pickupType = PICKUP_BUTTON;
@ -887,7 +887,7 @@ bool Bot::DoWaypointNav (void)
// is lift activated and bot is standing on it and lift is moving ? // is lift activated and bot is standing on it and lift is moving ?
if (m_liftState == LIFT_LOOKING_BUTTON_INSIDE || m_liftState == LIFT_ENTERING_IN || m_liftState == LIFT_WAIT_FOR_TEAMMATES || m_liftState == LIFT_WAITING_FOR) if (m_liftState == LIFT_LOOKING_BUTTON_INSIDE || m_liftState == LIFT_ENTERING_IN || m_liftState == LIFT_WAIT_FOR_TEAMMATES || m_liftState == LIFT_WAITING_FOR)
{ {
if (pev->groundentity == m_liftEntity && m_liftEntity->v.velocity.z != 0.0f && IsOnFloor () && ((waypoints.GetPath (m_prevWptIndex[0])->flags & FLAG_LIFT) || !IsEntityNull (m_targetEntity))) if (pev->groundentity == m_liftEntity && m_liftEntity->v.velocity.z != 0.0f && IsOnFloor () && ((waypoints.GetPath (m_prevWptIndex[0])->flags & FLAG_LIFT) || !IsNullEntity (m_targetEntity)))
{ {
m_liftState = LIFT_TRAVELING_BY; m_liftState = LIFT_TRAVELING_BY;
m_liftUsageTime = engine.Time () + 14.0f; m_liftUsageTime = engine.Time () + 14.0f;
@ -945,12 +945,12 @@ bool Bot::DoWaypointNav (void)
ResetCollideState (); ResetCollideState ();
} }
} }
else if (!IsEntityNull(m_liftEntity)) else if (!IsNullEntity(m_liftEntity))
{ {
edict_t *button = FindNearestButton (STRING (m_liftEntity->v.targetname)); edict_t *button = FindNearestButton (STRING (m_liftEntity->v.targetname));
// if we got a valid button entity // if we got a valid button entity
if (!IsEntityNull (button)) if (!IsNullEntity (button))
{ {
// lift is already used ? // lift is already used ?
bool liftUsed = false; bool liftUsed = false;
@ -958,7 +958,7 @@ bool Bot::DoWaypointNav (void)
// iterate though clients, and find if lift already used // iterate though clients, and find if lift already used
for (int i = 0; i < engine.MaxClients (); i++) for (int i = 0; i < engine.MaxClients (); i++)
{ {
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team != m_team || g_clients[i].ent == GetEntity () || IsEntityNull (g_clients[i].ent->v.groundentity)) if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team != m_team || g_clients[i].ent == GetEntity () || IsNullEntity (g_clients[i].ent->v.groundentity))
continue; continue;
if (g_clients[i].ent->v.groundentity == m_liftEntity) if (g_clients[i].ent->v.groundentity == m_liftEntity)
@ -1047,7 +1047,7 @@ bool Bot::DoWaypointNav (void)
} }
} }
if (!IsEntityNull (m_liftEntity) && !(m_currentPath->flags & FLAG_LIFT)) if (!IsNullEntity (m_liftEntity) && !(m_currentPath->flags & FLAG_LIFT))
{ {
if (m_liftState == LIFT_TRAVELING_BY) if (m_liftState == LIFT_TRAVELING_BY)
{ {
@ -1087,7 +1087,7 @@ bool Bot::DoWaypointNav (void)
// check if we are going through a door... // check if we are going through a door...
engine.TestLine (pev->origin, m_waypointOrigin, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); engine.TestLine (pev->origin, m_waypointOrigin, TRACE_IGNORE_MONSTERS, GetEntity (), &tr);
if (!IsEntityNull (tr.pHit) && IsEntityNull (m_liftEntity) && strncmp (STRING (tr.pHit->v.classname), "func_door", 9) == 0) if (!IsNullEntity (tr.pHit) && IsNullEntity (m_liftEntity) && strncmp (STRING (tr.pHit->v.classname), "func_door", 9) == 0)
{ {
// if the door is near enough... // if the door is near enough...
if ((engine.GetAbsOrigin (tr.pHit) - pev->origin).GetLengthSquared () < 2500.0f) if ((engine.GetAbsOrigin (tr.pHit) - pev->origin).GetLengthSquared () < 2500.0f)
@ -1104,7 +1104,7 @@ bool Bot::DoWaypointNav (void)
edict_t *button = FindNearestButton (STRING (tr.pHit->v.targetname)); edict_t *button = FindNearestButton (STRING (tr.pHit->v.targetname));
// check if we got valid button // check if we got valid button
if (!IsEntityNull (button)) if (!IsNullEntity (button))
{ {
m_pickupItem = button; m_pickupItem = button;
m_pickupType = PICKUP_BUTTON; m_pickupType = PICKUP_BUTTON;
@ -1122,7 +1122,7 @@ bool Bot::DoWaypointNav (void)
edict_t *ent = NULL; edict_t *ent = NULL;
if (m_doorOpenAttempt > 2 && !IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, 256.0f))) if (m_doorOpenAttempt > 2 && !IsNullEntity (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, 256.0f)))
{ {
if (IsValidPlayer (ent) && IsAlive (ent) && m_team != GetTeam (ent) && GetWeaponPenetrationPower (m_currentWeapon) > 0) if (IsValidPlayer (ent) && IsAlive (ent) && m_team != GetTeam (ent) && GetWeaponPenetrationPower (m_currentWeapon) > 0)
{ {
@ -1943,7 +1943,7 @@ void Bot::GetValidWaypoint (void)
// FIXME: Do some error checks if we got a waypoint // FIXME: Do some error checks if we got a waypoint
} }
else if (m_navTimeset + GetEstimatedReachTime () < engine.Time () && IsEntityNull (m_enemy)) else if (m_navTimeset + GetEstimatedReachTime () < engine.Time () && IsNullEntity (m_enemy))
{ {
if (m_team == TERRORIST) if (m_team == TERRORIST)
{ {
@ -2490,7 +2490,7 @@ bool Bot::HeadTowardWaypoint (void)
} }
// is there a jump waypoint right ahead and do we need to draw out the light weapon ? // is there a jump waypoint right ahead and do we need to draw out the light weapon ?
if (willJump && m_currentWeapon != WEAPON_KNIFE && m_currentWeapon != WEAPON_SCOUT && !m_isReloading && !UsesPistol () && (jumpDistance > 210.0f || (dst.z + 32.0f > src.z && jumpDistance > 150.0f) || ((dst - src).GetLength2D () < 60.0f && jumpDistance > 60.0f)) && IsEntityNull (m_enemy)) if (willJump && m_currentWeapon != WEAPON_KNIFE && m_currentWeapon != WEAPON_SCOUT && !m_isReloading && !UsesPistol () && (jumpDistance > 210.0f || (dst.z + 32.0f > src.z && jumpDistance > 150.0f) || ((dst - src).GetLength2D () < 60.0f && jumpDistance > 60.0f)) && IsNullEntity (m_enemy))
SelectWeaponByName ("weapon_knife"); // draw out the knife if we needed SelectWeaponByName ("weapon_knife"); // draw out the knife if we needed
// bot not already on ladder but will be soon? // bot not already on ladder but will be soon?
@ -3310,7 +3310,7 @@ int Bot::FindPlantedBomb (void)
edict_t *bombEntity = NULL; // temporaly pointer to bomb edict_t *bombEntity = NULL; // temporaly pointer to bomb
// search the bomb on the map // search the bomb on the map
while (!IsEntityNull (bombEntity = FIND_ENTITY_BY_CLASSNAME (bombEntity, "grenade"))) while (!IsNullEntity (bombEntity = FIND_ENTITY_BY_CLASSNAME (bombEntity, "grenade")))
{ {
if (strcmp (STRING (bombEntity->v.model) + 9, "c4.mdl") == 0) if (strcmp (STRING (bombEntity->v.model) + 9, "c4.mdl") == 0)
{ {
@ -3341,7 +3341,7 @@ bool Bot::IsPointOccupied (int index)
// check if this waypoint is already used // check if this waypoint is already used
// TODO: take in account real players // TODO: take in account real players
if (bot->m_notKilled) if (bot->m_notKilled && m_currentWaypointIndex != -1 && bot->m_prevWptIndex[0] != -1)
{ {
int occupyId = GetShootingConeDeviation (bot->GetEntity (), &pev->origin) >= 0.7f ? bot->m_prevWptIndex[0] : m_currentWaypointIndex; int occupyId = GetShootingConeDeviation (bot->GetEntity (), &pev->origin) >= 0.7f ? bot->m_prevWptIndex[0] : m_currentWaypointIndex;
@ -3367,7 +3367,7 @@ edict_t *Bot::FindNearestButton (const char *targetName)
edict_t *searchEntity = NULL, *foundEntity = NULL; edict_t *searchEntity = NULL, *foundEntity = NULL;
// find the nearest button which can open our target // find the nearest button which can open our target
while (!IsEntityNull(searchEntity = FIND_ENTITY_BY_TARGET (searchEntity, targetName))) while (!IsNullEntity(searchEntity = FIND_ENTITY_BY_TARGET (searchEntity, targetName)))
{ {
Vector entityOrign = engine.GetAbsOrigin (searchEntity); Vector entityOrign = engine.GetAbsOrigin (searchEntity);

View file

@ -15,7 +15,7 @@ NetworkMsg::NetworkMsg (void)
m_state = 0; m_state = 0;
m_bot = NULL; m_bot = NULL;
for (int i = 0; i < NETMSG_BOTVOICE; i++) for (int i = 0; i < NETMSG_NUM; i++)
m_registerdMessages[i] = -1; m_registerdMessages[i] = -1;
} }
@ -262,7 +262,7 @@ void NetworkMsg::Execute (void *p)
edict_t *killer = EntityOfIndex (killerIndex); edict_t *killer = EntityOfIndex (killerIndex);
edict_t *victim = EntityOfIndex (victimIndex); edict_t *victim = EntityOfIndex (victimIndex);
if (IsEntityNull (killer) || IsEntityNull (victim)) if (IsNullEntity (killer) || IsNullEntity (victim))
break; break;
if (yb_communication_type.GetInt () == 2) if (yb_communication_type.GetInt () == 2)
@ -289,7 +289,7 @@ void NetworkMsg::Execute (void *p)
{ {
Bot *bot = bots.GetBot (i); Bot *bot = bots.GetBot (i);
if (bot != NULL && bot->m_seeEnemyTime + 2.0f < engine.Time () && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && IsEntityNull (bot->m_enemy) && GetTeam (killer) != GetTeam (victim)) if (bot != NULL && bot->m_seeEnemyTime + 2.0f < engine.Time () && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && IsNullEntity (bot->m_enemy) && GetTeam (killer) != GetTeam (victim))
{ {
bot->m_actualReactionTime = 0.0f; bot->m_actualReactionTime = 0.0f;
bot->m_seeEnemyTime = engine.Time (); bot->m_seeEnemyTime = engine.Time ();

View file

@ -59,7 +59,7 @@ const char *FormatBuffer (const char *format, ...)
bool IsAlive (edict_t *ent) bool IsAlive (edict_t *ent)
{ {
if (IsEntityNull (ent)) if (IsNullEntity (ent))
return false; return false;
return ent->v.deadflag == DEAD_NO && ent->v.health > 0 && ent->v.movetype != MOVETYPE_NOCLIP; return ent->v.deadflag == DEAD_NO && ent->v.health > 0 && ent->v.movetype != MOVETYPE_NOCLIP;
@ -86,7 +86,7 @@ bool IsInViewCone (const Vector &origin, edict_t *ent)
bool IsVisible (const Vector &origin, edict_t *ent) bool IsVisible (const Vector &origin, edict_t *ent)
{ {
if (IsEntityNull (ent)) if (IsNullEntity (ent))
return false; return false;
TraceResult tr; TraceResult tr;
@ -178,7 +178,7 @@ void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex)
if (trace->flFraction == 1.0f) if (trace->flFraction == 1.0f)
return; return;
if (!IsEntityNull (trace->pHit)) if (!IsNullEntity (trace->pHit))
{ {
if (trace->pHit->v.solid == SOLID_BSP || trace->pHit->v.movetype == MOVETYPE_PUSHSTEP) if (trace->pHit->v.solid == SOLID_BSP || trace->pHit->v.movetype == MOVETYPE_PUSHSTEP)
entityIndex = IndexOfEntity (trace->pHit); entityIndex = IndexOfEntity (trace->pHit);
@ -245,221 +245,6 @@ void FreeLibraryMemory (void)
g_experienceData = NULL; g_experienceData = NULL;
} }
void FakeClientCommand (edict_t *fakeClient, const char *format, ...)
{
// the purpose of this function is to provide fakeclients (bots) with the same client
// command-scripting advantages (putting multiple commands in one line between semicolons)
// as real players. It is an improved version of botman's FakeClientCommand, in which you
// supply directly the whole string as if you were typing it in the bot's "console". It
// is supposed to work exactly like the pfnClientCommand (server-sided client command).
va_list ap;
static char command[256];
int stop, i, stringIndex = 0;
if (IsEntityNull (fakeClient))
return; // reliability check
// concatenate all the arguments in one string
va_start (ap, format);
_vsnprintf (command, sizeof (command), format, ap);
va_end (ap);
if (IsNullString (command))
return; // if nothing in the command buffer, return
g_isFakeCommand = true; // set the "fakeclient command" flag
int length = strlen (command); // get the total length of the command string
// process all individual commands (separated by a semicolon) one each a time
while (stringIndex < length)
{
int start = stringIndex; // save field start position (first character)
while (stringIndex < length && command[stringIndex] != ';')
stringIndex++; // reach end of field
if (command[stringIndex - 1] == '\n')
stop = stringIndex - 2; // discard any trailing '\n' if needed
else
stop = stringIndex - 1; // save field stop position (last character before semicolon or end)
for (i = start; i <= stop; i++)
g_fakeArgv[i - start] = command[i]; // store the field value in the g_fakeArgv global string
g_fakeArgv[i - start] = 0; // terminate the string
stringIndex++; // move the overall string index one step further to bypass the semicolon
int index = 0;
g_fakeArgc = 0; // let's now parse that command and count the different arguments
// count the number of arguments
while (index < i - start)
{
while (index < i - start && g_fakeArgv[index] == ' ')
index++; // ignore spaces
// is this field a group of words between quotes or a single word ?
if (g_fakeArgv[index] == '"')
{
index++; // move one step further to bypass the quote
while (index < i - start && g_fakeArgv[index] != '"')
index++; // reach end of field
index++; // move one step further to bypass the quote
}
else
while (index < i - start && g_fakeArgv[index] != ' ')
index++; // this is a single word, so reach the end of field
g_fakeArgc++; // we have processed one argument more
}
// tell now the MOD DLL to execute this ClientCommand...
MDLL_ClientCommand (fakeClient);
}
g_fakeArgv[0] = 0; // when it's done, reset the g_fakeArgv field
g_isFakeCommand = false; // reset the "fakeclient command" flag
g_fakeArgc = 0; // and the argument count
}
const char *GetField (const char *string, int fieldId, bool endLine)
{
// This function gets and returns a particuliar field in a string where several szFields are
// concatenated. Fields can be words, or groups of words between quotes ; separators may be
// white space or tabs. A purpose of this function is to provide bots with the same Cmd_Argv
// convenience the engine provides to real clients. This way the handling of real client
// commands and bot client commands is exactly the same, just have a look in engine.cpp
// for the hooking of pfnCmd_Argc, pfnCmd_Args and pfnCmd_Argv, which redirects the call
// either to the actual engine functions (when the caller is a real client), either on
// our function here, which does the same thing, when the caller is a bot.
static char field[256];
// reset the string
memset (field, 0, sizeof (field));
int length, i, index = 0, fieldCount = 0, start, stop;
field[0] = 0; // reset field
length = strlen (string); // get length of string
// while we have not reached end of line
while (index < length && fieldCount <= fieldId)
{
while (index < length && (string[index] == ' ' || string[index] == '\t'))
index++; // ignore spaces or tabs
// is this field multi-word between quotes or single word ?
if (string[index] == '"')
{
index++; // move one step further to bypass the quote
start = index; // save field start position
while ((index < length) && (string[index] != '"'))
index++; // reach end of field
stop = index - 1; // save field stop position
index++; // move one step further to bypass the quote
}
else
{
start = index; // save field start position
while (index < length && (string[index] != ' ' && string[index] != '\t'))
index++; // reach end of field
stop = index - 1; // save field stop position
}
// is this field we just processed the wanted one ?
if (fieldCount == fieldId)
{
for (i = start; i <= stop; i++)
field[i - start] = string[i]; // store the field value in a string
field[i - start] = 0; // terminate the string
break; // and stop parsing
}
fieldCount++; // we have parsed one field more
}
if (endLine)
field[strlen (field) - 1] = 0;
strtrim (field);
return (&field[0]); // returns the wanted field
}
void strtrim (char *string)
{
char *ptr = string;
int length = 0, toggleFlag = 0, increment = 0;
int i = 0;
while (*ptr++)
length++;
for (i = length - 1; i >= 0; i--)
{
if (!isspace (string[i]))
break;
else
{
string[i] = 0;
length--;
}
}
for (i = 0; i < length; i++)
{
if (isspace (string[i]) && !toggleFlag)
{
increment++;
if (increment + i < length)
string[i] = string[increment + i];
}
else
{
if (!toggleFlag)
toggleFlag = 1;
if (increment)
string[i] = string[increment + i];
}
}
string[length] = 0;
}
// Create a directory tree
void CreatePath (char *path)
{
for (char *ofs = path + 1 ; *ofs ; ofs++)
{
if (*ofs == '/')
{
// create the directory
*ofs = 0;
#ifdef PLATFORM_WIN32
mkdir (path);
#else
mkdir (path, 0777);
#endif
*ofs = '/';
}
}
#ifdef PLATFORM_WIN32
mkdir (path);
#else
mkdir (path, 0777);
#endif
}
void UpdateGlobalExperienceData (void) void UpdateGlobalExperienceData (void)
{ {
// this function called after each end of the round to update knowledge about most dangerous waypoints for each team. // this function called after each end of the round to update knowledge about most dangerous waypoints for each team.
@ -642,7 +427,7 @@ int GetWeaponPenetrationPower (int id)
bool IsValidPlayer (edict_t *ent) bool IsValidPlayer (edict_t *ent)
{ {
if (IsEntityNull (ent)) if (IsNullEntity (ent))
return false; return false;
if (ent->v.flags & FL_PROXY) if (ent->v.flags & FL_PROXY)
@ -667,7 +452,7 @@ bool IsPlayerVIP (edict_t *ent)
bool IsValidBot (edict_t *ent) bool IsValidBot (edict_t *ent)
{ {
if (bots.GetBot (ent) != NULL || (!IsEntityNull (ent) && (ent->v.flags & FL_FAKECLIENT))) if (bots.GetBot (ent) != NULL || (!IsNullEntity (ent) && (ent->v.flags & FL_FAKECLIENT)))
return true; return true;
return false; return false;
@ -705,11 +490,6 @@ bool OpenConfig (const char *fileName, const char *errorIfNotExists, File *outFi
return true; return true;
} }
const char *GetWaypointDir (void)
{
return FormatBuffer ("%s/addons/yapb/data/", engine.GetModName ());
}
void CheckWelcomeMessage (void) void CheckWelcomeMessage (void)
{ {
// the purpose of this function, is to send quick welcome message, to the listenserver entity. // the purpose of this function, is to send quick welcome message, to the listenserver entity.
@ -902,7 +682,7 @@ char *Localizer::TranslateInput (const char *input)
ptr++; ptr++;
strncpy (string, input, SIZEOF_CHAR (string)); strncpy (string, input, SIZEOF_CHAR (string));
strtrim (string); String::TrimExternalBuffer (string);
FOR_EACH_AE (m_langTab, i) FOR_EACH_AE (m_langTab, i)
{ {
@ -960,7 +740,7 @@ bool FindNearestPlayer (void **pvHolder, edict_t *to, float searchDistance, bool
} }
} }
if (IsEntityNull (survive)) if (IsNullEntity (survive))
return false; // nothing found return false; // nothing found
// fill the holder // fill the holder
@ -977,7 +757,7 @@ void SoundAttachToClients (edict_t *ent, const char *sample, float volume)
// this function called by the sound hooking code (in emit_sound) enters the played sound into // this function called by the sound hooking code (in emit_sound) enters the played sound into
// the array associated with the entity // the array associated with the entity
if (IsEntityNull (ent) || IsNullString (sample)) if (IsNullEntity (ent) || IsNullString (sample))
return; // reliability check return; // reliability check
const Vector &origin = engine.GetAbsOrigin (ent); const Vector &origin = engine.GetAbsOrigin (ent);
@ -1130,11 +910,11 @@ void SoundSimulateUpdate (int playerIndex)
} }
} }
uint16 GenerateBuildNumber (void) int GenerateBuildNumber (void)
{ {
// this function generates build number from the compiler date macros // this function generates build number from the compiler date macros
static uint16 buildNumber = 0; static int buildNumber = 0;
if (buildNumber != 0) if (buildNumber != 0)
return buildNumber; return buildNumber;

View file

@ -143,7 +143,7 @@ void Waypoint::FindInRadius (Array <int> &radiusHolder, float radius, const Vect
void Waypoint::Add (int flags, const Vector &waypointOrigin) void Waypoint::Add (int flags, const Vector &waypointOrigin)
{ {
if (IsEntityNull (g_hostEntity)) if (IsNullEntity (g_hostEntity))
return; return;
int index = -1, i; int index = -1, i;
@ -846,7 +846,7 @@ void Waypoint::SaveExperienceTab (void)
} }
} }
int result = Compressor::Compress (FormatBuffer ("%slearned/%s.exp", GetWaypointDir (), engine.GetMapName ()), (unsigned char *)&header, sizeof (ExtensionHeader), (unsigned char *)experienceSave, g_numWaypoints * g_numWaypoints * sizeof (ExperienceSave)); int result = Compressor::Compress (FormatBuffer ("%slearned/%s.exp", GetDataDir (), engine.GetMapName ()), (unsigned char *)&header, sizeof (ExtensionHeader), (unsigned char *)experienceSave, g_numWaypoints * g_numWaypoints * sizeof (ExperienceSave));
delete [] experienceSave; delete [] experienceSave;
@ -885,7 +885,7 @@ void Waypoint::InitExperienceTab (void)
(g_experienceData + (i * g_numWaypoints) + j)->team1Value = 0; (g_experienceData + (i * g_numWaypoints) + j)->team1Value = 0;
} }
} }
File fp (FormatBuffer ("%slearned/%s.exp", GetWaypointDir (), engine.GetMapName ()), "rb"); File fp (FormatBuffer ("%slearned/%s.exp", GetDataDir (), engine.GetMapName ()), "rb");
// if file exists, read the experience data from it // if file exists, read the experience data from it
if (fp.IsValid ()) if (fp.IsValid ())
@ -908,7 +908,7 @@ void Waypoint::InitExperienceTab (void)
{ {
ExperienceSave *experienceLoad = new ExperienceSave[g_numWaypoints * g_numWaypoints]; ExperienceSave *experienceLoad = new ExperienceSave[g_numWaypoints * g_numWaypoints];
Compressor::Uncompress (FormatBuffer ("%slearned/%s.exp", GetWaypointDir (), engine.GetMapName ()), sizeof (ExtensionHeader), (unsigned char *)experienceLoad, g_numWaypoints * g_numWaypoints * sizeof (ExperienceSave)); Compressor::Uncompress (FormatBuffer ("%slearned/%s.exp", GetDataDir (), engine.GetMapName ()), sizeof (ExtensionHeader), (unsigned char *)experienceLoad, g_numWaypoints * g_numWaypoints * sizeof (ExperienceSave));
for (i = 0; i < g_numWaypoints; i++) for (i = 0; i < g_numWaypoints; i++)
{ {
@ -958,7 +958,7 @@ void Waypoint::SaveVisibilityTab (void)
header.fileVersion = FV_VISTABLE; header.fileVersion = FV_VISTABLE;
header.pointNumber = g_numWaypoints; header.pointNumber = g_numWaypoints;
File fp (FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), engine.GetMapName ()), "wb"); File fp (FormatBuffer ("%slearned/%s.vis", GetDataDir (), engine.GetMapName ()), "wb");
if (!fp.IsValid ()) if (!fp.IsValid ())
{ {
@ -967,7 +967,7 @@ void Waypoint::SaveVisibilityTab (void)
} }
fp.Close (); fp.Close ();
Compressor::Compress (FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), engine.GetMapName ()), (unsigned char *) &header, sizeof (ExtensionHeader), (unsigned char *) m_visLUT, MAX_WAYPOINTS * (MAX_WAYPOINTS / 4) * sizeof (byte)); Compressor::Compress (FormatBuffer ("%slearned/%s.vis", GetDataDir (), engine.GetMapName ()), (unsigned char *) &header, sizeof (ExtensionHeader), (unsigned char *) m_visLUT, MAX_WAYPOINTS * (MAX_WAYPOINTS / 4) * sizeof (byte));
} }
void Waypoint::InitVisibilityTab (void) void Waypoint::InitVisibilityTab (void)
@ -977,7 +977,7 @@ void Waypoint::InitVisibilityTab (void)
ExtensionHeader header; ExtensionHeader header;
File fp (FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), engine.GetMapName ()), "rb"); File fp (FormatBuffer ("%slearned/%s.vis", GetDataDir (), engine.GetMapName ()), "rb");
m_redoneVisibility = false; m_redoneVisibility = false;
if (!fp.IsValid ()) if (!fp.IsValid ())
@ -1008,7 +1008,7 @@ void Waypoint::InitVisibilityTab (void)
return; return;
} }
int result = Compressor::Uncompress (FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), engine.GetMapName ()), sizeof (ExtensionHeader), (unsigned char *) m_visLUT, MAX_WAYPOINTS * (MAX_WAYPOINTS / 4) * sizeof (byte)); int result = Compressor::Uncompress (FormatBuffer ("%slearned/%s.vis", GetDataDir (), engine.GetMapName ()), sizeof (ExtensionHeader), (unsigned char *) m_visLUT, MAX_WAYPOINTS * (MAX_WAYPOINTS / 4) * sizeof (byte));
if (result == -1) if (result == -1)
{ {
@ -1137,9 +1137,7 @@ bool Waypoint::Load (void)
if (yb_waypoint_autodl_enable.GetBool ()) if (yb_waypoint_autodl_enable.GetBool ())
{ {
AddLogEntry (true, LL_DEFAULT, "%s.pwf does not exist, trying to download from waypoint database", map); AddLogEntry (true, LL_DEFAULT, "%s.pwf does not exist, trying to download from waypoint database", map);
WaypointDownloadError status = RequestWaypoint ();
WaypointDownloader dl;
WaypointDownloadError status = dl.DoDownload ();
if (status == WDE_SOCKET_ERROR) if (status == WDE_SOCKET_ERROR)
{ {
@ -1247,12 +1245,12 @@ String Waypoint::CheckSubfolderFile (void)
if (!IsNullString (yb_wptsubfolder.GetString ())) if (!IsNullString (yb_wptsubfolder.GetString ()))
returnFile += (String (yb_wptsubfolder.GetString ()) + "/"); returnFile += (String (yb_wptsubfolder.GetString ()) + "/");
returnFile = FormatBuffer ("%s%s%s.pwf", GetWaypointDir (), returnFile.GetBuffer (), engine.GetMapName ()); returnFile = FormatBuffer ("%s%s%s.pwf", GetDataDir (), returnFile.GetBuffer (), engine.GetMapName ());
if (File::Accessible (returnFile)) if (File::Accessible (returnFile))
return returnFile; return returnFile;
return FormatBuffer ("%s%s.pwf", GetWaypointDir (), engine.GetMapName ()); return FormatBuffer ("%s%s.pwf", GetDataDir (), engine.GetMapName ());
} }
float Waypoint::GetTravelTime (float maxSpeed, const Vector &src, const Vector &origin) float Waypoint::GetTravelTime (float maxSpeed, const Vector &src, const Vector &origin)
@ -1311,7 +1309,7 @@ bool Waypoint::IsNodeReachable (const Vector &src, const Vector &destination)
// check if we go through a func_illusionary, in which case return false // check if we go through a func_illusionary, in which case return false
engine.TestHull (src, destination, TRACE_IGNORE_MONSTERS, head_hull, g_hostEntity, &tr); engine.TestHull (src, destination, TRACE_IGNORE_MONSTERS, head_hull, g_hostEntity, &tr);
if (!IsEntityNull (tr.pHit) && strcmp ("func_illusionary", STRING (tr.pHit->v.classname)) == 0) if (!IsNullEntity (tr.pHit) && strcmp ("func_illusionary", STRING (tr.pHit->v.classname)) == 0)
return false; // don't add pathwaypoints through func_illusionaries return false; // don't add pathwaypoints through func_illusionaries
// check if this waypoint is "visible"... // check if this waypoint is "visible"...
@ -1499,7 +1497,7 @@ void Waypoint::Think (void)
{ {
// this function executes frame of waypoint operation code. // this function executes frame of waypoint operation code.
if (IsEntityNull (g_hostEntity)) if (IsNullEntity (g_hostEntity))
return; // this function is only valid on listenserver, and in waypoint enabled mode. return; // this function is only valid on listenserver, and in waypoint enabled mode.
float nearestDistance = 99999.0f; float nearestDistance = 99999.0f;
@ -2110,7 +2108,7 @@ void Waypoint::InitPathMatrix (void)
void Waypoint::SavePathMatrix (void) void Waypoint::SavePathMatrix (void)
{ {
File fp (FormatBuffer ("%slearned/%s.pmt", GetWaypointDir (), engine.GetMapName ()), "wb"); File fp (FormatBuffer ("%slearned/%s.pmt", GetDataDir (), engine.GetMapName ()), "wb");
// unable to open file // unable to open file
if (!fp.IsValid ()) if (!fp.IsValid ())
@ -2132,7 +2130,7 @@ void Waypoint::SavePathMatrix (void)
bool Waypoint::LoadPathMatrix (void) bool Waypoint::LoadPathMatrix (void)
{ {
File fp (FormatBuffer ("%slearned/%s.pmt", GetWaypointDir (), engine.GetMapName ()), "rb"); File fp (FormatBuffer ("%slearned/%s.pmt", GetDataDir (), engine.GetMapName ()), "rb");
// file doesn't exists return false // file doesn't exists return false
if (!fp.IsValid ()) if (!fp.IsValid ())
@ -2211,7 +2209,7 @@ void Waypoint::CreateBasic (void)
edict_t *ent = NULL; edict_t *ent = NULL;
// first of all, if map contains ladder points, create it // first of all, if map contains ladder points, create it
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_ladder"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_ladder")))
{ {
Vector ladderLeft = ent->v.absmin; Vector ladderLeft = ent->v.absmin;
Vector ladderRight = ent->v.absmax; Vector ladderRight = ent->v.absmax;
@ -2260,7 +2258,7 @@ void Waypoint::CreateBasic (void)
} }
// then terrortist spawnpoints // then terrortist spawnpoints
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_deathmatch"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_deathmatch")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2269,7 +2267,7 @@ void Waypoint::CreateBasic (void)
} }
// then add ct spawnpoints // then add ct spawnpoints
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_start"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_start")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2278,7 +2276,7 @@ void Waypoint::CreateBasic (void)
} }
// then vip spawnpoint // then vip spawnpoint
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_vip_start"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_vip_start")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2287,7 +2285,7 @@ void Waypoint::CreateBasic (void)
} }
// hostage rescue zone // hostage rescue zone
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_hostage_rescue"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_hostage_rescue")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2296,7 +2294,7 @@ void Waypoint::CreateBasic (void)
} }
// hostage rescue zone (same as above) // hostage rescue zone (same as above)
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_hostage_rescue"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_hostage_rescue")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2305,7 +2303,7 @@ void Waypoint::CreateBasic (void)
} }
// bombspot zone // bombspot zone
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_bomb_target"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_bomb_target")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2314,7 +2312,7 @@ void Waypoint::CreateBasic (void)
} }
// bombspot zone (same as above) // bombspot zone (same as above)
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_bomb_target"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_bomb_target")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2323,7 +2321,7 @@ void Waypoint::CreateBasic (void)
} }
// hostage entities // hostage entities
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "hostage_entity"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "hostage_entity")))
{ {
// if already saved || moving skip it // if already saved || moving skip it
if ((ent->v.effects & EF_NODRAW) && ent->v.speed > 0.0f) if ((ent->v.effects & EF_NODRAW) && ent->v.speed > 0.0f)
@ -2336,7 +2334,7 @@ void Waypoint::CreateBasic (void)
} }
// vip rescue (safety) zone // vip rescue (safety) zone
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_vip_safetyzone"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_vip_safetyzone")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2345,7 +2343,7 @@ void Waypoint::CreateBasic (void)
} }
// terrorist escape zone // terrorist escape zone
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_escapezone"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_escapezone")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2354,7 +2352,7 @@ void Waypoint::CreateBasic (void)
} }
// weapons on the map ? // weapons on the map ?
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "armoury_entity"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "armoury_entity")))
{ {
Vector origin = engine.GetAbsOrigin (ent); Vector origin = engine.GetAbsOrigin (ent);
@ -2381,11 +2379,11 @@ void Waypoint::EraseFromHardDisk (void)
const char *map = engine.GetMapName (); const char *map = engine.GetMapName ();
// if we're delete waypoint, delete all corresponding to it files // if we're delete waypoint, delete all corresponding to it files
deleteList[0] = FormatBuffer ("%s%s.pwf", GetWaypointDir (), map); // waypoint itself deleteList[0] = FormatBuffer ("%s%s.pwf", GetDataDir (), map); // waypoint itself
deleteList[1] = FormatBuffer ("%slearned/%s.exp", GetWaypointDir (), map); // corresponding to waypoint experience deleteList[1] = FormatBuffer ("%slearned/%s.exp", GetDataDir (), map); // corresponding to waypoint experience
deleteList[3] = FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), map); // corresponding to waypoint vistable deleteList[3] = FormatBuffer ("%slearned/%s.vis", GetDataDir (), map); // corresponding to waypoint vistable
deleteList[3] = FormatBuffer ("%slearned/%s.pmt", GetWaypointDir (), map); // corresponding to waypoint path matrix deleteList[3] = FormatBuffer ("%slearned/%s.pmt", GetDataDir (), map); // corresponding to waypoint path matrix
deleteList[4] = FormatBuffer ("%slearned/%s.xml", GetWaypointDir (), map); // corresponding to waypoint xml database deleteList[4] = FormatBuffer ("%slearned/%s.xml", GetDataDir (), map); // corresponding to waypoint xml database
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
@ -2400,6 +2398,11 @@ void Waypoint::EraseFromHardDisk (void)
Init (); // reintialize points Init (); // reintialize points
} }
const char *Waypoint::GetDataDir (void)
{
return FormatBuffer ("%s/addons/yapb/data/", engine.GetModName ());
}
void Waypoint::SetBombPosition (bool shouldReset) void Waypoint::SetBombPosition (bool shouldReset)
{ {
// this function stores the bomb position as a vector // this function stores the bomb position as a vector
@ -2414,7 +2417,7 @@ void Waypoint::SetBombPosition (bool shouldReset)
edict_t *ent = NULL; edict_t *ent = NULL;
while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) while (!IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade")))
{ {
if (strcmp (STRING (ent->v.model) + 9, "c4.mdl") == 0) if (strcmp (STRING (ent->v.model) + 9, "c4.mdl") == 0)
{ {
@ -2481,7 +2484,7 @@ Waypoint::~Waypoint (void)
m_pathMatrix = NULL; m_pathMatrix = NULL;
} }
void WaypointDownloader::FreeSocket (int sock) void Waypoint::CloseSocketHandle (int sock)
{ {
#if defined (PLATFORM_WIN32) #if defined (PLATFORM_WIN32)
if (sock != -1) if (sock != -1)
@ -2495,7 +2498,7 @@ void WaypointDownloader::FreeSocket (int sock)
} }
WaypointDownloadError WaypointDownloader::DoDownload (void) WaypointDownloadError Waypoint::RequestWaypoint (void)
{ {
#if defined (PLATFORM_WIN32) #if defined (PLATFORM_WIN32)
WORD requestedVersion = MAKEWORD (1, 1); WORD requestedVersion = MAKEWORD (1, 1);
@ -2516,7 +2519,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void)
if (socketHandle < 0) if (socketHandle < 0)
{ {
FreeSocket (socketHandle); CloseSocketHandle (socketHandle);
return WDE_SOCKET_ERROR; return WDE_SOCKET_ERROR;
} }
sockaddr_in dest; sockaddr_in dest;
@ -2529,14 +2532,14 @@ WaypointDownloadError WaypointDownloader::DoDownload (void)
if (result < 0) if (result < 0)
{ {
FreeSocket (socketHandle); CloseSocketHandle (socketHandle);
return WDE_SOCKET_ERROR; return WDE_SOCKET_ERROR;
} }
result = setsockopt (socketHandle, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof (timeout)); result = setsockopt (socketHandle, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof (timeout));
if (result < 0) if (result < 0)
{ {
FreeSocket (socketHandle); CloseSocketHandle (socketHandle);
return WDE_SOCKET_ERROR; return WDE_SOCKET_ERROR;
} }
memset (&dest, 0, sizeof (dest)); memset (&dest, 0, sizeof (dest));
@ -2547,7 +2550,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void)
if (connect (socketHandle, (struct sockaddr*) &dest, (int) sizeof (dest)) == -1) if (connect (socketHandle, (struct sockaddr*) &dest, (int) sizeof (dest)) == -1)
{ {
FreeSocket (socketHandle); CloseSocketHandle (socketHandle);
return WDE_CONNECT_ERROR; return WDE_CONNECT_ERROR;
} }
@ -2556,7 +2559,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void)
if (send (socketHandle, request.GetBuffer (), request.GetLength () + 1, 0) < 1) if (send (socketHandle, request.GetBuffer (), request.GetLength () + 1, 0) < 1)
{ {
FreeSocket (socketHandle); CloseSocketHandle (socketHandle);
return WDE_SOCKET_ERROR; return WDE_SOCKET_ERROR;
} }
@ -2576,7 +2579,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void)
// ugly, but whatever // ugly, but whatever
if (recvPosition > 2 && buffer[recvPosition - 2] == '4' && buffer[recvPosition - 1] == '0' && buffer[recvPosition] == '4') if (recvPosition > 2 && buffer[recvPosition - 2] == '4' && buffer[recvPosition - 1] == '0' && buffer[recvPosition] == '4')
{ {
FreeSocket (socketHandle); CloseSocketHandle (socketHandle);
return WDE_NOTFOUND_ERROR; return WDE_NOTFOUND_ERROR;
} }
@ -2603,7 +2606,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void)
if (!fp.IsValid ()) if (!fp.IsValid ())
{ {
FreeSocket (socketHandle); CloseSocketHandle (socketHandle);
return WDE_SOCKET_ERROR; return WDE_SOCKET_ERROR;
} }
@ -2622,7 +2625,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void)
} while (recvSize != 0); } while (recvSize != 0);
fp.Close (); fp.Close ();
FreeSocket (socketHandle); CloseSocketHandle (socketHandle);
return WDE_NOERROR; return WDE_NOERROR;
} }