diff --git a/.gitignore b/.gitignore index 20711bb..59e6f29 100644 --- a/.gitignore +++ b/.gitignore @@ -1,32 +1,33 @@ -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# ========================= -# Operating System Files -# ========================= - -# OSX -# ========================= - +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + .DS_Store .AppleDouble .LSOverride # Icon must ends with two \r. -Icon +Icon + # Thumbnails ._* @@ -34,23 +35,27 @@ Icon # Files that might appear on external disk .Spotlight-V100 .Trashes - -*.pdb -*.asm -*.tlog -*.obj -*.log -*.manifest -*.map -*.res -*.lib -*.exp -*.ilk -*.opensdf -*.dll -*.sdf -*.suo -*.idb -*.vspx -project/yapb.vcxproj.user -*.psess \ No newline at end of file + +*.pdb +*.asm +*.tlog +*.obj +*.log +*.manifest +*.map +*.res +*.lib +*.exp +*.ilk +*.opensdf +*.dll +*.sdf +*.suo +*.idb +*.vspx +project/yapb.vcxproj.user +*.psess +*.opendb +*.aps +*.db +*.enc diff --git a/include/compress.h b/include/compress.h index b64f3f3..398bf59 100644 --- a/include/compress.h +++ b/include/compress.h @@ -154,7 +154,7 @@ public: memset (m_textBuffer, 0, sizeof (m_textBuffer)); memset (m_right, 0, sizeof (m_right)); - memset (m_left, 0, sizeof (m_right)); + memset (m_left, 0, sizeof (m_left)); memset (m_parent, 0, sizeof (m_parent)); } @@ -355,4 +355,4 @@ public: static Compressor compressor = Compressor (); return compressor.InternalEncode (fileName, header, headerSize, buffer, bufferSize); } -}; \ No newline at end of file +}; diff --git a/include/core.h b/include/core.h index 2ca004d..d0d76b1 100644 --- a/include/core.h +++ b/include/core.h @@ -324,6 +324,22 @@ enum PickupType PICKUP_DEFUSEKIT }; +// fight style type +enum FightStyle +{ + FIGHT_NONE, + FIGHT_STRAFE, + FIGHT_STAY +}; + +// dodge type +enum StrafeDir +{ + STRAFE_DIR_NONE, + STRAFE_DIR_LEFT, + STRAFE_DIR_RIGHT +}; + // reload state enum ReloadState { @@ -361,6 +377,15 @@ enum LiftState LIFT_LEAVING }; +// wayponit auto-downloader +enum WaypointDownloadError +{ + WDE_SOCKET_ERROR, + WDE_CONNECT_ERROR, + WDE_NOTFOUND_ERROR, + WDE_NOERROR +}; + // game start messages for counter-strike... enum GameStartMessage { @@ -373,31 +398,6 @@ enum GameStartMessage GSM_SAY_TEAM = 10001 }; -// netmessage functions -enum NetworkMessage -{ - NETMSG_VGUI = 1, - NETMSG_SHOWMENU = 2, - NETMSG_WEAPONLIST = 3, - NETMSG_CURWEAPON = 4, - NETMSG_AMMOX = 5, - NETMSG_AMMOPICKUP = 6, - NETMSG_DAMAGE = 7, - NETMSG_MONEY = 8, - NETMSG_STATUSICON = 9, - NETMSG_DEATH = 10, - NETMSG_SCREENFADE = 11, - NETMSG_HLTV = 12, - NETMSG_TEXTMSG = 13, - NETMSG_SCOREINFO = 14, - NETMSG_BARTIME = 15, - NETMSG_SENDAUDIO = 17, - NETMSG_SAYTEXT = 18, - NETMSG_BOTVOICE = 19, - NETMSG_RESETHUD = 20, - NETMSG_UNDEFINED = 0 -}; - // sensing states enum SensingState { @@ -469,7 +469,7 @@ enum WaypointFlag // defines for waypoint connection flags field (16 bits are available) enum PathFlag { - PATHFLAG_JUMP = (1 << 0), // must jump for this connection + PATHFLAG_JUMP = (1 << 0) // must jump for this connection }; // enum pathfind search type @@ -526,6 +526,8 @@ const int MAX_WAYPOINTS = 1024; const int MAX_WEAPONS = 32; const int NUM_WEAPONS = 26; const int MAX_COLLIDE_MOVES = 3; +const int MAX_ENGINE_PLAYERS = 32; // we can have 64 players with xash +const int MAX_PRINT_BUFFER = 1024; // weapon masks const int WEAPON_PRIMARY = ((1 << WEAPON_XM1014) | (1 <id; }; void TakeDamage (edict_t *inflictor, int damage, int armor, int bits); - void TakeBlinded (const Vector &fade, int alpha); + void TakeBlinded (int r, int g, int b, int alpha); void DiscardWeaponForUser (edict_t *user, bool discardC4); @@ -1249,7 +1227,7 @@ class BotManager : public Singleton private: Array m_creationTab; // bot creation tab - Bot *m_bots[32]; // all available bots + Bot *m_bots[MAX_ENGINE_PLAYERS]; // all available bots float m_maintainTime; // time to maintain bot creation float m_quotaMaintainTime; // time to maintain bot quota @@ -1259,8 +1237,8 @@ private: bool m_economicsGood[2]; // is team able to buy anything bool m_deathMsgSent; // for fakeping - Array m_activeGrenades; // holds currently active grenades in the map - Array m_trackedPlayers; // holds array of connected players, and waits the player joins team + Array m_activeGrenades; // holds currently active grenades in the map + Array m_trackedPlayers; // holds array of connected players, and waits the player joins team edict_t *m_killerEntity; // killer entity for bots @@ -1326,7 +1304,7 @@ public: // grenades void UpdateActiveGrenades (void); - const Array &GetActiveGrenades (void); + const Array &GetActiveGrenades (void); inline bool HasActiveGrenades (void) { @@ -1339,43 +1317,6 @@ public: void SendDeathMsgFix (void); }; -// texts localizer -class Localizer : public Singleton -{ -public: - Array m_langTab; - -public: - Localizer (void) { m_langTab.RemoveAll (); } - ~Localizer (void) { m_langTab.RemoveAll (); } - - char *TranslateInput (const char *input); - void Destroy (void); -}; - -// netmessage handler class -class NetworkMsg : public Singleton -{ -private: - Bot *m_bot; - int m_state; - int m_message; - int m_registerdMessages[NETMSG_RESETHUD + 1]; - -public: - NetworkMsg (void); - ~NetworkMsg (void) { }; - - void Execute (void *p); - inline void Reset (void) { m_message = NETMSG_UNDEFINED; m_state = 0; m_bot = NULL; }; - void HandleMessageIfRequired (int messageType, int requiredType); - - inline void SetMessage (int message) { m_message = message; } - inline void SetBot (Bot *bot) { m_bot = bot; } - - inline int GetId (int messageType) { return m_registerdMessages[messageType]; } - inline void SetId (int messageType, int messsageIdentifier) { m_registerdMessages[messageType] = messsageIdentifier; } -}; // waypoint operation class class Waypoint : public Singleton @@ -1395,11 +1336,12 @@ private: Vector m_learnPosition; Vector m_foundBombOrigin; + int m_loadTries; int m_cacheWaypointIndex; int m_lastJumpWaypoint; int m_visibilityIndex; Vector m_lastWaypoint; - byte m_visLUT[MAX_WAYPOINTS][MAX_WAYPOINTS / 4]; + unsigned char m_visLUT[MAX_WAYPOINTS][MAX_WAYPOINTS / 4]; float m_pathDisplayTime; float m_arrowDisplayTime; @@ -1430,12 +1372,12 @@ public: void InitVisibilityTab (void); void InitTypes (void); - void AddPath (short int addIndex, short int pathIndex, float distance); + void AddPath (int addIndex, int pathIndex, float distance); int GetFacingIndex (void); int FindFarest (const Vector &origin, float maxDistance = 32.0); int FindNearest (const Vector &origin, float minDistance = 9999.0f, int flags = -1); - void FindInRadius (Array &radiusHolder, float radius, const Vector &origin, int maxCount = -1); + void FindInRadius (Array &holder, float radius, const Vector &origin, int maxCount = -1); void Add (int flags, const Vector &waypointOrigin = Vector::GetZero ()); void Delete (void); @@ -1456,6 +1398,7 @@ public: bool Load (void); void Save (void); + void CleanupPathMemory (void); bool Reachable (Bot *bot, int index); bool IsNodeReachable (const Vector &src, const Vector &destination); @@ -1482,191 +1425,54 @@ public: void SetGoalVisited (int index); void ClearVisitedGoals (void); - inline const Vector &GetBombPosition (void) - { - return m_foundBombOrigin; - } - - void SetBombPosition (bool shouldReset = false); + const char *GetDataDir (void); String CheckSubfolderFile (void); - // quick access - inline Path *operator [] (int index) - { - extern int g_numWaypoints; - - if (index < 0 || index >= g_numWaypoints) - assert (0); - - return GetPath (index); - } -}; - -// wayponit auto-downloader -enum WaypointDownloadError -{ - WDE_SOCKET_ERROR, - WDE_CONNECT_ERROR, - WDE_NOTFOUND_ERROR, - WDE_NOERROR -}; - -class WaypointDownloader -{ -public: + void SetBombPosition (bool shouldReset = false); + inline const Vector &GetBombPosition (void) { return m_foundBombOrigin; } // free's socket handle - void FreeSocket (int sock); + void CloseSocketHandle (int sock); // do actually downloading of waypoint file - WaypointDownloadError DoDownload (void); + WaypointDownloadError RequestWaypoint (void); }; -enum VarType -{ - VT_NORMAL = 0, - VT_READONLY, - VT_PASSWORD, - VT_NOSERVER, - VT_NOREGISTER -}; +#include -class ConVarWrapper : public Singleton -{ -private: - struct VarPair - { - VarType type; - cvar_t reg; - class ConVar *self; - }; - Array 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 () +// expose bot super-globals #define waypoints Waypoint::GetReference () +#define engine Engine::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 (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 (val)); - } - - inline void SetString (const char *val) - { - g_engfuncs.pfnCVarSetString (m_eptr->name, val); - } -}; - // prototypes of bot functions... 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 GetWaveLength (const char *fileName); -extern bool IsDedicatedServer (void); extern bool IsVisible (const Vector &origin, edict_t *ent); extern bool IsAlive (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 IsValidPlayer (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, MemoryFile *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 const char *GetMapName (void); -extern const char *GetWaypointDir (void); -extern const char *GetModName (void); -extern const char *GetField (const char *string, int fieldId, bool endLine = false); -extern const char *FormatBuffer (const char *format, ...); - -extern uint16 GenerateBuildNumber (void); -extern Vector GetEntityOrigin (edict_t *ent); - extern void FreeLibraryMemory (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 ServerCommand (const char *format, ...); -extern void RegisterCommand (const char *command, void funcPtr (void)); extern void CheckWelcomeMessage (void); extern void DetectCSVersion (void); -extern void PlaySound (edict_t *ent, const char *soundName); -extern void ServerPrint (const char *format, ...); -extern void ChartPrint (const char *format, ...); -extern void CenterPrint (const char *format, ...); -extern void ClientPrint (edict_t *ent, int dest, const char *format, ...); - extern void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...); -extern void TraceLine (const Vector &start, const Vector &end, bool ignoreMonsters, bool ignoreGlass, edict_t *ignoreEntity, TraceResult *ptr); -extern void TraceLine (const Vector &start, const Vector &end, bool ignoreMonsters, edict_t *ignoreEntity, TraceResult *ptr); -extern void TraceHull (const Vector &start, const Vector &end, bool ignoreMonsters, int hullNumber, edict_t *ignoreEntity, TraceResult *ptr); -extern void DrawLine (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, int red, int green, int blue, int brightness, int speed, int life); -extern void DrawArrow (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, int red, int green, int blue, int brightness, int speed, int life); extern void DisplayMenuToClient (edict_t *ent, MenuText *menu); extern void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex); extern void SoundAttachToClients (edict_t *ent, const char *sample, float volume); extern void SoundSimulateUpdate (int playerIndex); +extern const char *FormatBuffer (const char *format, ...); + // very global convars extern ConVar yb_jasonmode; extern ConVar yb_communication_type; @@ -1679,5 +1485,5 @@ extern ConVar yb_ignore_enemies; inline int Bot::GetIndex (void) { - return IndexOfEntity (GetEntity ()); -} \ No newline at end of file + return engine.IndexOfEntity (GetEntity ()); +} diff --git a/include/corelib.h b/include/corelib.h index 024aa95..d623331 100644 --- a/include/corelib.h +++ b/include/corelib.h @@ -1,4 +1,4 @@ -// +// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // @@ -21,6 +21,12 @@ #include #include +#ifdef _WIN32 +#include +#else +#include +#endif + // // Title: Utility Classes Header // @@ -698,10 +704,10 @@ public: // // Function: BuildVectors // - // Builds a 3D referential from a view angle, that is to say, the relative "forward", "right" and "upward" direction - // that a player would have if he were facing this view angle. World angles are stored in Vector structs too, the - // "x" component corresponding to the X angle (horizontal angle), and the "y" component corresponding to the Y angle - // (vertical angle). + // Builds a 3D referential from a view angle, that is to say, the relative "forward", "right" and "upward" direction + // that a player would have if he were facing this view angle. World angles are stored in Vector structs too, the + // "x" component corresponding to the X angle (horizontal angle), and the "y" component corresponding to the Y angle + // (vertical angle). // // Parameters: // forward - Forward referential vector. @@ -2297,7 +2303,7 @@ public: char buffer[1024]; va_start (ap, fmt); - vsprintf (buffer, fmt, ap); + vsnprintf (buffer, sizeof (buffer) - 1, fmt, ap); va_end (ap); Append (buffer); @@ -2368,7 +2374,7 @@ public: char buffer[1024]; va_start (ap, fmt); - vsprintf (buffer, fmt, ap); + vsnprintf (buffer, sizeof (buffer) - 1, fmt, ap); va_end (ap); Assign (buffer); @@ -2595,7 +2601,7 @@ public: holder[j++] = m_bufferPtr[i]; holder[j] = 0; - result.Assign(holder); + result.Assign (holder); delete [] holder; return result; @@ -3296,6 +3302,33 @@ public: return Split (sep); } + +public: + // + // Function: TrimExternalBuffer + // Trims string from both sides. + // + // Returns: + // None + // + static inline void TrimExternalBuffer (char *str) + { + int pos = 0; + char *dest = str; + + while (str[pos] <= ' ' && str[pos] > 0) + pos++; + + while (str[pos]) + { + *(dest++) = str[pos]; + pos++; + } + *(dest--) = '\0'; + + while (dest >= str && *dest <= ' ' && *dest > 0) + *(dest--) = '\0'; + } }; // @@ -3434,23 +3467,6 @@ public: return fgets (buffer, count, m_handle); } - // - // Function: GetBuffer - // Gets the line from file stream, and stores it inside string class. - // - // Parameters: - // buffer - String buffer, that should receive line. - // count - Max. size of buffer. - // - // Returns: - // True if operation succeeded, false otherwise. - // - bool GetBuffer (String &buffer, int count) - { - assert (m_handle != NULL); - return !String (fgets (buffer, count, m_handle)).IsEmpty (); - } - // // Function: Printf // Puts formatted buffer, into stream. @@ -3615,6 +3631,289 @@ public: } 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 + } +}; + +// +// Class: MemoryFile +// Simple Memory file wrapper class. (RO) +// +class MemoryFile +{ +public: + typedef unsigned char *(*MF_Loader) (const char *, int *); + typedef void (*MF_Unloader) (unsigned char *); + +public: + static MF_Loader Loader; + static MF_Unloader Unloader; + +protected: + int m_size; + int m_pos; + unsigned char *m_buffer; + + // + // Group: (Con/De)structors + // +public: + + // + // Function: File + // Default file class, constructor. + // + MemoryFile (void) + { + m_size = 0; + m_pos = 0; + + m_buffer = NULL; + } + + // + // Function: File + // Default file class, constructor, with file opening. + // + MemoryFile (const String &fileName) + { + m_size = 0; + m_pos = 0; + + m_buffer = NULL; + + Open (fileName); + } + + // + // Function: ~File + // Default file class, destructor. + // + ~MemoryFile (void) + { + Close (); + } + + // + // Function: Open + // Opens file and gets it's size. + // + // Parameters: + // fileName - String containing file name. + // + // Returns: + // True if operation succeeded, false otherwise. + // + bool Open (const char *fileName) + { + if (!Loader) + return false; + + m_size = 0; + m_pos = 0; + + m_buffer = Loader (fileName, &m_size); + + if (m_buffer == NULL || m_size < 0) + return false; + + return true; + } + + // + // Function: Close + // Closes file, and destroys STDIO file object. + // + void Close (void) + { + if (Unloader != NULL) + Unloader (m_buffer); + + m_size = 0; + m_pos = 0; + + m_buffer = NULL; + } + + // + // Function: GetChar + // Pops one character from the file stream. + // + // Returns: + // Popped from stream character + // + int GetChar (void) + { + if (m_buffer == NULL || m_pos >= m_size) + return -1; + + int readCh = m_buffer[m_pos]; + m_pos++; + + return readCh; + } + + // + // Function: GetBuffer + // Gets the single line, from the non-binary stream. + // + // Parameters: + // buffer - Pointer to buffer, that should receive string. + // count - Max. size of buffer. + // + // Returns: + // Pointer to string containing popped line. + // + char *GetBuffer (char *buffer, int count) + { + if (m_buffer == NULL || m_pos >= m_size) + return NULL; + + int start = m_pos; + int end = m_size - 1; + + if (m_size - m_pos > count - 1) + end = m_pos + count - 1; + + while (m_pos < end) + { + if (m_buffer[m_pos] == 0x0a) + end = m_pos; + + m_pos++; + } + + if (m_pos == start) + return NULL; + + int pos = start; + + for (; pos <= end; pos++) + buffer[pos - start] = m_buffer[pos]; + + if (buffer[pos - start - 2] == 0x0d) + { + buffer[pos - start - 2] = '\n'; + pos--; + } + + if (buffer[pos - start - 1] == 0x0d || buffer[pos - start - 1] == 0x0a) + buffer[pos - start - 1] = '\n'; + + buffer[pos - start] = 0; + + return buffer; + } + + // + // Function: Read + // Reads buffer from file stream in binary format. + // + // Parameters: + // buffer - Holder for read buffer. + // size - Size of the buffer to read. + // count - Number of buffer chunks to read. + // + // Returns: + // Number of bytes red from file. + // + int Read (void *buffer, int size, int count = 1) + { + if (!m_buffer|| m_pos >= m_size || buffer == NULL || !size || !count) + return 0; + + int blocksRead = min ((m_size - m_pos) / size, count) * size; + + memcpy (buffer, &m_buffer[m_pos], blocksRead); + m_pos += blocksRead; + + return blocksRead; + } + + // + // Function: Seek + // Seeks file stream with specified parameters. + // + // Parameters: + // offset - Offset where cursor should be set. + // origin - Type of offset set. + // + // Returns: + // True if operation success, false otherwise. + // + bool Seek (long offset, int origin) + { + if (m_buffer == NULL || m_pos >= m_size) + return false; + + if (origin == SEEK_SET) + { + if (offset >= m_size) + return false; + + m_pos = offset; + } + else if (origin == SEEK_END) + { + if (offset >= m_size) + return false; + + m_pos = m_size - offset; + } + else + { + if (m_pos + offset >= m_size) + return false; + + m_pos += offset; + } + return true; + } + + // + // Function: GetSize + // Gets the file size of opened file stream. + // + // Returns: + // Number of bytes in file. + // + int GetSize (void) + { + return m_size; + } + + // + // Function: IsValid + // Checks whether file stream is valid. + // + // Returns: + // True if file stream valid, false otherwise. + // + bool IsValid (void) + { + return m_buffer != NULL && m_size > 0; + } }; // @@ -3623,63 +3922,9 @@ public: // typedef Array StrVec; -// -// Class: Exception -// Simple exception raiser. -// -class Exception -{ -private: - String m_exceptionText; - String m_fileName; - int m_line; - -// -// Group: (Con/De)structors -// -public: - - // - // Function: Exception - // Default exception constructor. - // - // Parameters: - // exceptionText - Text to throw. - // fileName - Debug file name. - // line - Debug line number. - // - Exception (String exceptionText, String fileName = "(no)", int line = -1) : m_exceptionText (exceptionText), m_fileName (fileName), m_line (line) { } - - // - // Function: ~Exception - // Default exception destructor. - // - virtual ~Exception (void) { }; - -// -// Group: Functions -// -public: - - // - // Function: GetDescription - // Gets the description from throw object. - // - // Returns: - // Exception text. - // - inline const String &GetDescription (void) - { - static String result; - - if (m_fileName != "(no)" && m_line != -1) - result.AssignFormat ("Exception: %s at %s:%i", m_exceptionText.GetBuffer (), m_fileName.GetBuffer (), m_line); - else - result = m_exceptionText; - - return result; - } -}; +#ifndef FORCEINLINE +#define FORCEINLINE inline +#endif // // Class: Singleton @@ -3704,6 +3949,10 @@ protected: // virtual ~Singleton (void) { } +private: + Singleton (Singleton const &); + void operator = (Singleton const &); + public: // @@ -3714,10 +3963,9 @@ public: // Object pointer. // // - static inline T *GetObject (void) + static FORCEINLINE T *GetObject (void) { - static T reference; - return &reference; + return &GetReference (); } // @@ -3728,7 +3976,7 @@ public: // Object reference. // // - static inline T &GetReference (void) + static FORCEINLINE T &GetReference (void) { static T reference; return reference; @@ -3769,4 +4017,4 @@ public: // // Squared Length // -#define GET_SQUARE(in) (in * in) \ No newline at end of file +#define GET_SQUARE(in) (in * in) diff --git a/include/engine.h b/include/engine.h new file mode 100644 index 0000000..b709e28 --- /dev/null +++ b/include/engine.h @@ -0,0 +1,324 @@ +// +// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). +// Copyright (c) YaPB Development Team. +// +// This software is licensed under the BSD-style license. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// http://yapb.jeefo.net/license +// +// Purpose: Engine & Game interfaces. +// + +#pragma once + +// line draw +enum DrawLineType +{ + DRAW_SIMPLE, + DRAW_ARROW, + DRAW_NUM +}; + +// trace ignore +enum TraceIgnore +{ + TRACE_IGNORE_NONE = 0, + TRACE_IGNORE_GLASS = (1 << 0), + TRACE_IGNORE_MONSTERS = (1 << 1), + TRACE_IGNORE_EVERYTHING = TRACE_IGNORE_GLASS | TRACE_IGNORE_MONSTERS +}; + +// variable type +enum VarType +{ + VT_NORMAL = 0, + VT_READONLY, + VT_PASSWORD, + VT_NOSERVER, + VT_NOREGISTER +}; + +// netmessage functions +enum NetMsgId +{ + NETMSG_UNDEFINED = -1, + NETMSG_VGUI = 1, + NETMSG_SHOWMENU = 2, + NETMSG_WEAPONLIST = 3, + NETMSG_CURWEAPON = 4, + NETMSG_AMMOX = 5, + NETMSG_AMMOPICKUP = 6, + NETMSG_DAMAGE = 7, + NETMSG_MONEY = 8, + NETMSG_STATUSICON = 9, + NETMSG_DEATH = 10, + NETMSG_SCREENFADE = 11, + NETMSG_HLTV = 12, + NETMSG_TEXTMSG = 13, + NETMSG_SCOREINFO = 14, + NETMSG_BARTIME = 15, + NETMSG_SENDAUDIO = 17, + NETMSG_SAYTEXT = 18, + NETMSG_BOTVOICE = 19, + NETMSG_NUM = 21 +}; + +// variable reg pair +struct VarPair +{ + VarType type; + cvar_t reg; + bool regMissing; + class ConVar *self; +}; + +// translation pair +struct TranslatorPair +{ + const char *original; + const char *translated; +}; + +// network message block +struct MessageBlock +{ + int bot; + int state; + int msg; + int regMsgs[NETMSG_NUM]; +}; + +// provides utility functions to not call original engine (less call-cost) +class Engine : public Singleton +{ +private: + short m_drawModels[DRAW_NUM]; + + // bot client command + bool m_isBotCommand; + char m_arguments[256]; + int m_argumentCount; + + edict_t *m_startEntity; + edict_t *m_localEntity; + + Array m_cvars; + Array m_language; + + MessageBlock m_msgBlock; + +public: + Engine (void); + + ~Engine (void); + + // public functions +public: + + // precaches internal stuff + void Precache (edict_t *startEntity); + + // prints data to servers console + void Printf (const char *fmt, ...); + + // prints chat message to all players + void ChatPrintf (const char *fmt, ...); + + // prints center message to all players + void CenterPrintf (const char *fmt, ...); + + // prints message to client console + void ClientPrintf (edict_t *ent, const char *fmt, ...); + + // display world line + void DrawLine (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, int red, int green, int blue, int brightness, int speed, int life, DrawLineType type = DRAW_SIMPLE); + + // test line + void TestLine (const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult *ptr); + + // test line + void TestHull (const Vector &start, const Vector &end, int ignoreFlags, int hullNumber, edict_t *ignoreEntity, TraceResult *ptr); + + // get's the wave length + float GetWaveLength (const char *fileName); + + // we are on dedicated server ? + bool IsDedicatedServer (void); + + // get stripped down mod name + const char *GetModName (void); + + // get the valid mapname + const char *GetMapName (void); + + // get the "any" entity origin + Vector GetAbsOrigin (edict_t *ent); + + // send server command + void IssueCmd (const char *fmt, ...); + + // registers a server command + void RegisterCmd (const char *command, void func (void)); + + // play's sound to client + void EmitSound (edict_t *ent, const char *sound); + + // sends bot command + void IssueBotCommand (edict_t *ent, const char *fmt, ...); + + // adds cvar to registration stack + void PushVariableToStack (const char *variable, const char *value, VarType varType, bool regMissing, ConVar *self); + + // sends local registration stack for engine registration + void PushRegisteredConVarsToEngine (bool gameVars = false); + + // translates bot message into needed language + char *TraslateMessage (const char *input); + + // cleanup translator resources + void TerminateTranslator (void); + + // do actual network message processing + void ProcessMessageCapture (void *ptr); + + // public inlines +public: + + // get the current time on server + FORCEINLINE float Time (void) + { + return g_pGlobals->time; + } + + // get "maxplayers" limit on server + FORCEINLINE int MaxClients (void) + { + 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; + } + + // gets edict pointer out of entity index + FORCEINLINE edict_t *EntityOfIndex (const int index) + { + return static_cast (m_startEntity + index); + }; + + // gets edict index out of it's pointer + FORCEINLINE int IndexOfEntity (const edict_t *ent) + { + return static_cast (ent - m_startEntity); + }; + + // verify entity isn't null + FORCEINLINE bool IsNullEntity (const edict_t *ent) + { + return !ent || !IndexOfEntity (ent); + } + + // gets the player team + FORCEINLINE int GetTeam (edict_t *ent) + { + extern Client g_clients[MAX_ENGINE_PLAYERS]; + +#ifndef XASH_CSDM + return g_clients[IndexOfEntity (ent) - 1].team; +#else + return g_clients[IndexOfEntity (ent) - 1].team = ent->v.team == 1 ? TERRORIST : CT; +#endif + } + + // adds translation pair from config + inline void PushTranslationPair (const TranslatorPair &lang) + { + m_language.Push (lang); + } + + // resets the message capture mechanism + inline void ResetMessageCapture (void) + { + m_msgBlock.msg = NETMSG_UNDEFINED; + m_msgBlock.state = 0; + m_msgBlock.bot = 0; + }; + + // sets the currently executed message + inline void SetOngoingMessageId (int message) + { + m_msgBlock.msg = message; + } + + // set the bot entity that receive this message + inline void SetOngoingMessageReceiver (int id) + { + m_msgBlock.bot = id; + } + + // find registered message id + FORCEINLINE int FindMessageId (int type) + { + return m_msgBlock.regMsgs[type]; + } + + // assigns message id for message type + inline void AssignMessageId (int type, int id) + { + m_msgBlock.regMsgs[type] = id; + } + + // tries to set needed message id + FORCEINLINE void TryCaptureMessage (int type, int msgId) + { + if (type == m_msgBlock.regMsgs[msgId]) + SetOngoingMessageId (msgId); + } + + // static utility functions +public: + static const char *ExtractSingleField (const char *string, int id, bool terminate); +}; + +// simplify access for console variables +class ConVar +{ +public: + cvar_t *m_eptr; + +public: + ConVar (const char *name, const char *initval, VarType type = VT_NOSERVER, bool regMissing = false); + + FORCEINLINE bool GetBool (void) { return m_eptr->value > 0.0f; } + FORCEINLINE int GetInt (void) { return static_cast (m_eptr->value); } + FORCEINLINE float GetFloat (void) { return m_eptr->value; } + FORCEINLINE const char *GetString (void) { return m_eptr->string; } + FORCEINLINE void SetFloat (float val) { m_eptr->value = val; } + FORCEINLINE void SetInt (int val) { SetFloat (static_cast (val)); } + FORCEINLINE void SetString (const char *val) { g_engfuncs.pfnCvar_DirectSet (m_eptr, const_cast (val)); } +}; diff --git a/include/engine/const.h b/include/engine/const.h index 58f9325..eb53672 100644 --- a/include/engine/const.h +++ b/include/engine/const.h @@ -678,7 +678,7 @@ enum kRenderTransTexture, // src*a+dest*(1-a) kRenderGlow, // src*a+dest -- No Z buffer checks kRenderTransAlpha, // src*srca+dest*(1-srca) - kRenderTransAdd, // src*a+dest + kRenderTransAdd // src*a+dest }; enum @@ -703,7 +703,7 @@ enum kRenderFxDeadPlayer, // kRenderAmt is the player index kRenderFxExplode, // Scale up really big! kRenderFxGlowShell, // Glowing Shell - kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!) + kRenderFxClampMinScale // Keep this sprite from getting very small (SPRITES only!) }; diff --git a/include/engine/eiface.h b/include/engine/eiface.h index 48c924f..aafa72d 100644 --- a/include/engine/eiface.h +++ b/include/engine/eiface.h @@ -69,20 +69,15 @@ typedef enum { print_console, print_center, - print_chat, + print_chat } PRINT_TYPE; -typedef enum -{ - print_withtag = print_console | 0x3ff, -} PRINT_TYPE_EX; // (dz): added for bots needs - // For integrity checking of content on clients typedef enum { force_exactfile, // File on client must exactly match server's file force_model_samebounds, // For model files only, the geometry must fit in the same bbox - force_model_specifybounds, // For model files only, the geometry must fit in the specified bbox + force_model_specifybounds // For model files only, the geometry must fit in the specified bbox } FORCE_TYPE; // Returned by TraceLine @@ -100,8 +95,6 @@ typedef struct int iHitgroup; // 0 == generic, non zero is specific body part } TraceResult; -typedef edict_t *entity_t; - typedef uint32 CRC32_t; // Engine hands this to DLLs for functionality callbacks @@ -149,7 +142,7 @@ typedef struct enginefuncs_s void (*pfnGetAimVector) (edict_t *ent, float speed, float *rgflReturn); void (*pfnServerCommand) (char *str); void (*pfnServerExecute) (void); - void (*pfnClientCommand) (edict_t *ent, char *szFmt, ...); + void (*pfnClientCommand) (edict_t *ent, char const *szFmt, ...); void (*pfnParticleEffect) (const float *org, const float *dir, float color, float count); void (*pfnLightStyle) (int style, char *val); int (*pfnDecalIndex) (const char *name); @@ -203,7 +196,7 @@ typedef struct enginefuncs_s void (*pfnSetView) (const edict_t *client, const edict_t *pViewent); float (*pfnTime) (void); void (*pfnCrosshairAngle) (const edict_t *client, float pitch, float yaw); - byte *(*pfnLoadFileForMe) (char *szFilename, int *pLength); + byte *(*pfnLoadFileForMe) (char const *szFilename, int *pLength); void (*pfnFreeFile) (void *buffer); void (*pfnEndSection) (const char *pszSectionName); // trigger_endsection int (*pfnCompareFileTime) (char *filename1, char *filename2, int *compare); @@ -215,9 +208,9 @@ typedef struct enginefuncs_s void (*pfnRunPlayerMove) (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec); int (*pfnNumberOfEntities) (void); char *(*pfnGetInfoKeyBuffer) (edict_t *e); // passing in NULL gets the serverinfo - char *(*pfnInfoKeyValue) (char *infobuffer, char *key); + char *(*pfnInfoKeyValue) (char *infobuffer, char const *key); void (*pfnSetKeyValue) (char *infobuffer, char *key, char *value); - void (*pfnSetClientKeyValue) (int clientIndex, char *infobuffer, char *key, char *value); + void (*pfnSetClientKeyValue) (int clientIndex, char *infobuffer, char const *key, char const *value); int (*pfnIsMapValid) (char *szFilename); void (*pfnStaticDecal) (const float *origin, int decalIndex, int entityIndex, int modelIndex); int (*pfnPrecacheGeneric) (char *s); @@ -246,7 +239,7 @@ typedef struct enginefuncs_s void (*pfnDeltaUnsetFieldByIndex) (struct delta_s *pFields, int fieldNumber); void (*pfnSetGroupMask) (int mask, int op); int (*pfnCreateInstancedBaseline) (int classname, struct entity_state_s *baseline); - void (*pfnCvar_DirectSet) (struct cvar_s *var, char *value); + void (*pfnCvar_DirectSet) (struct cvar_t *var, char *value); void (*pfnForceUnmodified) (FORCE_TYPE type, float *mins, float *maxs, const char *szFilename); void (*pfnGetPlayerStats) (const edict_t *client, int *ping, int *packet_loss); void (*pfnAddServerCommand) (char *cmd_name, void (*function) (void)); @@ -280,7 +273,7 @@ typedef struct enginefuncs_s typedef struct KeyValueData_s { char *szClassName; // in: entity classname - char *szKeyName; // in: name of key + char const *szKeyName; // in: name of key char *szValue; // in: value of key int32 fHandled; // out: DLL sets to true if key-value pair was understood } KeyValueData; diff --git a/include/engine/extdll.h b/include/engine/extdll.h index e5e086e..450ec1b 100644 --- a/include/engine/extdll.h +++ b/include/engine/extdll.h @@ -20,7 +20,7 @@ #define DEBUG 1 #endif -#ifdef _WIN32 +#ifdef _MSC_VER #pragma warning (disable : 4244) // int or float down-conversion #pragma warning (disable : 4305) // int or float data truncation #pragma warning (disable : 4201) // nameless struct/union @@ -31,7 +31,7 @@ #pragma warning (disable : 4702) // unreachable code #pragma warning (disable : 4706) // assignment within conditional expression - /* (dz): disable deprecation warnings concerning unsafe CRT functions */ + /* disable deprecation warnings concerning unsafe CRT functions */ #if !defined _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE #endif diff --git a/include/engine/meta_api.h b/include/engine/meta_api.h index c4b9325..f1f6788 100644 --- a/include/engine/meta_api.h +++ b/include/engine/meta_api.h @@ -31,19 +31,19 @@ typedef enum PT_STARTUP, PT_CHANGELEVEL, PT_ANYTIME, - PT_ANYPAUSE, + PT_ANYPAUSE } PLUG_LOADTIME; typedef struct { - char *ifvers; - char *name; - char *version; - char *date; - char *author; - char *url; - char *logtag; + char const *ifvers; + char const *name; + char const *version; + char const *date; + char const *author; + char const *url; + char const *logtag; PLUG_LOADTIME loadable; PLUG_LOADTIME unloadable; } plugin_info_t; @@ -64,7 +64,7 @@ typedef enum PNL_DELAYED, PNL_PLUGIN, PNL_PLG_FORCED, - PNL_RELOAD, + PNL_RELOAD } PL_UNLOAD_REASON; typedef enum @@ -73,7 +73,7 @@ typedef enum MRES_IGNORED, MRES_HANDLED, MRES_OVERRIDE, - MRES_SUPERCEDE, + MRES_SUPERCEDE } META_RES; typedef struct meta_globals_s @@ -121,7 +121,7 @@ typedef enum GINFO_GAMEDIR, GINFO_DLL_FULLPATH, GINFO_DLL_FILENAME, - GINFO_REALDLL_FULLPATH, + GINFO_REALDLL_FULLPATH } ginfo_t; // Meta Utility Function table type. diff --git a/include/engine/util.h b/include/engine/util.h index 7951c3c..82ccd24 100644 --- a/include/engine/util.h +++ b/include/engine/util.h @@ -53,12 +53,6 @@ static inline edict_t *FIND_ENTITY_BY_TARGET (edict_t *entStart, const char *psz #define ClearBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) & ~(bits)) #define FBitSet(flBitVector, bit) ((int)(flBitVector) & (bit)) -// Pointer operators -#define PTR_TO_BYTE(in) *(byte *) (in) -#define PTR_TO_FLT(in) *(float *) (in) -#define PTR_TO_INT(in) *(int *) (in) -#define PTR_TO_STR(in) (char *) (in) - // Makes these more explicit, and easier to find #define FILE_GLOBAL static @@ -82,6 +76,7 @@ typedef int BOOL; // // Conversion among the three types of "entity", including identity-conversions. // +#if 0 static inline edict_t *ENT (const entvars_t *pev) { return pev->pContainingEntity; @@ -131,12 +126,14 @@ static inline entvars_t *VARS (EOFFSET eoffset) { return VARS (ENT (eoffset)); } +#endif static inline void MESSAGE_BEGIN (int msg_dest, int msg_type, const float *pOrigin, entvars_t *ent) { - (*g_engfuncs.pfnMessageBegin) (msg_dest, msg_type, pOrigin, ENT (ent)); + (*g_engfuncs.pfnMessageBegin) (msg_dest, msg_type, pOrigin, ent->pContainingEntity); } +#if 0 // Testing the three types of "entity" for nullity #define eoNullEntity 0 static inline BOOL FNullEnt (EOFFSET eoffset) @@ -162,6 +159,7 @@ static inline BOOL FStringNull (int stingPtr) #define cchMapNameMost 32 #define SAFE_FUNCTION_CALL(pfn,args) try { pfn args; } catch (...) { } +#endif // Dot products for view cone checking #define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees @@ -176,7 +174,7 @@ static inline BOOL FStrEq (const char *sz1, const char *sz2) } static inline BOOL FClassnameIs (edict_t *pent, const char *szClassname) { - return FStrEq (STRING (VARS (pent)->classname), szClassname); + return FStrEq (STRING (pent->v.classname), szClassname); } static inline BOOL FClassnameIs (entvars_t *pev, const char *szClassname) { @@ -207,8 +205,6 @@ typedef struct hudtextparms_s } hudtextparms_t; -extern Vector GetEntityOrigin (entvars_t *pevBModel); - #define AMBIENT_SOUND_STATIC 0 // medium radius attenuation #define AMBIENT_SOUND_EVERYWHERE 1 #define AMBIENT_SOUND_SMALLRADIUS 2 diff --git a/include/globals.h b/include/globals.h index 3a73f96..5f40d7f 100644 --- a/include/globals.h +++ b/include/globals.h @@ -20,7 +20,6 @@ extern bool g_autoWaypoint; extern bool g_botsCanPause; extern bool g_editNoclip; extern bool g_isMetamod; -extern bool g_isFakeCommand; extern bool g_sendAudioFinished; extern bool g_isCommencing; extern bool g_leaderChoosen[2]; @@ -39,7 +38,6 @@ extern float g_lastRadioTime[2]; extern int g_mapType; extern int g_numWaypoints; extern int g_gameFlags; -extern int g_fakeArgc; extern int g_highestDamageCT; extern int g_highestDamageT; @@ -50,15 +48,11 @@ extern int g_rusherWeaponPrefs[NUM_WEAPONS]; extern int g_carefulWeaponPrefs[NUM_WEAPONS]; extern int g_grenadeBuyPrecent[NUM_WEAPONS - 23]; extern int g_botBuyEconomyTable[NUM_WEAPONS - 15]; -extern int g_radioSelect[32]; +extern int g_radioSelect[MAX_ENGINE_PLAYERS]; extern int g_lastRadio[2]; extern int g_storeAddbotVars[4]; extern int *g_weaponPrefs[]; -extern short g_modelIndexLaser; -extern short g_modelIndexArrow; -extern char g_fakeArgv[256]; - extern Array > g_chatFactory; extern Array > g_chatterFactory; extern Array g_botNames; @@ -68,14 +62,13 @@ extern RandomSequenceOfUnique Random; extern WeaponSelect g_weaponSelect[NUM_WEAPONS + 1]; extern WeaponProperty g_weaponDefs[MAX_WEAPONS + 1]; -extern Client g_clients[32]; +extern Client g_clients[MAX_ENGINE_PLAYERS]; extern MenuText g_menus[21]; extern TaskItem g_taskFilters[]; extern Experience *g_experienceData; extern edict_t *g_hostEntity; -extern edict_t *g_worldEntity; extern Library *g_gameLib; extern gamefuncs_t g_functionTable; @@ -91,42 +84,3 @@ static inline bool IsNullString (const char *input) return *input == '\0'; } - -static inline float GetWorldTime (void) -{ - return g_pGlobals->time; -} - -static inline int GetMaxClients (void) -{ - return g_pGlobals->maxClients; -} - -static inline edict_t *EntityOfIndex (const int index) -{ - return static_cast (g_worldEntity + index); -}; - -static inline int IndexOfEntity(const edict_t *ent) -{ - return static_cast (ent - g_worldEntity); -}; - -static inline int EntOffsetOfEntity(const edict_t *ent) -{ - return (char *) ent - (char *) g_worldEntity; -} - -static inline bool IsEntityNull (const edict_t *ent) -{ - return !ent || !EntOffsetOfEntity (ent); -} - -static inline int GetTeam (edict_t *ent) -{ -#ifndef XASH_CSDM - return g_clients[IndexOfEntity (ent) - 1].team; -#else - return g_clients[IndexOfEntity (ent) - 1].team = ent->v.team == 1 ? TERRORIST : CT; -#endif -} \ No newline at end of file diff --git a/include/platform.h b/include/platform.h index 15634b6..b48457b 100644 --- a/include/platform.h +++ b/include/platform.h @@ -21,15 +21,15 @@ // detects the compiler #if defined (_MSC_VER) #define COMPILER_VISUALC _MSC_VER -#elif defined (__MINGW32__) - #define COMPILER_MINGW32 __MINGW32__ +#elif defined (__MINGW32_MAJOR_VERSION) + #define COMPILER_MINGW32 __MINGW32_MAJOR_VERSION #endif // configure export macros #if defined (COMPILER_VISUALC) || defined (COMPILER_MINGW32) - #define export extern "C" __declspec (dllexport) + #define SHARED_LIBRARAY_EXPORT extern "C" __declspec (dllexport) #elif defined (PLATFORM_LINUX) || defined (PLATFORM_OSX) - #define export extern "C" __attribute__((visibility("default"))) + #define SHARED_LIBRARAY_EXPORT extern "C" __attribute__((visibility("default"))) #else #error "Can't configure export macros. Compiler unrecognized." #endif @@ -38,6 +38,7 @@ #ifdef PLATFORM_WIN32 #include + #include #define DLL_ENTRYPOINT int STDCALL DllMain (HINSTANCE, DWORD dwReason, LPVOID) #define DLL_DETACHING (dwReason == DLL_PROCESS_DETACH) @@ -46,7 +47,7 @@ #if defined (COMPILER_VISUALC) #define DLL_GIVEFNPTRSTODLL extern "C" void STDCALL #elif defined (COMPILER_MINGW32) - #define DLL_GIVEFNPTRSTODLL export void STDCALL + #define DLL_GIVEFNPTRSTODLL SHARED_LIBRARAY_EXPORT void STDCALL #endif // specify export parameter @@ -157,4 +158,4 @@ public: { return m_ptr != NULL; } -}; \ No newline at end of file +}; diff --git a/include/resource.h b/include/resource.h index de10d08..561fa3d 100644 --- a/include/resource.h +++ b/include/resource.h @@ -11,17 +11,17 @@ // general product information #define PRODUCT_NAME "Yet Another POD-Bot" -#define PRODUCT_VERSION "2.7.2" +#define PRODUCT_VERSION "2.73" #define PRODUCT_AUTHOR "YaPB Dev Team" #define PRODUCT_URL "https://yapb.jeefo.net" #define PRODUCT_EMAIL "dmitry@jeefo.net" #define PRODUCT_LOGTAG "YAPB" #define PRODUCT_DESCRIPTION PRODUCT_NAME " v" PRODUCT_VERSION " - The Counter-Strike Bot" -#define PRODUCT_COPYRIGHT "Copyright © 2003-2016, by " PRODUCT_AUTHOR +#define PRODUCT_COPYRIGHT "Copyright © 2003-2016, by " PRODUCT_AUTHOR #define PRODUCT_LEGAL "Half-Life, Counter-Strike, Counter-Strike: Condition Zero, Steam, Valve is a trademark of Valve Corporation" #define PRODUCT_ORIGINAL_NAME "yapb.dll" #define PRODUCT_INTERNAL_NAME "skybot" -#define PRODUCT_VERSION_DWORD_INTERNAL 2,7,2 +#define PRODUCT_VERSION_DWORD_INTERNAL 2,73 #define PRODUCT_VERSION_DWORD PRODUCT_VERSION_DWORD_INTERNAL,0 #define PRODUCT_SUPPORT_VERSION "1.0 - CZ" #define PRODUCT_COMMENTS "http://github.com/jeefo/yapb/" diff --git a/project/makefile b/project/makefile index e86c21a..1fbf35b 100644 --- a/project/makefile +++ b/project/makefile @@ -16,13 +16,13 @@ OBJECTS = $(SRC_DIR)/basecode.cpp \ $(SRC_DIR)/chatlib.cpp \ $(SRC_DIR)/combat.cpp \ $(SRC_DIR)/globals.cpp \ + $(SRC_DIR)/engine.cpp \ $(SRC_DIR)/interface.cpp \ $(SRC_DIR)/navigate.cpp \ - $(SRC_DIR)/netmsg.cpp \ $(SRC_DIR)/support.cpp \ $(SRC_DIR)/waypoint.cpp \ -C_OPT_FLAGS = -O3 -DNDEBUG=1 -fno-exceptions -fno-rtti -funroll-loops -fomit-frame-pointer -pipe +C_OPT_FLAGS = -O3 -DNDEBUG=1 -fno-exceptions -fno-rtti -funroll-loops -fomit-frame-pointer -pipe -mtune=native C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3 C_GCC4_FLAGS = -fvisibility=hidden CPP_GCC4_FLAGS = -fvisibility-inlines-hidden @@ -47,13 +47,13 @@ ifeq "$(OS)" "Darwin" else LIB_EXT = so CFLAGS += -DLINUX -D_LINUX -DPOSIX - LINK += -shared + LINK += -shared -lsupc++ endif LINK += -m32 -lm -ldl -CFLAGS += -DHAVE_STDINT_H -D__extern_always_inline=inline -D_strdup=strdup -Dstricmp=strcasecmp -Dstrcmpi=strcasecmp -fno-strict-aliasing -m32 -Wall -Werror -Wno-uninitialized -Wno-unused -Wno-switch -Wno-c++11-compat-deprecated-writable-strings -CPPFLAGS += -Wno-invalid-offsetof -fno-exceptions -fno-rtti +CFLAGS += -DHAVE_STDINT_H -D__extern_always_inline=inline -D_strdup=strdup -Dstricmp=strcasecmp -Dstrcmpi=strcasecmp -fno-strict-aliasing -m32 -Wall -Werror -Wextra +CPPFLAGS += -fno-exceptions -fno-rtti -fno-builtin BINARY = $(PROJECT).$(LIB_EXT) @@ -72,30 +72,10 @@ endif IS_CLANG := $(shell $(CPP) --version | head -1 | grep clang > /dev/null && echo "1" || echo "0") ifeq "$(IS_CLANG)" "1" - CPP_MAJOR := $(shell $(CPP) --version | grep clang | sed "s/.*version \([0-9]\)*\.[0-9]*.*/\1/") - CPP_MINOR := $(shell $(CPP) --version | grep clang | sed "s/.*version [0-9]*\.\([0-9]\)*.*/\1/") -else - CPP_MAJOR := $(shell $(CPP) -dumpversion >&1 | cut -b1) - CPP_MINOR := $(shell $(CPP) -dumpversion >&1 | cut -b3) -endif - -# Clang || GCC >= 4 -ifeq "$(shell expr $(IS_CLANG) \| $(CPP_MAJOR) \>= 4)" "1" CFLAGS += $(C_GCC4_FLAGS) CPPFLAGS += $(CPP_GCC4_FLAGS) endif -ifeq "$(IS_CLANG)" "1" - CFLAGS += -Wno-logical-op-parentheses -else - CFLAGS += -Wno-parentheses -endif - -# Clang >= 3 || GCC >= 4.7 -ifeq "$(shell expr $(IS_CLANG) \& $(CPP_MAJOR) \>= 3 \| $(CPP_MAJOR) \>= 4 \& $(CPP_MINOR) \>= 7)" "1" - CFLAGS += -Wno-delete-non-virtual-dtor -endif - # OS is Linux and not using clang ifeq "$(shell expr $(OS) \= Linux \& $(IS_CLANG) \= 0)" "1" LINK += -static-libgcc @@ -142,3 +122,4 @@ default: all clean: rm -rf release rm -rf debug + diff --git a/project/yapb.vcxproj b/project/yapb.vcxproj index 5d6b43f..9f08cd2 100644 --- a/project/yapb.vcxproj +++ b/project/yapb.vcxproj @@ -14,6 +14,7 @@ + @@ -33,12 +34,12 @@ + - @@ -54,13 +55,14 @@ DynamicLibrary - v140_xp + v120_xp false + true DynamicLibrary - v140_xp false + v120_xp @@ -111,9 +113,7 @@ Disabled ..\include\engine;..\include;%(AdditionalIncludeDirectories) WIN32;_DEBUG;%(PreprocessorDefinitions) - Async MultiThreadedDebug - false core.h .\debug\inf\yapb.pch @@ -128,7 +128,12 @@ true EditAndContinue Default + EnableFastChecks false + Strict + true + Default + true NDEBUG;%(PreprocessorDefinitions) @@ -141,7 +146,6 @@ .\debug\yapb.dll true true - true .\debug\inf\yapb.pdb true .\debug\inf\yapb.map @@ -149,11 +153,8 @@ Windows false false - false - false .\debug\inf\yapb.lib - MachineX86 ws2_32.lib;%(AdditionalDependencies) false @@ -180,13 +181,13 @@ AnySuitable - false + true Speed false ..\mmgr;..\include\engine;..\include;%(AdditionalIncludeDirectories) NDEBUG;WIN32;%(PreprocessorDefinitions) false - StreamingSIMDExtensions2 + AdvancedVectorExtensions .\release\inf\yapb.pch @@ -209,6 +210,7 @@ true MultiThreaded true + true NDEBUG;%(PreprocessorDefinitions) diff --git a/project/yapb.vcxproj.filters b/project/yapb.vcxproj.filters index 5d07092..3fe3d15 100644 --- a/project/yapb.vcxproj.filters +++ b/project/yapb.vcxproj.filters @@ -39,9 +39,6 @@ include\engine - - include\engine - include\engine @@ -69,6 +66,12 @@ include + + include + + + include\engine + @@ -83,9 +86,6 @@ source - - source - source @@ -101,6 +101,9 @@ source + + source + diff --git a/source/Android.mk b/source/Android.mk index 078ce7a..671dcf4 100644 --- a/source/Android.mk +++ b/source/Android.mk @@ -22,13 +22,13 @@ LOCAL_SRC_FILES := \ chatlib.cpp \ combat.cpp \ globals.cpp \ + engine.cpp \ interface.cpp \ navigate.cpp \ - netmsg.cpp \ support.cpp \ waypoint.cpp \ -LOCAL_CFLAGS += -O2 -DLINUX -D_LINUX -DPOSIX -DHAVE_STDINT_H -D__extern_always_inline=inline -D_strdup=strdup -Dstricmp=strcasecmp -Dstrcmpi=strcasecmp -fno-strict-aliasing -Wall -Werror -Wno-uninitialized -Wno-unused -Wno-switch -Wno-c++11-compat-deprecated-writable-strings -LOCAL_CPPFLAGS += -w -Wno-invalid-offsetof -fno-exceptions -fno-rtti +LOCAL_CFLAGS += -O2 -DLINUX -D_LINUX -DPOSIX -DHAVE_STDINT_H -D__extern_always_inline=inline -D_strdup=strdup -Dstricmp=strcasecmp -Dstrcmpi=strcasecmp -fno-strict-aliasing -Wall -Werror +LOCAL_CPPFLAGS += -w -fno-exceptions -fno-rtti include $(BUILD_SHARED_LIBRARY) diff --git a/source/basecode.cpp b/source/basecode.cpp index 1b827c9..5acf1a3 100644 --- a/source/basecode.cpp +++ b/source/basecode.cpp @@ -1,4 +1,4 @@ -// +// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // @@ -53,18 +53,18 @@ void Bot::PushMessageQueue (int message) // notify other bots of the spoken text otherwise, bots won't respond to other bots (network messages aren't sent from bots) int entityIndex = GetIndex (); - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *otherBot = bots.GetBot (i); if (otherBot != NULL && otherBot->pev != pev) { - if (m_notKilled == IsAlive (otherBot->GetEntity ())) + if (m_notKilled == otherBot->m_notKilled) { otherBot->m_sayTextBuffer.entityIndex = entityIndex; strcpy (otherBot->m_sayTextBuffer.sayText, m_tempStrings); } - otherBot->m_sayTextBuffer.timeNextChat = GetWorldTime () + otherBot->m_sayTextBuffer.chatDelay; + otherBot->m_sayTextBuffer.timeNextChat = engine.Time () + otherBot->m_sayTextBuffer.chatDelay; } } } @@ -102,7 +102,7 @@ bool Bot::ItemIsVisible (const Vector &destination, char *itemName) TraceResult tr; // trace a line from bot's eyes to destination.. - TraceLine (EyePosition (), destination, true, GetEntity (), &tr); + engine.TestLine (EyePosition (), destination, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // check if line of sight to object is not blocked (i.e. visible) if (tr.flFraction != 1.0f) @@ -124,7 +124,7 @@ bool Bot::EntityIsVisible (const Vector &dest, bool fromBody) TraceResult tr; // trace a line from bot's eyes to destination... - TraceLine (fromBody ? pev->origin - Vector (0.0f, 0.0f, 1.0f) : EyePosition (), dest, true, true, GetEntity (), &tr); + engine.TestLine (fromBody ? pev->origin - Vector (0.0f, 0.0f, 1.0f) : EyePosition (), dest, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); // check if line of sight to object is not blocked (i.e. visible) return tr.flFraction >= 1.0f; @@ -133,14 +133,14 @@ bool Bot::EntityIsVisible (const Vector &dest, bool fromBody) void Bot::CheckGrenadeThrow (void) { // check if throwing a grenade is a good thing to do... - if (m_lastEnemy == NULL || yb_ignore_enemies.GetBool () || yb_jasonmode.GetBool () || m_grenadeCheckTime > GetWorldTime () || m_isUsingGrenade || GetTaskId () == TASK_PLANTBOMB || GetTaskId () == TASK_DEFUSEBOMB || m_isReloading || !IsAlive (m_lastEnemy)) + if (m_lastEnemy == NULL || yb_ignore_enemies.GetBool () || yb_jasonmode.GetBool () || m_grenadeCheckTime > engine.Time () || m_isUsingGrenade || GetTaskId () == TASK_PLANTBOMB || GetTaskId () == TASK_DEFUSEBOMB || m_isReloading || !IsAlive (m_lastEnemy)) { m_states &= ~(STATE_THROW_HE | STATE_THROW_FB | STATE_THROW_SG); return; } // check again in some seconds - m_grenadeCheckTime = GetWorldTime () + 0.5f; + m_grenadeCheckTime = engine.Time () + 0.5f; // check if we have grenades to throw int grenadeToThrow = CheckGrenades (); @@ -148,7 +148,7 @@ void Bot::CheckGrenadeThrow (void) // if we don't have grenades no need to check it this round again if (grenadeToThrow == -1) { - m_grenadeCheckTime = GetWorldTime () + 15.0f; // changed since, conzero can drop grens from dead players + m_grenadeCheckTime = engine.Time () + 15.0f; // changed since, conzero can drop grens from dead players m_states &= ~(STATE_THROW_HE | STATE_THROW_FB | STATE_THROW_SG); return; @@ -174,7 +174,7 @@ void Bot::CheckGrenadeThrow (void) if (GetNearbyFriendsNearPosition (m_lastEnemy->v.origin, 256.0f) > 0) allowThrowing = false; - if (allowThrowing && m_seeEnemyTime + 2.0 < GetWorldTime ()) + if (allowThrowing && m_seeEnemyTime + 2.0 < engine.Time ()) { const Vector &enemyPredict = ((m_lastEnemy->v.velocity * 0.5f).Get2D () + m_lastEnemy->v.origin); float searchRadius = m_lastEnemy->v.velocity.GetLength2D (); @@ -215,7 +215,7 @@ void Bot::CheckGrenadeThrow (void) else if (grenadeToThrow == WEAPON_SMOKE) { // start smoke grenade throwing? - if ((m_states & STATE_SEEING_ENEMY) && GetShootingConeDeviation (m_enemy, &pev->origin) >= 0.70f && m_seeEnemyTime + 2.0f < GetWorldTime ()) + if ((m_states & STATE_SEEING_ENEMY) && GetShootingConeDeviation (m_enemy, &pev->origin) >= 0.70f && m_seeEnemyTime + 2.0f < engine.Time ()) m_states &= ~STATE_THROW_SG; else m_states |= STATE_THROW_SG; @@ -235,7 +235,7 @@ void Bot::CheckGrenadeThrow (void) int friendCount = GetNearbyFriendsNearPosition (path->origin, 256.0f); - if (friendCount != 0 || !(m_difficulty == 4 && friendCount != 0)) + if (friendCount > 0 && m_difficulty < 4) continue; m_throw = path->origin; @@ -252,24 +252,24 @@ void Bot::CheckGrenadeThrow (void) } // start concussion grenade throwing? - if (allowThrowing && m_seeEnemyTime + 2.0f < GetWorldTime ()) + if (allowThrowing && m_seeEnemyTime + 2.0f < engine.Time ()) m_states |= STATE_THROW_FB; else m_states &= ~STATE_THROW_FB; } if (m_states & STATE_THROW_HE) - PushTask (TASK_THROWHEGRENADE, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0f, false); + PushTask (TASK_THROWHEGRENADE, TASKPRI_THROWGRENADE, -1, engine.Time () + 3.0f, false); else if (m_states & STATE_THROW_FB) - PushTask (TASK_THROWFLASHBANG, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0f, false); + PushTask (TASK_THROWFLASHBANG, TASKPRI_THROWGRENADE, -1, engine.Time () + 3.0f, false); else if (m_states & STATE_THROW_SG) - PushTask (TASK_THROWSMOKE, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0f, false); + PushTask (TASK_THROWSMOKE, TASKPRI_THROWGRENADE, -1, engine.Time () + 3.0f, false); // delay next grenade throw if (m_states & (STATE_THROW_HE | STATE_THROW_FB | STATE_THROW_SG)) { - m_grenadeCheckTime = GetWorldTime () + MAX_GRENADE_TIMER; - m_maxThrowTimer = GetWorldTime () + MAX_GRENADE_TIMER * 2.0f; + m_grenadeCheckTime = engine.Time () + MAX_GRENADE_TIMER; + m_maxThrowTimer = engine.Time () + MAX_GRENADE_TIMER * 2.0f; } } @@ -281,7 +281,7 @@ void Bot::AvoidGrenades (void) return; // check if old pointers to grenade is invalid - if (IsEntityNull (m_avoidGrenade)) + if (engine.IsNullEntity (m_avoidGrenade)) { m_avoidGrenade = NULL; m_needAvoidGrenade = 0; @@ -291,7 +291,7 @@ void Bot::AvoidGrenades (void) m_avoidGrenade = NULL; m_needAvoidGrenade = 0; } - Array activeGrenades = bots.GetActiveGrenades (); + Array activeGrenades = bots.GetActiveGrenades (); // find all grenades on the map FOR_EACH_AE (activeGrenades, it) @@ -305,23 +305,23 @@ void Bot::AvoidGrenades (void) if (!EntityIsVisible (ent->v.origin) && InFieldOfView (ent->v.origin - EyePosition ()) > pev->fov * 0.5f) continue; - if (m_turnAwayFromFlashbang < GetWorldTime () && m_personality == PERSONALITY_RUSHER && m_difficulty == 4 && strcmp (STRING (ent->v.model) + 9, "flashbang.mdl") == 0) + if (m_turnAwayFromFlashbang < engine.Time () && m_personality == PERSONALITY_RUSHER && m_difficulty == 4 && strcmp (STRING (ent->v.model) + 9, "flashbang.mdl") == 0) { // don't look at flash bang if (!(m_states & STATE_SEEING_ENEMY)) { - pev->v_angle.y = AngleNormalize ((GetEntityOrigin (ent) - EyePosition ()).ToAngles ().y + 180.0f); + pev->v_angle.y = AngleNormalize ((engine.GetAbsOrigin (ent) - EyePosition ()).ToAngles ().y + 180.0f); m_canChooseAimDirection = false; - m_turnAwayFromFlashbang = GetWorldTime () + Random.Float (1.0f, 2.0f); + m_turnAwayFromFlashbang = engine.Time () + Random.Float (1.0f, 2.0f); } } else if (strcmp (STRING (ent->v.model) + 9, "hegrenade.mdl") == 0) { - if (!IsEntityNull (m_avoidGrenade)) + if (!engine.IsNullEntity (m_avoidGrenade)) return; - if (GetTeam (ent->v.owner) == m_team && ent->v.owner != GetEntity ()) + if (engine.GetTeam (ent->v.owner) == m_team && ent->v.owner != GetEntity ()) return; if ((ent->v.flags & FL_ONGROUND) == 0) @@ -354,7 +354,7 @@ bool Bot::IsBehindSmokeClouds (edict_t *ent) return false; const Vector &betweenUs = (ent->v.origin - pev->origin).Normalize (); - Array activeGrenades = bots.GetActiveGrenades (); + Array activeGrenades = bots.GetActiveGrenades (); // find all grenades on the map FOR_EACH_AE (activeGrenades, it) @@ -372,7 +372,7 @@ bool Bot::IsBehindSmokeClouds (edict_t *ent) if (!EntityIsVisible (ent->v.origin) && InFieldOfView (ent->v.origin - EyePosition ()) > pev->fov / 3.0f) continue; - const Vector &entityOrigin = GetEntityOrigin (grenade); + const Vector &entityOrigin = engine.GetAbsOrigin (grenade); const Vector &betweenNade = (entityOrigin - pev->origin).Normalize (); const Vector &betweenResult = ((betweenNade.Get2D () * 150.0f + entityOrigin) - pev->origin).Normalize (); @@ -469,7 +469,7 @@ void Bot::VerifyBreakable (edict_t *touch) m_breakableEntity = FindBreakable (); - if (IsEntityNull (m_breakableEntity)) + if (engine.IsNullEntity (m_breakableEntity)) return; m_campButtons = pev->button & IN_DUCK; @@ -482,7 +482,7 @@ edict_t *Bot::FindBreakable (void) // this function checks if bot is blocked by a shoot able breakable in his moving direction TraceResult tr; - TraceLine (pev->origin, pev->origin + (m_destOrigin - pev->origin).Normalize () * 64.0f, false, false, GetEntity (), &tr); + engine.TestLine (pev->origin, pev->origin + (m_destOrigin - pev->origin).Normalize () * 72.0f, TRACE_IGNORE_NONE, GetEntity (), &tr); if (tr.flFraction != 1.0f) { @@ -491,11 +491,11 @@ edict_t *Bot::FindBreakable (void) // check if this isn't a triggered (bomb) breakable and if it takes damage. if true, shoot the crap! if (IsShootableBreakable (ent)) { - m_breakable = tr.vecEndPos; + m_breakableOrigin = engine.GetAbsOrigin (ent); return ent; } } - TraceLine (EyePosition (), EyePosition () + (m_destOrigin - EyePosition ()).Normalize () * 64.0f, false, false, GetEntity (), &tr); + engine.TestLine (EyePosition (), EyePosition () + (m_destOrigin - EyePosition ()).Normalize () * 72.0f, TRACE_IGNORE_NONE, GetEntity (), &tr); if (tr.flFraction != 1.0f) { @@ -503,12 +503,12 @@ edict_t *Bot::FindBreakable (void) if (IsShootableBreakable (ent)) { - m_breakable = tr.vecEndPos; + m_breakableOrigin = engine.GetAbsOrigin (ent); return ent; } } m_breakableEntity = NULL; - m_breakable.Zero (); + m_breakableOrigin.Zero (); return NULL; } @@ -572,19 +572,19 @@ void Bot::FindItem (void) const float searchRadius = 340.0f; - if (!IsEntityNull (m_pickupItem)) + if (!engine.IsNullEntity (m_pickupItem)) { bool itemExists = false; pickupItem = m_pickupItem; - while (!IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, searchRadius))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, searchRadius))) { if ((ent->v.effects & EF_NODRAW) || IsValidPlayer (ent->v.owner)) continue; // someone owns this weapon or it hasn't re spawned yet if (ent == pickupItem) { - if (ItemIsVisible (GetEntityOrigin (ent), const_cast (STRING (ent->v.classname)))) + if (ItemIsVisible (engine.GetAbsOrigin (ent), const_cast (STRING (ent->v.classname)))) itemExists = true; break; @@ -612,14 +612,14 @@ void Bot::FindItem (void) m_pickupItem = NULL; m_pickupType = PICKUP_NONE; - while (!IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, searchRadius))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, searchRadius))) { bool allowPickup = false; // assume can't use it until known otherwise if ((ent->v.effects & EF_NODRAW) || ent == m_itemIgnore) continue; // someone owns this weapon or it hasn't respawned yet - entityOrigin = GetEntityOrigin (ent); + entityOrigin = engine.GetAbsOrigin (ent); // check if line of sight to object is not blocked (i.e. visible) if (ItemIsVisible (entityOrigin, const_cast (STRING (ent->v.classname)))) @@ -716,12 +716,12 @@ void Bot::FindItem (void) m_itemIgnore = ent; allowPickup = false; - if (!m_defendHostage && m_difficulty >= 3 && Random.Long (0, 100) < 30 && m_timeCamping + 15.0f < GetWorldTime ()) + if (!m_defendHostage && m_difficulty >= 3 && Random.Long (0, 100) < 30 && m_timeCamping + 15.0f < engine.Time ()) { int index = FindDefendWaypoint (entityOrigin); - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0f, 60.0f), true); // push camp task on to stack - PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (3.0f, 6.0f), true); // push move command + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (30.0f, 60.0f), true); // push camp task on to stack + PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (3.0f, 6.0f), true); // push move command if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand) m_campButtons |= IN_DUCK; @@ -748,7 +748,7 @@ void Bot::FindItem (void) float bombTimer = mp_c4timer.GetFloat (); float timeMidBlowup = g_timeBombPlanted + (bombTimer * 0.5f + bombTimer * 0.25f) - waypoints.GetTravelTime (pev->maxspeed, pev->origin, path->origin); - if (timeMidBlowup > GetWorldTime ()) + if (timeMidBlowup > engine.Time ()) { RemoveCertainTask (TASK_MOVETOPOSITION); // remove any move tasks @@ -772,11 +772,11 @@ void Bot::FindItem (void) { if (pickupType == PICKUP_HOSTAGE) { - if (IsEntityNull (ent) || ent->v.health <= 0) + if (engine.IsNullEntity (ent) || ent->v.health <= 0) allowPickup = false; // never pickup dead hostage - else for (int i = 0; i < GetMaxClients (); i++) + else for (int i = 0; i < engine.MaxClients (); i++) { - if ((bot = bots.GetBot (i)) != NULL && IsAlive (bot->GetEntity ())) + if ((bot = bots.GetBot (i)) != NULL && bot->m_notKilled) { for (int j = 0; j < MAX_HOSTAGES; j++) { @@ -835,8 +835,8 @@ void Bot::FindItem (void) { int index = FindDefendWaypoint (entityOrigin); - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0f, 70.0f), true); // push camp task on to stack - PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (10.0f, 30.0f), true); // push move command + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (30.0f, 70.0f), true); // push camp task on to stack + PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (10.0f, 30.0f), true); // push move command if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand) m_campButtons |= IN_DUCK; @@ -866,11 +866,11 @@ void Bot::FindItem (void) } } // end of the while loop - if (!IsEntityNull (pickupItem)) + if (!engine.IsNullEntity (pickupItem)) { - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - if ((bot = bots.GetBot (i)) != NULL && IsAlive (bot->GetEntity ()) && bot->m_pickupItem == pickupItem) + if ((bot = bots.GetBot (i)) != NULL && bot->m_notKilled && bot->m_pickupItem == pickupItem) { m_pickupItem = NULL; m_pickupType = PICKUP_NONE; @@ -899,7 +899,7 @@ void Bot::GetCampDirection (Vector *dest) TraceResult tr; const Vector &src = EyePosition (); - TraceLine (src, *dest, true, GetEntity (), &tr); + engine.TestLine (src, *dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // check if the trace hit something... if (tr.flFraction < 1.0f) @@ -966,12 +966,12 @@ void Bot::SwitchChatterIcon (bool show) if ((g_gameFlags & GAME_LEGACY) || yb_communication_type.GetInt () != 2) return; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (!(g_clients[i].flags & CF_USED) || (g_clients[i].ent->v.flags & FL_FAKECLIENT) || g_clients[i].team != m_team) continue; - MESSAGE_BEGIN (MSG_ONE, netmsg.GetId (NETMSG_BOTVOICE), NULL, g_clients[i].ent); // begin message + MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_BOTVOICE), NULL, g_clients[i].ent); // begin message WRITE_BYTE (show); // switch on/off WRITE_BYTE (GetIndex ()); MESSAGE_END (); @@ -988,30 +988,28 @@ void Bot::InstantChatterMessage (int type) if (m_notKilled) SwitchChatterIcon (true); - static float reportTime = GetWorldTime (); - // delay only reportteam if (type == Radio_ReportTeam) { - if (reportTime >= GetWorldTime ()) + if (m_timeRepotingInDelay < engine.Time ()) return; - reportTime = GetWorldTime () + Random.Float (30.0f, 80.0f); + m_timeRepotingInDelay = engine.Time () + Random.Float (30.0f, 60.0f); } String defaultSound = g_chatterFactory[type].GetRandomElement ().name; String painSound = g_chatterFactory[Chatter_DiePain].GetRandomElement ().name; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - edict_t *ent = EntityOfIndex (i); + edict_t *ent = engine.EntityOfIndex (i); - if (!IsValidPlayer (ent) || IsValidBot (ent) || GetTeam (ent) != m_team) + if (!IsValidPlayer (ent) || IsValidBot (ent) || engine.GetTeam (ent) != m_team) continue; g_sendAudioFinished = false; - MESSAGE_BEGIN (MSG_ONE, netmsg.GetId (NETMSG_SENDAUDIO), NULL, ent); // begin message + MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_SENDAUDIO), NULL, ent); // begin message WRITE_BYTE (GetIndex ()); if (pev->deadflag & DEAD_DYING) @@ -1049,10 +1047,10 @@ void Bot::ChatterMessage (int message) bool shouldExecute = false; - if (m_chatterTimes[message] < GetWorldTime () || m_chatterTimes[message] == 99999.0f) + if (m_chatterTimes[message] < engine.Time () || m_chatterTimes[message] == 99999.0f) { if (m_chatterTimes[message] != 99999.0f) - m_chatterTimes[message] = GetWorldTime () + g_chatterFactory[message][0].repeatTime; + m_chatterTimes[message] = engine.Time () + g_chatterFactory[message][0].repeatTime; shouldExecute = true; } @@ -1073,18 +1071,18 @@ void Bot::CheckMessageQueue (void) return; // get message from stack - int currentQueueMessage = GetMessageQueue (); + int state = GetMessageQueue (); // nothing to do? - if (currentQueueMessage == GSM_IDLE || (currentQueueMessage == GSM_RADIO && yb_csdm_mode.GetInt () == 2)) + if (state == GSM_IDLE || (state == GSM_RADIO && yb_csdm_mode.GetInt () == 2)) return; - switch (currentQueueMessage) + switch (state) { case GSM_BUY_STUFF: // general buy message // buy weapon - if (m_nextBuyTime > GetWorldTime ()) + if (m_nextBuyTime > engine.Time ()) { // keep sending message PushMessageQueue (GSM_BUY_STUFF); @@ -1100,7 +1098,7 @@ void Bot::CheckMessageQueue (void) } m_buyPending = false; - m_nextBuyTime = GetWorldTime () + Random.Float (0.5f, 1.3f); + m_nextBuyTime = engine.Time () + Random.Float (0.5f, 1.3f); // if bot buying is off then no need to buy if (!yb_botbuy.GetBool ()) @@ -1147,12 +1145,12 @@ void Bot::CheckMessageQueue (void) case GSM_RADIO: // general radio message issued // if last bot radio command (global) happened just a second ago, delay response - if (g_lastRadioTime[m_team] + 1.0f < GetWorldTime ()) + if (g_lastRadioTime[m_team] + 1.0f < engine.Time ()) { // if same message like previous just do a yes/no if (m_radioSelect != Radio_Affirmative && m_radioSelect != Radio_Negative) { - if (m_radioSelect == g_lastRadio[m_team] && g_lastRadioTime[m_team] + 1.5f > GetWorldTime ()) + if (m_radioSelect == g_lastRadio[m_team] && g_lastRadioTime[m_team] + 1.5f > engine.Time ()) m_radioSelect = -1; else { @@ -1161,13 +1159,13 @@ void Bot::CheckMessageQueue (void) else g_lastRadio[m_team] = -1; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); if (bot != NULL) { - if (pev != bot->pev && GetTeam (bot->GetEntity ()) == m_team) + if (pev != bot->pev && bot->m_team == m_team) { bot->m_radioOrder = m_radioSelect; bot->m_radioEntity = GetEntity (); @@ -1248,26 +1246,26 @@ 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_GoGoGo) - FakeClientCommand (GetEntity (), "radio1"); + engine.IssueBotCommand (GetEntity (), "radio1"); else if (m_radioSelect < Radio_Affirmative) { m_radioSelect -= Radio_GoGoGo - 1; - FakeClientCommand (GetEntity (), "radio2"); + engine.IssueBotCommand (GetEntity (), "radio2"); } else { m_radioSelect -= Radio_Affirmative - 1; - FakeClientCommand (GetEntity (), "radio3"); + engine.IssueBotCommand (GetEntity (), "radio3"); } // 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) InstantChatterMessage (m_radioSelect); g_radioInsteadVoice = false; // reset radio to voice - g_lastRadioTime[m_team] = GetWorldTime (); // store last radio usage + g_lastRadioTime[m_team] = engine.Time (); // store last radio usage } else PushMessageQueue (GSM_RADIO); @@ -1399,7 +1397,7 @@ void Bot::PurchaseWeapons (void) // this function does all the work in selecting correct buy menus for most weapons/items WeaponSelect *selectedWeapon = NULL; - m_nextBuyTime = GetWorldTime () + Random.Float (0.3f, 0.5f); + m_nextBuyTime = engine.Time () + Random.Float (0.3f, 0.5f); int count = 0, foundWeapons = 0; int choices[NUM_WEAPONS]; @@ -1561,16 +1559,16 @@ void Bot::PurchaseWeapons (void) if (selectedWeapon != NULL) { - FakeClientCommand (GetEntity (), "buy;menuselect %d", selectedWeapon->buyGroup); + engine.IssueBotCommand (GetEntity (), "buy;menuselect %d", selectedWeapon->buyGroup); 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 { if (m_team == TERRORIST) - FakeClientCommand(GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT); + engine.IssueBotCommand(GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT); else - FakeClientCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT); + engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT); } } } @@ -1590,9 +1588,9 @@ void Bot::PurchaseWeapons (void) { // if bot is rich, buy kevlar + helmet, else buy a single kevlar if (m_moneyAmount > 1500 && !IsRestricted (WEAPON_ARMORHELM)) - FakeClientCommand (GetEntity (), "buyequip;menuselect 2"); + engine.IssueBotCommand (GetEntity (), "buyequip;menuselect 2"); else if (!IsRestricted (WEAPON_ARMOR)) - FakeClientCommand (GetEntity (), "buyequip;menuselect 1"); + engine.IssueBotCommand (GetEntity (), "buyequip;menuselect 1"); } break; @@ -1649,17 +1647,17 @@ void Bot::PurchaseWeapons (void) if (selectedWeapon != NULL) { - FakeClientCommand (GetEntity (), "buy;menuselect %d", selectedWeapon->buyGroup); + engine.IssueBotCommand (GetEntity (), "buy;menuselect %d", selectedWeapon->buyGroup); 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 { - if (GetTeam (GetEntity ()) == TERRORIST) - FakeClientCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT); + if (engine.GetTeam (GetEntity ()) == TERRORIST) + engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT); else - FakeClientCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT); + engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT); } } } @@ -1669,22 +1667,22 @@ void Bot::PurchaseWeapons (void) if (Random.Long (1, 100) < g_grenadeBuyPrecent[0] && m_moneyAmount >= 400 && !IsRestricted (WEAPON_EXPLOSIVE)) { // buy a he grenade - FakeClientCommand (GetEntity (), "buyequip"); - FakeClientCommand (GetEntity (), "menuselect 4"); + engine.IssueBotCommand (GetEntity (), "buyequip"); + engine.IssueBotCommand (GetEntity (), "menuselect 4"); } if (Random.Long (1, 100) < g_grenadeBuyPrecent[1] && m_moneyAmount >= 300 && teamEcoValid && !IsRestricted (WEAPON_FLASHBANG)) { // buy a concussion grenade, i.e., 'flashbang' - FakeClientCommand (GetEntity (), "buyequip"); - FakeClientCommand (GetEntity (), "menuselect 3"); + engine.IssueBotCommand (GetEntity (), "buyequip"); + engine.IssueBotCommand (GetEntity (), "menuselect 3"); } if (Random.Long (1, 100) < g_grenadeBuyPrecent[2] && m_moneyAmount >= 400 && teamEcoValid && !IsRestricted (WEAPON_SMOKE)) { // buy a smoke grenade - FakeClientCommand (GetEntity (), "buyequip"); - FakeClientCommand (GetEntity (), "menuselect 5"); + engine.IssueBotCommand (GetEntity (), "buyequip"); + engine.IssueBotCommand (GetEntity (), "menuselect 5"); } break; @@ -1692,22 +1690,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 (isOldGame) - FakeClientCommand (GetEntity (), "buyequip;menuselect 6"); + engine.IssueBotCommand (GetEntity (), "buyequip;menuselect 6"); else - FakeClientCommand (GetEntity (), "defuser"); // use alias in SteamCS + engine.IssueBotCommand (GetEntity (), "defuser"); // use alias in SteamCS } break; case BUYSTATE_AMMO: // buy enough primary & secondary ammo (do not check for money here) 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 if (HasPrimaryWeapon ()) - FakeClientCommand (GetEntity (), "buy;menuselect 7"); + engine.IssueBotCommand (GetEntity (), "buy;menuselect 7"); // buy enough primary ammo - FakeClientCommand (GetEntity (), "buy;menuselect 6"); + engine.IssueBotCommand (GetEntity (), "buy;menuselect 6"); // try to reload secondary weapon if (m_reloadState != RELOAD_PRIMARY) @@ -1720,18 +1718,6 @@ void Bot::PurchaseWeapons (void) PushMessageQueue (GSM_BUY_STUFF); } -TaskItem *ClampDesire (TaskItem *first, float min, float max) -{ - // this function iven some values min and max, clamp the inputs to be inside the [min, max] range. - - if (first->desire < min) - first->desire = min; - else if (first->desire > max) - first->desire = max; - - return first; -} - TaskItem *MaxDesire (TaskItem *first, TaskItem *second) { // this function returns the behavior having the higher activation level. @@ -1776,7 +1762,7 @@ float HysteresisDesire (float cur, float min, float max, float old) void Bot::UpdateEmotions (void) { // slowly increase/decrease dynamic emotions back to their base level - if (m_nextEmotionUpdate > GetWorldTime ()) + if (m_nextEmotionUpdate > engine.Time ()) return; if (m_agressionLevel > m_baseAgressionLevel) @@ -1795,7 +1781,7 @@ void Bot::UpdateEmotions (void) if (m_fearLevel < 0.0f) m_fearLevel = 0.0f; - m_nextEmotionUpdate = GetWorldTime () + 1.0f; + m_nextEmotionUpdate = engine.Time () + 1.0f; } void Bot::SetConditionsOverride (void) @@ -1803,7 +1789,7 @@ void Bot::SetConditionsOverride (void) if (m_currentWeapon != WEAPON_KNIFE && m_difficulty > 3 && ((m_aimFlags & AIM_ENEMY) || (m_states & (STATE_SEEING_ENEMY | STATE_SUSPECT_ENEMY)) || (GetTaskId () == TASK_SEEKCOVER && (m_isReloading || m_isVIP))) && !yb_jasonmode.GetBool () && GetTaskId () != TASK_CAMP && !IsOnLadder ()) { m_moveToGoal = false; // don't move to goal - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); if (IsValidPlayer (m_enemy)) CombatFight (); @@ -1830,12 +1816,12 @@ void Bot::SetConditionsOverride (void) if (nearestToEnemyPoint != -1 && nearestToEnemyPoint != m_currentWaypointIndex && fabsf (waypoints.GetPath (nearestToEnemyPoint)->origin.z - m_enemy->v.origin.z) < 16.0f) { - PushTask (TASK_MOVETOPOSITION, TASKPRI_HIDE, nearestToEnemyPoint, GetWorldTime () + Random.Float (5.0f, 10.0f), true); + PushTask (TASK_MOVETOPOSITION, TASKPRI_HIDE, nearestToEnemyPoint, engine.Time () + Random.Float (5.0f, 10.0f), true); m_isEnemyReachable = false; m_enemy = NULL; - m_enemyIgnoreTimer = GetWorldTime () + ((length / pev->maxspeed) * 0.5f); + m_enemyIgnoreTimer = engine.Time () + ((length / pev->maxspeed) * 0.5f); } } } @@ -1860,9 +1846,9 @@ void Bot::SetConditions (void) } // did bot just kill an enemy? - if (!IsEntityNull (m_lastVictim)) + if (!engine.IsNullEntity (m_lastVictim)) { - if (GetTeam (m_lastVictim) != m_team) + if (engine.GetTeam (m_lastVictim) != m_team) { // add some aggression because we just killed somebody m_agressionLevel += 0.1f; @@ -1927,9 +1913,9 @@ void Bot::SetConditions (void) } // check if our current enemy is still valid - if (!IsEntityNull (m_lastEnemy)) + if (!engine.IsNullEntity (m_lastEnemy)) { - if (!IsAlive (m_lastEnemy) && m_shootAtDeadTime < GetWorldTime ()) + if (!IsAlive (m_lastEnemy) && m_shootAtDeadTime < engine.Time ()) { m_lastEnemyOrigin.Zero (); m_lastEnemy = NULL; @@ -1942,15 +1928,15 @@ void Bot::SetConditions (void) } // don't listen if seeing enemy, just checked for sounds or being blinded (because its inhuman) - if (!yb_ignore_enemies.GetBool () && m_soundUpdateTime < GetWorldTime () && m_blindTime < GetWorldTime () && m_seeEnemyTime + 1.0f < GetWorldTime ()) + if (!yb_ignore_enemies.GetBool () && m_soundUpdateTime < engine.Time () && m_blindTime < engine.Time () && m_seeEnemyTime + 1.0f < engine.Time ()) { ReactOnSound (); - m_soundUpdateTime = GetWorldTime () + 0.25f; + m_soundUpdateTime = engine.Time () + 0.25f; } - else if (m_heardSoundTime < GetWorldTime ()) + else if (m_heardSoundTime < engine.Time ()) m_states &= ~STATE_HEARING_ENEMY; - if (IsEntityNull (m_enemy) && !IsEntityNull (m_lastEnemy) && !m_lastEnemyOrigin.IsZero ()) + if (engine.IsNullEntity (m_enemy) && !engine.IsNullEntity (m_lastEnemy) && !m_lastEnemyOrigin.IsZero ()) { m_aimFlags |= AIM_PREDICT_PATH; @@ -1960,9 +1946,9 @@ void Bot::SetConditions (void) CheckGrenadeThrow (); // check if there are items needing to be used/collected - if (m_itemCheckTime < GetWorldTime () || !IsEntityNull (m_pickupItem)) + if (m_itemCheckTime < engine.Time () || !engine.IsNullEntity (m_pickupItem)) { - m_itemCheckTime = GetWorldTime () + 0.4f; + m_itemCheckTime = engine.Time () + 0.4f; FindItem (); } ApplyTaskFilters (); @@ -1993,7 +1979,7 @@ void Bot::ApplyTaskFilters (void) } // bot found some item to use? - if (!IsEntityNull (m_pickupItem) && GetTaskId () != TASK_ESCAPEFROMBOMB) + if (!engine.IsNullEntity (m_pickupItem) && GetTaskId () != TASK_ESCAPEFROMBOMB) { m_states |= STATE_PICKUP_ITEM; @@ -2001,7 +1987,7 @@ void Bot::ApplyTaskFilters (void) g_taskFilters[TASK_PICKUPITEM].desire = 50.0f; // always pickup button else { - float distance = (500.0f - (GetEntityOrigin (m_pickupItem) - pev->origin).GetLength ()) * 0.2f; + float distance = (500.0f - (engine.GetAbsOrigin (m_pickupItem) - pev->origin).GetLength ()) * 0.2f; if (distance > 50.0f) distance = 50.0f; @@ -2028,8 +2014,8 @@ void Bot::ApplyTaskFilters (void) // retreat level depends on bot health float retreatLevel = (100.0f - (pev->health > 100.0f ? 100.0f : pev->health)) * tempFear; - float timeSeen = m_seeEnemyTime - GetWorldTime (); - float timeHeard = m_heardSoundTime - GetWorldTime (); + float timeSeen = m_seeEnemyTime - engine.Time (); + float timeHeard = m_heardSoundTime - engine.Time (); float ratio = 0.0f; if (timeSeen > timeHeard) @@ -2053,7 +2039,7 @@ void Bot::ApplyTaskFilters (void) // if half of the round is over, allow hunting // FIXME: it probably should be also team/map dependant - if (GetTaskId () != TASK_ESCAPEFROMBOMB && IsEntityNull (m_enemy) && g_timeRoundMid < GetWorldTime () && !m_isUsingGrenade && m_currentWaypointIndex != waypoints.FindNearest (m_lastEnemyOrigin) && m_personality != PERSONALITY_CAREFUL) + if (GetTaskId () != TASK_ESCAPEFROMBOMB && engine.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); @@ -2075,7 +2061,7 @@ void Bot::ApplyTaskFilters (void) } // blinded behavior - if (m_blindTime > GetWorldTime ()) + if (m_blindTime > engine.Time ()) g_taskFilters[TASK_BLINDED].desire = TASKPRI_BLINDED; else g_taskFilters[TASK_BLINDED].desire = 0.0f; @@ -2242,7 +2228,7 @@ void Bot::TaskComplete (void) bool Bot::EnemyIsThreat (void) { - if (IsEntityNull (m_enemy) || GetTaskId () == TASK_SEEKCOVER) + if (engine.IsNullEntity (m_enemy) || GetTaskId () == TASK_SEEKCOVER) return false; // if bot is camping, he should be firing anyway and not leaving his position @@ -2263,7 +2249,7 @@ bool Bot::ReactOnEnemy (void) if (!EnemyIsThreat ()) return false; - if (m_enemyReachableTimer < GetWorldTime ()) + if (m_enemyReachableTimer < engine.Time ()) { int i = waypoints.FindNearest (pev->origin); int enemyIndex = waypoints.FindNearest (m_enemy->v.origin); @@ -2276,12 +2262,12 @@ bool Bot::ReactOnEnemy (void) else m_isEnemyReachable = true; - m_enemyReachableTimer = GetWorldTime () + 1.0f; + m_enemyReachableTimer = engine.Time () + 1.0f; } if (m_isEnemyReachable) { - m_navTimeset = GetWorldTime (); // override existing movement by attack movement + m_navTimeset = engine.Time (); // override existing movement by attack movement return true; } return false; @@ -2290,7 +2276,7 @@ bool Bot::ReactOnEnemy (void) bool Bot::LastEnemyShootable (void) { // 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 () || engine.IsNullEntity (m_lastEnemy)) return false; return GetShootingConeDeviation (GetEntity (), &m_lastEnemyOrigin) >= 0.90f && IsShootableThruObstacle (m_lastEnemyOrigin); @@ -2298,7 +2284,7 @@ bool Bot::LastEnemyShootable (void) void Bot::CheckRadioCommands (void) { - // this function handling radio and reactings to it + // this function handling radio and reacting to it float distance = (m_radioEntity->v.origin - pev->origin).GetLength (); @@ -2319,18 +2305,18 @@ void Bot::CheckRadioCommands (void) // check if line of sight to object is not blocked (i.e. visible) 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 (engine.IsNullEntity (m_targetEntity) && engine.IsNullEntity (m_enemy) && Random.Long (0, 100) < (m_personality == PERSONALITY_CAREFUL ? 80 : 20)) { int numFollowers = 0; // Check if no more followers are allowed - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); if (bot != NULL) { - if (IsAlive (bot->GetEntity ())) + if (bot->m_notKilled) { if (bot->m_targetEntity == m_radioEntity) numFollowers++; @@ -2352,19 +2338,19 @@ void Bot::CheckRadioCommands (void) TaskID taskID = GetTaskId (); if (taskID == TASK_PAUSE || taskID == TASK_CAMP) - GetTask ()->time = GetWorldTime (); + GetTask ()->time = engine.Time (); PushTask (TASK_FOLLOWUSER, TASKPRI_FOLLOWUSER, -1, 0.0f, true); } else if (numFollowers > allowedFollowers) { - for (int i = 0; (i < GetMaxClients () && numFollowers > allowedFollowers); i++) + for (int i = 0; (i < engine.MaxClients () && numFollowers > allowedFollowers); i++) { Bot *bot = bots.GetBot (i); if (bot != NULL) { - if (IsAlive (bot->GetEntity ())) + if (bot->m_notKilled) { if (bot->m_targetEntity == m_radioEntity) { @@ -2384,7 +2370,7 @@ void Bot::CheckRadioCommands (void) break; case Radio_HoldPosition: - if (!IsEntityNull (m_targetEntity)) + if (!engine.IsNullEntity (m_targetEntity)) { if (m_targetEntity == m_radioEntity) { @@ -2393,7 +2379,7 @@ void Bot::CheckRadioCommands (void) m_campButtons = 0; - PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + Random.Float (30.0f, 60.0f), false); + PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, engine.Time () + Random.Float (30.0f, 60.0f), false); } } break; @@ -2403,9 +2389,9 @@ void Bot::CheckRadioCommands (void) break; case Radio_TakingFire: - if (IsEntityNull (m_targetEntity)) + if (engine.IsNullEntity (m_targetEntity)) { - if (IsEntityNull (m_enemy) && m_seeEnemyTime + 4.0f < GetWorldTime ()) + if (engine.IsNullEntity (m_enemy) && m_seeEnemyTime + 4.0f < engine.Time ()) { // decrease fear levels to lower probability of bot seeking cover again m_fearLevel -= 0.2f; @@ -2434,7 +2420,7 @@ void Bot::CheckRadioCommands (void) case Radio_NeedBackup: case Chatter_ScaredEmotion: 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 < GetWorldTime ()) + if (((engine.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; @@ -2466,7 +2452,7 @@ void Bot::CheckRadioCommands (void) if (m_fearLevel < 0.0f) m_fearLevel = 0.0f; } - else if ((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 2048.0f) + else if ((engine.IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 2048.0f) { TaskID taskID = GetTaskId (); @@ -2479,7 +2465,7 @@ void Bot::CheckRadioCommands (void) RadioMessage (Radio_Affirmative); // don't pause/camp anymore - GetTask ()->time = GetWorldTime (); + GetTask ()->time = engine.Time (); m_targetEntity = NULL; MakeVectors (m_radioEntity->v.v_angle); @@ -2490,7 +2476,7 @@ void Bot::CheckRadioCommands (void) PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0f, true); } } - else if (!IsEntityNull (m_doubleJumpEntity)) + else if (!engine.IsNullEntity (m_doubleJumpEntity)) { RadioMessage (Radio_Affirmative); ResetDoubleJumpState (); @@ -2501,7 +2487,7 @@ void Bot::CheckRadioCommands (void) break; case Radio_ShesGonnaBlow: - if (IsEntityNull (m_enemy) && distance < 2048.0f && g_bombPlanted && m_team == TERRORIST) + if (engine.IsNullEntity (m_enemy) && distance < 2048.0f && g_bombPlanted && m_team == TERRORIST) { RadioMessage (Radio_Affirmative); @@ -2530,7 +2516,7 @@ void Bot::CheckRadioCommands (void) break; case Radio_StormTheFront: - if (((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) && Random.Long (0, 100) > 50) + if (((engine.IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) && Random.Long (0, 100) > 50) { RadioMessage (Radio_Affirmative); @@ -2538,7 +2524,7 @@ void Bot::CheckRadioCommands (void) TaskID taskID = GetTaskId (); if (taskID == TASK_PAUSE || taskID == TASK_CAMP) - GetTask ()->time = GetWorldTime (); + GetTask ()->time = engine.Time (); m_targetEntity = NULL; @@ -2561,7 +2547,7 @@ void Bot::CheckRadioCommands (void) break; case Radio_Fallback: - if ((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) + if ((engine.IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) { m_fearLevel += 0.5f; @@ -2581,10 +2567,10 @@ void Bot::CheckRadioCommands (void) TaskID taskID = GetTaskId (); if (taskID == TASK_PAUSE) - GetTask ()->time = GetWorldTime (); + GetTask ()->time = engine.Time (); m_targetEntity = NULL; - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time (); // if bot has no enemy if (m_lastEnemyOrigin.IsZero ()) @@ -2592,7 +2578,7 @@ void Bot::CheckRadioCommands (void) float nearestDistance = 99999.0f; // take nearest enemy to ordering player - for (int i = 0; i < GetMaxClients (); 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) continue; @@ -2621,68 +2607,64 @@ void Bot::CheckRadioCommands (void) case Radio_SectorClear: // is bomb planted and it's a ct - if (g_bombPlanted) + if (!g_bombPlanted) + break; + + // check if it's a ct command + if (engine.GetTeam (m_radioEntity) == CT && m_team == CT && IsValidBot (m_radioEntity) && g_timeNextBombUpdate < engine.Time ()) { + float minDistance = 99999.0f; int bombPoint = -1; - // check if it's a ct command - if (GetTeam (m_radioEntity) == CT && m_team == CT && IsValidBot (m_radioEntity)) + // find nearest bomb waypoint to player + FOR_EACH_AE (waypoints.m_goalPoints, i) { - if (g_timeNextBombUpdate < GetWorldTime ()) + distance = (waypoints.GetPath (waypoints.m_goalPoints[i])->origin - m_radioEntity->v.origin).GetLengthSquared (); + + if (distance < minDistance) { - float minDistance = 99999.0f; - - // find nearest bomb waypoint to player - FOR_EACH_AE (waypoints.m_goalPoints, i) - { - distance = (waypoints.GetPath (waypoints.m_goalPoints[i])->origin - m_radioEntity->v.origin).GetLengthSquared (); - - if (distance < minDistance) - { - minDistance = distance; - bombPoint = waypoints.m_goalPoints[i]; - } - } - - // mark this waypoint as restricted point - if (bombPoint != -1 && !waypoints.IsGoalVisited (bombPoint)) - { - // does this bot want to defuse? - if (GetTaskId () == TASK_NORMAL) - { - // is he approaching this goal? - if (GetTask ()->data == bombPoint) - { - GetTask ()->data = -1; - RadioMessage (Radio_Affirmative); - - } - } - waypoints.SetGoalVisited (bombPoint); - } - g_timeNextBombUpdate = GetWorldTime () + 0.5f; + minDistance = distance; + bombPoint = waypoints.m_goalPoints[i]; } } + + // mark this waypoint as restricted point + if (bombPoint != -1 && !waypoints.IsGoalVisited (bombPoint)) + { + // does this bot want to defuse? + if (GetTaskId () == TASK_NORMAL) + { + // is he approaching this goal? + if (GetTask ()->data == bombPoint) + { + GetTask ()->data = -1; + RadioMessage (Radio_Affirmative); + + } + } + waypoints.SetGoalVisited (bombPoint); + } + g_timeNextBombUpdate = engine.Time () + 0.5f; } break; case Radio_GetInPosition: - if ((IsEntityNull (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) + if ((engine.IsNullEntity (m_enemy) && EntityIsVisible (m_radioEntity->v.origin)) || distance < 1024.0f) { RadioMessage (Radio_Affirmative); if (GetTaskId () == TASK_CAMP) - GetTask ()->time = GetWorldTime () + Random.Float (30.0f, 60.0f); + GetTask ()->time = engine.Time () + Random.Float (30.0f, 60.0f); else { // don't pause anymore TaskID taskID = GetTaskId (); if (taskID == TASK_PAUSE) - GetTask ()->time = GetWorldTime (); + GetTask ()->time = engine.Time (); m_targetEntity = NULL; - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time (); // if bot has no enemy if (m_lastEnemyOrigin.IsZero ()) @@ -2690,7 +2672,7 @@ void Bot::CheckRadioCommands (void) float nearestDistance = 99999.0f; // take nearest enemy to ordering player - for (int i = 0; i < GetMaxClients (); 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) continue; @@ -2711,9 +2693,9 @@ void Bot::CheckRadioCommands (void) int index = FindDefendWaypoint (m_radioEntity->v.origin); // push camp task on to stack - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0f, 60.0f), true); + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (30.0f, 60.0f), true); // push move command - PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (30.0f, 60.0f), true); + PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (30.0f, 60.0f), true); if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand) m_campButtons |= IN_DUCK; @@ -2730,15 +2712,15 @@ void Bot::TryHeadTowardRadioEntity (void) { TaskID taskID = GetTaskId (); - if (taskID == TASK_MOVETOPOSITION || m_headedTime + 15.0f < GetWorldTime () || !IsAlive (m_radioEntity) || m_hasC4) + if (taskID == TASK_MOVETOPOSITION || m_headedTime + 15.0f < engine.Time () || !IsAlive (m_radioEntity) || m_hasC4) return; if ((IsValidBot (m_radioEntity) && Random.Long (0, 100) < 25 && m_personality == PERSONALITY_NORMAL) || !(m_radioEntity->v.flags & FL_FAKECLIENT)) { if (taskID == TASK_PAUSE || taskID == TASK_CAMP) - GetTask ()->time = GetWorldTime (); + GetTask ()->time = engine.Time (); - m_headedTime = GetWorldTime (); + m_headedTime = engine.Time (); m_position = m_radioEntity->v.origin; DeleteSearchNodes (); @@ -2762,11 +2744,11 @@ void Bot::SelectLeaderEachTeam (int team) } g_leaderChoosen[CT] = true; } - else if ((team == TERRORIST) && !g_leaderChoosen[TERRORIST]) + else if (team == TERRORIST && !g_leaderChoosen[TERRORIST]) { Bot *botLeader = bots.GetHighestFragsBot(team); - if (botLeader != NULL && IsAlive (botLeader->GetEntity())) + if (botLeader != NULL && botLeader->m_notKilled) { botLeader->m_isLeader = true; @@ -2865,7 +2847,7 @@ void Bot::ChooseAimDirection (void) m_lookAt = m_lastEnemyOrigin; // did bot just see enemy and is quite aggressive? - if (m_seeEnemyTime + 2.0f - m_actualReactionTime + m_baseAgressionLevel > GetWorldTime ()) + if (m_seeEnemyTime + 2.0f - m_actualReactionTime + m_baseAgressionLevel > engine.Time ()) { // feel free to fire if shootable if (!UsesSniper () && LastEnemyShootable ()) @@ -2878,8 +2860,8 @@ void Bot::ChooseAimDirection (void) if (m_trackingEdict == m_lastEnemy) { - if (m_timeNextTracking < GetWorldTime ()) - changePredictedEnemy = IsAlive (m_lastEnemy); + if (m_timeNextTracking < engine.Time ()) + changePredictedEnemy = false; } if (changePredictedEnemy) @@ -2887,7 +2869,7 @@ void Bot::ChooseAimDirection (void) m_lookAt = waypoints.GetPath (GetAimingWaypoint (m_lastEnemyOrigin))->origin; m_camp = m_lookAt; - m_timeNextTracking = GetWorldTime () + 2.0f; + m_timeNextTracking = engine.Time () + 1.25f; m_trackingEdict = m_lastEnemy; } else @@ -2922,19 +2904,19 @@ void Bot::ChooseAimDirection (void) void Bot::Think (void) { - if (m_thinkFps <= GetWorldTime ()) + if (m_thinkFps <= engine.Time ()) { // execute delayed think - ThinkDelayed (); + ThinkFrame (); // skip some frames - m_thinkFps = GetWorldTime () + m_thinkInterval; + m_thinkFps = engine.Time () + m_thinkInterval; } else UpdateLookAngles (); } -void Bot::ThinkDelayed (void) +void Bot::ThinkFrame (void) { pev->button = 0; pev->flags |= FL_FAKECLIENT; // restore fake client bit, if it were removed by some evil action =) @@ -2945,7 +2927,7 @@ void Bot::ThinkDelayed (void) m_canChooseAimDirection = true; m_notKilled = IsAlive (GetEntity ()); - m_team = GetTeam (GetEntity ()); + m_team = engine.GetTeam (GetEntity ()); if (m_team == TERRORIST && (g_mapType & MAP_DE)) m_hasC4 = !!(pev->weapons & (1 << WEAPON_C4)); @@ -2960,32 +2942,32 @@ void Bot::ThinkDelayed (void) // no movement allowed in 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; // if bot tk punishment is enabled slay the tk - if (yb_tkpunish.GetInt () != 2 || IsValidBot (EntityOfIndex (m_voteKickIndex))) + if (yb_tkpunish.GetInt () != 2 || IsValidBot (engine.EntityOfIndex (m_voteKickIndex))) return; - edict_t *killer = EntityOfIndex (m_lastVoteKick); + edict_t *killer = engine.EntityOfIndex (m_lastVoteKick); killer->v.frags++; MDLL_ClientKill (killer); } 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; } extern ConVar yb_chat; - if (yb_chat.GetBool () && !RepliesToPlayer () && m_lastChatTime + 10.0 < GetWorldTime () && g_lastChatTime + 5.0f < GetWorldTime ()) // bot chatting turned on? + if (yb_chat.GetBool () && !RepliesToPlayer () && m_lastChatTime + 10.0 < engine.Time () && g_lastChatTime + 5.0f < engine.Time ()) // bot chatting turned on? { // say a text every now and then if (Random.Long (1, 1500) < 2) { - m_lastChatTime = GetWorldTime (); - g_lastChatTime = GetWorldTime (); + m_lastChatTime = engine.Time (); + g_lastChatTime = engine.Time (); char *pickedPhrase = const_cast (g_chatFactory[CHAT_DEAD].GetRandomElement ().GetBuffer ()); bool sayBufferExists = false; @@ -3023,7 +3005,7 @@ void Bot::ThinkDelayed (void) CheckMessageQueue (); // check for pending messages // remove voice icon - if (g_lastRadioTime[g_clients[IndexOfEntity (GetEntity ()) - 1].realTeam] + Random.Float (0.8f, 2.1f) < GetWorldTime ()) + if (g_lastRadioTime[g_clients[engine.IndexOfEntity (GetEntity ()) - 1].team2] + Random.Float (0.8f, 2.1f) < engine.Time ()) SwitchChatterIcon (false); // hide icon if (botMovement) @@ -3034,7 +3016,7 @@ void Bot::ThinkDelayed (void) void Bot::PeriodicThink (void) { - if (m_timePeriodicUpdate > GetWorldTime ()) + if (m_timePeriodicUpdate > engine.Time ()) return; // this function is called from main think function @@ -3048,12 +3030,12 @@ void Bot::PeriodicThink (void) CheckSpawnTimeConditions (); // clear enemy far away - if (!m_lastEnemyOrigin.IsZero () && !IsEntityNull (m_lastEnemy) && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0f) + if (!m_lastEnemyOrigin.IsZero () && !engine.IsNullEntity (m_lastEnemy) && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0f) { m_lastEnemy = NULL; m_lastEnemyOrigin.Zero (); } - m_timePeriodicUpdate = GetWorldTime () + 0.5f; + m_timePeriodicUpdate = engine.Time () + 0.5f; } void Bot::RunTask_Normal (void) @@ -3068,14 +3050,14 @@ void Bot::RunTask_Normal (void) } // 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 < GetWorldTime () && !HasShield () && GetNearbyFriendsNearPosition (pev->origin, 96) == 0) + if (m_currentWeapon == WEAPON_KNIFE && (engine.IsNullEntity (m_lastEnemy) || !IsAlive (m_lastEnemy)) && engine.IsNullEntity (m_enemy) && m_knifeAttackTime < engine.Time () && !HasShield () && GetNearbyFriendsNearPosition (pev->origin, 96) == 0) { if (Random.Long (0, 100) < 40) pev->button |= IN_ATTACK; else pev->button |= IN_ATTACK2; - m_knifeAttackTime = GetWorldTime () + Random.Float (2.5f, 6.0f); + m_knifeAttackTime = engine.Time () + Random.Float (2.5f, 6.0f); } if (m_reloadState == RELOAD_NONE && GetAmmo () != 0 && GetAmmoInClip () < 5 && g_weaponDefs[m_currentWeapon].ammo1 != -1) @@ -3098,17 +3080,17 @@ void Bot::RunTask_Normal (void) m_prevGoalIndex = -1; // spray logo sometimes if allowed to do so - if (m_timeLogoSpray < GetWorldTime () && 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 () && engine.IsNullEntity (m_pickupItem)) { if (!((g_mapType & MAP_DE) && g_bombPlanted && m_team == CT)) - PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, GetWorldTime () + 1.0f, false); + PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, engine.Time () + 1.0f, false); } // reached waypoint is a camp waypoint if ((m_currentPath->flags & FLAG_CAMP) && !yb_csdm_mode.GetBool () && yb_camping_allowed.GetBool ()) { // check if bot has got a primary weapon and hasn't camped before - if (HasPrimaryWeapon () && m_timeCamping + 10.0f < GetWorldTime () && !HasHostage ()) + if (HasPrimaryWeapon () && m_timeCamping + 10.0f < engine.Time () && !HasHostage ()) { bool campingAllowed = true; @@ -3125,7 +3107,7 @@ void Bot::RunTask_Normal (void) } // don't allow vip on as_ maps to camp + don't allow terrorist carrying c4 to camp - if (campingAllowed && IsPlayerVIP (GetEntity ()) || ((g_mapType & MAP_DE) && m_team == TERRORIST && !g_bombPlanted && m_hasC4)) + if (campingAllowed && (IsPlayerVIP (GetEntity ()) || ((g_mapType & MAP_DE) && m_team == TERRORIST && !g_bombPlanted && m_hasC4))) campingAllowed = false; // check if another bot is already camping here @@ -3147,7 +3129,7 @@ void Bot::RunTask_Normal (void) MakeVectors (pev->v_angle); - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (20.0f, 40.0f), true); + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (20.0f, 40.0f), true); m_camp = Vector (m_currentPath->campStartX, m_currentPath->campStartY, 0.0f); m_aimFlags |= AIM_CAMP; @@ -3184,8 +3166,8 @@ void Bot::RunTask_Normal (void) { int index = FindDefendWaypoint (m_currentPath->origin); - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (60.0f, 120.0f), true); // push camp task on to stack - PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (5.0f, 10.0f), true); // push move command + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (60.0f, 120.0f), true); // push camp task on to stack + PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (5.0f, 10.0f), true); // push move command if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand) m_campButtons |= IN_DUCK; @@ -3206,7 +3188,7 @@ void Bot::RunTask_Normal (void) RadioMessage (Radio_NeedBackup); InstantChatterMessage (Chatter_ScaredEmotion); - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (4.0f, 8.0f), true); + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (4.0f, 8.0f), true); } else PushTask (TASK_PLANTBOMB, TASKPRI_PLANTBOMB, -1, 0.0f, false); @@ -3223,10 +3205,8 @@ void Bot::RunTask_Normal (void) if (m_personality == PERSONALITY_RUSHER) campTime *= 0.5f; - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (25.0, 40.0), true); // push camp task on to stack - PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (5.0f, 11.0f), true); // push move command - - DebugMsg ("i'm ct and going to defend bomb!"); + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + campTime, true); // push camp task on to stack + PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (5.0f, 11.0f), true); // push move command if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand) m_campButtons |= IN_DUCK; @@ -3264,13 +3244,13 @@ void Bot::RunTask_Normal (void) m_moveSpeed = m_minSpeed; } - if ((yb_walking_allowed.GetBool () && mp_footsteps.GetBool ()) && m_difficulty >= 2 && !(m_aimFlags & AIM_ENEMY) && (m_heardSoundTime + 8.0f >= GetWorldTime () || (m_states & (STATE_HEARING_ENEMY | STATE_SUSPECT_ENEMY))) && GetNearbyEnemiesNearPosition (pev->origin, 1024.0f) >= 1 && !yb_jasonmode.GetBool () && !g_bombPlanted) + if ((yb_walking_allowed.GetBool () && mp_footsteps.GetBool ()) && m_difficulty >= 2 && !(m_aimFlags & AIM_ENEMY) && (m_heardSoundTime + 8.0f >= engine.Time () || (m_states & (STATE_HEARING_ENEMY | STATE_SUSPECT_ENEMY))) && GetNearbyEnemiesNearPosition (pev->origin, 1024.0f) >= 1 && !yb_jasonmode.GetBool () && !g_bombPlanted) m_moveSpeed = GetWalkSpeed (); // bot hasn't seen anything in a long time and is asking his teammates to report in - if (m_seeEnemyTime + Random.Float (45.0f, 80.0f) < GetWorldTime () && Random.Long (0, 100) < 30 && g_timeRoundStart + 20.0f < GetWorldTime () && m_askCheckTime < GetWorldTime ()) + if (m_seeEnemyTime + Random.Float (45.0f, 80.0f) < engine.Time () && Random.Long (0, 100) < 30 && g_timeRoundStart + 20.0f < engine.Time () && m_askCheckTime < engine.Time ()) { - m_askCheckTime = GetWorldTime () + Random.Float (45.0f, 80.0f); + m_askCheckTime = engine.Time () + Random.Float (45.0f, 80.0f); RadioMessage (Radio_ReportTeam); } } @@ -3280,13 +3260,13 @@ void Bot::RunTask_Spray (void) m_aimFlags |= AIM_ENTITY; // bot didn't spray this round? - if (m_timeLogoSpray < GetWorldTime () && GetTask ()->time > GetWorldTime ()) + if (m_timeLogoSpray < engine.Time () && GetTask ()->time > engine.Time ()) { MakeVectors (pev->v_angle); Vector sprayOrigin = EyePosition () + g_pGlobals->v_forward * 128.0f; TraceResult tr; - TraceLine (EyePosition (), sprayOrigin, true, GetEntity (), &tr); + engine.TestLine (EyePosition (), sprayOrigin, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // no wall in front? if (tr.flFraction >= 1.0f) @@ -3294,15 +3274,15 @@ void Bot::RunTask_Spray (void) m_entity = sprayOrigin; - if (GetTask ()->time - 0.5f < GetWorldTime ()) + if (GetTask ()->time - 0.5f < engine.Time ()) { // emit spraycan sound EMIT_SOUND_DYN2 (GetEntity (), CHAN_VOICE, "player/sprayer.wav", 1.0, ATTN_NORM, 0, 100.0f); - TraceLine (EyePosition (), EyePosition () + g_pGlobals->v_forward * 128.0f, true, GetEntity (), &tr); + engine.TestLine (EyePosition (), EyePosition () + g_pGlobals->v_forward * 128.0f, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // paint the actual logo decal DecalTrace (pev, &tr, m_logotypeIndex); - m_timeLogoSpray = GetWorldTime () + Random.Float (60.0f, 90.0f); + m_timeLogoSpray = engine.Time () + Random.Float (60.0f, 90.0f); } } else @@ -3311,7 +3291,7 @@ void Bot::RunTask_Spray (void) m_moveToGoal = false; m_checkTerrain = false; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; @@ -3324,7 +3304,7 @@ void Bot::RunTask_HuntEnemy (void) m_checkTerrain = true; // if we've got new enemy... - if (!IsEntityNull (m_enemy) || IsEntityNull (m_lastEnemy)) + if (!engine.IsNullEntity (m_enemy) || engine.IsNullEntity (m_lastEnemy)) { // forget about it... TaskComplete (); @@ -3333,7 +3313,7 @@ void Bot::RunTask_HuntEnemy (void) m_lastEnemy = NULL; m_lastEnemyOrigin.Zero (); } - else if (GetTeam (m_lastEnemy) == m_team) + else if (engine.GetTeam (m_lastEnemy) == m_team) { // don't hunt down our teammate... RemoveCertainTask (TASK_HUNTENEMY); @@ -3376,7 +3356,7 @@ void Bot::RunTask_HuntEnemy (void) { if (m_currentWaypointIndex != -1) { - if (m_currentPath->radius < 32 && !IsOnLadder () && !IsInWater () && m_seeEnemyTime + 4.0f > GetWorldTime () && m_difficulty < 2) + if (m_currentPath->radius < 32 && !IsOnLadder () && !IsInWater () && m_seeEnemyTime + 4.0f > engine.Time () && m_difficulty < 2) pev->button |= IN_DUCK; } @@ -3390,7 +3370,7 @@ void Bot::RunTask_SeekCover (void) { m_aimFlags |= AIM_NAVPOINT; - if (IsEntityNull (m_lastEnemy) || !IsAlive (m_lastEnemy)) + if (engine.IsNullEntity (m_lastEnemy) || !IsAlive (m_lastEnemy)) { TaskComplete (); m_prevGoalIndex = -1; @@ -3404,7 +3384,7 @@ void Bot::RunTask_SeekCover (void) m_pathType = SEARCH_PATH_FASTEST; // start hide task - PushTask (TASK_HIDE, TASKPRI_HIDE, -1, GetWorldTime () + Random.Float (5.0f, 15.0f), false); + PushTask (TASK_HIDE, TASKPRI_HIDE, -1, engine.Time () + Random.Float (5.0f, 15.0f), false); Vector dest = m_lastEnemyOrigin; // get a valid look direction @@ -3478,7 +3458,7 @@ void Bot::RunTask_Attack (void) m_moveToGoal = false; m_checkTerrain = false; - if (!IsEntityNull (m_enemy)) + if (!engine.IsNullEntity (m_enemy)) { IgnoreCollisionShortly (); @@ -3497,7 +3477,7 @@ void Bot::RunTask_Attack (void) TaskComplete (); m_destOrigin = m_lastEnemyOrigin; } - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); } void Bot::RunTask_Pause (void) @@ -3505,7 +3485,7 @@ void Bot::RunTask_Pause (void) m_moveToGoal = false; m_checkTerrain = false; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; @@ -3530,7 +3510,7 @@ void Bot::RunTask_Pause (void) pev->button |= m_campButtons; // stop camping if time over or gets hurt by something else than bullets - if (GetTask ()->time < GetWorldTime () || m_lastDamageType > 0) + if (GetTask ()->time < engine.Time () || m_lastDamageType > 0) TaskComplete (); } @@ -3538,7 +3518,7 @@ void Bot::RunTask_Blinded (void) { m_moveToGoal = false; m_checkTerrain = false; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); // if bot remembers last enemy position if (m_difficulty >= 2 && !m_lastEnemyOrigin.IsZero () && IsValidPlayer (m_lastEnemy) && !UsesSniper ()) @@ -3551,7 +3531,7 @@ void Bot::RunTask_Blinded (void) m_strafeSpeed = m_blindSidemoveSpeed; pev->button |= m_blindButton; - if (m_blindTime < GetWorldTime ()) + if (m_blindTime < engine.Time ()) TaskComplete (); } @@ -3577,17 +3557,17 @@ void Bot::RunTask_Camp (void) SetIdealReactionTimes (); m_idealReactionTime *= 0.5f; - m_navTimeset = GetWorldTime (); - m_timeCamping = GetWorldTime (); + m_navTimeset = engine.Time (); + m_timeCamping = engine.Time (); m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; GetValidWaypoint (); - if (m_nextCampDirTime < GetWorldTime ()) + if (m_nextCampDirTime < engine.Time ()) { - m_nextCampDirTime = GetWorldTime () + Random.Float (2.0f, 5.0f); + m_nextCampDirTime = engine.Time () + Random.Float (2.0f, 5.0f); if (m_currentPath->flags & FLAG_CAMP) { @@ -3664,7 +3644,7 @@ void Bot::RunTask_Camp (void) pev->button |= m_campButtons; // stop camping if time over or gets hurt by something else than bullets - if (GetTask ()->time < GetWorldTime () || m_lastDamageType > 0) + if (GetTask ()->time < engine.Time () || m_lastDamageType > 0) TaskComplete (); } @@ -3678,7 +3658,7 @@ void Bot::RunTask_Hide (void) SetIdealReactionTimes (); m_idealReactionTime *= 0.5f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; @@ -3702,7 +3682,7 @@ void Bot::RunTask_Hide (void) m_campButtons = 0; m_prevGoalIndex = -1; - if (!IsEntityNull (m_enemy)) + if (!engine.IsNullEntity (m_enemy)) CombatFight (); return; @@ -3722,10 +3702,10 @@ void Bot::RunTask_Hide (void) } pev->button |= m_campButtons; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); // stop camping if time over or gets hurt by something else than bullets - if (GetTask ()->time < GetWorldTime () || m_lastDamageType > 0) + if (GetTask ()->time < engine.Time () || m_lastDamageType > 0) TaskComplete (); } @@ -3780,7 +3760,7 @@ void Bot::RunTask_PlantBomb (void) { m_moveToGoal = false; m_checkTerrain = false; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); if (m_currentPath->flags & FLAG_CROUCH) pev->button |= (IN_ATTACK | IN_DUCK); @@ -3805,9 +3785,9 @@ void Bot::RunTask_PlantBomb (void) float guardTime = mp_c4timer.GetFloat () * 0.5f + mp_c4timer.GetFloat () * 0.25f; // push camp task on to stack - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + guardTime, true); + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + guardTime, true); // push move command - PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + guardTime, true); + PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + guardTime, true); if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand) m_campButtons |= IN_DUCK; @@ -3823,7 +3803,7 @@ void Bot::RunTask_DefuseBomb (void) float defuseRemainingTime = fullDefuseTime; if (m_hasProgressBar /*&& IsOnFloor ()*/) - defuseRemainingTime = fullDefuseTime - GetWorldTime (); + defuseRemainingTime = fullDefuseTime - engine.Time (); bool defuseError = false; @@ -3921,7 +3901,7 @@ void Bot::RunTask_DefuseBomb (void) pev->button |= IN_USE; // if defusing is not already started, maybe crouch before - if (!m_hasProgressBar && m_duckDefuseCheckTime < GetWorldTime ()) + if (!m_hasProgressBar && m_duckDefuseCheckTime < engine.Time ()) { if (m_difficulty >= 2 && m_numEnemiesLeft != 0) m_duckDefuse = true; @@ -3949,7 +3929,7 @@ void Bot::RunTask_DefuseBomb (void) else m_duckDefuse = true; // duck } - m_duckDefuseCheckTime = GetWorldTime () + 1.5f; + m_duckDefuseCheckTime = engine.Time () + 1.5f; } // press duck button @@ -3964,7 +3944,7 @@ void Bot::RunTask_DefuseBomb (void) pev->button |= IN_USE; m_reloadState = RELOAD_NONE; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); // don't move when defusing m_moveToGoal = false; @@ -3986,7 +3966,7 @@ void Bot::RunTask_DefuseBomb (void) void Bot::RunTask_FollowUser (void) { - if (IsEntityNull (m_targetEntity) || !IsAlive (m_targetEntity)) + if (engine.IsNullEntity (m_targetEntity) || !IsAlive (m_targetEntity)) { m_targetEntity = NULL; TaskComplete (); @@ -3999,9 +3979,9 @@ void Bot::RunTask_FollowUser (void) MakeVectors (m_targetEntity->v.v_angle); TraceResult tr; - TraceLine (m_targetEntity->v.origin + m_targetEntity->v.view_ofs, g_pGlobals->v_forward * 500.0f, true, true, 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 (!engine.IsNullEntity (tr.pHit) && IsValidPlayer (tr.pHit) && engine.GetTeam (tr.pHit) != m_team) { m_targetEntity = NULL; m_lastEnemy = tr.pHit; @@ -4025,10 +4005,10 @@ void Bot::RunTask_FollowUser (void) m_moveSpeed = 0.0f; if (m_followWaitTime == 0.0f) - m_followWaitTime = GetWorldTime (); + m_followWaitTime = engine.Time (); else { - if (m_followWaitTime + 3.0f < GetWorldTime ()) + if (m_followWaitTime + 3.0f < engine.Time ()) { // stop following if we have been waiting too long m_targetEntity = NULL; @@ -4096,7 +4076,7 @@ void Bot::RunTask_Throw_HE (void) m_moveSpeed = 0.0f; m_moveToGoal = false; } - else if (!(m_states & STATE_SUSPECT_ENEMY) && !IsEntityNull (m_enemy)) + else if (!(m_states & STATE_SUSPECT_ENEMY) && !engine.IsNullEntity (m_enemy)) dest = m_enemy->v.origin + m_enemy->v.velocity.Get2D () * 0.5f; m_isUsingGrenade = true; @@ -4104,10 +4084,10 @@ void Bot::RunTask_Throw_HE (void) IgnoreCollisionShortly (); - if (m_maxThrowTimer < GetWorldTime () || (pev->origin - dest).GetLengthSquared () < GET_SQUARE (400.0f)) + if (m_maxThrowTimer < engine.Time () || (pev->origin - dest).GetLengthSquared () < GET_SQUARE (400.0f)) { // heck, I don't wanna blow up myself - m_grenadeCheckTime = GetWorldTime () + MAX_GRENADE_TIMER; + m_grenadeCheckTime = engine.Time () + MAX_GRENADE_TIMER; SelectBestWeapon (); TaskComplete (); @@ -4121,7 +4101,7 @@ void Bot::RunTask_Throw_HE (void) if (m_grenade.GetLengthSquared () <= 100.0f) { - m_grenadeCheckTime = GetWorldTime () + MAX_GRENADE_TIMER; + m_grenadeCheckTime = engine.Time () + MAX_GRENADE_TIMER; m_grenade = m_lookAt; SelectBestWeapon (); @@ -4131,7 +4111,7 @@ void Bot::RunTask_Throw_HE (void) { edict_t *ent = NULL; - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) { if (ent->v.owner == GetEntity () && strcmp (STRING (ent->v.model) + 9, "hegrenade.mdl") == 0) { @@ -4139,7 +4119,7 @@ void Bot::RunTask_Throw_HE (void) if (m_grenade.GetLengthSquared () > 100.0f) ent->v.velocity = m_grenade; - m_grenadeCheckTime = GetWorldTime () + MAX_GRENADE_TIMER; + m_grenadeCheckTime = engine.Time () + MAX_GRENADE_TIMER; SelectBestWeapon (); TaskComplete (); @@ -4148,7 +4128,7 @@ void Bot::RunTask_Throw_HE (void) } } - if (IsEntityNull (ent)) + if (engine.IsNullEntity (ent)) { if (m_currentWeapon != WEAPON_EXPLOSIVE) { @@ -4172,7 +4152,7 @@ void Bot::RunTask_Throw_FL (void) m_strafeSpeed = 0.0f; m_moveSpeed = 0.0f; } - else if (!(m_states & STATE_SUSPECT_ENEMY) && !IsEntityNull (m_enemy)) + else if (!(m_states & STATE_SUSPECT_ENEMY) && !engine.IsNullEntity (m_enemy)) dest = m_enemy->v.origin + m_enemy->v.velocity.Get2D () * 0.5; m_isUsingGrenade = true; @@ -4185,9 +4165,9 @@ void Bot::RunTask_Throw_FL (void) if (m_grenade.GetLengthSquared () < 100.0f) m_grenade = CheckToss (pev->origin, dest); - if (m_maxThrowTimer < GetWorldTime () || m_grenade.GetLengthSquared () <= 100.0f) + if (m_maxThrowTimer < engine.Time () || m_grenade.GetLengthSquared () <= 100.0f) { - m_grenadeCheckTime = GetWorldTime () + MAX_GRENADE_TIMER; + m_grenadeCheckTime = engine.Time () + MAX_GRENADE_TIMER; m_grenade = m_lookAt; SelectBestWeapon (); @@ -4196,7 +4176,7 @@ void Bot::RunTask_Throw_FL (void) else { edict_t *ent = NULL; - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) { if (ent->v.owner == GetEntity () && strcmp (STRING (ent->v.model) + 9, "flashbang.mdl") == 0) { @@ -4204,7 +4184,7 @@ void Bot::RunTask_Throw_FL (void) if (m_grenade.GetLengthSquared () > 100.0f) ent->v.velocity = m_grenade; - m_grenadeCheckTime = GetWorldTime () + MAX_GRENADE_TIMER; + m_grenadeCheckTime = engine.Time () + MAX_GRENADE_TIMER; SelectBestWeapon (); TaskComplete (); @@ -4212,7 +4192,7 @@ void Bot::RunTask_Throw_FL (void) } } - if (IsEntityNull (ent)) + if (engine.IsNullEntity (ent)) { if (m_currentWeapon != WEAPON_FLASHBANG) { @@ -4244,12 +4224,12 @@ void Bot::RunTask_Throw_SG (void) Vector src = m_lastEnemyOrigin - pev->velocity; // predict where the enemy is in 0.5 secs - if (!IsEntityNull (m_enemy)) + if (!engine.IsNullEntity (m_enemy)) src = src + m_enemy->v.velocity * 0.5f; m_grenade = (src - EyePosition ()).Normalize (); - if (m_maxThrowTimer < GetWorldTime () || GetTask ()->time < GetWorldTime () + 0.5f) + if (m_maxThrowTimer < engine.Time () || GetTask ()->time < engine.Time () + 0.5f) { m_aimFlags &= ~AIM_GRENADE; m_states &= ~STATE_THROW_SG; @@ -4263,10 +4243,10 @@ void Bot::RunTask_Throw_SG (void) if (pev->weapons & (1 << WEAPON_SMOKE)) { SelectWeaponByName ("weapon_smokegrenade"); - GetTask ()->time = GetWorldTime () + MAX_GRENADE_TIMER; + GetTask ()->time = engine.Time () + MAX_GRENADE_TIMER; } else - GetTask ()->time = GetWorldTime () + 0.1f; + GetTask ()->time = engine.Time () + 0.1f; } else if (!(pev->oldbuttons & IN_ATTACK)) pev->button |= IN_ATTACK; @@ -4274,7 +4254,7 @@ void Bot::RunTask_Throw_SG (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) < GetWorldTime ())) + if (!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 (); return; @@ -4286,11 +4266,11 @@ void Bot::RunTask_DoubleJump (void) m_moveToGoal = false; m_checkTerrain = false; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - if (m_duckForJump < GetWorldTime ()) + if (m_duckForJump < engine.Time ()) pev->button |= IN_DUCK; MakeVectors (Vector::GetZero ()); @@ -4299,14 +4279,14 @@ void Bot::RunTask_DoubleJump (void) dest.z = 180.0f; TraceResult tr; - TraceLine (EyePosition (), dest, false, true, GetEntity (), &tr); + engine.TestLine (EyePosition (), dest, TRACE_IGNORE_GLASS, GetEntity (), &tr); if (tr.flFraction < 1.0f && tr.pHit == m_doubleJumpEntity) { if (m_doubleJumpEntity->v.button & IN_JUMP) { - m_duckForJump = GetWorldTime () + Random.Float (3.0f, 5.0f); - GetTask ()->time = GetWorldTime (); + m_duckForJump = engine.Time () + Random.Float (3.0f, 5.0f); + GetTask ()->time = engine.Time (); } } return; @@ -4366,7 +4346,7 @@ void Bot::RunTask_EscapeFromBomb (void) m_campButtons = IN_DUCK; // we're reached destination point so just sit down and camp - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + 10.0f, true); + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + 10.0f, true); } else if (!GoalIsValid ()) // didn't choose goal waypoint yet? { @@ -4404,7 +4384,7 @@ void Bot::RunTask_ShootBreakable (void) m_aimFlags |= AIM_OVERRIDE; // Breakable destroyed? - if (IsEntityNull (FindBreakable ())) + if (engine.IsNullEntity (FindBreakable ())) { TaskComplete (); return; @@ -4413,9 +4393,9 @@ void Bot::RunTask_ShootBreakable (void) m_checkTerrain = false; m_moveToGoal = false; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); - Vector src = m_breakable; + Vector src = m_breakableOrigin; m_camp = src; // is bot facing the breakable? @@ -4438,14 +4418,14 @@ void Bot::RunTask_ShootBreakable (void) void Bot::RunTask_PickupItem () { - if (IsEntityNull (m_pickupItem)) + if (engine.IsNullEntity (m_pickupItem)) { m_pickupItem = NULL; TaskComplete (); return; } - Vector dest = GetEntityOrigin (m_pickupItem); + Vector dest = engine.GetAbsOrigin (m_pickupItem); m_destOrigin = dest; m_entity = dest; @@ -4453,8 +4433,6 @@ void Bot::RunTask_PickupItem () // find the distance to the item float itemDistance = (dest - pev->origin).GetLength (); - int id = 0; - switch (m_pickupType) { case PICKUP_DROPPED_C4: @@ -4467,6 +4445,8 @@ void Bot::RunTask_PickupItem () // near to weapon? if (itemDistance < 50.0f) { + int id = 0; + for (id = 0; id < 7; id++) { if (strcmp (g_weaponSelect[id].modelName, STRING (m_pickupItem->v.model) + 9) == 0) @@ -4476,33 +4456,33 @@ void Bot::RunTask_PickupItem () if (id < 7) { // secondary weapon. i.e., pistol - int weaponID = 0; + int wid = 0; for (id = 0; id < 7; id++) { if (pev->weapons & (1 << g_weaponSelect[id].id)) - weaponID = id; + wid = id; } - if (weaponID > 0) + if (wid > 0) { - SelectWeaponbyNumber (weaponID); - FakeClientCommand (GetEntity (), "drop"); + SelectWeaponbyNumber (wid); + engine.IssueBotCommand (GetEntity (), "drop"); 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); } else { // primary weapon - int weaponID = GetHighestWeapon (); + int wid = GetHighestWeapon (); - if ((weaponID > 6) || HasShield ()) + if (wid > 6 || HasShield ()) { - SelectWeaponbyNumber (weaponID); - FakeClientCommand (GetEntity (), "drop"); + SelectWeaponbyNumber (wid); + engine.IssueBotCommand (GetEntity (), "drop"); } EquipInBuyzone (BUYSTATE_PRIMARY_WEAPON); } @@ -4521,12 +4501,12 @@ void Bot::RunTask_PickupItem () else if (itemDistance < 50.0f) // near to shield? { // get current best weapon to check if it's a primary in need to be dropped - int weaponID = GetHighestWeapon (); + int wid = GetHighestWeapon (); - if (weaponID > 6) + if (wid > 6) { - SelectWeaponbyNumber (weaponID); - FakeClientCommand (GetEntity (), "drop"); + SelectWeaponbyNumber (wid); + engine.IssueBotCommand (GetEntity (), "drop"); } } break; @@ -4578,7 +4558,7 @@ void Bot::RunTask_PickupItem () 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 (engine.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_pickupItem = NULL; @@ -4604,7 +4584,7 @@ void Bot::RunTask_PickupItem () case PICKUP_BUTTON: m_aimFlags |= AIM_ENTITY; - if (IsEntityNull (m_pickupItem) || m_buttonPushTime < GetWorldTime ()) // it's safer... + if (engine.IsNullEntity (m_pickupItem) || m_buttonPushTime < engine.Time ()) // it's safer... { TaskComplete (); m_pickupType = PICKUP_NONE; @@ -4628,7 +4608,7 @@ void Bot::RunTask_PickupItem () m_pickupItem = NULL; m_pickupType = PICKUP_NONE; - m_buttonPushTime = GetWorldTime () + 3.0f; + m_buttonPushTime = engine.Time () + 3.0f; TaskComplete (); } @@ -4752,29 +4732,29 @@ void Bot::CheckSpawnTimeConditions (void) // this function is called instead of BotAI when buying finished, but freezetime is not yet left. // switch to knife if time to do this - if (m_checkKnifeSwitch && !m_checkWeaponSwitch && m_buyingFinished && m_spawnTime + Random.Float (4.0f, 6.5f) < GetWorldTime ()) + if (m_checkKnifeSwitch && !m_checkWeaponSwitch && m_buyingFinished && m_spawnTime + Random.Float (4.0f, 6.5f) < engine.Time ()) { if (Random.Long (1, 100) < 2 && yb_spraypaints.GetBool ()) - PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, GetWorldTime () + 1.0f, false); + PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, engine.Time () + 1.0f, false); if (m_difficulty >= 2 && Random.Long (0, 100) < (m_personality == PERSONALITY_RUSHER ? 99 : 50) && !m_isReloading && (g_mapType & (MAP_CS | MAP_DE | MAP_ES | MAP_AS))) { if (yb_jasonmode.GetBool ()) { SelectPistol (); - FakeClientCommand (GetEntity (), "drop"); + engine.IssueBotCommand (GetEntity (), "drop"); } else SelectWeaponByName ("weapon_knife"); } 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 () && engine.IsNullEntity (m_targetEntity) && !m_isLeader && !m_hasC4) AttachToUser (); } // check if we already switched weapon mode - if (m_checkWeaponSwitch && m_buyingFinished && m_spawnTime + Random.Float (2.0f, 3.5f) < GetWorldTime ()) + if (m_checkWeaponSwitch && m_buyingFinished && m_spawnTime + Random.Float (2.0f, 3.5f) < engine.Time ()) { if (HasShield () && IsShieldDrawn ()) pev->button |= IN_ATTACK2; @@ -4805,8 +4785,7 @@ void Bot::BotAI (void) { // this function gets called each frame and is the core of all bot ai. from here all other subroutines are called - float movedDistance; // length of different vector (distance bot moved) - TraceResult tr; + float movedDistance = 2.0f; // length of different vector (distance bot moved) // increase reaction time m_actualReactionTime += 0.3f; @@ -4820,22 +4799,20 @@ void Bot::BotAI (void) if (m_viewDistance > m_maxViewDistance) m_viewDistance = m_maxViewDistance; - if (m_blindTime > GetWorldTime ()) + if (m_blindTime > engine.Time ()) m_maxViewDistance = 4096.0f; m_moveSpeed = pev->maxspeed; - if (m_prevTime <= GetWorldTime ()) + if (m_prevTime <= engine.Time ()) { // see how far bot has moved since the previous position... movedDistance = (m_prevOrigin - pev->origin).GetLength (); // save current position as previous m_prevOrigin = pev->origin; - m_prevTime = GetWorldTime () + 0.2f; + m_prevTime = engine.Time () + 0.2f; } - else - movedDistance = 2.0f; // if there's some radio message to respond, check it if (m_radioOrder != 0) @@ -4847,7 +4824,7 @@ void Bot::BotAI (void) // some stuff required by by chatter engine if (yb_communication_type.GetInt () == 2) { - if ((m_states & STATE_SEEING_ENEMY) && !IsEntityNull (m_enemy)) + if ((m_states & STATE_SEEING_ENEMY) && !engine.IsNullEntity (m_enemy)) { int hasFriendNearby = GetNearbyFriendsNearPosition (pev->origin, 512.0f); @@ -4857,7 +4834,7 @@ void Bot::BotAI (void) else if (!hasFriendNearby && Random.Long (0, 100) < 45 && m_team == TERRORIST && IsPlayerVIP (m_enemy)) ChatterMessage (Chatter_VIPSpotted); - else if (!hasFriendNearby && Random.Long (0, 100) < 50 && GetTeam (m_enemy) != m_team && IsGroupOfEnemies (m_enemy->v.origin, 2, 384.0f)) + else if (!hasFriendNearby && Random.Long (0, 100) < 50 && engine.GetTeam (m_enemy) != m_team && IsGroupOfEnemies (m_enemy->v.origin, 2, 384.0f)) ChatterMessage (Chatter_ScaredEmotion); else if (!hasFriendNearby && Random.Long (0, 100) < 40 && ((m_enemy->v.weapons & (1 << WEAPON_AWP)) || (m_enemy->v.weapons & (1 << WEAPON_SCOUT)) || (m_enemy->v.weapons & (1 << WEAPON_G3SG1)) || (m_enemy->v.weapons & (1 << WEAPON_SG550)))) @@ -4869,7 +4846,7 @@ void Bot::BotAI (void) } // if bomb planted warn teammates ! - if (g_canSayBombPlanted && g_bombPlanted && GetTeam (GetEntity ()) == CT) + if (g_canSayBombPlanted && g_bombPlanted && engine.GetTeam (GetEntity ()) == CT) { g_canSayBombPlanted = false; ChatterMessage (Chatter_GottaFindTheBomb); @@ -4889,11 +4866,11 @@ void Bot::BotAI (void) UpdateLookAngles (); // and turn to chosen aim direction // the bots wants to fire at something? - if (m_wantsToFire && !m_isUsingGrenade && m_shootTime <= GetWorldTime ()) + if (m_wantsToFire && !m_isUsingGrenade && m_shootTime <= engine.Time ()) FireWeapon (); // if bot didn't fire a bullet try again next frame // check for reloading - if (m_reloadCheckTime <= GetWorldTime ()) + if (m_reloadCheckTime <= engine.Time ()) CheckReload (); // set the reaction time (surprise momentum) different each frame according to skill @@ -4919,7 +4896,7 @@ void Bot::BotAI (void) if ((m_currentPath->flags & FLAG_CROUCH) && !(m_currentPath->flags & FLAG_CAMP)) pev->button |= IN_DUCK; - m_timeWaypointMove = GetWorldTime (); + m_timeWaypointMove = engine.Time (); if (IsInWater ()) // special movement for swimming here { @@ -4950,27 +4927,27 @@ void Bot::BotAI (void) } // time to reach waypoint - if (m_navTimeset + GetEstimatedReachTime () < GetWorldTime () && IsEntityNull (m_enemy)) + if (m_navTimeset + GetEstimatedReachTime () < engine.Time () && engine.IsNullEntity (m_enemy)) { GetValidWaypoint (); // clear these pointers, bot mingh be stuck getting to them - if (!IsEntityNull (m_pickupItem) && !m_hasProgressBar) + if (!engine.IsNullEntity (m_pickupItem) && !m_hasProgressBar) m_itemIgnore = m_pickupItem; m_pickupItem = NULL; m_breakableEntity = NULL; - m_itemCheckTime = GetWorldTime () + 5.0f; + m_itemCheckTime = engine.Time () + 5.0f; m_pickupType = PICKUP_NONE; } - if (m_duckTime >= GetWorldTime ()) + if (m_duckTime >= engine.Time ()) pev->button |= IN_DUCK; if (pev->button & IN_JUMP) - m_jumpTime = GetWorldTime (); + m_jumpTime = engine.Time (); - if (m_jumpTime + 0.85f > GetWorldTime ()) + if (m_jumpTime + 0.85f > engine.Time ()) { if (!IsOnFloor () && !IsInWater ()) pev->button |= IN_DUCK; @@ -4993,7 +4970,7 @@ void Bot::BotAI (void) } // display some debugging thingy to host entity - if (!IsEntityNull (g_hostEntity) && yb_debug.GetInt () >= 1) + if (!engine.IsNullEntity (g_hostEntity) && yb_debug.GetInt () >= 1) DisplayDebugOverlay (); // save the previous speed (for checking if stuck) @@ -5005,7 +4982,7 @@ void Bot::DisplayDebugOverlay (void) { bool displayDebugOverlay = false; - if (g_hostEntity->v.iuser2 == IndexOfEntity (GetEntity ())) + if (g_hostEntity->v.iuser2 == engine.IndexOfEntity (GetEntity ())) displayDebugOverlay = true; if (!displayDebugOverlay && yb_debug.GetInt () >= 2) @@ -5023,7 +5000,7 @@ void Bot::DisplayDebugOverlay (void) if (!m_tasks.IsEmpty ()) { - if (taskID != GetTaskId () || index != m_currentWaypointIndex || goal != GetTask ()->data || timeDebugUpdate < GetWorldTime ()) + if (taskID != GetTaskId () || index != m_currentWaypointIndex || goal != GetTask ()->data || timeDebugUpdate < engine.Time ()) { taskID = GetTaskId (); index = m_currentWaypointIndex; @@ -5121,9 +5098,9 @@ void Bot::DisplayDebugOverlay (void) char enemyName[80], weaponName[80], aimFlags[64], botType[32]; - if (!IsEntityNull (m_enemy)) + if (!engine.IsNullEntity (m_enemy)) strncpy (enemyName, STRING (m_enemy->v.netname), SIZEOF_CHAR (enemyName)); - else if (!IsEntityNull (m_lastEnemy)) + else if (!engine.IsNullEntity (m_lastEnemy)) { strcpy (enemyName, " (L)"); strncat (enemyName, STRING (m_lastEnemy->v.netname), SIZEOF_CHAR (enemyName)); @@ -5134,17 +5111,17 @@ void Bot::DisplayDebugOverlay (void) char pickupName[80]; memset (pickupName, 0, sizeof (pickupName)); - if (!IsEntityNull (m_pickupItem)) + if (!engine.IsNullEntity (m_pickupItem)) strncpy (pickupName, STRING (m_pickupItem->v.classname), SIZEOF_CHAR (pickupName)); else strcpy (pickupName, " (null)"); - WeaponSelect *selectTab = &g_weaponSelect[0]; + WeaponSelect *tab = &g_weaponSelect[0]; char weaponCount = 0; - while (m_currentWeapon != selectTab->id && weaponCount < NUM_WEAPONS) + while (m_currentWeapon != tab->id && weaponCount < NUM_WEAPONS) { - selectTab++; + tab++; weaponCount++; } memset (aimFlags, 0, sizeof (aimFlags)); @@ -5191,12 +5168,12 @@ void Bot::DisplayDebugOverlay (void) } } else - strncpy (weaponName, selectTab->weaponName, SIZEOF_CHAR (weaponName)); + strncpy (weaponName, tab->weaponName, SIZEOF_CHAR (weaponName)); char outputBuffer[512]; memset (outputBuffer, 0, sizeof (outputBuffer)); - sprintf (outputBuffer, "\n\n\n\n%s (H:%.1f/A:%.1f)- Task: %d=%s Desire:%.02f\nItem: %s Clip: %d Ammo: %d%s Money: %d AimFlags: %s\nSP=%.02f SSP=%.02f I=%d PG=%d G=%d T: %.02f MT: %d\nEnemy=%s Pickup=%s Type=%s\n", STRING (pev->netname), pev->health, pev->armorvalue, taskID, taskName, GetTask ()->desire, &weaponName[7], GetAmmoInClip (), GetAmmo (), m_isReloading ? " (R)" : "", m_moneyAmount, aimFlags, m_moveSpeed, m_strafeSpeed, index, m_prevGoalIndex, goal, m_navTimeset - GetWorldTime (), pev->movetype, enemyName, pickupName, botType); + sprintf (outputBuffer, "\n\n\n\n%s (H:%.1f/A:%.1f)- Task: %d=%s Desire:%.02f\nItem: %s Clip: %d Ammo: %d%s Money: %d AimFlags: %s\nSP=%.02f SSP=%.02f I=%d PG=%d G=%d T: %.02f MT: %d\nEnemy=%s Pickup=%s Type=%s\n", STRING (pev->netname), pev->health, pev->armorvalue, taskID, taskName, GetTask ()->desire, &weaponName[7], GetAmmoInClip (), GetAmmo (), m_isReloading ? " (R)" : "", m_moneyAmount, aimFlags, m_moveSpeed, m_strafeSpeed, index, m_prevGoalIndex, goal, m_navTimeset - engine.Time (), pev->movetype, enemyName, pickupName, botType); MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, g_hostEntity); WRITE_BYTE (TE_TEXTMESSAGE); @@ -5218,20 +5195,20 @@ void Bot::DisplayDebugOverlay (void) WRITE_STRING (const_cast (&outputBuffer[0])); MESSAGE_END (); - timeDebugUpdate = GetWorldTime () + 1.0; + timeDebugUpdate = engine.Time () + 1.0; } // green = destination origin // blue = ideal angles // red = view angles - DrawArrow (g_hostEntity, EyePosition (), m_destOrigin, 10, 0, 0, 255, 0, 250, 5, 1); + engine.DrawLine (g_hostEntity, EyePosition (), m_destOrigin, 10, 0, 0, 255, 0, 250, 5, 1, DRAW_ARROW); MakeVectors (m_idealAngles); - DrawArrow (g_hostEntity, EyePosition () - Vector (0.0f, 0.0f, 16.0f), EyePosition () + g_pGlobals->v_forward * 300.0f, 10, 0, 0, 0, 255, 250, 5, 1); + engine.DrawLine (g_hostEntity, EyePosition () - Vector (0.0f, 0.0f, 16.0f), EyePosition () + g_pGlobals->v_forward * 300.0f, 10, 0, 0, 0, 255, 250, 5, 1, DRAW_ARROW); MakeVectors (pev->v_angle); - DrawArrow (g_hostEntity, EyePosition () - Vector (0.0f, 0.0f, 32.0f), EyePosition () + g_pGlobals->v_forward * 300.0f, 10, 0, 255, 0, 0, 250, 5, 1); + engine.DrawLine (g_hostEntity, EyePosition () - Vector (0.0f, 0.0f, 32.0f), EyePosition () + g_pGlobals->v_forward * 300.0f, 10, 0, 255, 0, 0, 250, 5, 1, DRAW_ARROW); // now draw line from source to destination PathNode *node = &m_navNode[0]; @@ -5244,7 +5221,7 @@ void Bot::DisplayDebugOverlay (void) if (node != NULL) { const Vector &dstPath = waypoints.GetPath (node->index)->origin; - DrawArrow (g_hostEntity, srcPath, dstPath, 15, 0, 255, 100, 55, 200, 5, 1); + engine.DrawLine (g_hostEntity, srcPath, dstPath, 15, 0, 255, 100, 55, 200, 5, 1, DRAW_ARROW); } } } @@ -5255,7 +5232,7 @@ bool Bot::HasHostage (void) { for (int i = 0; i < MAX_HOSTAGES; i++) { - if (!IsEntityNull (m_hostages[i])) + if (!engine.IsNullEntity (m_hostages[i])) { // don't care about dead hostages if (m_hostages[i]->v.health <= 0.0f || (pev->origin - m_hostages[i]->v.origin).GetLength () > 600.0f) @@ -5287,11 +5264,11 @@ void Bot::TakeDamage (edict_t *inflictor, int damage, int armor, int bits) if (IsValidPlayer (inflictor)) { - if (yb_tkpunish.GetBool () && GetTeam (inflictor) == m_team && !IsValidBot (inflictor)) + if (yb_tkpunish.GetBool () && engine.GetTeam (inflictor) == m_team && !IsValidBot (inflictor)) { // alright, die you teamkiller!!! m_actualReactionTime = 0.0f; - m_seeEnemyTime = GetWorldTime(); + m_seeEnemyTime = engine.Time(); m_enemy = inflictor; m_lastEnemy = m_enemy; @@ -5321,13 +5298,13 @@ void Bot::TakeDamage (edict_t *inflictor, int damage, int armor, int bits) } RemoveCertainTask (TASK_CAMP); - if (IsEntityNull (m_enemy) && m_team != GetTeam (inflictor)) + if (engine.IsNullEntity (m_enemy) && m_team != engine.GetTeam (inflictor)) { m_lastEnemy = inflictor; m_lastEnemyOrigin = inflictor->v.origin; // FIXME - Bot doesn't necessary sees this enemy - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time (); } if (yb_csdm_mode.GetInt () == 0) @@ -5345,48 +5322,47 @@ void Bot::TakeDamage (edict_t *inflictor, int damage, int armor, int bits) } } -void Bot::TakeBlinded (const Vector &fade, int alpha) +void Bot::TakeBlinded (int r, int g, int b, int alpha) { // this function gets called by network message handler, when screenfade message get's send - // it's used to make bot blind froumd the grenade. + // it's used to make bot blind from the grenade. - - if (fade.x != 255.0f || fade.y != 255.0f || fade.z != 255.0f || alpha <= 170.0f) + if (r != 255 || g != 255 || b != 255 || alpha <= 170) return; m_enemy = NULL; m_maxViewDistance = Random.Float (10.0f, 20.0f); - m_blindTime = GetWorldTime () + static_cast (alpha - 200.0f) / 16.0f; + m_blindTime = engine.Time () + static_cast (alpha - 200) / 16.0f; if (m_difficulty <= 2) { m_blindMoveSpeed = 0.0f; m_blindSidemoveSpeed = 0.0f; m_blindButton = IN_DUCK; + + return; } - else if (m_difficulty > 2) + + m_blindMoveSpeed = -pev->maxspeed; + m_blindSidemoveSpeed = 0.0f; + + float walkSpeed = GetWalkSpeed (); + + if (Random.Long (0, 100) > 50) + m_blindSidemoveSpeed = walkSpeed; + else + m_blindSidemoveSpeed = -walkSpeed; + + if (pev->health < 85.0f) + m_blindMoveSpeed = -walkSpeed; + else if (m_personality == PERSONALITY_CAREFUL) { - m_blindMoveSpeed = -pev->maxspeed; - m_blindSidemoveSpeed = 0.0f; - - float walkSpeed = GetWalkSpeed (); - - if (Random.Long (0, 100) > 50) - m_blindSidemoveSpeed = walkSpeed; - else - m_blindSidemoveSpeed = -walkSpeed; - - if (pev->health < 85.0f) - m_blindMoveSpeed = -walkSpeed; - else if (m_personality == PERSONALITY_CAREFUL) - { - m_blindMoveSpeed = 0.0f; - m_blindButton = IN_DUCK; - } - else - m_blindMoveSpeed = walkSpeed; + m_blindMoveSpeed = 0.0f; + m_blindButton = IN_DUCK; } + else + m_blindMoveSpeed = walkSpeed; } void Bot::CollectGoalExperience (int damage, int team) @@ -5437,7 +5413,7 @@ void Bot::CollectExperienceData (edict_t *attacker, int damage) if (!IsValidPlayer (attacker)) return; - int attackerTeam = GetTeam (attacker); + int attackerTeam = engine.GetTeam (attacker); int victimTeam = m_team; if (attackerTeam == victimTeam ) @@ -5506,7 +5482,7 @@ void Bot::HandleChatterMessage (const char *tempMessage) if (FStrEq (tempMessage, "#CTs_Win") && m_team == CT) { - if (g_timeRoundMid > GetWorldTime ()) + if (g_timeRoundMid > engine.Time ()) ChatterMessage (Chatter_QuicklyWonTheRound); else ChatterMessage (Chatter_WonTheRound); @@ -5514,7 +5490,7 @@ void Bot::HandleChatterMessage (const char *tempMessage) if (FStrEq (tempMessage, "#Terrorists_Win") && m_team == TERRORIST) { - if (g_timeRoundMid > GetWorldTime ()) + if (g_timeRoundMid > engine.Time ()) ChatterMessage (Chatter_QuicklyWonTheRound); else ChatterMessage (Chatter_WonTheRound); @@ -5559,17 +5535,17 @@ void Bot::DiscardWeaponForUser (edict_t *user, bool discardC4) if (discardC4) { SelectWeaponByName ("weapon_c4"); - FakeClientCommand (GetEntity (), "drop"); + engine.IssueBotCommand (GetEntity (), "drop"); } else { SelectBestWeapon (); - FakeClientCommand (GetEntity (), "drop"); + engine.IssueBotCommand (GetEntity (), "drop"); } m_pickupItem = NULL; m_pickupType = PICKUP_NONE; - m_itemCheckTime = GetWorldTime () + 5.0f; + m_itemCheckTime = engine.Time () + 5.0f; if (m_inBuyZone) { @@ -5577,7 +5553,7 @@ void Bot::DiscardWeaponForUser (edict_t *user, bool discardC4) m_buyState = BUYSTATE_PRIMARY_WEAPON; PushMessageQueue (GSM_BUY_STUFF); - m_nextBuyTime = GetWorldTime (); + m_nextBuyTime = engine.Time (); } } } @@ -5601,18 +5577,18 @@ void Bot::DebugMsg (const char *format, ...) return; va_list ap; - char buffer[1024]; + char buffer[MAX_PRINT_BUFFER]; va_start (ap, format); - vsprintf (buffer, format, ap); + vsnprintf (buffer, SIZEOF_CHAR (buffer), format, ap); va_end (ap); - char printBuf[1024]; + char printBuf[MAX_PRINT_BUFFER]; sprintf (printBuf, "%s: %s", STRING (pev->netname), buffer); bool playMessage = false; - if (level == 3 && !IsEntityNull (g_hostEntity) && g_hostEntity->v.iuser2 == IndexOfEntity (GetEntity ())) + if (level == 3 && !engine.IsNullEntity (g_hostEntity) && g_hostEntity->v.iuser2 == engine.IndexOfEntity (GetEntity ())) playMessage = true; else if (level != 3) playMessage = true; @@ -5622,7 +5598,7 @@ void Bot::DebugMsg (const char *format, ...) if (playMessage) { - ServerPrint (printBuf); + engine.Printf (printBuf); SayText (printBuf); } } @@ -5642,7 +5618,7 @@ Vector Bot::CheckToss(const Vector &start, const Vector &stop) return Vector::GetZero (); Vector midPoint = start + (end - start) * 0.5f; - TraceHull (midPoint, midPoint + Vector (0.0f, 0.0f, 500.0f), true, head_hull, ENT (pev), &tr); + engine.TestHull (midPoint, midPoint + Vector (0.0f, 0.0f, 500.0f), TRACE_IGNORE_MONSTERS, head_hull, GetEntity (), &tr); if (tr.flFraction < 1.0f) { @@ -5665,12 +5641,12 @@ Vector Bot::CheckToss(const Vector &start, const Vector &stop) Vector apex = start + nadeVelocity * timeOne; apex.z = midPoint.z; - TraceHull (start, apex, false, head_hull, ENT (pev), &tr); + engine.TestHull (start, apex, TRACE_IGNORE_NONE, head_hull, GetEntity (), &tr); if (tr.flFraction < 1.0f || tr.fAllSolid) return Vector::GetZero (); - TraceHull (end, apex, true, head_hull, ENT (pev), &tr); + engine.TestHull (end, apex, TRACE_IGNORE_MONSTERS, head_hull, GetEntity (), &tr); if (tr.flFraction != 1.0f) { @@ -5704,12 +5680,12 @@ Vector Bot::CheckThrow(const Vector &start, const Vector &stop) Vector apex = start + (stop - start) * 0.5f; apex.z += 0.5f * gravity * (time * 0.5f) * (time * 0.5f); - TraceHull (start, apex, false, head_hull, GetEntity (), &tr); + engine.TestHull (start, apex, TRACE_IGNORE_NONE, head_hull, GetEntity (), &tr); if (tr.flFraction != 1.0f) return Vector::GetZero (); - TraceHull (stop, apex, true, head_hull, GetEntity (), &tr); + engine.TestHull (stop, apex, TRACE_IGNORE_MONSTERS, head_hull, GetEntity (), &tr); if (tr.flFraction != 1.0 || tr.fAllSolid) { @@ -5733,7 +5709,7 @@ Vector Bot::CheckBombAudible (void) const Vector &bombOrigin = waypoints.GetBombPosition (); - float timeElapsed = ((GetWorldTime () - g_timeBombPlanted) / mp_c4timer.GetFloat ()) * 100.0f; + float timeElapsed = ((engine.Time () - g_timeBombPlanted) / mp_c4timer.GetFloat ()) * 100.0f; float desiredRadius = 768.0f; // start the manual calculations @@ -5765,7 +5741,7 @@ byte Bot::ThrottledMsec (void) { // estimate msec to use for this command based on time passed from the previous command - return static_cast ((GetWorldTime () - m_lastCommandTime) * 1000.0f); + return static_cast ((engine.Time () - m_lastCommandTime) * 1000.0f); } void Bot::RunPlayerMovement (void) @@ -5784,10 +5760,10 @@ void Bot::RunPlayerMovement (void) // elapses, that bot will behave like a ghost : no movement, but bullets and players can // pass through it. Then, when the next frame will begin, the stucking problem will arise ! - m_frameInterval = GetWorldTime () - m_lastCommandTime; + m_frameInterval = engine.Time () - m_lastCommandTime; byte msecVal = ThrottledMsec (); - m_lastCommandTime = GetWorldTime (); + m_lastCommandTime = engine.Time (); (*g_engfuncs.pfnRunPlayerMove) (pev->pContainingEntity, m_moveAngles, m_moveSpeed, m_strafeSpeed, 0.0f, pev->button, pev->impulse, msecVal); } @@ -5837,7 +5813,7 @@ float Bot::GetBombTimeleft (void) if (!g_bombPlanted) return 0.0f; - float timeLeft = ((g_timeBombPlanted + mp_c4timer.GetFloat ()) - GetWorldTime ()); + float timeLeft = ((g_timeBombPlanted + mp_c4timer.GetFloat ()) - engine.Time ()); if (timeLeft < 0.0f) return 0.0f; @@ -5900,12 +5876,12 @@ bool Bot::OutOfBombTimer (void) bool hasTeammatesWithDefuserKit = false; // check if our teammates has defusal kit - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = NULL; // temporaly pointer to bot // search players with defuse kit - if ((bot = bots.GetBot (i)) != NULL && GetTeam (bot->GetEntity ()) == CT && bot->m_hasDefuser && (bombOrigin - bot->pev->origin).GetLength () < 500.0f) + if ((bot = bots.GetBot (i)) != NULL && bot->m_team == CT && bot->m_hasDefuser && (bombOrigin - bot->pev->origin).GetLength () < 500.0f) { hasTeammatesWithDefuserKit = true; break; @@ -5939,9 +5915,9 @@ void Bot::ReactOnSound (void) float minDistance = 99999.0f; // loop through all enemy clients to check for hearable stuff - for (int i = 0; i < GetMaxClients (); 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].ent == GetEntity () || g_clients[i].team == m_team || g_clients[i].timeSoundLasting < GetWorldTime ()) + if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].ent == GetEntity () || g_clients[i].team == m_team || g_clients[i].timeSoundLasting < engine.Time ()) continue; float distance = (g_clients[i].soundPosition - pev->origin).GetLength (); @@ -5967,13 +5943,13 @@ void Bot::ReactOnSound (void) if (IsValidPlayer (player)) { // change to best weapon if heard something - if (m_shootTime < GetWorldTime () - 5.0f && IsOnFloor () && m_currentWeapon != WEAPON_C4 && m_currentWeapon != WEAPON_EXPLOSIVE && m_currentWeapon != WEAPON_SMOKE && m_currentWeapon != WEAPON_FLASHBANG && !yb_jasonmode.GetBool ()) + if (m_shootTime < engine.Time () - 5.0f && IsOnFloor () && m_currentWeapon != WEAPON_C4 && m_currentWeapon != WEAPON_EXPLOSIVE && m_currentWeapon != WEAPON_SMOKE && m_currentWeapon != WEAPON_FLASHBANG && !yb_jasonmode.GetBool ()) SelectBestWeapon (); - m_heardSoundTime = GetWorldTime (); + m_heardSoundTime = engine.Time (); m_states |= STATE_HEARING_ENEMY; - if ((Random.Long (0, 100) < 15) && IsEntityNull (m_enemy) && IsEntityNull (m_lastEnemy) && m_seeEnemyTime + 7.0f < GetWorldTime ()) + if ((Random.Long (0, 100) < 15) && engine.IsNullEntity (m_enemy) && engine.IsNullEntity (m_lastEnemy) && m_seeEnemyTime + 7.0f < engine.Time ()) ChatterMessage (Chatter_HeardEnemy); // didn't bot already have an enemy ? take this one... @@ -5997,7 +5973,7 @@ void Bot::ReactOnSound (void) // if bot had an enemy but the heard one is nearer, take it instead float distance = (m_lastEnemyOrigin - pev->origin).GetLengthSquared (); - if (distance > (player->v.origin - pev->origin).GetLengthSquared () && m_seeEnemyTime + 2.0f < GetWorldTime ()) + if (distance > (player->v.origin - pev->origin).GetLengthSquared () && m_seeEnemyTime + 2.0f < engine.Time ()) { m_lastEnemy = player; m_lastEnemyOrigin = player->v.origin; @@ -6016,7 +5992,21 @@ void Bot::ReactOnSound (void) m_enemyOrigin = m_lastEnemyOrigin; m_states |= STATE_SEEING_ENEMY; - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time (); + } + else // check if heard enemy can be shoot through some obstacle + { + if (m_difficulty > 2 && m_lastEnemy == player && m_seeEnemyTime + 3.0 > engine.Time () && yb_shoots_thru_walls.GetBool () && IsShootableThruObstacle (player->v.origin + player->v.view_ofs)) + { + m_enemy = player; + m_lastEnemy = player; + m_enemyOrigin = player->v.origin; + m_lastEnemyOrigin = player->v.origin; + + m_states |= (STATE_SEEING_ENEMY | STATE_SUSPECT_ENEMY); + m_seeEnemyTime = engine.Time (); + + } } } } @@ -6038,10 +6028,10 @@ void Bot::EquipInBuyzone (int buyState) bool checkBuyTime = false; if (mp_buytime.m_eptr != NULL) - checkBuyTime = (g_timeRoundStart + Random.Float (10.0f, 20.0f) + mp_buytime.GetFloat () < GetWorldTime ()); + checkBuyTime = (g_timeRoundStart + Random.Float (10.0f, 20.0f) + mp_buytime.GetFloat () < engine.Time ()); // if bot is in buy zone, try to buy ammo for this weapon... - if (m_seeEnemyTime + 5.0f < GetWorldTime () && m_lastEquipTime + 15.0f < GetWorldTime () && m_inBuyZone && checkBuyTime && !g_bombPlanted && m_moneyAmount > g_botBuyEconomyTable[0]) + if (m_seeEnemyTime + 5.0f < engine.Time () && m_lastEquipTime + 15.0f < engine.Time () && m_inBuyZone && checkBuyTime && !g_bombPlanted && m_moneyAmount > g_botBuyEconomyTable[0]) { m_buyingFinished = false; m_buyState = buyState; @@ -6049,8 +6039,8 @@ void Bot::EquipInBuyzone (int buyState) // push buy message PushMessageQueue (GSM_BUY_STUFF); - m_nextBuyTime = GetWorldTime (); - m_lastEquipTime = GetWorldTime (); + m_nextBuyTime = engine.Time (); + m_lastEquipTime = engine.Time (); } } @@ -6058,17 +6048,19 @@ bool Bot::IsBombDefusing (const Vector &bombOrigin) { // this function finds if somebody currently defusing the bomb. - // @todo: need to check progress bar for non-bots clients. + if (!g_bombPlanted) + return false; + bool defusingInProgress = false; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); if (bot == NULL || bot == this) continue; // skip invalid bots - if (m_team != GetTeam (bot->GetEntity ()) || bot->GetTaskId () == TASK_ESCAPEFROMBOMB) + if (m_team != bot->m_team || bot->GetTaskId () == TASK_ESCAPEFROMBOMB) continue; // skip other mess if ((bot->pev->origin - bombOrigin).GetLength () < 140.0f && (bot->GetTaskId () == TASK_DEFUSEBOMB || bot->m_hasProgressBar)) @@ -6076,12 +6068,13 @@ bool Bot::IsBombDefusing (const Vector &bombOrigin) defusingInProgress = true; break; } + Client *client = &g_clients[i]; // 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; - 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; break; @@ -6096,4 +6089,4 @@ float Bot::GetWalkSpeed (void) return pev->maxspeed; return static_cast ((static_cast (pev->maxspeed) * 0.5f) + (static_cast (pev->maxspeed) / 50.0f)) - 18.0f; -} \ No newline at end of file +} diff --git a/source/chatlib.cpp b/source/chatlib.cpp index 783f3ae..b2285a9 100644 --- a/source/chatlib.cpp +++ b/source/chatlib.cpp @@ -47,7 +47,7 @@ void StripTags (char *buffer) // have we stripped too much (all the stuff)? 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; @@ -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) @@ -95,7 +95,7 @@ char *HumanizeName (char *name) if (Random.Long (1, 100) < 80) StripTags (outputName); else - strtrim (outputName); + String::TrimExternalBuffer (outputName); // sometimes switch name to lower characters // 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)) return; - #define ASSIGN_TALK_ENTITY() if (!IsEntityNull (talkEntity)) strncat (m_tempStrings, HumanizeName (const_cast (STRING (talkEntity->v.netname))), SIZEOF_CHAR (m_tempStrings)) + #define ASSIGN_TALK_ENTITY() if (!engine.IsNullEntity (talkEntity)) strncat (m_tempStrings, HumanizeName (const_cast (STRING (talkEntity->v.netname))), SIZEOF_CHAR (m_tempStrings)) memset (&m_tempStrings, 0, sizeof (m_tempStrings)); @@ -185,7 +185,7 @@ void Bot::PrepareChatMessage (char *text) int highestFrags = -9000; // just pick some start value int index = 0; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (!(g_clients[i].flags & CF_USED) || g_clients[i].ent == GetEntity ()) continue; @@ -204,17 +204,17 @@ void Bot::PrepareChatMessage (char *text) } // mapname? else if (*pattern == 'm') - strncat (m_tempStrings, GetMapName (), SIZEOF_CHAR (m_tempStrings)); + strncat (m_tempStrings, engine.GetMapName (), SIZEOF_CHAR (m_tempStrings)); // roundtime? else if (*pattern == 'r') { - int time = static_cast (g_timeRoundEnd - GetWorldTime ()); + int time = static_cast (g_timeRoundEnd - engine.Time ()); strncat (m_tempStrings, FormatBuffer ("%02d:%02d", time / 60, time % 60), SIZEOF_CHAR (m_tempStrings)); } // chat reply? else if (*pattern == 's') { - talkEntity = EntityOfIndex (m_sayTextBuffer.entityIndex); + talkEntity = engine.EntityOfIndex (m_sayTextBuffer.entityIndex); ASSIGN_TALK_ENTITY (); } // teammate alive? @@ -222,7 +222,7 @@ void Bot::PrepareChatMessage (char *text) { int i; - for (i = 0; i < GetMaxClients (); i++) + for (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 ()) continue; @@ -230,9 +230,9 @@ void Bot::PrepareChatMessage (char *text) break; } - if (i < GetMaxClients ()) + if (i < engine.MaxClients ()) { - if (!IsEntityNull (pev->dmg_inflictor) && m_team == GetTeam (pev->dmg_inflictor)) + if (!engine.IsNullEntity (pev->dmg_inflictor) && m_team == engine.GetTeam (pev->dmg_inflictor)) talkEntity = pev->dmg_inflictor; else talkEntity = g_clients[i].ent; @@ -241,7 +241,7 @@ void Bot::PrepareChatMessage (char *text) } else // no teammates alive... { - for (i = 0; i < GetMaxClients (); i++) + for (i = 0; i < engine.MaxClients (); i++) { if (!(g_clients[i].flags & CF_USED) || g_clients[i].team != m_team || g_clients[i].ent == GetEntity ()) continue; @@ -249,7 +249,7 @@ void Bot::PrepareChatMessage (char *text) break; } - if (i < GetMaxClients ()) + if (i < engine.MaxClients ()) { talkEntity = g_clients[i].ent; @@ -261,27 +261,27 @@ void Bot::PrepareChatMessage (char *text) { int i; - for (i = 0; i < GetMaxClients (); i++) + for (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 ()) continue; break; } - if (i < GetMaxClients ()) + if (i < engine.MaxClients ()) { talkEntity = g_clients[i].ent; ASSIGN_TALK_ENTITY (); } else // no teammates alive... { - for (i = 0; i < GetMaxClients (); i++) + for (i = 0; i < engine.MaxClients (); i++) { if (!(g_clients[i].flags & CF_USED) || g_clients[i].team == m_team || g_clients[i].ent == GetEntity ()) continue; break; } - if (i < GetMaxClients ()) + if (i < engine.MaxClients ()) { talkEntity = g_clients[i].ent; ASSIGN_TALK_ENTITY (); @@ -290,14 +290,14 @@ void Bot::PrepareChatMessage (char *text) } else if (*pattern == 'd') { - if (g_gameFlags == GAME_CZERO) + if (g_gameFlags & GAME_CZERO) { if (Random.Long (1, 100) < 30) strcat (m_tempStrings, "CZ"); else strcat (m_tempStrings, "Condition Zero"); } - else if (g_gameFlags == GAME_CSTRIKE16 || g_gameFlags == GAME_LEGACY) + else if ((g_gameFlags & GAME_CSTRIKE16) || (g_gameFlags & GAME_LEGACY)) { if (Random.Long (1, 100) < 30) strcat (m_tempStrings, "CS"); @@ -399,7 +399,7 @@ bool Bot::RepliesToPlayer (void) char text[256]; // check is time to chat is good - if (m_sayTextBuffer.timeNextChat < GetWorldTime ()) + if (m_sayTextBuffer.timeNextChat < engine.Time ()) { if (Random.Long (1, 100) < m_sayTextBuffer.chatProbability + Random.Long (2, 10) && ParseChat (reinterpret_cast (&text))) { @@ -408,7 +408,7 @@ bool Bot::RepliesToPlayer (void) m_sayTextBuffer.entityIndex = -1; m_sayTextBuffer.sayText[0] = 0x0; - m_sayTextBuffer.timeNextChat = GetWorldTime () + m_sayTextBuffer.chatDelay; + m_sayTextBuffer.timeNextChat = engine.Time () + m_sayTextBuffer.chatDelay; return true; } @@ -426,7 +426,7 @@ void Bot::SayText (const char *text) if (IsNullString (text)) return; - FakeClientCommand (GetEntity (), "say \"%s\"", text); + engine.IssueBotCommand (GetEntity (), "say \"%s\"", text); } void Bot::TeamSayText (const char *text) @@ -436,5 +436,5 @@ void Bot::TeamSayText (const char *text) if (IsNullString (text)) return; - FakeClientCommand (GetEntity (), "say_team \"%s\"", text); + engine.IssueBotCommand (GetEntity (), "say_team \"%s\"", text); } diff --git a/source/combat.cpp b/source/combat.cpp index da95900..b24cc31 100644 --- a/source/combat.cpp +++ b/source/combat.cpp @@ -20,7 +20,7 @@ int Bot::GetNearbyFriendsNearPosition(const Vector &origin, float radius) { int count = 0; - for (int i = 0; i < GetMaxClients (); 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 ()) continue; @@ -35,7 +35,7 @@ int Bot::GetNearbyEnemiesNearPosition(const Vector &origin, float radius) { int count = 0; - for (int i = 0; i < GetMaxClients (); 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) continue; @@ -48,7 +48,7 @@ int Bot::GetNearbyEnemiesNearPosition(const Vector &origin, float radius) bool Bot::IsEnemyHiddenByRendering (edict_t *enemy) { - if (IsEntityNull (enemy) || !yb_check_enemy_rendering.GetBool ()) + if (engine.IsNullEntity (enemy) || !yb_check_enemy_rendering.GetBool ()) return false; entvars_t &v = enemy->v; @@ -107,7 +107,7 @@ bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart) *bodyPart = 0; - TraceLine (eyes, spot, true, true, pev->pContainingEntity, &result); + engine.TestLine (eyes, spot, TRACE_IGNORE_EVERYTHING, pev->pContainingEntity, &result); if (result.flFraction >= 1.0f) { @@ -120,8 +120,7 @@ bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart) // check top of head spot = spot + Vector (0, 0, 25.0f); - - TraceLine (eyes, spot, true, true, pev->pContainingEntity, &result); + engine.TestLine (eyes, spot, TRACE_IGNORE_EVERYTHING, pev->pContainingEntity, &result); if (result.flFraction >= 1.0f) { @@ -143,7 +142,7 @@ bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart) else spot.z = target->v.origin.z - standFeet; - TraceLine (eyes, spot, true, true, pev->pContainingEntity, &result); + engine.TestLine (eyes, spot, TRACE_IGNORE_EVERYTHING, pev->pContainingEntity, &result); if (result.flFraction >= 1.0f) { @@ -159,7 +158,7 @@ bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart) Vector perp (-dir.y, dir.x, 0.0f); spot = target->v.origin + Vector (perp.x * edgeOffset, perp.y * edgeOffset, 0); - TraceLine (eyes, spot, true, true, pev->pContainingEntity, &result); + engine.TestLine (eyes, spot, TRACE_IGNORE_EVERYTHING, pev->pContainingEntity, &result); if (result.flFraction >= 1.0f) { @@ -170,7 +169,7 @@ bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart) } spot = target->v.origin - Vector (perp.x * edgeOffset, perp.y * edgeOffset, 0); - TraceLine (eyes, spot, true, true, pev->pContainingEntity, &result); + engine.TestLine (eyes, spot, TRACE_IGNORE_EVERYTHING, pev->pContainingEntity, &result); if (result.flFraction >= 1.0f) { @@ -184,17 +183,17 @@ bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart) bool Bot::IsEnemyViewable (edict_t *player) { - if (IsEntityNull (player)) + if (engine.IsNullEntity (player)) return false; bool forceTrueIfVisible = false; - if (IsValidPlayer (pev->dmg_inflictor) && GetTeam (pev->dmg_inflictor) != m_team) + if (IsValidPlayer (pev->dmg_inflictor) && engine.GetTeam (pev->dmg_inflictor) != m_team) forceTrueIfVisible = true; if ((IsInViewCone (player->v.origin + pev->view_ofs) || forceTrueIfVisible) && CheckVisibility (player, &m_enemyOrigin, &m_visibility)) { - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time (); m_lastEnemy = player; m_lastEnemyOrigin = player->v.origin; @@ -208,7 +207,7 @@ bool Bot::LookupEnemy (void) // this function tries to find the best suitable enemy for the bot // do not search for enemies while we're blinded, or shooting disabled by user - if (m_enemyIgnoreTimer > GetWorldTime () || m_blindTime > GetWorldTime () || yb_ignore_enemies.GetBool ()) + if (m_enemyIgnoreTimer > engine.Time () || m_blindTime > engine.Time () || yb_ignore_enemies.GetBool ()) return false; edict_t *player, *newEnemy = NULL; @@ -216,10 +215,10 @@ bool Bot::LookupEnemy (void) float nearestDistance = m_viewDistance; // clear suspected flag - if (m_seeEnemyTime + 3.0f < GetWorldTime ()) + if (m_seeEnemyTime + 3.0f < engine.Time ()) m_states &= ~STATE_SUSPECT_ENEMY; - if (!IsEntityNull (m_enemy) && m_enemyUpdateTime > GetWorldTime ()) + if (!engine.IsNullEntity (m_enemy) && m_enemyUpdateTime > engine.Time ()) { player = m_enemy; @@ -229,9 +228,9 @@ bool Bot::LookupEnemy (void) } // the old enemy is no longer visible or - if (IsEntityNull (newEnemy)) + if (engine.IsNullEntity (newEnemy)) { - m_enemyUpdateTime = GetWorldTime () + 0.5f; + m_enemyUpdateTime = engine.Time () + 0.5f; // ignore shielded enemies, while we have real one edict_t *shieldEnemy = NULL; @@ -245,7 +244,7 @@ bool Bot::LookupEnemy (void) byte *pvs = ENGINE_SET_PVS (reinterpret_cast (&potentialVisibility)); // search the world for players... - for (int i = 0; i < GetMaxClients (); 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 ()) continue; @@ -257,19 +256,19 @@ bool Bot::LookupEnemy (void) continue; // do some blind by smoke grenade - if (m_blindRecognizeTime < GetWorldTime () && IsBehindSmokeClouds (player)) + if (m_blindRecognizeTime < engine.Time () && IsBehindSmokeClouds (player)) { - m_blindRecognizeTime = GetWorldTime () + Random.Float (1.0f, 2.0f); + m_blindRecognizeTime = engine.Time () + Random.Float (1.0f, 2.0f); if (Random.Long (0, 100) < 50) ChatterMessage (Chatter_BehindSmoke); } if (player->v.button & (IN_ATTACK | IN_ATTACK2)) - m_blindRecognizeTime = GetWorldTime () - 0.1f; + m_blindRecognizeTime = engine.Time () - 0.1f; // see if bot can see the player... - if (m_blindRecognizeTime < GetWorldTime () && IsEnemyViewable (player)) + if (m_blindRecognizeTime < engine.Time () && IsEnemyViewable (player)) { if (IsEnemyProtectedByShield (player)) { @@ -290,7 +289,7 @@ bool Bot::LookupEnemy (void) } } - if (IsEntityNull (newEnemy) && !IsEntityNull (shieldEnemy)) + if (engine.IsNullEntity (newEnemy) && !engine.IsNullEntity (shieldEnemy)) newEnemy = shieldEnemy; } @@ -304,7 +303,7 @@ bool Bot::LookupEnemy (void) if (newEnemy == m_enemy) { // if enemy is still visible and in field of view, keep it keep track of when we last saw an enemy - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time (); // zero out reaction time m_actualReactionTime = 0.0f; @@ -315,15 +314,15 @@ bool Bot::LookupEnemy (void) } else { - if (m_seeEnemyTime + 3.0 < GetWorldTime () && (m_hasC4 || HasHostage () || !IsEntityNull (m_targetEntity))) + if (m_seeEnemyTime + 3.0 < engine.Time () && (m_hasC4 || HasHostage () || !engine.IsNullEntity (m_targetEntity))) RadioMessage (Radio_EnemySpotted); m_targetEntity = NULL; // stop following when we see an enemy... if (Random.Long (0, 100) < m_difficulty * 25) - m_enemySurpriseTime = GetWorldTime () + m_actualReactionTime * 0.5f; + m_enemySurpriseTime = engine.Time () + m_actualReactionTime * 0.5f; else - m_enemySurpriseTime = GetWorldTime () + m_actualReactionTime; + m_enemySurpriseTime = engine.Time () + m_actualReactionTime; // zero out reaction time m_actualReactionTime = 0.0f; @@ -333,24 +332,24 @@ bool Bot::LookupEnemy (void) m_enemyReachableTimer = 0.0f; // keep track of when we last saw an enemy - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time (); if (!(pev->oldbuttons & IN_ATTACK)) return true; // now alarm all teammates who see this bot & don't have an actual enemy of the bots enemy should simulate human players seeing a teammate firing - for (int j = 0; j < GetMaxClients (); j++) + for (int j = 0; j < engine.MaxClients (); j++) { if (!(g_clients[j].flags & CF_USED) || !(g_clients[j].flags & CF_ALIVE) || g_clients[j].team != m_team || g_clients[j].ent == GetEntity ()) continue; Bot *friendBot = bots.GetBot (g_clients[j].ent); - if (friendBot != NULL && friendBot->m_seeEnemyTime + 2.0f < GetWorldTime () && IsEntityNull (friendBot->m_lastEnemy) && IsVisible (pev->origin, ENT (friendBot->pev)) && friendBot->IsInViewCone (pev->origin)) + if (friendBot != NULL && friendBot->m_seeEnemyTime + 2.0f < engine.Time () && engine.IsNullEntity (friendBot->m_lastEnemy) && IsVisible (pev->origin, friendBot->GetEntity ()) && friendBot->IsInViewCone (pev->origin)) { friendBot->m_lastEnemy = newEnemy; friendBot->m_lastEnemyOrigin = m_lastEnemyOrigin; - friendBot->m_seeEnemyTime = GetWorldTime (); + friendBot->m_seeEnemyTime = engine.Time (); friendBot->m_states |= (STATE_SUSPECT_ENEMY | STATE_HEARING_ENEMY); friendBot->m_aimFlags |= AIM_LAST_ENEMY; } @@ -358,7 +357,7 @@ bool Bot::LookupEnemy (void) return true; } } - else if (!IsEntityNull (m_enemy)) + else if (!engine.IsNullEntity (m_enemy)) { newEnemy = m_enemy; m_lastEnemy = newEnemy; @@ -368,11 +367,11 @@ bool Bot::LookupEnemy (void) m_enemy = NULL; // shoot at dying players if no new enemy to give some more human-like illusion - if (m_seeEnemyTime + 0.1f > GetWorldTime ()) + if (m_seeEnemyTime + 0.1f > engine.Time ()) { if (!UsesSniper ()) { - m_shootAtDeadTime = GetWorldTime () + 0.4f; + m_shootAtDeadTime = engine.Time () + 0.4f; m_actualReactionTime = 0.0f; m_states |= STATE_SUSPECT_ENEMY; @@ -380,7 +379,7 @@ bool Bot::LookupEnemy (void) } return false; } - else if (m_shootAtDeadTime > GetWorldTime ()) + else if (m_shootAtDeadTime > engine.Time ()) { m_actualReactionTime = 0.0f; m_states |= STATE_SUSPECT_ENEMY; @@ -393,7 +392,7 @@ bool Bot::LookupEnemy (void) // if no enemy visible check if last one shoot able through wall if (yb_shoots_thru_walls.GetBool () && m_difficulty >= 2 && IsShootableThruObstacle (newEnemy->v.origin)) { - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time (); m_states |= STATE_SUSPECT_ENEMY; m_aimFlags |= AIM_LAST_ENEMY; @@ -407,14 +406,14 @@ bool Bot::LookupEnemy (void) } // check if bots should reload... - if ((m_aimFlags <= AIM_PREDICT_PATH && m_seeEnemyTime + 3.0f < GetWorldTime () && !(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)) && engine.IsNullEntity (m_lastEnemy) && engine.IsNullEntity (m_enemy) && GetTaskId () != TASK_SHOOTBREAKABLE && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB) || g_roundEnded) { if (!m_reloadState) m_reloadState = RELOAD_PRIMARY; } // is the bot using a sniper rifle or a zoomable rifle? - if ((UsesSniper () || UsesZoomableRifle ()) && m_zoomCheckTime + 1.0f < GetWorldTime ()) + if ((UsesSniper () || UsesZoomableRifle ()) && m_zoomCheckTime + 1.0f < engine.Time ()) { if (pev->fov < 90.0f) // let the bot zoom out pev->button |= IN_ATTACK2; @@ -558,20 +557,20 @@ bool Bot::IsFriendInLineOfFire (float distance) MakeVectors (pev->v_angle); TraceResult tr; - TraceLine (EyePosition (), EyePosition () + 10000.0f * pev->v_angle, false, false, GetEntity (), &tr); + engine.TestLine (EyePosition (), EyePosition () + 10000.0f * pev->v_angle, TRACE_IGNORE_NONE, GetEntity (), &tr); // check if we hit something - if (!IsEntityNull (tr.pHit) && tr.pHit != g_worldEntity) + if (!engine.IsNullEntity (tr.pHit)) { - int playerIndex = IndexOfEntity (tr.pHit) - 1; + int playerIndex = engine.IndexOfEntity (tr.pHit) - 1; // check valid range - if (playerIndex >= 0 && playerIndex < GetMaxClients () && g_clients[playerIndex].team == m_team && (g_clients[playerIndex].flags & CF_ALIVE)) + if (playerIndex >= 0 && playerIndex < engine.MaxClients () && g_clients[playerIndex].team == m_team && (g_clients[playerIndex].flags & CF_ALIVE)) return true; } // search the world for players - for (int i = 0; i < GetMaxClients (); 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 ()) continue; @@ -606,12 +605,12 @@ bool Bot::IsShootableThruObstacle (const Vector &dest) TraceResult tr; float obstacleDistance = 0.0f; - TraceLine (EyePosition (), dest, true, GetEntity (), &tr); + engine.TestLine (EyePosition (), dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); if (tr.fStartSolid) { const Vector &source = tr.vecEndPos; - TraceLine (dest, source, true, GetEntity (), &tr); + engine.TestLine (dest, source, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); if (tr.flFraction != 1.0f) { @@ -657,7 +656,7 @@ bool Bot::IsShootableThruObstacleEx (const Vector &dest) int numHits = 0; TraceResult tr; - TraceLine (source, dest, true, true, GetEntity (), &tr); + engine.TestLine (source, dest, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); while (tr.flFraction != 1.0f && numHits < 3) { @@ -671,7 +670,7 @@ bool Bot::IsShootableThruObstacleEx (const Vector &dest) point = point + direction; thikness++; } - TraceLine (point, dest, true, true, GetEntity (), &tr); + engine.TestLine (point, dest, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); } if (numHits < 3 && thikness < 98) @@ -686,7 +685,7 @@ bool Bot::DoFirePause (float distance) { // returns true if bot needs to pause between firing to compensate for punchangle & weapon spread - if (m_firePause > GetWorldTime ()) + if (m_firePause > engine.Time ()) return true; if ((m_aimFlags & AIM_ENEMY) && !m_enemyOrigin.IsZero ()) @@ -711,8 +710,8 @@ bool Bot::DoFirePause (float distance) // check if we need to compensate recoil if (tanf (sqrtf (fabsf (xPunch * xPunch) + fabsf (yPunch * yPunch))) * distance > offset + 30.0f + ((100 - (m_difficulty * 25)) / 100.f)) { - if (m_firePause < GetWorldTime () - 0.4f) - m_firePause = GetWorldTime () + Random.Float (0.4f, 0.4f + 0.3f * ((100 - (m_difficulty * 25)) / 100.f)); + if (m_firePause < engine.Time () - 0.4f) + m_firePause = engine.Time () + Random.Float (0.4f, 0.4f + 0.3f * ((100 - (m_difficulty * 25)) / 100.f)); return true; } @@ -727,22 +726,22 @@ void Bot::FireWeapon (void) // if using grenade stop this if (m_isUsingGrenade) { - m_shootTime = GetWorldTime () + 0.1f; + m_shootTime = engine.Time () + 0.1f; return; } // or if friend in line of fire, stop this too but do not update shoot time - if (!IsEntityNull (m_enemy)) + if (!engine.IsNullEntity (m_enemy)) { if (IsFriendInLineOfFire (distance)) { - m_fightStyle = 0; - m_lastFightStyleCheck = GetWorldTime (); + m_fightStyle = FIGHT_STRAFE; + m_lastFightStyleCheck = engine.Time (); return; } } - WeaponSelect *selectTab = &g_weaponSelect[0]; + WeaponSelect *tab = &g_weaponSelect[0]; edict_t *enemy = m_enemy; @@ -754,22 +753,22 @@ void Bot::FireWeapon (void) goto WeaponSelectEnd; // 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 && !engine.IsNullEntity (enemy) && pev->health >= enemy->v.health && distance < 100.0f && !IsOnLadder () && !IsGroupOfEnemies (pev->origin)) goto WeaponSelectEnd; // loop through all the weapons until terminator is found... - while (selectTab[selectIndex].id) + while (tab[selectIndex].id) { // is the bot carrying this weapon? - if (weapons & (1 << selectTab[selectIndex].id)) + if (weapons & (1 << tab[selectIndex].id)) { // is enough ammo available to fire AND check is better to use pistol in our current situation... - if (m_ammoInClip[selectTab[selectIndex].id] > 0 && !IsWeaponBadInDistance (selectIndex, distance)) + if (m_ammoInClip[tab[selectIndex].id] > 0 && !IsWeaponBadInDistance (selectIndex, distance)) chosenWeaponIndex = selectIndex; } selectIndex++; } - selectId = selectTab[chosenWeaponIndex].id; + selectId = tab[chosenWeaponIndex].id; // if no available weapon... if (chosenWeaponIndex == 0) @@ -777,21 +776,21 @@ void Bot::FireWeapon (void) selectIndex = 0; // loop through all the weapons until terminator is found... - while (selectTab[selectIndex].id) + while (tab[selectIndex].id) { - int id = selectTab[selectIndex].id; + int id = tab[selectIndex].id; // is the bot carrying this weapon? if (weapons & (1 << id)) { - if ( g_weaponDefs[id].ammo1 != -1 && g_weaponDefs[id].ammo1 < 32 && m_ammo[g_weaponDefs[id].ammo1] >= selectTab[selectIndex].minPrimaryAmmo) + if ( g_weaponDefs[id].ammo1 != -1 && g_weaponDefs[id].ammo1 < 32 && m_ammo[g_weaponDefs[id].ammo1] >= tab[selectIndex].minPrimaryAmmo) { // available ammo found, reload weapon - if (m_reloadState == RELOAD_NONE || m_reloadCheckTime > GetWorldTime ()) + if (m_reloadState == RELOAD_NONE || m_reloadCheckTime > engine.Time ()) { m_isReloading = true; m_reloadState = RELOAD_PRIMARY; - m_reloadCheckTime = GetWorldTime (); + m_reloadCheckTime = engine.Time (); RadioMessage (Radio_NeedBackup); } @@ -809,7 +808,7 @@ WeaponSelectEnd: if (!m_isReloading) { m_reloadState = RELOAD_NONE; - m_reloadCheckTime = GetWorldTime () + 3.0f; + m_reloadCheckTime = engine.Time () + 3.0f; } // select this weapon if it isn't already selected @@ -824,14 +823,14 @@ WeaponSelectEnd: return; } - if (selectTab[chosenWeaponIndex].id != selectId) + if (tab[chosenWeaponIndex].id != selectId) { chosenWeaponIndex = 0; // loop through all the weapons until terminator is found... - while (selectTab[chosenWeaponIndex].id) + while (tab[chosenWeaponIndex].id) { - if (selectTab[chosenWeaponIndex].id == selectId) + if (tab[chosenWeaponIndex].id == selectId) break; chosenWeaponIndex++; @@ -841,17 +840,17 @@ WeaponSelectEnd: // if we're have a glock or famas vary burst fire mode CheckBurstMode (distance); - if (HasShield () && m_shieldCheckTime < GetWorldTime () && GetTaskId () != TASK_CAMP) // better shield gun usage + if (HasShield () && m_shieldCheckTime < engine.Time () && GetTaskId () != TASK_CAMP) // better shield gun usage { if (distance >= 750.0f && !IsShieldDrawn ()) 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 () || (!engine.IsNullEntity (m_enemy) && ((m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable(m_enemy)))) pev->button |= IN_ATTACK2; // draw out the shield - m_shieldCheckTime = GetWorldTime () + 1.0f; + m_shieldCheckTime = engine.Time () + 1.0f; } - if (UsesSniper () && m_zoomCheckTime + 1.0f < GetWorldTime ()) // is the bot holding a sniper rifle? + if (UsesSniper () && m_zoomCheckTime + 1.0f < engine.Time ()) // is the bot holding a sniper rifle? { if (distance > 1500.0f && pev->fov >= 40.0f) // should the bot switch to the long-range zoom? pev->button |= IN_ATTACK2; @@ -862,13 +861,13 @@ WeaponSelectEnd: else if (distance <= 150.0f && pev->fov < 90.0f) // else should the bot restore the normal view ? pev->button |= IN_ATTACK2; - m_zoomCheckTime = GetWorldTime (); + m_zoomCheckTime = engine.Time (); - if (!IsEntityNull (m_enemy) && (m_states & STATE_SEEING_ENEMY)) + if (!engine.IsNullEntity (m_enemy) && (m_states & STATE_SEEING_ENEMY)) { m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); } } else if (m_difficulty < 4 && UsesZoomableRifle ()) // else is the bot holding a zoomable rifle? @@ -879,11 +878,11 @@ WeaponSelectEnd: else if (distance <= 800.0f && pev->fov < 90.0f) // else should the bot restore the normal view? pev->button |= IN_ATTACK2; - m_zoomCheckTime = GetWorldTime (); + m_zoomCheckTime = engine.Time (); } // need to care for burst fire? - if (distance < 256.0f || m_blindTime > GetWorldTime ()) + if (distance < 256.0f || m_blindTime > engine.Time ()) { if (selectId == WEAPON_KNIFE) { @@ -897,7 +896,7 @@ WeaponSelectEnd: } else { - if (selectTab[chosenWeaponIndex].primaryFireHold && m_ammo[g_weaponDefs[selectTab[selectIndex].id].ammo1] > selectTab[selectIndex].minPrimaryAmmo) // if automatic weapon, just press attack + if (tab[chosenWeaponIndex].primaryFireHold && m_ammo[g_weaponDefs[tab[selectIndex].id].ammo1] > tab[selectIndex].minPrimaryAmmo) // if automatic weapon, just press attack pev->button |= IN_ATTACK; else // if not, toggle buttons { @@ -905,7 +904,7 @@ WeaponSelectEnd: pev->button |= IN_ATTACK; } } - m_shootTime = GetWorldTime (); + m_shootTime = engine.Time (); } else { @@ -915,14 +914,14 @@ WeaponSelectEnd: // don't attack with knife over long distance if (selectId == WEAPON_KNIFE) { - m_shootTime = GetWorldTime (); + m_shootTime = engine.Time (); return; } - if (selectTab[chosenWeaponIndex].primaryFireHold) + if (tab[chosenWeaponIndex].primaryFireHold) { - m_shootTime = GetWorldTime (); - m_zoomCheckTime = GetWorldTime (); + m_shootTime = engine.Time (); + m_zoomCheckTime = engine.Time (); pev->button |= IN_ATTACK; // use primary attack } @@ -930,8 +929,8 @@ WeaponSelectEnd: { pev->button |= IN_ATTACK; - m_shootTime = GetWorldTime () + Random.Float (0.15f, 0.35f); - m_zoomCheckTime = GetWorldTime () - 0.09f; + m_shootTime = engine.Time () + Random.Float (0.15f, 0.35f); + m_zoomCheckTime = engine.Time () - 0.09f; } } } @@ -944,9 +943,9 @@ bool Bot::IsWeaponBadInDistance (int weaponIndex, float distance) if (m_difficulty < 2) return false; - int weaponID = g_weaponSelect[weaponIndex].id; + int wid = g_weaponSelect[weaponIndex].id; - if (weaponID == WEAPON_KNIFE) + if (wid == WEAPON_KNIFE) return false; // check is ammo available for secondary weapon @@ -954,11 +953,11 @@ bool Bot::IsWeaponBadInDistance (int weaponIndex, float distance) return false; // better use pistol in short range distances, when using sniper weapons - if ((weaponID == WEAPON_SCOUT || weaponID == WEAPON_AWP || weaponID == WEAPON_G3SG1 || weaponID == WEAPON_SG550) && distance < 500.0f) + if ((wid == WEAPON_SCOUT || wid == WEAPON_AWP || wid == WEAPON_G3SG1 || wid == WEAPON_SG550) && distance < 500.0f) return true; // shotguns is too inaccurate at long distances, so weapon is bad - if ((weaponID == WEAPON_M3 || weaponID == WEAPON_XM1014) && distance > 750.0f) + if ((wid == WEAPON_M3 || wid == WEAPON_XM1014) && distance > 750.0f) return true; return false; @@ -969,7 +968,7 @@ void Bot::FocusEnemy (void) // aim for the head and/or body m_lookAt = GetAimPosition (); - if (m_enemySurpriseTime > GetWorldTime ()) + if (m_enemySurpriseTime > engine.Time ()) return; float distance = (m_lookAt - EyePosition ()).GetLength2D (); // how far away is the enemy scum? @@ -1012,18 +1011,18 @@ void Bot::FocusEnemy (void) void Bot::CombatFight (void) { // no enemy? no need to do strafing - if (IsEntityNull (m_enemy)) + if (engine.IsNullEntity (m_enemy)) return; float distance = (m_lookAt - EyePosition ()).GetLength2D (); // how far away is the enemy scum? - if (m_timeWaypointMove < GetWorldTime ()) + if (m_timeWaypointMove < engine.Time ()) { int approach; if (m_currentWeapon == WEAPON_KNIFE) // knife? approach = 100; - if ((m_states & STATE_SUSPECT_ENEMY) && !(m_states & STATE_SEEING_ENEMY)) // if suspecting enemy stand still + else if ((m_states & STATE_SUSPECT_ENEMY) && !(m_states & STATE_SEEING_ENEMY)) // if suspecting enemy stand still approach = 49; else if (m_isReloading || m_isVIP) // if reloading or vip back off approach = 29; @@ -1056,50 +1055,50 @@ void Bot::CombatFight (void) if (UsesSniper ()) { - m_fightStyle = 1; - m_lastFightStyleCheck = GetWorldTime (); + m_fightStyle = FIGHT_STAY; + m_lastFightStyleCheck = engine.Time (); } else if (UsesRifle () || UsesSubmachineGun ()) { - if (m_lastFightStyleCheck + 3.0f < GetWorldTime ()) + if (m_lastFightStyleCheck + 3.0f < engine.Time ()) { int rand = Random.Long (1, 100); if (distance < 450.0f) - m_fightStyle = 0; + m_fightStyle = FIGHT_STRAFE; else if (distance < 1024.0f) { if (rand < (UsesSubmachineGun () ? 50 : 30)) - m_fightStyle = 0; + m_fightStyle = FIGHT_STRAFE; else - m_fightStyle = 1; + m_fightStyle = FIGHT_STAY; } else { if (rand < (UsesSubmachineGun () ? 80 : 93)) - m_fightStyle = 1; + m_fightStyle = FIGHT_STAY; else - m_fightStyle = 0; + m_fightStyle = FIGHT_STRAFE; } - m_lastFightStyleCheck = GetWorldTime (); + m_lastFightStyleCheck = engine.Time (); } } else { - if (m_lastFightStyleCheck + 3.0f < GetWorldTime ()) + if (m_lastFightStyleCheck + 3.0f < engine.Time ()) { if (Random.Long (0, 100) < 50) - m_fightStyle = 1; + m_fightStyle = FIGHT_STRAFE; else - m_fightStyle = 0; + m_fightStyle = FIGHT_STAY; - m_lastFightStyleCheck = GetWorldTime (); + m_lastFightStyleCheck = engine.Time (); } } - if (m_fightStyle == 0 || ((pev->button & IN_RELOAD) || m_isReloading) || (UsesPistol () && distance < 400.0f) || m_currentWeapon == WEAPON_KNIFE) + if (m_fightStyle == FIGHT_STRAFE || ((pev->button & IN_RELOAD) || m_isReloading) || (UsesPistol () && distance < 400.0f) || m_currentWeapon == WEAPON_KNIFE) { - if (m_strafeSetTime < GetWorldTime ()) + if (m_strafeSetTime < engine.Time ()) { // to start strafing, we have to first figure out if the target is on the left side or right side MakeVectors (m_enemy->v.v_angle); @@ -1108,24 +1107,24 @@ void Bot::CombatFight (void) const Vector &rightSide = g_pGlobals->v_right.Normalize2D (); if ((dirToPoint | rightSide) < 0) - m_combatStrafeDir = 1; + m_combatStrafeDir = STRAFE_DIR_LEFT; else - m_combatStrafeDir = 0; + m_combatStrafeDir = STRAFE_DIR_RIGHT; if (Random.Long (1, 100) < 30) - m_combatStrafeDir ^= 1; + m_combatStrafeDir = (m_combatStrafeDir == STRAFE_DIR_LEFT ? STRAFE_DIR_RIGHT : STRAFE_DIR_LEFT); - m_strafeSetTime = GetWorldTime () + Random.Float (0.5f, 3.0f); + m_strafeSetTime = engine.Time () + Random.Float (0.5f, 3.0f); } - if (m_combatStrafeDir == 0) + if (m_combatStrafeDir == STRAFE_DIR_RIGHT) { if (!CheckWallOnLeft ()) m_strafeSpeed = -pev->maxspeed; else { - m_combatStrafeDir ^= 1; - m_strafeSetTime = GetWorldTime () + 1.0f; + m_combatStrafeDir = STRAFE_DIR_LEFT; + m_strafeSetTime = engine.Time () + 1.5f; } } else @@ -1134,12 +1133,12 @@ void Bot::CombatFight (void) m_strafeSpeed = pev->maxspeed; else { - m_combatStrafeDir ^= 1; - m_strafeSetTime = GetWorldTime () + 1.0f; + m_combatStrafeDir = STRAFE_DIR_RIGHT; + m_strafeSetTime = engine.Time () + 1.5f; } } - if (m_difficulty >= 3 && (m_jumpTime + 5.0f < GetWorldTime () && IsOnFloor () && Random.Long (0, 1000) < (m_isReloading ? 8 : 2) && pev->velocity.GetLength2D () > 150.0f) && !UsesSniper ()) + if (m_difficulty >= 3 && (m_jumpTime + 5.0f < engine.Time () && IsOnFloor () && Random.Long (0, 1000) < (m_isReloading ? 8 : 2) && pev->velocity.GetLength2D () > 150.0f) && !UsesSniper ()) pev->button |= IN_JUMP; if (m_moveSpeed > 0.0f && distance > 100.0f && m_currentWeapon != WEAPON_KNIFE) @@ -1148,18 +1147,18 @@ void Bot::CombatFight (void) if (m_currentWeapon == WEAPON_KNIFE) m_strafeSpeed = 0.0f; } - else if (m_fightStyle == 1) + else if (m_fightStyle == FIGHT_STAY) { - if (!(m_visibility & (VISIBLE_HEAD | VISIBLE_BODY)) && GetTaskId () != TASK_SEEKCOVER && GetTaskId () != TASK_HUNTENEMY && (m_visibility & VISIBLE_BODY) && !(m_visibility & VISIBLE_OTHER) && waypoints.IsDuckVisible (m_currentWaypointIndex, waypoints.FindNearest (m_enemy->v.origin))) - m_duckTime = GetWorldTime () + 0.5f; + if ((m_visibility & (VISIBLE_HEAD | VISIBLE_BODY)) && GetTaskId () != TASK_SEEKCOVER && GetTaskId () != TASK_HUNTENEMY && waypoints.IsDuckVisible (m_currentWaypointIndex, waypoints.FindNearest (m_enemy->v.origin))) + m_duckTime = engine.Time () + 0.5f; m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); } } - if (m_duckTime > GetWorldTime ()) + if (m_duckTime > engine.Time ()) { m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; @@ -1171,7 +1170,7 @@ void Bot::CombatFight (void) if (m_isReloading) { m_moveSpeed = -pev->maxspeed; - m_duckTime = GetWorldTime () - 1.0f; + m_duckTime = engine.Time () - 1.0f; } if (!IsInWater () && !IsOnLadder () && (m_moveSpeed > 0.0f || m_strafeSpeed >= 0.0f)) @@ -1224,7 +1223,7 @@ bool Bot::IsEnemyProtectedByShield (edict_t *enemy) { // this function returns true, if enemy protected by the shield - if (IsEntityNull (enemy) || IsShieldDrawn ()) + if (engine.IsNullEntity (enemy) || IsShieldDrawn ()) return false; // check if enemy has shield and this shield is drawn @@ -1245,19 +1244,19 @@ bool Bot::UsesSniper (void) bool Bot::UsesRifle (void) { - WeaponSelect *selectTab = &g_weaponSelect[0]; + WeaponSelect *tab = &g_weaponSelect[0]; int count = 0; - while (selectTab->id) + while (tab->id) { - if (m_currentWeapon == selectTab->id) + if (m_currentWeapon == tab->id) break; - selectTab++; + tab++; count++; } - if (selectTab->id && count > 13) + if (tab->id && count > 13) return true; return false; @@ -1265,20 +1264,20 @@ bool Bot::UsesRifle (void) bool Bot::UsesPistol (void) { - WeaponSelect *selectTab = &g_weaponSelect[0]; + WeaponSelect *tab = &g_weaponSelect[0]; int count = 0; // loop through all the weapons until terminator is found - while (selectTab->id) + while (tab->id) { - if (m_currentWeapon == selectTab->id) + if (m_currentWeapon == tab->id) break; - selectTab++; + tab++; count++; } - if (selectTab->id && count < 7) + if (tab->id && count < 7) return true; return false; @@ -1331,30 +1330,30 @@ void Bot::SelectBestWeapon (void) if (m_isReloading) return; - WeaponSelect *selectTab = &g_weaponSelect[0]; + WeaponSelect *tab = &g_weaponSelect[0]; int selectIndex = 0; int chosenWeaponIndex = 0; // loop through all the weapons until terminator is found... - while (selectTab[selectIndex].id) + while (tab[selectIndex].id) { // is the bot NOT carrying this weapon? - if (!(pev->weapons & (1 << selectTab[selectIndex].id))) + if (!(pev->weapons & (1 << tab[selectIndex].id))) { selectIndex++; // skip to next weapon continue; } - int id = selectTab[selectIndex].id; + int id = tab[selectIndex].id; bool ammoLeft = false; // is the bot already holding this weapon and there is still ammo in clip? - if (selectTab[selectIndex].id == m_currentWeapon && (GetAmmoInClip () < 0 || GetAmmoInClip () >= selectTab[selectIndex].minPrimaryAmmo)) + if (tab[selectIndex].id == m_currentWeapon && (GetAmmoInClip () < 0 || GetAmmoInClip () >= tab[selectIndex].minPrimaryAmmo)) ammoLeft = true; // is no ammo required for this weapon OR enough ammo available to fire - if (g_weaponDefs[id].ammo1 < 0 || (g_weaponDefs[id].ammo1 < 32 && m_ammo[g_weaponDefs[id].ammo1] >= selectTab[selectIndex].minPrimaryAmmo)) + if (g_weaponDefs[id].ammo1 < 0 || (g_weaponDefs[id].ammo1 < 32 && m_ammo[g_weaponDefs[id].ammo1] >= tab[selectIndex].minPrimaryAmmo)) ammoLeft = true; if (ammoLeft) @@ -1366,11 +1365,11 @@ void Bot::SelectBestWeapon (void) chosenWeaponIndex %= NUM_WEAPONS + 1; selectIndex = chosenWeaponIndex; - int id = selectTab[selectIndex].id; + int id = tab[selectIndex].id; // select this weapon if it isn't already selected if (m_currentWeapon != id) - SelectWeaponByName (selectTab[selectIndex].weaponName); + SelectWeaponByName (tab[selectIndex].weaponName); m_isReloading = false; m_reloadState = RELOAD_NONE; @@ -1388,33 +1387,33 @@ void Bot::SelectPistol (void) int Bot::GetHighestWeapon (void) { - WeaponSelect *selectTab = &g_weaponSelect[0]; + WeaponSelect *tab = &g_weaponSelect[0]; int weapons = pev->weapons; int num = 0; int i = 0; // loop through all the weapons until terminator is found... - while (selectTab->id) + while (tab->id) { // is the bot carrying this weapon? - if (weapons & (1 << selectTab->id)) + if (weapons & (1 << tab->id)) num = i; i++; - selectTab++; + tab++; } return num; } void Bot::SelectWeaponByName (const char *name) { - FakeClientCommand (GetEntity (), name); + engine.IssueBotCommand (GetEntity (), name); } void Bot::SelectWeaponbyNumber (int num) { - FakeClientCommand (GetEntity (), g_weaponSelect[num].weaponName); + engine.IssueBotCommand (GetEntity (), g_weaponSelect[num].weaponName); } void Bot::AttachToUser (void) @@ -1423,7 +1422,7 @@ void Bot::AttachToUser (void) Array foundUsers; // search friends near us - for (int i = 0; i < GetMaxClients (); 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 ()) continue; @@ -1444,14 +1443,14 @@ void Bot::AttachToUser (void) void Bot::CommandTeam (void) { // prevent spamming - if (m_timeTeamOrder > GetWorldTime () + 2 || yb_csdm_mode.GetInt () == 2 || yb_communication_type.GetInt () == 0) + if (m_timeTeamOrder > engine.Time () + 2 || yb_csdm_mode.GetInt () == 2 || yb_communication_type.GetInt () == 0) return; bool memberNear = false; bool memberExists = false; // search teammates seen by this bot - for (int i = 0; i < GetMaxClients (); 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 ()) continue; @@ -1477,7 +1476,7 @@ void Bot::CommandTeam (void) else if (memberExists && yb_communication_type.GetInt () == 2) ChatterMessage(Chatter_ScaredEmotion); - m_timeTeamOrder = GetWorldTime () + Random.Float (5.0f, 30.0f); + m_timeTeamOrder = engine.Time () + Random.Float (5.0f, 30.0f); } bool Bot::IsGroupOfEnemies (const Vector &location, int numEnemies, int radius) @@ -1485,7 +1484,7 @@ bool Bot::IsGroupOfEnemies (const Vector &location, int numEnemies, int radius) int numPlayers = 0; // search the world for enemy players... - for (int i = 0; i < GetMaxClients (); 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].ent == GetEntity ()) continue; @@ -1513,7 +1512,7 @@ void Bot::CheckReload (void) } m_isReloading = false; // update reloading status - m_reloadCheckTime = GetWorldTime () + 3.0f; + m_reloadCheckTime = engine.Time () + 3.0f; if (m_reloadState != RELOAD_NONE) { @@ -1620,7 +1619,7 @@ void Bot::CheckReload (void) else { // if we have enemy don't reload next weapon - if ((m_states & (STATE_SEEING_ENEMY | STATE_HEARING_ENEMY)) || m_seeEnemyTime + 5.0f > GetWorldTime ()) + if ((m_states & (STATE_SEEING_ENEMY | STATE_HEARING_ENEMY)) || m_seeEnemyTime + 5.0f > engine.Time ()) { m_reloadState = RELOAD_NONE; return; diff --git a/source/engine.cpp b/source/engine.cpp new file mode 100644 index 0000000..f77db7d --- /dev/null +++ b/source/engine.cpp @@ -0,0 +1,1062 @@ +// +// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). +// Copyright (c) YaPB Development Team. +// +// This software is licensed under the BSD-style license. +// Additional exceptions apply. For full license details, see LICENSE.txt or visit: +// http://yapb.jeefo.net/license +// + +#include + +Engine::Engine (void) +{ + m_startEntity = NULL; + m_localEntity = NULL; + + m_language.RemoveAll (); + ResetMessageCapture (); + + for (int i = 0; i < NETMSG_NUM; i++) + m_msgBlock.regMsgs[i] = NETMSG_UNDEFINED; + + m_isBotCommand = false; + m_argumentCount = 0; + memset (m_arguments, 0, sizeof (m_arguments)); + + m_cvars.RemoveAll (); + m_language.RemoveAll (); +} + +Engine::~Engine (void) +{ + TerminateTranslator (); + ResetMessageCapture (); + + for (int i = 0; i < NETMSG_NUM; i++) + m_msgBlock.regMsgs[i] = NETMSG_UNDEFINED; +} + +void Engine::Precache (edict_t *startEntity) +{ + // this function precaches needed models and initialize class variables + + m_drawModels[DRAW_SIMPLE] = PRECACHE_MODEL (ENGINE_STR ("sprites/laserbeam.spr")); + m_drawModels[DRAW_ARROW] = PRECACHE_MODEL (ENGINE_STR ("sprites/arrow1.spr")); + + m_localEntity = NULL; + m_startEntity = startEntity; +} + +void Engine::Printf (const char *fmt, ...) +{ + // this function outputs string into server console + + va_list ap; + char string[MAX_PRINT_BUFFER]; + + va_start (ap, fmt); + vsnprintf (string, SIZEOF_CHAR (string), TraslateMessage (fmt), ap); + va_end (ap); + + strcat (string, "\n"); + g_engfuncs.pfnServerPrint (string); +} + +void Engine::ChatPrintf (const char *fmt, ...) +{ + va_list ap; + char string[MAX_PRINT_BUFFER]; + + va_start (ap, fmt); + vsnprintf (string, SIZEOF_CHAR (string), TraslateMessage (fmt), ap); + va_end (ap); + + if (IsDedicatedServer ()) + { + Printf (string); + return; + } + strcat (string, "\n"); + + MESSAGE_BEGIN (MSG_BROADCAST, FindMessageId (NETMSG_TEXTMSG)); + WRITE_BYTE (HUD_PRINTTALK); + WRITE_STRING (string); + MESSAGE_END (); +} + +void Engine::CenterPrintf (const char *fmt, ...) +{ + va_list ap; + char string[MAX_PRINT_BUFFER]; + + va_start (ap, fmt); + vsnprintf (string, SIZEOF_CHAR (string), TraslateMessage (fmt), ap); + va_end (ap); + + if (IsDedicatedServer ()) + { + Printf (string); + return; + } + strcat (string, "\n"); + + MESSAGE_BEGIN (MSG_BROADCAST, FindMessageId (NETMSG_TEXTMSG)); + WRITE_BYTE (HUD_PRINTCENTER); + WRITE_STRING (string); + MESSAGE_END (); +} + +void Engine::ClientPrintf (edict_t *ent, const char *fmt, ...) +{ + va_list ap; + char string[MAX_PRINT_BUFFER]; + + va_start (ap, fmt); + vsnprintf (string, SIZEOF_CHAR (string), TraslateMessage (fmt), ap); + va_end (ap); + + if (IsNullEntity (ent) || ent == g_hostEntity) + { + Printf (string); + return; + } + strcat (string, "\n"); + g_engfuncs.pfnClientPrintf (ent, print_console, string); +} + +void Engine::DrawLine (edict_t * ent, const Vector &start, const Vector &end, int width, int noise, int red, int green, int blue, int brightness, int speed, int life, DrawLineType type) +{ + // this function draws a arrow visible from the client side of the player whose player entity + // is pointed to by ent, from the vector location start to the vector location end, + // which is supposed to last life tenths seconds, and having the color defined by RGB. + + if (!IsValidPlayer (ent)) + return; // reliability check + + MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, ent); + WRITE_BYTE (TE_BEAMPOINTS); + WRITE_COORD (end.x); + WRITE_COORD (end.y); + WRITE_COORD (end.z); + WRITE_COORD (start.x); + WRITE_COORD (start.y); + WRITE_COORD (start.z); + WRITE_SHORT (m_drawModels[type]); + WRITE_BYTE (0); // framestart + WRITE_BYTE (10); // framerate + WRITE_BYTE (life); // life in 0.1's + WRITE_BYTE (width); // width + WRITE_BYTE (noise); // noise + + WRITE_BYTE (red); // r, g, b + WRITE_BYTE (green); // r, g, b + WRITE_BYTE (blue); // r, g, b + + WRITE_BYTE (brightness); // brightness + WRITE_BYTE (speed); // speed + MESSAGE_END (); +} + +void Engine::TestLine (const Vector &start, const Vector &end, int ignoreFlags, edict_t *ignoreEntity, TraceResult *ptr) +{ + // this function traces a line dot by dot, starting from vecStart in the direction of vecEnd, + // ignoring or not monsters (depending on the value of IGNORE_MONSTERS, true or false), and stops + // at the first obstacle encountered, returning the results of the trace in the TraceResult structure + // ptr. Such results are (amongst others) the distance traced, the hit surface, the hit plane + // vector normal, etc. See the TraceResult structure for details. This function allows to specify + // whether the trace starts "inside" an entity's polygonal model, and if so, to specify that entity + // in ignoreEntity in order to ignore it as a possible obstacle. + + int engineFlags = 0; + + if (ignoreFlags & TRACE_IGNORE_MONSTERS) + engineFlags = 1; + + if (ignoreFlags & TRACE_IGNORE_GLASS) + engineFlags |= 0x100; + + g_engfuncs.pfnTraceLine (start, end, engineFlags, ignoreEntity, ptr); +} + +void Engine::TestHull (const Vector &start, const Vector &end, int ignoreFlags, int hullNumber, edict_t *ignoreEntity, TraceResult *ptr) +{ + // this function traces a hull dot by dot, starting from vecStart in the direction of vecEnd, + // ignoring or not monsters (depending on the value of IGNORE_MONSTERS, true or + // false), and stops at the first obstacle encountered, returning the results + // of the trace in the TraceResult structure ptr, just like TraceLine. Hulls that can be traced + // (by parameter hull_type) are point_hull (a line), head_hull (size of a crouching player), + // human_hull (a normal body size) and large_hull (for monsters?). Not all the hulls in the + // game can be traced here, this function is just useful to give a relative idea of spatial + // reachability (i.e. can a hostage pass through that tiny hole ?) Also like TraceLine, this + // function allows to specify whether the trace starts "inside" an entity's polygonal model, + // and if so, to specify that entity in ignoreEntity in order to ignore it as an obstacle. + + (*g_engfuncs.pfnTraceHull) (start, end, (ignoreFlags & TRACE_IGNORE_MONSTERS), hullNumber, ignoreEntity, ptr); +} + +float Engine::GetWaveLength (const char *fileName) +{ + extern ConVar yb_chatter_path; + const char *filePath = FormatBuffer ("%s/%s/%s.wav", GetModName (), yb_chatter_path.GetString (), fileName); + + File fp (filePath, "rb"); + + // we're got valid handle? + if (!fp.IsValid ()) + return 0.0f; + + // check if we have engine function for this + if (g_engfuncs.pfnGetApproxWavePlayLen != NULL) + { + fp.Close (); + return g_engfuncs.pfnGetApproxWavePlayLen (filePath) / 1000.0f; + } + + // else fuck with manual search + struct WavHeader + { + char riffChunkId[4]; + unsigned long packageSize; + char chunkID[4]; + char formatChunkId[4]; + unsigned long formatChunkLength; + unsigned short dummy; + unsigned short channels; + unsigned long sampleRate; + unsigned long bytesPerSecond; + unsigned short bytesPerSample; + unsigned short bitsPerSample; + char dataChunkId[4]; + unsigned long dataChunkLength; + } waveHdr; + + memset (&waveHdr, 0, sizeof (waveHdr)); + + if (fp.Read (&waveHdr, sizeof (WavHeader)) == 0) + { + AddLogEntry (true, LL_ERROR, "Wave File %s - has wrong or unsupported format", filePath); + return 0.0f; + } + + if (strncmp (waveHdr.chunkID, "WAVE", 4) != 0) + { + AddLogEntry (true, LL_ERROR, "Wave File %s - has wrong wave chunk id", filePath); + return 0.0f; + } + fp.Close (); + + if (waveHdr.dataChunkLength == 0) + { + AddLogEntry (true, LL_ERROR, "Wave File %s - has zero length!", filePath); + return 0.0f; + } + return static_cast (waveHdr.dataChunkLength) / static_cast (waveHdr.bytesPerSecond); +} + +bool Engine::IsDedicatedServer (void) +{ + // return true if server is dedicated server, false otherwise + static bool dedicated = g_engfuncs.pfnIsDedicatedServer () > 0; + + return dedicated; +} + +const char *Engine::GetModName (void) +{ + // this function returns mod name without path + + static char engineModName[256]; + + g_engfuncs.pfnGetGameDir (engineModName); + int length = strlen (engineModName); + + int stop = length - 1; + while ((engineModName[stop] == '\\' || engineModName[stop] == '/') && stop > 0) + stop--; + + int start = stop; + while (engineModName[start] != '\\' && engineModName[start] != '/' && start > 0) + start--; + + if (engineModName[start] == '\\' || engineModName[start] == '/') + start++; + + for (length = start; length <= stop; length++) + engineModName[length - start] = engineModName[length]; + + engineModName[length - start] = 0; // terminate the string + + return &engineModName[0]; +} + +const char *Engine::GetMapName (void) +{ + // this function gets the map name and store it in the map_name global string variable. + + static char engineMap[256]; + strncpy (engineMap, const_cast (g_pGlobals->pStringBase + static_cast (g_pGlobals->mapname)), SIZEOF_CHAR (engineMap)); + + return &engineMap[0]; +} + +Vector Engine::GetAbsOrigin (edict_t *ent) +{ + // 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. + + if (IsNullEntity (ent)) + return Vector::GetZero (); + + if (ent->v.origin.IsZero ()) + return ent->v.absmin + ent->v.size * 0.5f; + + return ent->v.origin; +} + +void Engine::RegisterCmd (const char * command, void func (void)) +{ + // this function tells the engine that a new server command is being declared, in addition + // to the standard ones, whose name is command_name. The engine is thus supposed to be aware + // that for every "command_name" server command it receives, it should call the function + // pointed to by "function" in order to handle it. + + g_engfuncs.pfnAddServerCommand (const_cast (command), func); +} + +void Engine::EmitSound (edict_t *ent, const char *sound) +{ + 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] = 0x0; + 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] = 0x0; + m_argumentCount = 0; +} + +const char *Engine::ExtractSingleField (const char *string, int id, bool terminate) +{ + // this function gets and returns a particular field in a string where several strings are concatenated + + static char field[256]; + field[0] = 0x0; + + 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, ...) +{ + // this function asks the engine to execute a server command + + va_list ap; + char string[MAX_PRINT_BUFFER]; + + // concatenate all the arguments in one string + va_start (ap, fmt); + vsnprintf (string, SIZEOF_CHAR (string), fmt, ap); + va_end (ap); + + strcat (string, "\n"); + g_engfuncs.pfnServerCommand (string); +} + +void Engine::PushVariableToStack (const char *variable, const char *value, VarType varType, bool regMissing, ConVar *self) +{ + // this function adds globally defined variable to registration stack + + VarPair pair; + memset (&pair, 0, sizeof (VarPair)); + + pair.reg.name = const_cast (variable); + pair.reg.string = const_cast (value); + pair.regMissing = regMissing; + + 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; + + pair.reg.flags = engineFlags; + pair.self = self; + pair.type = varType; + + m_cvars.Push (pair); +} + +void Engine::PushRegisteredConVarsToEngine (bool gameVars) +{ + // this function pushes all added global variables to engine registration + + FOR_EACH_AE (m_cvars, i) + { + VarPair *ptr = &m_cvars[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); + + if (ptr->regMissing && ptr->self->m_eptr == NULL) + { + g_engfuncs.pfnCVarRegister (&ptr->reg); + ptr->self->m_eptr = g_engfuncs.pfnCVarGetPointer (ptr->reg.name); + } + InternalAssert (ptr->self->m_eptr != NULL); // ensure game var exists + } + } +} + +char *Engine::TraslateMessage (const char *input) +{ + // this function translate input string into needed language + + if (IsDedicatedServer ()) + return const_cast (&input[0]); + + static char string[MAX_PRINT_BUFFER]; + const char *ptr = input + strlen (input) - 1; + + while (ptr > input && *ptr == '\n') + ptr--; + + if (ptr != input) + ptr++; + + strncpy (string, input, SIZEOF_CHAR (string)); + String::TrimExternalBuffer (string); + + FOR_EACH_AE (m_language, i) + { + if (strcmp (string, m_language[i].original) == 0) + { + strncpy (string, m_language[i].translated, SIZEOF_CHAR (string)); + + if (ptr != input) + strncat (string, ptr, MAX_PRINT_BUFFER - 1 - strlen (string)); + + return &string[0]; + } + } + return const_cast (&input[0]); // nothing found +} + +void Engine::TerminateTranslator (void) +{ + // this function terminates language translator and frees all memory + + FOR_EACH_AE (m_language, it) + { + delete[] m_language[it].original; + delete[] m_language[it].translated; + } + m_language.RemoveAll (); +} + +void Engine::ProcessMessageCapture (void *ptr) +{ + if (m_msgBlock.msg == NETMSG_UNDEFINED) + return; + + // some needed variables + static byte r, g, b; + static byte enabled; + + static int damageArmor, damageTaken, damageBits; + static int killerIndex, victimIndex, playerIndex; + static int index, numPlayers; + static int state, id, clip; + + static Vector damageOrigin; + static WeaponProperty weaponProp; + + // some widely used stuff + Bot *bot = bots.GetBot (m_msgBlock.bot); + + char *strVal = reinterpret_cast (ptr); + int intVal = *reinterpret_cast (ptr); + unsigned char byteVal = *reinterpret_cast (ptr); + + // now starts of network message execution + switch (m_msgBlock.msg) + { + case NETMSG_VGUI: + // this message is sent when a VGUI menu is displayed. + + if (m_msgBlock.state == 0) + { + switch (intVal) + { + case VMS_TEAM: + bot->m_startAction = GSM_TEAM_SELECT; + break; + + case VMS_TF: + case VMS_CT: + bot->m_startAction = GSM_CLASS_SELECT; + break; + } + } + break; + + case NETMSG_SHOWMENU: + // this message is sent when a text menu is displayed. + + if (m_msgBlock.state < 3) // ignore first 3 fields of message + break; + + if (strcmp (strVal, "#Team_Select") == 0) // team select menu? + bot->m_startAction = GSM_TEAM_SELECT; + else if (strcmp (strVal, "#Team_Select_Spect") == 0) // team select menu? + bot->m_startAction = GSM_TEAM_SELECT; + else if (strcmp (strVal, "#IG_Team_Select_Spect") == 0) // team select menu? + bot->m_startAction = GSM_TEAM_SELECT; + else if (strcmp (strVal, "#IG_Team_Select") == 0) // team select menu? + bot->m_startAction = GSM_TEAM_SELECT; + else if (strcmp (strVal, "#IG_VIP_Team_Select") == 0) // team select menu? + bot->m_startAction = GSM_TEAM_SELECT; + else if (strcmp (strVal, "#IG_VIP_Team_Select_Spect") == 0) // team select menu? + bot->m_startAction = GSM_TEAM_SELECT; + else if (strcmp (strVal, "#Terrorist_Select") == 0) // T model select? + bot->m_startAction = GSM_CLASS_SELECT; + else if (strcmp (strVal, "#CT_Select") == 0) // CT model select menu? + bot->m_startAction = GSM_CLASS_SELECT; + + break; + + case NETMSG_WEAPONLIST: + // this message is sent when a client joins the game. All of the weapons are sent with the weapon ID and information about what ammo is used. + + switch (m_msgBlock.state) + { + case 0: + strncpy (weaponProp.className, strVal, SIZEOF_CHAR (weaponProp.className)); + break; + + case 1: + weaponProp.ammo1 = intVal; // ammo index 1 + break; + + case 2: + weaponProp.ammo1Max = intVal; // max ammo 1 + break; + + case 5: + weaponProp.slotID = intVal; // slot for this weapon + break; + + case 6: + weaponProp.position = intVal; // position in slot + break; + + case 7: + weaponProp.id = intVal; // weapon ID + break; + + case 8: + weaponProp.flags = intVal; // flags for weapon (WTF???) + g_weaponDefs[weaponProp.id] = weaponProp; // store away this weapon with it's ammo information... + break; + } + break; + + case NETMSG_CURWEAPON: + // this message is sent when a weapon is selected (either by the bot chosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased + + switch (m_msgBlock.state) + { + case 0: + state = intVal; // state of the current weapon (WTF???) + break; + + case 1: + id = intVal; // weapon ID of current weapon + break; + + case 2: + clip = intVal; // ammo currently in the clip for this weapon + + if (id <= 31) + { + if (state != 0) + bot->m_currentWeapon = id; + + // ammo amount decreased ? must have fired a bullet... + if (id == bot->m_currentWeapon && bot->m_ammoInClip[id] > clip) + bot->m_timeLastFired = Time (); // remember the last bullet time + + bot->m_ammoInClip[id] = clip; + } + break; + } + break; + + case NETMSG_AMMOX: + // this message is sent whenever ammo amounts are adjusted (up or down). NOTE: Logging reveals that CS uses it very unreliable! + + switch (m_msgBlock.state) + { + case 0: + index = intVal; // ammo index (for type of ammo) + break; + + case 1: + bot->m_ammo[index] = intVal; // store it away + break; + } + break; + + case NETMSG_AMMOPICKUP: + // this message is sent when the bot picks up some ammo (AmmoX messages are also sent so this message is probably + // not really necessary except it allows the HUD to draw pictures of ammo that have been picked up. The bots + // don't really need pictures since they don't have any eyes anyway. + + switch (m_msgBlock.state) + { + case 0: + index = intVal; + break; + + case 1: + bot->m_ammo[index] = intVal; + break; + } + break; + + case NETMSG_DAMAGE: + // this message gets sent when the bots are getting damaged. + + switch (m_msgBlock.state) + { + case 0: + damageArmor = intVal; + break; + + case 1: + damageTaken = intVal; + break; + + case 2: + damageBits = intVal; + + if (bot != NULL && (damageArmor > 0 || damageTaken > 0)) + bot->TakeDamage (bot->pev->dmg_inflictor, damageTaken, damageArmor, damageBits); + break; + } + break; + + case NETMSG_MONEY: + // this message gets sent when the bots money amount changes + + if (m_msgBlock.state == 0) + bot->m_moneyAmount = intVal; // amount of money + break; + + case NETMSG_STATUSICON: + switch (m_msgBlock.state) + { + case 0: + enabled = byteVal; + break; + + case 1: + if (strcmp (strVal, "defuser") == 0) + bot->m_hasDefuser = (enabled != 0); + else if (strcmp (strVal, "buyzone") == 0) + { + bot->m_inBuyZone = (enabled != 0); + + // try to equip in buyzone + bot->EquipInBuyzone (BUYSTATE_PRIMARY_WEAPON); + } + else if (strcmp (strVal, "vipsafety") == 0) + bot->m_inVIPZone = (enabled != 0); + else if (strcmp (strVal, "c4") == 0) + bot->m_inBombZone = (enabled == 2); + + break; + } + break; + + case NETMSG_DEATH: // this message sends on death + switch (m_msgBlock.state) + { + case 0: + killerIndex = intVal; + break; + + case 1: + victimIndex = intVal; + break; + + case 2: + bots.SetDeathMsgState (true); + + if (killerIndex != 0 && killerIndex != victimIndex) + { + edict_t *killer = EntityOfIndex (killerIndex); + edict_t *victim = EntityOfIndex (victimIndex); + + if (IsNullEntity (killer) || IsNullEntity (victim)) + break; + + if (yb_communication_type.GetInt () == 2) + { + // need to send congrats on well placed shot + for (int i = 0; i < MaxClients (); i++) + { + Bot *bot = bots.GetBot (i); + + if (bot != NULL && bot->m_notKilled && killer != bot->GetEntity () && bot->EntityIsVisible (victim->v.origin) && GetTeam (killer) == bot->m_team && GetTeam (killer) != GetTeam (victim)) + { + if (killer == g_hostEntity) + bot->HandleChatterMessage ("#Bot_NiceShotCommander"); + else + bot->HandleChatterMessage ("#Bot_NiceShotPall"); + + break; + } + } + } + + // notice nearby to victim teammates, that attacker is near + for (int i = 0; i < MaxClients (); i++) + { + Bot *bot = bots.GetBot (i); + + if (bot != NULL && bot->m_seeEnemyTime + 2.0f < Time () && bot->m_notKilled && bot->m_team == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && IsNullEntity (bot->m_enemy) && GetTeam (killer) != GetTeam (victim)) + { + bot->m_actualReactionTime = 0.0f; + bot->m_seeEnemyTime = Time (); + bot->m_enemy = killer; + bot->m_lastEnemy = killer; + bot->m_lastEnemyOrigin = killer->v.origin; + } + } + + Bot *bot = bots.GetBot (killer); + + // is this message about a bot who killed somebody? + if (bot != NULL) + bot->m_lastVictim = victim; + + else // did a human kill a bot on his team? + { + Bot *target = bots.GetBot (victim); + + if (target != NULL) + { + if (GetTeam (killer) == GetTeam (victim)) + target->m_voteKickIndex = killerIndex; + + target->m_notKilled = false; + } + } + } + break; + } + break; + + case NETMSG_SCREENFADE: // this message gets sent when the screen fades (flashbang) + switch (m_msgBlock.state) + { + case 3: + r = byteVal; + break; + + case 4: + g = byteVal; + break; + + case 5: + b = byteVal; + break; + + case 6: + bot->TakeBlinded (r, g, b, byteVal); + break; + } + break; + + case NETMSG_HLTV: // round restart in steam cs + switch (m_msgBlock.state) + { + case 0: + numPlayers = intVal; + break; + + case 1: + if (numPlayers == 0 && intVal == 0) + RoundInit (); + break; + } + break; + + + case NETMSG_TEXTMSG: + if (m_msgBlock.state == 1) + { + if (FStrEq (strVal, "#CTs_Win") || + FStrEq (strVal, "#Bomb_Defused") || + FStrEq (strVal, "#Terrorists_Win") || + FStrEq (strVal, "#Round_Draw") || + FStrEq (strVal, "#All_Hostages_Rescued") || + FStrEq (strVal, "#Target_Saved") || + FStrEq (strVal, "#Hostages_Not_Rescued") || + FStrEq (strVal, "#Terrorists_Not_Escaped") || + FStrEq (strVal, "#VIP_Not_Escaped") || + FStrEq (strVal, "#Escaping_Terrorists_Neutralized") || + FStrEq (strVal, "#VIP_Assassinated") || + FStrEq (strVal, "#VIP_Escaped") || + FStrEq (strVal, "#Terrorists_Escaped") || + FStrEq (strVal, "#CTs_PreventEscape") || + FStrEq (strVal, "#Target_Bombed") || + FStrEq (strVal, "#Game_Commencing") || + FStrEq (strVal, "#Game_will_restart_in")) + { + g_roundEnded = true; + + if (FStrEq (strVal, "#Game_Commencing")) + g_isCommencing = true; + + if (FStrEq (strVal, "#CTs_Win")) + { + bots.SetLastWinner (CT); // update last winner for economics + + if (yb_communication_type.GetInt () == 2) + { + Bot *bot = bots.FindOneValidAliveBot (); + + if (bot != NULL && bot->m_notKilled) + bot->HandleChatterMessage (strVal); + } + } + + if (FStrEq (strVal, "#Game_will_restart_in")) + { + bots.CheckTeamEconomics (CT, true); + bots.CheckTeamEconomics (TERRORIST, true); + } + + if (FStrEq (strVal, "#Terrorists_Win")) + { + bots.SetLastWinner (TERRORIST); // update last winner for economics + + if (yb_communication_type.GetInt () == 2) + { + Bot *bot = bots.FindOneValidAliveBot (); + + if (bot != NULL && bot->m_notKilled) + bot->HandleChatterMessage (strVal); + } + } + waypoints.SetBombPosition (true); + } + else if (!g_bombPlanted && FStrEq (strVal, "#Bomb_Planted")) + { + g_bombPlanted = g_bombSayString = true; + g_timeBombPlanted = Time (); + + for (int i = 0; i < MaxClients (); i++) + { + Bot *bot = bots.GetBot (i); + + if (bot != NULL && bot->m_notKilled) + { + bot->DeleteSearchNodes (); + bot->ResetTasks (); + + if (yb_communication_type.GetInt () == 2 && Random.Long (0, 100) < 75 && bot->m_team == CT) + bot->ChatterMessage (Chatter_WhereIsTheBomb); + } + } + waypoints.SetBombPosition (); + } + else if (bot != NULL && FStrEq (strVal, "#Switch_To_BurstFire")) + bot->m_weaponBurstMode = BM_ON; + else if (bot != NULL && FStrEq (strVal, "#Switch_To_SemiAuto")) + bot->m_weaponBurstMode = BM_OFF; + } + break; + + case NETMSG_SCOREINFO: + switch (m_msgBlock.state) + { + case 0: + playerIndex = intVal; + break; + + case 4: + if (playerIndex >= 0 && playerIndex <= MaxClients ()) + { +#ifndef XASH_CSDM + Client &client = g_clients[playerIndex - 1]; + + if (intVal == 1) + client.team2 = TERRORIST; + else if (intVal == 2) + client.team2 = CT; + else + client.team2 = SPECTATOR; + + if (yb_csdm_mode.GetInt () == 2) + client.team = playerIndex; + else + client.team = client.team2; +#endif + } + break; + } + break; + + case NETMSG_BARTIME: + if (m_msgBlock.state == 0) + { + if (intVal > 0) + bot->m_hasProgressBar = true; // the progress bar on a hud + else if (intVal == 0) + bot->m_hasProgressBar = false; // no progress bar or disappeared + } + break; + + default: + AddLogEntry (true, LL_FATAL, "Network message handler error. Call to unrecognized message id (%d).\n", m_msgBlock.msg); + } + m_msgBlock.state++; // and finally update network message state +} + +ConVar::ConVar (const char *name, const char *initval, VarType type, bool regMissing) : m_eptr (NULL) +{ + engine.PushVariableToStack (name, initval, type, regMissing, this); +} diff --git a/source/globals.cpp b/source/globals.cpp index 0b6b886..6f4415e 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -9,6 +9,13 @@ #include +// forward for super-globals +//NetworkMsg netmsg; +//Localizer locale; +//Waypoint waypoints; +//BotManager bots; +//Engine engine; + bool g_canSayBombPlanted = true; bool g_isMetamod = false; bool g_radioInsteadVoice = false; @@ -19,7 +26,6 @@ bool g_bombPlanted = false; bool g_bombSayString = false; bool g_isCommencing = false; bool g_editNoclip = false; -bool g_isFakeCommand = false; bool g_waypointOn = false; bool g_waypointsChanged = true; bool g_autoWaypoint = false; @@ -38,8 +44,7 @@ float g_autoPathDistance = 250.0f; int g_lastRadio[2]; int g_storeAddbotVars[4]; -int g_radioSelect[32]; -int g_fakeArgc = 0; +int g_radioSelect[MAX_ENGINE_PLAYERS]; int g_gameFlags = 0; int g_numWaypoints = 0; int g_mapType = 0; @@ -48,9 +53,6 @@ int g_highestDamageCT = 1; int g_highestDamageT = 1; int g_highestKills = 1; -short g_modelIndexLaser = 0; -short g_modelIndexArrow = 0; -char g_fakeArgv[256]; Array > g_chatFactory; Array > g_chatterFactory; @@ -70,10 +72,9 @@ BlendAPI_t g_serverBlendingAPI = NULL; FuncPointers_t g_funcPointers = NULL; enginefuncs_t g_engfuncs; -Client g_clients[32]; +Client g_clients[MAX_ENGINE_PLAYERS]; WeaponProperty g_weaponDefs[MAX_WEAPONS + 1]; -edict_t *g_worldEntity = NULL; edict_t *g_hostEntity = NULL; globalvars_t *g_pGlobals = NULL; Experience *g_experienceData = NULL; @@ -104,10 +105,10 @@ int *g_weaponPrefs[] = // metamod engine & dllapi function tables metamod_funcs_t gMetaFunctionTable = { - NULL, // pfnEntityAPI_t () - NULL, // pfnEntityAPI_t_Post () - GetEntityAPI2, // pfnEntityAPI_t2 () - GetEntityAPI2_Post, // pfnEntityAPI_t2_Post () + NULL, // pfnGetEntityAPI () + NULL, // pfnGetEntityAPI_Post () + GetEntityAPI2, // pfnGetEntityAPI2 () + GetEntityAPI2_Post, // pfnGetEntityAPI2_Post () NULL, // pfnGetNewDLLFunctions () NULL, // pfnGetNewDLLFunctions_Post () GetEngineFunctions, // pfnGetEngineFunctions () @@ -429,4 +430,4 @@ MenuText g_menus[21] = "3. Bidirectional (Both Ways)\v\v" "0. Exit" } -}; \ No newline at end of file +}; diff --git a/source/interface.cpp b/source/interface.cpp index 897177c..75671b4 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -1,4 +1,4 @@ -// +// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // @@ -81,7 +81,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c if (selection >= 1 && selection <= 7) bots.SetWeaponMode (selection); else - ClientPrint (ent, print_withtag, "Choose weapon from 1 to 7 range"); + engine.ClientPrintf (ent, "Choose weapon from 1 to 7 range"); } // force all bots to vote to specified map @@ -92,12 +92,14 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c int nominatedMap = atoi (arg1); // loop through all players - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - if (bots.GetBot (i) != NULL) - bots.GetBot (i)->m_voteMap = nominatedMap; + Bot *bot = bots.GetBot (i); + + if (bot != NULL) + bot->m_voteMap = nominatedMap; } - ClientPrint (ent, print_withtag, "All dead bots will vote for map #%d", nominatedMap); + engine.ClientPrintf (ent, "All dead bots will vote for map #%d", nominatedMap); } } @@ -113,68 +115,67 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c "Git Commit Author: %s\n" "------------------------------------------------"; - ClientPrint (ent, print_console, versionData, PRODUCT_NAME, PRODUCT_VERSION, GenerateBuildNumber (), __DATE__, __TIME__, PRODUCT_GIT_HASH, PRODUCT_GIT_COMMIT_AUTHOR); + engine.ClientPrintf (ent, versionData, PRODUCT_NAME, PRODUCT_VERSION, GenerateBuildNumber (), __DATE__, __TIME__, PRODUCT_GIT_HASH, PRODUCT_GIT_COMMIT_AUTHOR); } // display some sort of help information else if (stricmp (arg0, "?") == 0 || stricmp (arg0, "help") == 0) { - ClientPrint (ent, print_console, "Bot Commands:"); - ClientPrint (ent, print_console, "%s version\t - display version information.", self); - ClientPrint (ent, print_console, "%s add\t - create a bot in current game.", self); - ClientPrint (ent, print_console, "%s fill\t - fill the server with random bots.", self); - ClientPrint (ent, print_console, "%s kickall\t - disconnects all bots from current game.", self); - ClientPrint (ent, print_console, "%s killbots\t - kills all bots in current game.", self); - ClientPrint (ent, print_console, "%s kick\t - disconnect one random bot from game.", self); - ClientPrint (ent, print_console, "%s weaponmode\t - select bot weapon mode.", self); - ClientPrint (ent, print_console, "%s votemap\t - allows dead bots to vote for specific map.", self); - ClientPrint (ent, print_console, "%s cmenu\t - displaying bots command menu.", self); + engine.ClientPrintf (ent, "Bot Commands:"); + engine.ClientPrintf (ent, "%s version\t - display version information.", self); + engine.ClientPrintf (ent, "%s add\t - create a bot in current game.", self); + engine.ClientPrintf (ent, "%s fill\t - fill the server with random bots.", self); + engine.ClientPrintf (ent, "%s kickall\t - disconnects all bots from current game.", self); + engine.ClientPrintf (ent, "%s killbots\t - kills all bots in current game.", self); + engine.ClientPrintf (ent, "%s kick\t - disconnect one random bot from game.", self); + engine.ClientPrintf (ent, "%s weaponmode\t - select bot weapon mode.", self); + engine.ClientPrintf (ent, "%s votemap\t - allows dead bots to vote for specific map.", self); + engine.ClientPrintf (ent, "%s cmenu\t - displaying bots command menu.", self); if (stricmp (arg1, "full") == 0 || stricmp (arg1, "f") == 0 || stricmp (arg1, "?") == 0) { - ClientPrint (ent, print_console, "%s add_t\t - creates one random bot to terrorist team.", self); - ClientPrint (ent, print_console, "%s add_ct\t - creates one random bot to ct team.", self); - ClientPrint (ent, print_console, "%s kick_t\t - disconnect one random bot from terrorist team.", self); - ClientPrint (ent, print_console, "%s kick_ct\t - disconnect one random bot from ct team.", self); - ClientPrint (ent, print_console, "%s kill_t\t - kills all bots on terrorist team.", self); - ClientPrint (ent, print_console, "%s kill_ct\t - kills all bots on ct team.", self); - ClientPrint (ent, print_console, "%s list\t - display list of bots currently playing.", self); - ClientPrint (ent, print_console, "%s order\t - execute specific command on specified bot.", self); - ClientPrint (ent, print_console, "%s time\t - displays current time on server.", self); - ClientPrint (ent, print_console, "%s deletewp\t - erase waypoint file from hard disk (permanently).", self); + engine.ClientPrintf (ent, "%s add_t\t - creates one random bot to terrorist team.", self); + engine.ClientPrintf (ent, "%s add_ct\t - creates one random bot to ct team.", self); + engine.ClientPrintf (ent, "%s kick_t\t - disconnect one random bot from terrorist team.", self); + engine.ClientPrintf (ent, "%s kick_ct\t - disconnect one random bot from ct team.", self); + engine.ClientPrintf (ent, "%s kill_t\t - kills all bots on terrorist team.", self); + engine.ClientPrintf (ent, "%s kill_ct\t - kills all bots on ct team.", self); + engine.ClientPrintf (ent, "%s list\t - display list of bots currently playing.", self); + engine.ClientPrintf (ent, "%s order\t - execute specific command on specified bot.", self); + engine.ClientPrintf (ent, "%s time\t - displays current time on server.", self); + engine.ClientPrintf (ent, "%s deletewp\t - erase waypoint file from hard disk (permanently).", self); - if (!IsDedicatedServer ()) + if (!engine.IsDedicatedServer ()) { - ServerPrint ("%s autowp\t - toggle autowaypointing.", self); - ServerPrint ("%s wp\t - toggle waypoint showing.", self); - ServerPrint ("%s wp on noclip\t - enable noclip cheat", self); - ServerPrint ("%s wp save nocheck\t - save waypoints without checking.", self); - ServerPrint ("%s wp add\t - open menu for waypoint creation.", self); - ServerPrint ("%s wp menu\t - open main waypoint menu.", self); - ServerPrint ("%s wp addbasic\t - creates basic waypoints on map.", self); - ServerPrint ("%s wp find\t - show direction to specified waypoint.", self); - ServerPrint ("%s wp load\t - load the waypoint file from hard disk.", self); - ServerPrint ("%s wp check\t - checks if all waypoints connections are valid.", self); - ServerPrint ("%s wp cache\t - cache nearest waypoint.", self); - ServerPrint ("%s wp teleport\t - teleport hostile to specified waypoint.", self); - ServerPrint ("%s wp setradius\t - manually sets the wayzone radius for this waypoint.", self); - ServerPrint ("%s path autodistance - opens menu for setting autopath maximum distance.", self); - ServerPrint ("%s path cache\t - remember the nearest to player waypoint.", self); - ServerPrint ("%s path create\t - opens menu for path creation.", self); - ServerPrint ("%s path delete\t - delete path from cached to nearest waypoint.", self); - ServerPrint ("%s path create_in\t - creating incoming path connection.", self); - ServerPrint ("%s path create_out\t - creating outgoing path connection.", self); - ServerPrint ("%s path create_both\t - creating both-ways path connection.", self); - ServerPrint ("%s exp save\t - save the experience data.", self); + engine.Printf ("%s autowp\t - toggle autowaypointing.", self); + engine.Printf ("%s wp\t - toggle waypoint showing.", self); + engine.Printf ("%s wp on noclip\t - enable noclip cheat", self); + engine.Printf ("%s wp save nocheck\t - save waypoints without checking.", self); + engine.Printf ("%s wp add\t - open menu for waypoint creation.", self); + engine.Printf ("%s wp menu\t - open main waypoint menu.", self); + engine.Printf ("%s wp addbasic\t - creates basic waypoints on map.", self); + engine.Printf ("%s wp find\t - show direction to specified waypoint.", self); + engine.Printf ("%s wp load\t - load the waypoint file from hard disk.", self); + engine.Printf ("%s wp check\t - checks if all waypoints connections are valid.", self); + engine.Printf ("%s wp cache\t - cache nearest waypoint.", self); + engine.Printf ("%s wp teleport\t - teleport hostile to specified waypoint.", self); + engine.Printf ("%s wp setradius\t - manually sets the wayzone radius for this waypoint.", self); + engine.Printf ("%s path autodistance - opens menu for setting autopath maximum distance.", self); + engine.Printf ("%s path cache\t - remember the nearest to player waypoint.", self); + engine.Printf ("%s path create\t - opens menu for path creation.", self); + engine.Printf ("%s path delete\t - delete path from cached to nearest waypoint.", self); + engine.Printf ("%s path create_in\t - creating incoming path connection.", self); + engine.Printf ("%s path create_out\t - creating outgoing path connection.", self); + engine.Printf ("%s path create_both\t - creating both-ways path connection.", self); + engine.Printf ("%s exp save\t - save the experience data.", self); } } } - else if (stricmp (arg0, "bot_takedamage") == 0 && !IsNullString (arg1)) { bool isOn = !!(atoi (arg1) == 1); - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); @@ -197,21 +198,21 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c else { DisplayMenuToClient (ent, NULL); // reset menu display - CenterPrint ("You're dead, and have no access to this menu"); + engine.CenterPrintf ("You're dead, and have no access to this menu"); } } // 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) { - if (IsDedicatedServer () || IsEntityNull (g_hostEntity)) + if (engine.IsDedicatedServer () || engine.IsNullEntity (g_hostEntity)) return 2; // enables or disable waypoint displaying if (stricmp (arg1, "on") == 0) { g_waypointOn = true; - ServerPrint ("Waypoint Editing Enabled"); + engine.Printf ("Waypoint Editing Enabled"); // enables noclip cheat if (stricmp (arg2, "noclip") == 0) @@ -219,16 +220,16 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c if (g_editNoclip) { g_hostEntity->v.movetype = MOVETYPE_WALK; - ServerPrint ("Noclip Cheat Disabled"); + engine.Printf ("Noclip Cheat Disabled"); } else { g_hostEntity->v.movetype = MOVETYPE_NOCLIP; - ServerPrint ("Noclip Cheat Enabled"); + engine.Printf ("Noclip Cheat Enabled"); } g_editNoclip = !g_editNoclip; // switch on/off (XOR it!) } - ServerCommand ("yapb wp mdl on"); + engine.IssueCmd ("yapb wp mdl on"); } // switching waypoint editing off @@ -238,8 +239,8 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c g_editNoclip = false; g_hostEntity->v.movetype = MOVETYPE_WALK; - ServerPrint ("Waypoint Editing Disabled"); - ServerCommand ("yapb wp mdl off"); + engine.Printf ("Waypoint Editing Disabled"); + engine.IssueCmd ("yapb wp mdl off"); } // toggles displaying player models on spawn spots @@ -249,24 +250,24 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c if (stricmp (arg2, "on") == 0) { - while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start"))) + while (!engine.IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start"))) spawnEntity->v.effects &= ~EF_NODRAW; - while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch"))) + while (!engine.IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch"))) spawnEntity->v.effects &= ~EF_NODRAW; - while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start"))) + while (!engine.IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start"))) spawnEntity->v.effects &= ~EF_NODRAW; - ServerCommand ("mp_roundtime 9"); // reset round time to maximum - ServerCommand ("mp_timelimit 0"); // disable the time limit - ServerCommand ("mp_freezetime 0"); // disable freezetime + engine.IssueCmd ("mp_roundtime 9"); // reset round time to maximum + engine.IssueCmd ("mp_timelimit 0"); // disable the time limit + engine.IssueCmd ("mp_freezetime 0"); // disable freezetime } else if (stricmp (arg2, "off") == 0) { - while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start"))) + while (!engine.IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_start"))) spawnEntity->v.effects |= EF_NODRAW; - while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch"))) + while (!engine.IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_player_deathmatch"))) spawnEntity->v.effects |= EF_NODRAW; - while (!IsEntityNull (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start"))) + while (!engine.IsNullEntity (spawnEntity = FIND_ENTITY_BY_CLASSNAME (spawnEntity, "info_vip_start"))) spawnEntity->v.effects |= EF_NODRAW; } } @@ -286,7 +287,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c else if (stricmp (arg1, "addbasic") == 0) { waypoints.CreateBasic (); - CenterPrint ("Basic waypoints was Created"); + engine.CenterPrintf ("Basic waypoints was Created"); } // delete nearest to host edict waypoint @@ -299,17 +300,17 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c // save waypoint data into file on hard disk else if (stricmp (arg1, "save") == 0) { - char *waypointSaveMessage = locale.TranslateInput ("Waypoints Saved"); + char *waypointSaveMessage = engine.TraslateMessage ("Waypoints Saved"); if (FStrEq (arg2, "nocheck")) { waypoints.Save (); - ServerPrint (waypointSaveMessage); + engine.Printf (waypointSaveMessage); } else if (waypoints.NodesValid ()) { waypoints.Save (); - ServerPrint (waypointSaveMessage); + engine.Printf (waypointSaveMessage); } } @@ -321,14 +322,14 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c else if (stricmp (arg1, "load") == 0) { if (waypoints.Load ()) - ServerPrint ("Waypoints loaded"); + engine.Printf ("Waypoints loaded"); } // check all nodes for validation else if (stricmp (arg1, "check") == 0) { if (waypoints.NodesValid ()) - CenterPrint ("Nodes work Fine"); + engine.CenterPrintf ("Nodes work Fine"); } // opens menu for setting (removing) waypoint flags @@ -355,7 +356,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c (*g_engfuncs.pfnSetOrigin) (g_hostEntity, path->origin); g_waypointOn = true; - ServerPrint ("Player '%s' teleported to waypoint #%d (x:%.1f, y:%.1f, z:%.1f)", STRING (g_hostEntity->v.netname), teleportPoint, path->origin.x, path->origin.y, path->origin.z); //-V807 + engine.Printf ("Player '%s' teleported to waypoint #%d (x:%.1f, y:%.1f, z:%.1f)", STRING (g_hostEntity->v.netname), teleportPoint, path->origin.x, path->origin.y, path->origin.z); //-V807 g_editNoclip = true; } } @@ -366,13 +367,13 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c // otherwise display waypoint current status else - ServerPrint ("Waypoints are %s", g_waypointOn == true ? "Enabled" : "Disabled"); + engine.Printf ("Waypoints are %s", g_waypointOn == true ? "Enabled" : "Disabled"); } // path waypoint editing system (supported only on listen server) else if (stricmp (arg0, "pathwaypoint") == 0 || stricmp (arg0, "path") == 0 || stricmp (arg0, "pwp") == 0) { - if (IsDedicatedServer () || IsEntityNull (g_hostEntity)) + if (engine.IsDedicatedServer () || engine.IsNullEntity (g_hostEntity)) return 2; // opens path creation menu @@ -403,7 +404,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c // automatic waypoint handling (supported only on listen server) else if (stricmp (arg0, "autowaypoint") == 0 || stricmp (arg0, "autowp") == 0) { - if (IsDedicatedServer () || IsEntityNull (g_hostEntity)) + if (engine.IsDedicatedServer () || engine.IsNullEntity (g_hostEntity)) return 2; // enable autowaypointing @@ -418,13 +419,13 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c g_autoWaypoint = false; // display status - ServerPrint ("Auto-Waypoint %s", g_autoWaypoint ? "Enabled" : "Disabled"); + engine.Printf ("Auto-Waypoint %s", g_autoWaypoint ? "Enabled" : "Disabled"); } // experience system handling (supported only on listen server) else if (stricmp (arg0, "experience") == 0 || stricmp (arg0, "exp") == 0) { - if (IsDedicatedServer () || IsEntityNull (g_hostEntity)) + if (engine.IsDedicatedServer () || engine.IsNullEntity (g_hostEntity)) return 2; // write experience table (and visibility table) to hard disk @@ -433,7 +434,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c waypoints.SaveExperienceTab (); waypoints.SaveVisibilityTab (); - ServerPrint ("Experience tab saved"); + engine.Printf ("Experience tab saved"); } } else @@ -453,7 +454,7 @@ void CommandHandler (void) // check status for dedicated server command if (BotCommandHandler (g_hostEntity, IsNullString (CMD_ARGV (1)) ? "help" : CMD_ARGV (1), CMD_ARGV (2), CMD_ARGV (3), CMD_ARGV (4), CMD_ARGV (5), CMD_ARGV (6), CMD_ARGV (0)) == 0) - ServerPrint ("Unknown command: %s", CMD_ARGV (1)); + engine.Printf ("Unknown command: %s", CMD_ARGV (1)); } void ParseVoiceEvent (const String &base, int type, float timeToRepeat) @@ -467,7 +468,7 @@ void ParseVoiceEvent (const String &base, int type, float timeToRepeat) { temp[i].Trim ().TrimQuotes (); - if (GetWaveLength (temp[i]) == 0.0f) + if (engine.GetWaveLength (temp[i]) <= 0.0f) continue; chatterItem.name = temp[i]; @@ -478,9 +479,19 @@ void ParseVoiceEvent (const String &base, int type, float timeToRepeat) temp.RemoveAll (); } +// forwards for MemoryFile +MemoryFile::MF_Loader MemoryFile::Loader = NULL; +MemoryFile::MF_Unloader MemoryFile::Unloader = NULL; + void InitConfig (void) { - File fp; + if (!MemoryFile::Loader && !MemoryFile::Unloader) + { + MemoryFile::Loader = reinterpret_cast (g_engfuncs.pfnLoadFileForMe); + MemoryFile::Unloader = reinterpret_cast (g_engfuncs.pfnFreeFile); + } + + MemoryFile fp; char line[512]; KeywordFactory replyKey; @@ -505,7 +516,7 @@ void InitConfig (void) if (pair.GetElementNumber () > 1) strncpy (line, pair[0].Trim ().GetBuffer (), SIZEOF_CHAR (line)); - strtrim (line); + String::TrimExternalBuffer (line); line[32] = 0; BotName item; @@ -531,7 +542,7 @@ void InitConfig (void) while (fp.GetBuffer (line, 255)) { 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) { @@ -577,7 +588,7 @@ void InitConfig (void) if (chatType != 3) line[79] = 0; - strtrim (line); + String::TrimExternalBuffer (line); switch (chatType) { @@ -833,13 +844,13 @@ void InitConfig (void) // LOCALIZER INITITALIZATION if (OpenConfig ("lang.cfg", "Specified language not found", &fp, true) && !(g_gameFlags & GAME_LEGACY)) { - if (IsDedicatedServer ()) + if (engine.IsDedicatedServer ()) return; // dedicated server will use only english translation enum Lang { Lang_Original, Lang_Translate } langState = static_cast (2); char buffer[1024]; - LanguageItem temp = {"", ""}; + TranslatorPair temp = {"", ""}; while (fp.GetBuffer (line, 255)) { @@ -849,17 +860,17 @@ void InitConfig (void) if (!IsNullString (buffer)) { - strtrim (buffer); + String::TrimExternalBuffer (buffer); temp.translated = _strdup (buffer); buffer[0] = 0x0; } if (!IsNullString (temp.translated) && !IsNullString (temp.original)) - locale.m_langTab.Push (temp); + engine.PushTranslationPair (temp); } else if (strncmp (line, "[TRANSLATED]", 12) == 0) { - strtrim (buffer); + String::TrimExternalBuffer (buffer); temp.original = _strdup (buffer); buffer[0] = 0x0; @@ -904,7 +915,7 @@ void CommandHandler_NotMM (void) // the stdio command-line parsing in C when you write "long main (long argc, char **argv)". // this function is handler for non-metamod launch of yapb, it's just print error message. - ServerPrint ("You're launched standalone version of yapb. Metamod is not installed or not enabled!"); + engine.Printf ("You're launched standalone version of yapb. Metamod is not installed or not enabled!"); } void GameDLLInit (void) @@ -940,22 +951,22 @@ void GameDLLInit (void) gameVersionStr.Replace ("Legacy", "1.6 Limited"); } - ServerPrint ("YaPB Bot has detect game version as Counter-Strike: %s", gameVersionStr.GetBuffer ()); + engine.Printf ("YaPB Bot has detect game version as Counter-Strike: %s", gameVersionStr.GetBuffer ()); } // register server command(s) - RegisterCommand ("yapb", CommandHandler); - RegisterCommand ("yb", CommandHandler); + engine.RegisterCmd ("yapb", CommandHandler); + engine.RegisterCmd ("yb", CommandHandler); // execute main config - ServerCommand ("exec addons/yapb/conf/yapb.cfg"); + engine.IssueCmd ("exec addons/yapb/conf/yapb.cfg"); // set correct version string yb_version.SetString (FormatBuffer ("%d.%d.%d.%u", PRODUCT_VERSION_DWORD_INTERNAL, GenerateBuildNumber ())); // register fake metamod command handler if we not! under mm if (!g_isMetamod) - RegisterCommand ("meta", CommandHandler_NotMM); + engine.RegisterCmd ("meta", CommandHandler_NotMM); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -976,7 +987,7 @@ void Touch (edict_t *pentTouched, edict_t *pentOther) // the two entities both have velocities, for example two players colliding, this function // is called twice, once for each entity moving. - if (!IsEntityNull (pentOther) && (pentOther->v.flags & FL_FAKECLIENT)) + if (!engine.IsNullEntity (pentOther) && (pentOther->v.flags & FL_FAKECLIENT)) { Bot *bot = bots.GetBot (pentOther); @@ -1001,9 +1012,8 @@ int Spawn (edict_t *ent) if (strcmp (entityClassname, "worldspawn") == 0) { - g_worldEntity = ent; // save the world entity for future use - - convars.PushRegisteredConVarsToEngine (true); + engine.Precache (ent); + engine.PushRegisteredConVarsToEngine (true); PRECACHE_SOUND (ENGINE_STR ("weapons/xbow_hit1.wav")); // waypoint add PRECACHE_SOUND (ENGINE_STR ("weapons/mine_activate.wav")); // waypoint delete @@ -1012,14 +1022,8 @@ int Spawn (edict_t *ent) PRECACHE_SOUND (ENGINE_STR ("common/wpn_moveselect.wav")); // path add/delete cancel PRECACHE_SOUND (ENGINE_STR ("common/wpn_denyselect.wav")); // path add/delete error - g_modelIndexLaser = PRECACHE_MODEL (ENGINE_STR ("sprites/laserbeam.spr")); - g_modelIndexArrow = PRECACHE_MODEL (ENGINE_STR ("sprites/arrow1.spr")); - g_roundEnded = true; - RoundInit (); - - g_mapType = NULL; // reset map type as worldspawn is the first entity spawned - + g_mapType = 0; // 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 if (!(g_gameFlags & GAME_LEGACY) && g_engfuncs.pfnCVarGetPointer ("bot_stop") != NULL) @@ -1079,9 +1083,9 @@ int Spawn (edict_t *ent) g_mapType |= MAP_ES; // next maps doesn't have map-specific entities, so determine it by name - else if (strncmp (GetMapName (), "fy_", 3) == 0) // fun map + else if (strncmp (engine.GetMapName (), "fy_", 3) == 0) // fun map g_mapType |= MAP_FY; - else if (strncmp (GetMapName (), "ka_", 3) == 0) // knife arena map + else if (strncmp (engine.GetMapName (), "ka_", 3) == 0) // knife arena map g_mapType |= MAP_KA; if (g_isMetamod) @@ -1157,9 +1161,9 @@ void ClientDisconnect (edict_t *ent) bots.AdjustQuota (false, ent); - int i = IndexOfEntity (ent) - 1; + int i = engine.IndexOfEntity (ent) - 1; - InternalAssert (i >= 0 && i < 32); + InternalAssert (i >= 0 && i < MAX_ENGINE_PLAYERS); Bot *bot = bots.GetBot (i); @@ -1188,14 +1192,14 @@ void ClientUserInfoChanged (edict_t *ent, char *infobuffer) // change their player model). But most commonly, this function is in charge of handling // team changes, recounting the teams population, etc... - if (IsDedicatedServer () && !IsValidBot (ent)) + if (engine.IsDedicatedServer () && !IsValidBot (ent)) { const char *passwordField = yb_password_key.GetString (); const char *password = yb_password.GetString (); if (!IsNullString (passwordField) || !IsNullString (password)) { - int clientIndex = IndexOfEntity (ent) - 1; + int clientIndex = engine.IndexOfEntity (ent) - 1; if (strcmp (password, INFOKEY_VALUE (infobuffer, const_cast (passwordField))) == 0) g_clients[clientIndex].flags |= CF_ADMIN; @@ -1231,7 +1235,7 @@ void ClientCommand (edict_t *ent) static int fillServerTeam = 5; 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[engine.IndexOfEntity (ent) - 1].flags & CF_ADMIN))) { if (stricmp (command, "yapb") == 0 || stricmp (command, "yb") == 0) { @@ -1240,11 +1244,11 @@ void ClientCommand (edict_t *ent) switch (state) { case 0: - ClientPrint (ent, print_withtag, "Unknown command: %s", arg1); + engine.ClientPrintf (ent, "Unknown command: %s", arg1); break; case 2: - ClientPrint (ent, print_withtag, "Command %s, can only be executed from server console.", arg1); + engine.ClientPrintf (ent, "Command %s, can only be executed from server console.", arg1); break; } if (g_isMetamod) @@ -1252,9 +1256,9 @@ void ClientCommand (edict_t *ent) return; } - else if (stricmp (command, "menuselect") == 0 && !IsNullString (arg1) && g_clients[IndexOfEntity (ent) - 1].menu != NULL) + else if (stricmp (command, "menuselect") == 0 && !IsNullString (arg1) && g_clients[engine.IndexOfEntity (ent) - 1].menu != NULL) { - Client *client = &g_clients[IndexOfEntity (ent) - 1]; + Client *client = &g_clients[engine.IndexOfEntity (ent) - 1]; int selection = atoi (arg1); if (client->menu == &g_menus[12]) @@ -1329,9 +1333,9 @@ void ClientCommand (edict_t *ent) { case 1: if (g_waypointOn) - ServerCommand ("yapb waypoint off"); + engine.IssueCmd ("yapb waypoint off"); else - ServerCommand ("yapb waypoint on"); + engine.IssueCmd ("yapb waypoint on"); break; case 2: @@ -1423,7 +1427,7 @@ void ClientCommand (edict_t *ent) if (path->flags & FLAG_NOHOSTAGE) noHostagePoints++; } - ServerPrint ("Waypoints: %d - T Points: %d\n" + engine.Printf ("Waypoints: %d - T Points: %d\n" "CT Points: %d - Goal Points: %d\n" "Rescue Points: %d - Camp Points: %d\n" "Block Hostage Points: %d - Sniper Points: %d\n", g_numWaypoints, terrPoints, ctPoints, goalPoints, rescuePoints, campPoints, noHostagePoints, sniperPoints); @@ -1435,7 +1439,7 @@ void ClientCommand (edict_t *ent) g_autoWaypoint &= 1; g_autoWaypoint ^= 1; - CenterPrint ("Auto-Waypoint %s", g_autoWaypoint ? "Enabled" : "Disabled"); + engine.CenterPrintf ("Auto-Waypoint %s", g_autoWaypoint ? "Enabled" : "Disabled"); break; case 3: @@ -1447,7 +1451,7 @@ void ClientCommand (edict_t *ent) if (waypoints.NodesValid ()) waypoints.Save (); else - CenterPrint ("Waypoint not saved\nThere are errors, see console"); + engine.CenterPrintf ("Waypoint not saved\nThere are errors, see console"); break; case 5: @@ -1460,13 +1464,13 @@ void ClientCommand (edict_t *ent) case 7: if (waypoints.NodesValid ()) - CenterPrint ("Nodes works fine"); + engine.CenterPrintf ("Nodes works fine"); else - CenterPrint ("There are errors, see console"); + engine.CenterPrintf ("There are errors, see console"); break; case 8: - ServerCommand ("yapb wp on noclip"); + engine.IssueCmd ("yapb wp on noclip"); break; case 9: @@ -1593,7 +1597,7 @@ void ClientCommand (edict_t *ent) else { DisplayMenuToClient (ent, NULL); // reset menu display - CenterPrint ("You're dead, and have no access to this menu"); + engine.CenterPrintf ("You're dead, and have no access to this menu"); } break; @@ -1626,7 +1630,7 @@ void ClientCommand (edict_t *ent) bot->m_doubleJumpOrigin = client->ent->v.origin; bot->m_doubleJumpEntity = client->ent; - bot->PushTask (TASK_DOUBLEJUMP, TASKPRI_DOUBLEJUMP, -1, GetWorldTime (), true); + bot->PushTask (TASK_DOUBLEJUMP, TASKPRI_DOUBLEJUMP, -1, engine.Time (), true); bot->TeamSayText (FormatBuffer ("Ok %s, i will help you!", STRING (ent->v.netname))); } else if (selection == 2) @@ -1662,9 +1666,9 @@ void ClientCommand (edict_t *ent) g_autoPathDistance = autoDistanceValue[selection - 1]; if (g_autoPathDistance == 0) - CenterPrint ("AutoPath disabled"); + engine.CenterPrintf ("AutoPath disabled"); else - CenterPrint ("AutoPath maximum distance set to %f", g_autoPathDistance); + engine.CenterPrintf ("AutoPath maximum distance set to %f", g_autoPathDistance); if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); @@ -2011,7 +2015,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; @@ -2027,9 +2031,9 @@ void ClientCommand (edict_t *ent) int team = -1; if (FStrEq (command, "say_team")) - team = GetTeam (ent); + team = engine.GetTeam (ent); - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (!(g_clients[i].flags & CF_USED) || (team != -1 && team != g_clients[i].team) || isAlive != IsAlive (g_clients[i].ent)) continue; @@ -2038,17 +2042,17 @@ void ClientCommand (edict_t *ent) if (target != NULL) { - target->m_sayTextBuffer.entityIndex = IndexOfEntity (ent); + target->m_sayTextBuffer.entityIndex = engine.IndexOfEntity (ent); if (IsNullString (CMD_ARGS ())) continue; strncpy (target->m_sayTextBuffer.sayText, CMD_ARGS (), SIZEOF_CHAR (target->m_sayTextBuffer.sayText)); - target->m_sayTextBuffer.timeNextChat = GetWorldTime () + target->m_sayTextBuffer.chatDelay; + target->m_sayTextBuffer.timeNextChat = engine.Time () + target->m_sayTextBuffer.chatDelay; } } } - int clientIndex = IndexOfEntity (ent) - 1; + int clientIndex = engine.IndexOfEntity (ent) - 1; // check if this player alive, and issue something if ((g_clients[clientIndex].flags & CF_ALIVE) && g_radioSelect[clientIndex] != 0 && strncmp (command, "menuselect", 10) == 0) @@ -2061,19 +2065,19 @@ void ClientCommand (edict_t *ent) if (radioCommand != Radio_Affirmative && radioCommand != Radio_Negative && radioCommand != Radio_ReportingIn) { - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); // validate bot - if (bot != NULL && GetTeam (bot->GetEntity ()) == g_clients[clientIndex].team && VARS (ent) != bot->pev && bot->m_radioOrder == 0) + if (bot != NULL && bot->m_team == g_clients[clientIndex].team && ent != bot->GetEntity () && bot->m_radioOrder == 0) { bot->m_radioOrder = radioCommand; bot->m_radioEntity = ent; } } } - g_lastRadioTime[g_clients[clientIndex].team] = GetWorldTime (); + g_lastRadioTime[g_clients[clientIndex].team] = engine.Time (); } g_radioSelect[clientIndex] = 0; } @@ -2106,12 +2110,12 @@ void ServerActivate (edict_t *pentEdictList, int edictCount, int clientMax) bots.CreateKillerEntity (); // execute main config - ServerCommand ("exec addons/yapb/conf/yapb.cfg"); + engine.IssueCmd ("exec addons/yapb/conf/yapb.cfg"); - if (File::Accessible (FormatBuffer ("%s/maps/%s_yapb.cfg", GetModName (), GetMapName ()))) + if (File::Accessible (FormatBuffer ("%s/maps/%s_yapb.cfg", engine.GetModName (), engine.GetMapName ()))) { - ServerCommand ("exec maps/%s_yapb.cfg", GetMapName ()); - ServerPrint ("Executing Map-Specific config file"); + engine.IssueCmd ("exec maps/%s_yapb.cfg", engine.GetMapName ()); + engine.Printf ("Executing Map-Specific config file"); } bots.InitQuota (); @@ -2164,11 +2168,11 @@ void StartFrame (void) bots.PeriodicThink (); // record some stats of all players on the server - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - edict_t *player = EntityOfIndex (i + 1); + edict_t *player = engine.EntityOfIndex (i + 1); - if (!IsEntityNull (player) && (player->v.flags & FL_CLIENT)) + if (!engine.IsNullEntity (player) && (player->v.flags & FL_CLIENT)) { g_clients[i].ent = player; g_clients[i].flags |= CF_USED; @@ -2195,7 +2199,7 @@ void StartFrame (void) } } - if (!IsDedicatedServer () && !IsEntityNull (g_hostEntity)) + if (!engine.IsDedicatedServer () && !engine.IsNullEntity (g_hostEntity)) { if (g_waypointOn) waypoints.Think (); @@ -2204,31 +2208,33 @@ void StartFrame (void) } bots.SetDeathMsgState (false); - if (g_timePerSecondUpdate < GetWorldTime ()) + if (g_timePerSecondUpdate < engine.Time ()) { - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - edict_t *player = EntityOfIndex (i + 1); + edict_t *player = engine.EntityOfIndex (i + 1); // code below is executed only on dedicated server - if (IsDedicatedServer () && !IsEntityNull (player) && (player->v.flags & FL_CLIENT) && !(player->v.flags & FL_FAKECLIENT)) + if (engine.IsDedicatedServer () && !engine.IsNullEntity (player) && (player->v.flags & FL_CLIENT) && !(player->v.flags & FL_FAKECLIENT)) { - if (g_clients[i].flags & CF_ADMIN) + Client &client = g_clients[i]; + + if (client.flags & CF_ADMIN) { if (IsNullString (yb_password_key.GetString ()) && IsNullString (yb_password.GetString ())) - g_clients[i].flags &= ~CF_ADMIN; - else if (strcmp (yb_password.GetString (), INFOKEY_VALUE (GET_INFOKEYBUFFER (g_clients[i].ent), const_cast (yb_password_key.GetString ())))) + client.flags &= ~CF_ADMIN; + else if (strcmp (yb_password.GetString (), INFOKEY_VALUE (GET_INFOKEYBUFFER (client.ent), const_cast (yb_password_key.GetString ())))) { - g_clients[i].flags &= ~CF_ADMIN; - ServerPrint ("Player %s had lost remote access to yapb.", STRING (player->v.netname)); + client.flags &= ~CF_ADMIN; + engine.Printf ("Player %s had lost remote access to yapb.", STRING (player->v.netname)); } } - else if (!(g_clients[i].flags & CF_ADMIN) && !IsNullString (yb_password_key.GetString ()) && !IsNullString (yb_password.GetString ())) + else if (!(client.flags & CF_ADMIN) && !IsNullString (yb_password_key.GetString ()) && !IsNullString (yb_password.GetString ())) { - if (strcmp (yb_password.GetString (), INFOKEY_VALUE (GET_INFOKEYBUFFER (g_clients[i].ent), const_cast (yb_password_key.GetString ()))) == 0) + if (strcmp (yb_password.GetString (), INFOKEY_VALUE (GET_INFOKEYBUFFER (client.ent), const_cast (yb_password_key.GetString ()))) == 0) { - g_clients[i].flags |= CF_ADMIN; - ServerPrint ("Player %s had gained full remote access to yapb.", STRING (player->v.netname)); + client.flags |= CF_ADMIN; + engine.Printf ("Player %s had gained full remote access to yapb.", STRING (player->v.netname)); } } } @@ -2249,9 +2255,9 @@ void StartFrame (void) if (csdm_active != NULL && csdm_active->value > 0) yb_csdm_mode.SetInt (mp_freeforall != NULL && mp_freeforall->value > 0 ? 2 : 1); } - g_timePerSecondUpdate = GetWorldTime () + 1.0f; + g_timePerSecondUpdate = engine.Time () + 1.0f; } - else if (g_timePerSecondUpdate * 0.5f < GetWorldTime ()) + else if (g_timePerSecondUpdate * 0.5f < engine.Time ()) bots.UpdateActiveGrenades (); // keep bot number up to date @@ -2365,7 +2371,7 @@ void pfnEmitSound (edict_t *entity, int channel, const char *sample, float volum (*g_engfuncs.pfnEmitSound) (entity, channel, sample, volume, attenuation, flags, pitch); } -void pfnClientCommand (edict_t *ent, char *format, ...) +void pfnClientCommand (edict_t *ent, char const *format, ...) { // this function forces the client whose player entity is ent to issue a client command. // How it works is that clients all have a g_xgv global string in their client DLL that @@ -2379,18 +2385,17 @@ void pfnClientCommand (edict_t *ent, char *format, ...) // 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 // 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 - // using FakeClientCommand(). + // case it's a bot asking for a client command, we handle it like we do for bot commands va_list ap; - char buffer[1024]; + char buffer[MAX_PRINT_BUFFER]; va_start (ap, format); - _vsnprintf (buffer, sizeof (buffer), format, ap); + _vsnprintf (buffer, SIZEOF_CHAR (buffer), format, ap); va_end (ap); // is the target entity an official bot, or a third party bot ? - if (IsValidBot (ent) || (ent->v.flags & FL_DORMANT)) + if (ent->v.flags & FL_FAKECLIENT) { if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); // prevent bots to be forced to issue client commands @@ -2409,73 +2414,71 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed // this function called each time a message is about to sent. // store the message type in our own variables, since the GET_USER_MSG_ID () will just do a lot of strcmp()'s... - if (g_isMetamod && netmsg.GetId (NETMSG_MONEY) == -1) + if (g_isMetamod && engine.FindMessageId (NETMSG_MONEY) == -1) { - netmsg.SetId (NETMSG_VGUI, GET_USER_MSG_ID (PLID, "VGUIMenu", NULL)); - netmsg.SetId (NETMSG_SHOWMENU, GET_USER_MSG_ID (PLID, "ShowMenu", NULL)); - netmsg.SetId (NETMSG_WEAPONLIST, GET_USER_MSG_ID (PLID, "WeaponList", NULL)); - netmsg.SetId (NETMSG_CURWEAPON, GET_USER_MSG_ID (PLID, "CurWeapon", NULL)); - netmsg.SetId (NETMSG_AMMOX, GET_USER_MSG_ID (PLID, "AmmoX", NULL)); - netmsg.SetId (NETMSG_AMMOPICKUP, GET_USER_MSG_ID (PLID, "AmmoPickup", NULL)); - netmsg.SetId (NETMSG_DAMAGE, GET_USER_MSG_ID (PLID, "Damage", NULL)); - netmsg.SetId (NETMSG_MONEY, GET_USER_MSG_ID (PLID, "Money", NULL)); - netmsg.SetId (NETMSG_STATUSICON, GET_USER_MSG_ID (PLID, "StatusIcon", NULL)); - netmsg.SetId (NETMSG_DEATH, GET_USER_MSG_ID (PLID, "DeathMsg", NULL)); - netmsg.SetId (NETMSG_SCREENFADE, GET_USER_MSG_ID (PLID, "ScreenFade", NULL)); - netmsg.SetId (NETMSG_HLTV, GET_USER_MSG_ID (PLID, "HLTV", NULL)); - netmsg.SetId (NETMSG_TEXTMSG, GET_USER_MSG_ID (PLID, "TextMsg", NULL)); - netmsg.SetId (NETMSG_SCOREINFO, GET_USER_MSG_ID (PLID, "ScoreInfo", NULL)); - netmsg.SetId (NETMSG_BARTIME, GET_USER_MSG_ID (PLID, "BarTime", NULL)); - netmsg.SetId (NETMSG_SENDAUDIO, GET_USER_MSG_ID (PLID, "SendAudio", NULL)); - netmsg.SetId (NETMSG_SAYTEXT, GET_USER_MSG_ID (PLID, "SayText", NULL)); - netmsg.SetId (NETMSG_RESETHUD, GET_USER_MSG_ID (PLID, "ResetHUD", NULL)); + engine.AssignMessageId (NETMSG_VGUI, GET_USER_MSG_ID (PLID, "VGUIMenu", NULL)); + engine.AssignMessageId (NETMSG_SHOWMENU, GET_USER_MSG_ID (PLID, "ShowMenu", NULL)); + engine.AssignMessageId (NETMSG_WEAPONLIST, GET_USER_MSG_ID (PLID, "WeaponList", NULL)); + engine.AssignMessageId (NETMSG_CURWEAPON, GET_USER_MSG_ID (PLID, "CurWeapon", NULL)); + engine.AssignMessageId (NETMSG_AMMOX, GET_USER_MSG_ID (PLID, "AmmoX", NULL)); + engine.AssignMessageId (NETMSG_AMMOPICKUP, GET_USER_MSG_ID (PLID, "AmmoPickup", NULL)); + engine.AssignMessageId (NETMSG_DAMAGE, GET_USER_MSG_ID (PLID, "Damage", NULL)); + engine.AssignMessageId (NETMSG_MONEY, GET_USER_MSG_ID (PLID, "Money", NULL)); + engine.AssignMessageId (NETMSG_STATUSICON, GET_USER_MSG_ID (PLID, "StatusIcon", NULL)); + engine.AssignMessageId (NETMSG_DEATH, GET_USER_MSG_ID (PLID, "DeathMsg", NULL)); + engine.AssignMessageId (NETMSG_SCREENFADE, GET_USER_MSG_ID (PLID, "ScreenFade", NULL)); + engine.AssignMessageId (NETMSG_HLTV, GET_USER_MSG_ID (PLID, "HLTV", NULL)); + engine.AssignMessageId (NETMSG_TEXTMSG, GET_USER_MSG_ID (PLID, "TextMsg", NULL)); + engine.AssignMessageId (NETMSG_SCOREINFO, GET_USER_MSG_ID (PLID, "ScoreInfo", NULL)); + engine.AssignMessageId (NETMSG_BARTIME, GET_USER_MSG_ID (PLID, "BarTime", NULL)); + engine.AssignMessageId (NETMSG_SENDAUDIO, GET_USER_MSG_ID (PLID, "SendAudio", NULL)); + engine.AssignMessageId (NETMSG_SAYTEXT, GET_USER_MSG_ID (PLID, "SayText", NULL)); if (!(g_gameFlags & GAME_LEGACY)) - netmsg.SetId (NETMSG_BOTVOICE, GET_USER_MSG_ID (PLID, "BotVoice", NULL)); + engine.AssignMessageId (NETMSG_BOTVOICE, GET_USER_MSG_ID (PLID, "BotVoice", NULL)); } - netmsg.Reset (); + engine.ResetMessageCapture (); - if (msgDest == MSG_SPEC && msgType == netmsg.GetId (NETMSG_HLTV) && !(g_gameFlags & GAME_LEGACY)) - netmsg.SetMessage (NETMSG_HLTV); + if ((!(g_gameFlags & GAME_LEGACY) || (g_gameFlags & GAME_XASH)) && msgDest == MSG_SPEC && msgType == engine.FindMessageId (NETMSG_HLTV)) + engine.SetOngoingMessageId (NETMSG_HLTV); - netmsg.HandleMessageIfRequired (msgType, NETMSG_WEAPONLIST); + engine.TryCaptureMessage (msgType, NETMSG_WEAPONLIST); - if (!IsEntityNull (ed)) + if (!engine.IsNullEntity (ed)) { int index = bots.GetIndex (ed); // is this message for a bot? - if (index != -1 && !(ed->v.flags & FL_DORMANT) && bots.GetBot (index)->GetEntity () == ed) + if (index != -1 && !(ed->v.flags & FL_DORMANT)) { - netmsg.Reset (); - netmsg.SetBot (bots.GetBot (index)); + engine.ResetMessageCapture (); + engine.SetOngoingMessageReceiver (index); // message handling is done in usermsg.cpp - netmsg.HandleMessageIfRequired (msgType, NETMSG_VGUI); - netmsg.HandleMessageIfRequired (msgType, NETMSG_CURWEAPON); - netmsg.HandleMessageIfRequired (msgType, NETMSG_AMMOX); - netmsg.HandleMessageIfRequired (msgType, NETMSG_AMMOPICKUP); - netmsg.HandleMessageIfRequired (msgType, NETMSG_DAMAGE); - netmsg.HandleMessageIfRequired (msgType, NETMSG_MONEY); - netmsg.HandleMessageIfRequired (msgType, NETMSG_STATUSICON); - netmsg.HandleMessageIfRequired (msgType, NETMSG_SCREENFADE); - netmsg.HandleMessageIfRequired (msgType, NETMSG_BARTIME); - netmsg.HandleMessageIfRequired (msgType, NETMSG_TEXTMSG); - netmsg.HandleMessageIfRequired (msgType, NETMSG_SHOWMENU); - netmsg.HandleMessageIfRequired (msgType, NETMSG_RESETHUD); + engine.TryCaptureMessage (msgType, NETMSG_VGUI); + engine.TryCaptureMessage (msgType, NETMSG_CURWEAPON); + engine.TryCaptureMessage (msgType, NETMSG_AMMOX); + engine.TryCaptureMessage (msgType, NETMSG_AMMOPICKUP); + engine.TryCaptureMessage (msgType, NETMSG_DAMAGE); + engine.TryCaptureMessage (msgType, NETMSG_MONEY); + engine.TryCaptureMessage (msgType, NETMSG_STATUSICON); + engine.TryCaptureMessage (msgType, NETMSG_SCREENFADE); + engine.TryCaptureMessage (msgType, NETMSG_BARTIME); + engine.TryCaptureMessage (msgType, NETMSG_TEXTMSG); + engine.TryCaptureMessage (msgType, NETMSG_SHOWMENU); } } else if (msgDest == MSG_ALL) { - netmsg.Reset (); + engine.ResetMessageCapture (); - netmsg.HandleMessageIfRequired (msgType, NETMSG_SCOREINFO); - netmsg.HandleMessageIfRequired (msgType, NETMSG_DEATH); - netmsg.HandleMessageIfRequired (msgType, NETMSG_TEXTMSG); + engine.TryCaptureMessage (msgType, NETMSG_SCOREINFO); + engine.TryCaptureMessage (msgType, NETMSG_DEATH); + engine.TryCaptureMessage (msgType, NETMSG_TEXTMSG); if (msgType == SVC_INTERMISSION) { - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); @@ -2493,7 +2496,7 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed void pfnMessageEnd (void) { - netmsg.Reset (); + engine.ResetMessageCapture (); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2515,7 +2518,7 @@ void pfnMessageEnd_Post (void) void pfnWriteByte (int value) { // if this message is for a bot, call the client message function... - netmsg.Execute ((void *) &value); + engine.ProcessMessageCapture ((void *) &value); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2526,7 +2529,7 @@ void pfnWriteByte (int value) void pfnWriteChar (int value) { // if this message is for a bot, call the client message function... - netmsg.Execute ((void *) &value); + engine.ProcessMessageCapture ((void *) &value); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2537,7 +2540,7 @@ void pfnWriteChar (int value) void pfnWriteShort (int value) { // if this message is for a bot, call the client message function... - netmsg.Execute ((void *) &value); + engine.ProcessMessageCapture ((void *) &value); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2548,7 +2551,7 @@ void pfnWriteShort (int value) void pfnWriteLong (int value) { // if this message is for a bot, call the client message function... - netmsg.Execute ((void *) &value); + engine.ProcessMessageCapture ((void *) &value); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2559,7 +2562,7 @@ void pfnWriteLong (int value) void pfnWriteAngle (float value) { // if this message is for a bot, call the client message function... - netmsg.Execute ((void *) &value); + engine.ProcessMessageCapture ((void *) &value); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2570,7 +2573,7 @@ void pfnWriteAngle (float value) void pfnWriteCoord (float value) { // if this message is for a bot, call the client message function... - netmsg.Execute ((void *) &value); + engine.ProcessMessageCapture ((void *) &value); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2581,7 +2584,7 @@ void pfnWriteCoord (float value) void pfnWriteString (const char *sz) { // if this message is for a bot, call the client message function... - netmsg.Execute ((void *) sz); + engine.ProcessMessageCapture ((void *) sz); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2592,7 +2595,7 @@ void pfnWriteString (const char *sz) void pfnWriteEntity (int value) { // if this message is for a bot, call the client message function... - netmsg.Execute ((void *) &value); + engine.ProcessMessageCapture ((void *) &value); if (g_isMetamod) RETURN_META (MRES_IGNORED); @@ -2609,13 +2612,13 @@ int pfnCmd_Argc (void) // DLL for a command we are holding here. Of course, real clients commands are still retrieved // the normal way, by asking the engine. - // is this a bot issuing that client command ? - if (g_isFakeCommand) + // is this a bot issuing that client command? + if (engine.IsBotCommand ()) { 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) @@ -2634,28 +2637,12 @@ const char *pfnCmd_Args (void) // normal way, by asking the engine. // 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) - RETURN_META_VALUE (MRES_SUPERCEDE, &g_fakeArgv[4]); - - return &g_fakeArgv[4]; // skip the "say" bot client command - } - 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_META_VALUE (MRES_SUPERCEDE, engine.GetOverrideArgs ()); - return g_fakeArgv; // else return the whole bot client command string we know + return engine.GetOverrideArgs (); // else return the whole bot client command string we know } if (g_isMetamod) @@ -2673,13 +2660,13 @@ const char *pfnCmd_Argv (int argc) // DLL for a command we are holding here. Of course, real clients commands are still retrieved // the normal way, by asking the engine. - // is this a bot issuing that client command ? - if (g_isFakeCommand) + // is this a bot issuing that client command? + if (engine.IsBotCommand ()) { 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) RETURN_META_VALUE (MRES_IGNORED, NULL); @@ -2741,43 +2728,41 @@ int pfnRegUserMsg (const char *name, int size) int message = REG_USER_MSG (name, size); if (strcmp (name, "VGUIMenu") == 0) - netmsg.SetId (NETMSG_VGUI, message); + engine.AssignMessageId (NETMSG_VGUI, message); else if (strcmp (name, "ShowMenu") == 0) - netmsg.SetId (NETMSG_SHOWMENU, message); + engine.AssignMessageId (NETMSG_SHOWMENU, message); else if (strcmp (name, "WeaponList") == 0) - netmsg.SetId (NETMSG_WEAPONLIST, message); + engine.AssignMessageId (NETMSG_WEAPONLIST, message); else if (strcmp (name, "CurWeapon") == 0) - netmsg.SetId (NETMSG_CURWEAPON, message); + engine.AssignMessageId (NETMSG_CURWEAPON, message); else if (strcmp (name, "AmmoX") == 0) - netmsg.SetId (NETMSG_AMMOX, message); + engine.AssignMessageId (NETMSG_AMMOX, message); else if (strcmp (name, "AmmoPickup") == 0) - netmsg.SetId (NETMSG_AMMOPICKUP, message); + engine.AssignMessageId (NETMSG_AMMOPICKUP, message); else if (strcmp (name, "Damage") == 0) - netmsg.SetId (NETMSG_DAMAGE, message); + engine.AssignMessageId (NETMSG_DAMAGE, message); else if (strcmp (name, "Money") == 0) - netmsg.SetId (NETMSG_MONEY, message); + engine.AssignMessageId (NETMSG_MONEY, message); else if (strcmp (name, "StatusIcon") == 0) - netmsg.SetId (NETMSG_STATUSICON, message); + engine.AssignMessageId (NETMSG_STATUSICON, message); else if (strcmp (name, "DeathMsg") == 0) - netmsg.SetId (NETMSG_DEATH, message); + engine.AssignMessageId (NETMSG_DEATH, message); else if (strcmp (name, "ScreenFade") == 0) - netmsg.SetId (NETMSG_SCREENFADE, message); + engine.AssignMessageId (NETMSG_SCREENFADE, message); else if (strcmp (name, "HLTV") == 0) - netmsg.SetId (NETMSG_HLTV, message); + engine.AssignMessageId (NETMSG_HLTV, message); else if (strcmp (name, "TextMsg") == 0) - netmsg.SetId (NETMSG_TEXTMSG, message); + engine.AssignMessageId (NETMSG_TEXTMSG, message); else if (strcmp (name, "ScoreInfo") == 0) - netmsg.SetId (NETMSG_SCOREINFO, message); + engine.AssignMessageId (NETMSG_SCOREINFO, message); else if (strcmp (name, "BarTime") == 0) - netmsg.SetId (NETMSG_BARTIME, message); + engine.AssignMessageId (NETMSG_BARTIME, message); else if (strcmp (name, "SendAudio") == 0) - netmsg.SetId (NETMSG_SENDAUDIO, message); + engine.AssignMessageId (NETMSG_SENDAUDIO, message); else if (strcmp (name, "SayText") == 0) - netmsg.SetId (NETMSG_SAYTEXT, message); + engine.AssignMessageId (NETMSG_SAYTEXT, message); else if (strcmp (name, "BotVoice") == 0) - netmsg.SetId (NETMSG_BOTVOICE, message); - else if (strcmp (name, "ResetHUD") == 0) - netmsg.SetId (NETMSG_RESETHUD, message); + engine.AssignMessageId (NETMSG_BOTVOICE, message); return message; } @@ -2788,17 +2773,17 @@ void pfnAlertMessage (ALERT_TYPE alertType, char *format, ...) char buffer[1024]; va_start (ap, format); - vsprintf (buffer, format, ap); + vsnprintf (buffer, SIZEOF_CHAR (buffer), format, ap); va_end (ap); if ((g_mapType & MAP_DE) && g_bombPlanted && strstr (buffer, "_Defuse_") != NULL) { // notify all terrorists that CT is starting bomb defusing - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); - if (bot != NULL && GetTeam (bot->GetEntity ()) == TERRORIST && IsAlive (bot->GetEntity ())) + if (bot != NULL && bot->m_team == TERRORIST && bot->m_notKilled) { bot->ResetTasks (); bot->MoveToVector (waypoints.GetBombPosition ()); @@ -2814,7 +2799,7 @@ void pfnAlertMessage (ALERT_TYPE alertType, char *format, ...) gamedll_funcs_t gameDLLFunc; -export int GetEntityAPI2 (gamefuncs_t *functionTable, int *) +SHARED_LIBRARAY_EXPORT int GetEntityAPI2 (gamefuncs_t *functionTable, int *) { // this function is called right after FuncPointers_t() by the engine in the game DLL (or // what it BELIEVES to be the game DLL), in order to copy the list of MOD functions that can @@ -2858,7 +2843,7 @@ export int GetEntityAPI2 (gamefuncs_t *functionTable, int *) return TRUE; } -export int GetEntityAPI2_Post (gamefuncs_t *functionTable, int *) +SHARED_LIBRARAY_EXPORT int GetEntityAPI2_Post (gamefuncs_t *functionTable, int *) { // this function is called right after FuncPointers_t() by the engine in the game DLL (or // what it BELIEVES to be the game DLL), in order to copy the list of MOD functions that can @@ -2879,7 +2864,7 @@ export int GetEntityAPI2_Post (gamefuncs_t *functionTable, int *) return TRUE; } -export int GetNewDLLFunctions (newgamefuncs_t *functionTable, int *interfaceVersion) +SHARED_LIBRARAY_EXPORT int GetNewDLLFunctions (newgamefuncs_t *functionTable, int *interfaceVersion) { // it appears that an extra function table has been added in the engine to gamedll interface // since the date where the first enginefuncs table standard was frozen. These ones are @@ -2900,11 +2885,11 @@ export int GetNewDLLFunctions (newgamefuncs_t *functionTable, int *interfaceVers return TRUE; } -export int GetEngineFunctions (enginefuncs_t *functionTable, int *) +SHARED_LIBRARAY_EXPORT int GetEngineFunctions (enginefuncs_t *functionTable, int *) { if (g_isMetamod) memset (functionTable, 0, sizeof (enginefuncs_t)); - + functionTable->pfnChangeLevel = pfnChangeLevel; functionTable->pfnFindEntityByString = pfnFindEntityByString; functionTable->pfnEmitSound = pfnEmitSound; @@ -2926,11 +2911,11 @@ export int GetEngineFunctions (enginefuncs_t *functionTable, int *) functionTable->pfnCmd_Argc = pfnCmd_Argc; functionTable->pfnSetClientMaxspeed = pfnSetClientMaxspeed; functionTable->pfnAlertMessage = pfnAlertMessage; - + return TRUE; } -export int GetEngineFunctions_Post (enginefuncs_t *functionTable, int *) +SHARED_LIBRARAY_EXPORT int GetEngineFunctions_Post (enginefuncs_t *functionTable, int *) { memset (functionTable, 0, sizeof (enginefuncs_t)); @@ -2939,7 +2924,7 @@ export int GetEngineFunctions_Post (enginefuncs_t *functionTable, int *) return TRUE; } -export int Server_GetBlendingInterface (int version, void **ppinterface, void *pstudio, float (*rotationmatrix)[3][4], float (*bonetransform)[128][3][4]) +SHARED_LIBRARAY_EXPORT int Server_GetBlendingInterface (int version, void **ppinterface, void *pstudio, float (*rotationmatrix)[3][4], float (*bonetransform)[128][3][4]) { // this function synchronizes the studio model animation blending interface (i.e, what parts // of the body move, which bones, which hitboxes and how) between the server and the game DLL. @@ -2951,63 +2936,24 @@ export int Server_GetBlendingInterface (int version, void **ppinterface, void *p return (*g_serverBlendingAPI) (version, ppinterface, pstudio, rotationmatrix, bonetransform); } -export int Meta_Query (char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs) +SHARED_LIBRARAY_EXPORT int Meta_Query (char *, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs) { // this function is the first function ever called by metamod in the plugin DLL. Its purpose // is for metamod to retrieve basic information about the plugin, such as its meta-interface // version, for ensuring compatibility with the current version of the running metamod. - // keep track of the pointers to metamod function tables metamod gives us gpMetaUtilFuncs = pMetaUtilFuncs; *pPlugInfo = &Plugin_info; - // check for interface version compatibility - if (strcmp (ifvers, Plugin_info.ifvers) != 0) - { - int metaMajor = 0, metaMinor = 0, pluginMajor = 0, pluginMinor = 0; - - LOG_CONSOLE (PLID, "%s: meta-interface version mismatch (metamod: %s, %s: %s)", Plugin_info.name, ifvers, Plugin_info.name, Plugin_info.ifvers); - LOG_MESSAGE (PLID, "%s: meta-interface version mismatch (metamod: %s, %s: %s)", Plugin_info.name, ifvers, Plugin_info.name, Plugin_info.ifvers); - - // if plugin has later interface version, it's incompatible (update metamod) - sscanf (ifvers, "%d:%d", &metaMajor, &metaMinor); - sscanf (META_INTERFACE_VERSION, "%d:%d", &pluginMajor, &pluginMinor); - - if (pluginMajor > metaMajor || (pluginMajor == metaMajor && pluginMinor > metaMinor)) - { - LOG_CONSOLE (PLID, "metamod version is too old for this plugin; update metamod"); - LOG_MMERROR (PLID, "metamod version is too old for this plugin; update metamod"); - - return FALSE; - } - - // if plugin has older major interface version, it's incompatible (update plugin) - else if (pluginMajor < metaMajor) - { - LOG_CONSOLE (PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin"); - LOG_MMERROR (PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin"); - - return FALSE; - } - } return TRUE; // tell metamod this plugin looks safe } -export int Meta_Attach (PLUG_LOADTIME now, metamod_funcs_t *functionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs) +SHARED_LIBRARAY_EXPORT int Meta_Attach (PLUG_LOADTIME, metamod_funcs_t *functionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs) { // this function is called when metamod attempts to load the plugin. Since it's the place // where we can tell if the plugin will be allowed to run or not, we wait until here to make // our initialization stuff, like registering CVARs and dedicated server commands. - // are we allowed to load this plugin now ? - if (now > Plugin_info.loadable) - { - LOG_CONSOLE (PLID, "%s: plugin NOT attaching (can't load plugin right now)", Plugin_info.name); - LOG_MMERROR (PLID, "%s: plugin NOT attaching (can't load plugin right now)", Plugin_info.name); - - return FALSE; // returning false prevents metamod from attaching this plugin - } - // keep track of the pointers to engine function tables metamod gives us gpMetaGlobals = pMGlobals; memcpy (functionTable, &gMetaFunctionTable, sizeof (metamod_funcs_t)); @@ -3016,27 +2962,18 @@ export int Meta_Attach (PLUG_LOADTIME now, metamod_funcs_t *functionTable, meta_ return TRUE; // returning true enables metamod to attach this plugin } -export int Meta_Detach (PLUG_LOADTIME now, PL_UNLOAD_REASON reason) +SHARED_LIBRARAY_EXPORT int Meta_Detach (PLUG_LOADTIME, PL_UNLOAD_REASON) { // this function is called when metamod unloads the plugin. A basic check is made in order // to prevent unloading the plugin if its processing should not be interrupted. - // is metamod allowed to unload the plugin? - if (now > Plugin_info.unloadable && reason != PNL_CMD_FORCED) - { - LOG_CONSOLE (PLID, "%s: plugin not detaching (can't unload plugin right now)", Plugin_info.name); - LOG_MMERROR (PLID, "%s: plugin not detaching (can't unload plugin right now)", Plugin_info.name); - - return FALSE; // returning false prevents metamod from unloading this plugin - } - bots.RemoveAll (); // kick all bots off this server FreeLibraryMemory (); return TRUE; } -export void Meta_Init (void) +SHARED_LIBRARAY_EXPORT void Meta_Init (void) { // this function is called by metamod, before any other interface functions. Purpose of this // function to give plugin a chance to determine is plugin running under metamod or not. @@ -3062,7 +2999,16 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t g_pGlobals = pGlobals; // register our cvars - convars.PushRegisteredConVarsToEngine (); + engine.PushRegisteredConVarsToEngine (); + + // ensure we're have all needed directories + { + const char *mod = engine.GetModName (); + + // create the needed paths + File::CreatePath (const_cast (FormatBuffer ("%s/addons/yapb/conf/lang", mod))); + File::CreatePath (const_cast (FormatBuffer ("%s/addons/yapb/data/learned", mod))); + } #ifdef PLATFORM_ANDROID g_gameFlags |= (GAME_LEGACY | GAME_XASH | GAME_MOBILITY); @@ -3071,13 +3017,13 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t return; // we should stop the attempt for loading the real gamedll, since metamod handle this for us #ifdef LOAD_HARDFP - #define GAME_SERVER_DLL "libserver_hardfp.so" + const char *serverDLL = "libserver_hardfp.so"; #else - #define GAME_SERVER_DLL "libserver.so" + const char *serverDLL = "libserver.so"; #endif char gameDLLName[256]; - snprintf (gameDLLName, SIZEOF_CHAR (gameDLLName), "%s/%s", getenv ("XASH3D_GAMELIBDIR"), GAME_SERVER_DLL); + snprintf (gameDLLName, SIZEOF_CHAR (gameDLLName), "%s/%s", getenv ("XASH3D_GAMELIBDIR"), serverDLL); g_gameLib = new Library (gameDLLName); @@ -3109,7 +3055,7 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t { ModSupport *mod = &s_supportedMods[i]; - if (strcmp (mod->name, GetModName ()) == 0 && File::Accessible (FormatBuffer ("%s/dlls/%s", mod->name, + if (strcmp (mod->name, engine.GetModName ()) == 0 && File::Accessible (FormatBuffer ("%s/dlls/%s", mod->name, #if defined (PLATFORM_WIN32) mod->winLib #elif defined (PLATFORM_LINUX) @@ -3145,10 +3091,10 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t g_gameLib = new Library (gameDLLName); if (!g_gameLib->IsLoaded ()) - AddLogEntry (true, LL_FATAL | LL_IGNORE, "Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", gameDLLName, GetModName ()); + AddLogEntry (true, LL_FATAL | LL_IGNORE, "Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", gameDLLName, engine.GetModName ()); } else - AddLogEntry (true, LL_FATAL | LL_IGNORE, "Mod that you has started, not supported by this bot (gamedir: %s)", GetModName ()); + AddLogEntry (true, LL_FATAL | LL_IGNORE, "Mod that you has started, not supported by this bot (gamedir: %s)", engine.GetModName ()); #endif g_funcPointers = g_gameLib->GetFuncAddr ("GiveFnptrsToDll"); @@ -3175,81 +3121,26 @@ DLL_ENTRYPOINT if (DLL_DETACHING) { FreeLibraryMemory (); // free everything that's freeable - delete g_gameLib; // if dynamic link library of mod is load, free it } DLL_RETENTRY; // the return data type is OS specific too } -void ConVarWrapper::RegisterVariable (const char *variable, const char *value, VarType varType, ConVar *self) +void LinkEntity_Helper (EntityPtr_t &addr, const char *name, entvars_t *pev) { - VarPair newVariable; - memset (&newVariable, 0, sizeof (VarPair)); + if (addr == NULL) + addr = g_gameLib->GetFuncAddr (name); - newVariable.reg.name = const_cast (variable); - newVariable.reg.string = const_cast (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) -{ - // here we're see an ugliest hack :) - if (entAddress == NULL || (g_gameFlags & GAME_OFFICIAL_CSBOT)) - entAddress = g_gameLib->GetFuncAddr (name); - - if (entAddress == NULL) + if (addr == NULL) return; - entAddress (pev); + addr (pev); } #define LINK_ENTITY(entityName) \ -export void entityName (entvars_t *pev) \ +SHARED_LIBRARAY_EXPORT void entityName (entvars_t *pev) \ { \ - static EntityPtr_t addr = NULL; \ + static EntityPtr_t addr; \ LinkEntity_Helper (addr, #entityName, pev); \ } \ diff --git a/source/manager.cpp b/source/manager.cpp index 1679461..131bcf9 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -1,4 +1,4 @@ -// +// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // @@ -41,11 +41,12 @@ BotManager::BotManager (void) m_creationTab.RemoveAll (); m_killerEntity = NULL; + m_balanceCount = 0; } BotManager::~BotManager (void) { - // this is a bot manager class destructor, do not use GetMaxClients () here !! + // this is a bot manager class destructor, do not use engine.MaxClients () here !! Free (); } @@ -66,13 +67,13 @@ void BotManager::CreateKillerEntity (void) void BotManager::DestroyKillerEntity (void) { - if (!IsEntityNull (m_killerEntity)) + if (!engine.IsNullEntity (m_killerEntity)) g_engfuncs.pfnRemoveEntity (m_killerEntity); } void BotManager::TouchWithKillerEntity (Bot *bot) { - if (IsEntityNull (m_killerEntity)) + if (engine.IsNullEntity (m_killerEntity)) { MDLL_ClientKill (bot->GetEntity ()); return; @@ -117,12 +118,12 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality, if (g_numWaypoints < 1) // don't allow creating bots with no waypoints loaded { - CenterPrint ("Map is not waypointed. Cannot create bot"); + engine.CenterPrintf ("Map is not waypointed. Cannot create bot"); return 0; } else if (g_waypointsChanged) // don't allow creating bots with changed waypoints (distance tables are messed up) { - CenterPrint ("Waypoints have been changed. Load waypoints again..."); + engine.CenterPrintf ("Waypoints have been changed. Load waypoints again..."); return 0; } @@ -194,14 +195,14 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality, strcpy (outputName, prefixedName); } - if (IsEntityNull ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName)))) + if (engine.IsNullEntity ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName)))) { - CenterPrint ("Maximum players reached (%d/%d). Unable to create Bot.", GetMaxClients (), GetMaxClients ()); + engine.CenterPrintf ("Maximum players reached (%d/%d). Unable to create Bot.", engine.MaxClients (), engine.MaxClients ()); return 2; } - int index = IndexOfEntity (bot) - 1; + int index = engine.IndexOfEntity (bot) - 1; - InternalAssert (index >= 0 && index <= 32); // check index + InternalAssert (index >= 0 && index <= MAX_ENGINE_PLAYERS); // check index InternalAssert (m_bots[index] == NULL); // check bot slot m_bots[index] = new Bot (bot, difficulty, personality, team, member, steamId); @@ -209,7 +210,7 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality, if (m_bots[index] == NULL) TerminateOnMalloc (); - ServerPrint ("Connecting Bot..."); + engine.Printf ("Connecting Bot..."); return 1; } @@ -217,12 +218,12 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality, int BotManager::GetIndex (edict_t *ent) { // this function returns index of bot (using own bot array) - if (IsEntityNull (ent)) + if (engine.IsNullEntity (ent)) return -1; - int index = IndexOfEntity (ent) - 1; + int index = engine.IndexOfEntity (ent) - 1; - if (index < 0 || index >= 32) + if (index < 0 || index >= MAX_ENGINE_PLAYERS) return -1; if (m_bots[index] != NULL) @@ -235,7 +236,7 @@ Bot *BotManager::GetBot (int index) { // this function finds a bot specified by index, and then returns pointer to it (using own bot array) - if (index < 0 || index >= 32) + if (index < 0 || index >= MAX_ENGINE_PLAYERS) return NULL; if (m_bots[index] != NULL) @@ -257,7 +258,7 @@ Bot *BotManager::FindOneValidAliveBot (void) Array foundBots; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (foundBots.GetSize () > 4) break; @@ -276,7 +277,7 @@ void BotManager::Think (void) { // this function calls think () function for all available at call moment bots - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (m_bots[i] != NULL) m_bots[i]->Think (); @@ -287,7 +288,7 @@ void BotManager::PeriodicThink (void) { // this function calls periodic SecondThink () function for all available at call moment bots - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (m_bots[i] != NULL) m_bots[i]->PeriodicThink (); @@ -329,9 +330,9 @@ void BotManager::AddBot (const String &name, const String &difficulty, const Str void BotManager::AdjustQuota (bool isPlayerConnection, edict_t *ent) { - // this function increases or decreases bot quota amount depending on autovacate variables + // this function increases or decreases bot quota amount depending on auto vacate variables - if (!IsDedicatedServer () || !yb_autovacate.GetBool () || GetBot (ent) != NULL) + if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || GetBot (ent) != NULL) return; if (isPlayerConnection) @@ -374,7 +375,7 @@ void BotManager::VerifyPlayersHasJoinedTeam (int &desiredCount) if (!m_trackedPlayers.GetElementNumber ()) return; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Client &cl = g_clients[i]; @@ -405,7 +406,7 @@ void BotManager::MaintainBotQuota (void) return; // bot's creation update - if (!m_creationTab.IsEmpty () && m_maintainTime < GetWorldTime ()) + if (!m_creationTab.IsEmpty () && m_maintainTime < engine.Time ()) { CreateQueue last = m_creationTab.Pop (); int resultOfCall = CreateBot (last.name, last.difficulty, last.personality, last.team, last.member); @@ -421,11 +422,11 @@ void BotManager::MaintainBotQuota (void) m_creationTab.RemoveAll (); // maximum players reached, so set quota to maximum players yb_quota.SetInt (GetBotsNum ()); } - m_maintainTime = GetWorldTime () + 0.45f; + m_maintainTime = engine.Time () + 0.20f; } // now keep bot number up to date - if (m_quotaMaintainTime < GetWorldTime ()) + if (m_quotaMaintainTime < engine.Time ()) { // don't allow that quota is below zero if (yb_quota.GetInt () < 0) @@ -447,9 +448,9 @@ void BotManager::MaintainBotQuota (void) desiredCount = max (0, yb_quota.GetInt () * numHumans); if (yb_autovacate.GetBool ()) - desiredCount = min (desiredCount, GetMaxClients () - (numHumans + 1)); + desiredCount = min (desiredCount, engine.MaxClients () - (numHumans + 1)); else - desiredCount = min (desiredCount, GetMaxClients () - numHumans); + desiredCount = min (desiredCount, engine.MaxClients () - numHumans); if (yb_autovacate_smart_kick.GetBool () && numBots > 1 && desiredCount > 1) VerifyPlayersHasJoinedTeam (desiredCount); @@ -459,7 +460,7 @@ void BotManager::MaintainBotQuota (void) else if (desiredCount < numBots) RemoveRandom (); - m_quotaMaintainTime = GetWorldTime () + 0.90f; + m_quotaMaintainTime = engine.Time () + 0.90f; } } @@ -467,8 +468,8 @@ void BotManager::InitQuota (void) { m_balanceCount = 0; - m_maintainTime = GetWorldTime () + 3.0f; - m_quotaMaintainTime = GetWorldTime () + 3.0f; + m_maintainTime = engine.Time () + 3.0f; + m_quotaMaintainTime = engine.Time () + 3.0f; m_trackedPlayers.RemoveAll (); m_creationTab.RemoveAll (); @@ -478,7 +479,7 @@ void BotManager::FillServer (int selection, int personality, int difficulty, int { // this function fill server with bots, with specified team & personality - if (GetBotsNum () >= GetMaxClients () - GetHumansNum ()) + if (GetBotsNum () >= engine.MaxClients () - GetHumansNum ()) return; if (selection == 1 || selection == 2) @@ -499,14 +500,13 @@ void BotManager::FillServer (int selection, int personality, int difficulty, int {"Random"}, }; - int toAdd = numToAdd == -1 ? GetMaxClients () - (GetHumansNum () + GetBotsNum ()) : numToAdd; + int toAdd = numToAdd == -1 ? engine.MaxClients () - (GetHumansNum () + GetBotsNum ()) : numToAdd; for (int i = 0; i <= toAdd; i++) AddBot ("", difficulty, personality, selection, -1); yb_quota.SetInt (toAdd); - - CenterPrint ("Fill Server with %s bots...", &teamDesc[selection][0]); + engine.CenterPrintf ("Fill Server with %s bots...", &teamDesc[selection][0]); } void BotManager::RemoveAll (bool zeroQuota) @@ -514,9 +514,9 @@ void BotManager::RemoveAll (bool zeroQuota) // this function drops all bot clients from server (this function removes only yapb's)`q if (zeroQuota) - CenterPrint ("Bots are removed from server."); + engine.CenterPrintf ("Bots are removed from server."); - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (m_bots[i] != NULL) // is this slot used? m_bots[i]->Kick (); @@ -535,9 +535,9 @@ void BotManager::RemoveFromTeam (Team team, bool removeAll) { // this function remove random bot from specified team (if removeAll value = 1 then removes all players from team) - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - if (m_bots[i] != NULL && team == GetTeam (m_bots[i]->GetEntity ())) + if (m_bots[i] != NULL && team == engine.GetTeam (m_bots[i]->GetEntity ())) { m_bots[i]->Kick (); @@ -551,7 +551,6 @@ void BotManager::RemoveMenu (edict_t *ent, int selection) { // this function displays remove bot menu to specified entity (this function show's only yapb's). - if (selection > 4 || selection < 1) return; @@ -565,10 +564,10 @@ void BotManager::RemoveMenu (edict_t *ent, int selection) 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) && !engine.IsNullEntity (m_bots[i]->GetEntity ())) { 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), engine.GetTeam (m_bots[i]->GetEntity ()) == CT ? " \\y(CT)\\w" : " \\r(T)\\w"); } else sprintf (buffer, "%s\\d %1.1d. Not a Bot\\w\n", buffer, i - ((selection - 1) * 8) + 1); @@ -612,7 +611,7 @@ void BotManager::KillAll (int team) { // this function kills all bots on server (only this dll controlled bots) - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (m_bots[i] != NULL) { @@ -622,7 +621,7 @@ void BotManager::KillAll (int team) m_bots[i]->Kill (); } } - CenterPrint ("All Bots died !"); + engine.CenterPrintf ("All Bots died !"); } void BotManager::RemoveRandom (void) @@ -633,7 +632,7 @@ void BotManager::RemoveRandom (void) // first try to kick the bot that is currently dead - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (m_bots[i] != NULL && !m_bots[i]->m_notKilled) // is this slot used? { @@ -652,7 +651,7 @@ void BotManager::RemoveRandom (void) float score = 9999.0f; // search bots in this team - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); @@ -671,7 +670,7 @@ void BotManager::RemoveRandom (void) } // worst case, just kick some random bot - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (m_bots[i] != NULL) // is this slot used? { @@ -730,27 +729,22 @@ void BotManager::SetWeaponMode (int selection) else yb_jasonmode.SetInt (0); - CenterPrint ("%s weapon mode selected", &modeName[selection][0]); + engine.CenterPrintf ("%s weapon mode selected", &modeName[selection][0]); } void BotManager::ListBots (void) { // this function list's bots currently playing on the server - ServerPrint ("%-3.5s %-9.13s %-17.18s %-3.4s %-3.4s %-3.4s", "index", "name", "personality", "team", "difficulty", "frags"); + engine.Printf ("%-3.5s %-9.13s %-17.18s %-3.4s %-3.4s %-3.4s", "index", "name", "personality", "team", "difficulty", "frags"); - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - edict_t *player = EntityOfIndex (i); + Bot *bot = GetBot (i); // is this player slot valid - if (IsValidBot (player)) - { - Bot *bot = GetBot (player); - - if (bot != NULL) - ServerPrint ("[%-3.1d] %-9.13s %-17.18s %-3.4s %-3.1d %-3.1d", i, STRING (player->v.netname), bot->m_personality == PERSONALITY_RUSHER ? "rusher" : bot->m_personality == PERSONALITY_NORMAL ? "normal" : "careful", GetTeam (player) != 0 ? "CT" : "T", bot->m_difficulty, static_cast (player->v.frags)); - } + if (bot != NULL) + engine.Printf ("[%-3.1d] %-9.13s %-17.18s %-3.4s %-3.1d %-3.1d", i, STRING (bot->pev->netname), bot->m_personality == PERSONALITY_RUSHER ? "rusher" : bot->m_personality == PERSONALITY_NORMAL ? "normal" : "careful", bot->m_team == CT ? "CT" : "T", bot->m_difficulty, static_cast (bot->pev->frags)); } } @@ -760,7 +754,7 @@ int BotManager::GetBotsNum (void) int count = 0; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (m_bots[i] != NULL) count++; @@ -774,11 +768,11 @@ Bot *BotManager::GetHighestFragsBot (int team) float bestScore = -1; // search bots in this team - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); - if (bot != NULL && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == team) + if (bot != NULL && bot->m_notKilled && bot->m_team == team) { if (bot->pev->frags > bestScore) { @@ -798,7 +792,7 @@ void BotManager::CheckTeamEconomics (int team, bool setTrue) extern ConVar yb_economics_rounds; - if (!yb_economics_rounds.GetBool () || setTrue) + if (setTrue || !yb_economics_rounds.GetBool ()) { m_economicsGood[team] = true; return; // don't check economics while economics disable @@ -808,9 +802,9 @@ void BotManager::CheckTeamEconomics (int team, bool setTrue) int numTeamPlayers = 0; // start calculating - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - if (m_bots[i] != NULL && GetTeam (m_bots[i]->GetEntity ()) == team) + if (m_bots[i] != NULL && engine.GetTeam (m_bots[i]->GetEntity ()) == team) { if (m_bots[i]->m_moneyAmount <= g_botBuyEconomyTable[0]) numPoorPlayers++; @@ -836,7 +830,7 @@ void BotManager::Free (void) { // this function free all bots slots (used on server shutdown) - for (int i = 0; i < 32; i++) + for (int i = 0; i < MAX_ENGINE_PLAYERS; i++) Free (i); } @@ -854,7 +848,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c // when bot setup completed, (this is a bot class constructor) char rejectReason[128]; - int clientIndex = IndexOfEntity (bot); + int clientIndex = engine.IndexOfEntity (bot); memset (reinterpret_cast (this), 0, sizeof (*this)); @@ -877,7 +871,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c SET_CLIENT_KEYVALUE (clientIndex, buffer, "*bot", "1"); rejectReason[0] = 0; // reset the reject reason template string - MDLL_ClientConnect (bot, "BOT", FormatBuffer ("127.0.0.%d", IndexOfEntity (bot) + 100), rejectReason); + MDLL_ClientConnect (bot, "BOT", FormatBuffer ("127.0.0.%d", engine.IndexOfEntity (bot) + 100), rejectReason); // should be set after client connect if (yb_avatar_display.GetBool () && !steamId.IsEmpty ()) @@ -889,7 +883,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c if (!IsNullString (rejectReason)) { AddLogEntry (true, LL_WARNING, "Server refused '%s' connection (%s)", STRING (bot->v.netname), rejectReason); - ServerCommand ("kick \"%s\"", STRING (bot->v.netname)); // kick the bot player if the server refused it + engine.IssueCmd ("kick \"%s\"", STRING (bot->v.netname)); // kick the bot player if the server refused it bot->v.flags |= FL_KILLME; } @@ -918,8 +912,8 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c yb_difficulty.SetInt (difficulty); } - m_lastCommandTime = GetWorldTime () - 0.1f; - m_frameInterval = GetWorldTime (); + m_lastCommandTime = engine.Time () - 0.1f; + m_frameInterval = engine.Time (); m_timePeriodicUpdate = 0.0f; switch (personality) @@ -952,7 +946,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c // copy them over to the temp level variables m_agressionLevel = m_baseAgressionLevel; m_fearLevel = m_baseFearLevel; - m_nextEmotionUpdate = GetWorldTime () + 0.5f; + m_nextEmotionUpdate = engine.Time () + 0.5f; // just to be sure m_actMessageIndex = 0; @@ -965,7 +959,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c int newBotsNum = bots.GetBotsNum () + 1; // keep quota number up to date - if (newBotsNum < GetMaxClients () && newBotsNum > yb_quota.GetInt ()) + if (newBotsNum < engine.MaxClients () && newBotsNum > yb_quota.GetInt ()) yb_quota.SetInt (newBotsNum); NewRound (); @@ -999,7 +993,7 @@ int BotManager::GetHumansNum (void) int count = 0; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Client *cl = &g_clients[i]; @@ -1015,7 +1009,7 @@ int BotManager::GetHumansAliveNum (void) int count = 0; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Client *cl = &g_clients[i]; @@ -1031,7 +1025,7 @@ int BotManager::GetHumansJoinedTeam (void) int count = 0; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Client *cl = &g_clients[i]; @@ -1072,8 +1066,8 @@ void Bot::NewRound (void) for (i = 0; i < 5; i++) m_prevWptIndex[i] = -1; - m_navTimeset = GetWorldTime (); - m_team = GetTeam (GetEntity ()); + m_navTimeset = engine.Time (); + m_team = engine.GetTeam (GetEntity ()); switch (m_personality) { @@ -1102,13 +1096,14 @@ void Bot::NewRound (void) m_maxThrowTimer = 0.0f; m_timeTeamOrder = 0.0f; + m_timeRepotingInDelay = Random.Float (40.0f, 240.0f); m_askCheckTime = 0.0f; m_minSpeed = 260.0f; m_prevSpeed = 0.0f; m_prevOrigin = Vector (9999.0f, 9999.0f, 9999.0f); - m_prevTime = GetWorldTime (); - m_blindRecognizeTime = GetWorldTime (); - m_lookUpdateTime = GetWorldTime (); + m_prevTime = engine.Time (); + m_blindRecognizeTime = engine.Time (); + m_lookUpdateTime = engine.Time (); m_viewDistance = 4096.0f; m_maxViewDistance = 4096.0f; @@ -1119,7 +1114,7 @@ void Bot::NewRound (void) m_itemCheckTime = 0.0f; m_breakableEntity = NULL; - m_breakable.Zero (); + m_breakableOrigin.Zero (); m_timeDoorOpen = 0.0f; ResetCollideState (); @@ -1157,7 +1152,7 @@ void Bot::NewRound (void) SetIdealReactionTimes (true); m_targetEntity = NULL; - m_tasks = NULL; + m_tasks.RemoveAll (); m_followWaitTime = 0.0f; for (i = 0; i < MAX_HOSTAGES; i++) @@ -1170,8 +1165,8 @@ void Bot::NewRound (void) m_reloadState = RELOAD_NONE; m_reloadCheckTime = 0.0f; - m_shootTime = GetWorldTime (); - m_playerTargetTime = GetWorldTime (); + m_shootTime = engine.Time (); + m_playerTargetTime = engine.Time (); m_firePause = 0.0f; m_timeLastFired = 0.0f; @@ -1185,7 +1180,7 @@ void Bot::NewRound (void) m_jumpFinished = false; m_isStuck = false; - m_sayTextBuffer.timeNextChat = GetWorldTime (); + m_sayTextBuffer.timeNextChat = engine.Time (); m_sayTextBuffer.entityIndex = -1; m_sayTextBuffer.sayText[0] = 0x0; @@ -1200,8 +1195,8 @@ void Bot::NewRound (void) m_currentWeapon = 0; } - m_knifeAttackTime = GetWorldTime () + Random.Float (1.3f, 2.6f); - m_nextBuyTime = GetWorldTime () + Random.Float (0.6f, 2.0f); + m_knifeAttackTime = engine.Time () + Random.Float (1.3f, 2.6f); + m_nextBuyTime = engine.Time () + Random.Float (0.6f, 2.0f); m_buyPending = false; m_inBombZone = false; @@ -1210,8 +1205,8 @@ void Bot::NewRound (void) m_shieldCheckTime = 0.0f; m_zoomCheckTime = 0.0f; m_strafeSetTime = 0.0f; - m_combatStrafeDir = 0; - m_fightStyle = 0; + m_combatStrafeDir = STRAFE_DIR_NONE; + m_fightStyle = FIGHT_NONE; m_lastFightStyleCheck = 0.0f; m_checkWeaponSwitch = true; @@ -1224,9 +1219,9 @@ void Bot::NewRound (void) m_defendHostage = false; m_headedTime = 0.0f; - m_timeLogoSpray = GetWorldTime () + Random.Float (0.5f, 2.0f); - m_spawnTime = GetWorldTime (); - m_lastChatTime = GetWorldTime (); + m_timeLogoSpray = engine.Time () + Random.Float (0.5f, 2.0f); + m_spawnTime = engine.Time (); + m_lastChatTime = engine.Time (); m_timeCamping = 0; m_campDirection = 0; @@ -1234,7 +1229,7 @@ void Bot::NewRound (void) m_campButtons = 0; m_soundUpdateTime = 0.0f; - m_heardSoundTime = GetWorldTime (); + m_heardSoundTime = engine.Time (); // clear its message queue for (i = 0; i < 32; i++) @@ -1270,13 +1265,13 @@ void Bot::Kick (void) { // this function kick off one bot from the server. - ServerCommand ("kick \"%s\"", STRING (pev->netname)); - CenterPrint ("Bot '%s' kicked", STRING (pev->netname)); + engine.IssueCmd ("kick \"%s\"", STRING (pev->netname)); + engine.CenterPrintf ("Bot '%s' kicked", STRING (pev->netname)); int newBotsNum = bots.GetBotsNum () - 1; // keep quota number up to date - if (newBotsNum < GetMaxClients () && newBotsNum < yb_quota.GetInt ()) + if (newBotsNum < engine.MaxClients () && newBotsNum < yb_quota.GetInt ()) yb_quota.SetInt (newBotsNum); } @@ -1287,7 +1282,7 @@ void Bot::StartGame (void) #ifdef XASH_CSDM 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"); @@ -1314,7 +1309,7 @@ void Bot::StartGame (void) m_wantedTeam = 5; // 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) { @@ -1332,7 +1327,7 @@ void Bot::StartGame (void) } // 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) m_notStarted = false; @@ -1351,9 +1346,9 @@ void BotManager::CalculatePingOffsets (void) int averagePing = 0; int numHumans = 0; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - edict_t *ent = EntityOfIndex (i + 1); + edict_t *ent = engine.EntityOfIndex (i + 1); if (!IsValidPlayer (ent)) continue; @@ -1374,7 +1369,7 @@ void BotManager::CalculatePingOffsets (void) else averagePing = Random.Long (30, 40); - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = GetBot (i); @@ -1405,7 +1400,7 @@ void BotManager::CalculatePingOffsets (void) 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 || engine.IsNullEntity (to) || (to->v.flags & FL_FAKECLIENT)) return; if (!(to->v.flags & FL_CLIENT) && !(((to->v.button & IN_SCORE) || !(to->v.oldbuttons & IN_SCORE)))) @@ -1417,9 +1412,9 @@ void BotManager::SendPingDataOffsets (edict_t *to) // missing from sdk static const int SVC_PINGS = 17; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { - Bot *bot = GetBot (i); + Bot *bot = m_bots[i]; if (bot == NULL) continue; @@ -1470,7 +1465,7 @@ void BotManager::SendDeathMsgFix (void) { m_deathMsgSent = false; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) SendPingDataOffsets (g_clients[i].ent); } } @@ -1483,7 +1478,7 @@ void BotManager::UpdateActiveGrenades (void) m_activeGrenades.RemoveAll (); // search the map for any type of grenade - while (!IsEntityNull (grenade = FIND_ENTITY_BY_CLASSNAME (grenade, "grenade"))) + while (!engine.IsNullEntity (grenade = FIND_ENTITY_BY_CLASSNAME (grenade, "grenade"))) { // do not count c4 as a grenade if (strcmp (STRING (grenade->v.model) + 9, "c4.mdl") == 0) @@ -1493,7 +1488,7 @@ void BotManager::UpdateActiveGrenades (void) } } -const Array &BotManager::GetActiveGrenades (void) +const Array &BotManager::GetActiveGrenades (void) { return m_activeGrenades; } diff --git a/source/navigate.cpp b/source/navigate.cpp index b2b3da0..e610d4d 100644 --- a/source/navigate.cpp +++ b/source/navigate.cpp @@ -1,4 +1,4 @@ -// +// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // @@ -18,11 +18,11 @@ int Bot::FindGoal (void) { edict_t *pent = NULL; - while (!IsEntityNull (pent = FIND_ENTITY_BY_STRING (pent, "classname", "weaponbox"))) + while (!engine.IsNullEntity (pent = FIND_ENTITY_BY_STRING (pent, "classname", "weaponbox"))) { if (strcmp (STRING (pent->v.model), "models/w_backpack.mdl") == 0) { - int index = waypoints.FindNearest (GetEntityOrigin (pent)); + int index = waypoints.FindNearest (engine.GetAbsOrigin (pent)); if (index >= 0 && index < g_numWaypoints) return m_loosedBombWptIndex = index; @@ -30,6 +30,10 @@ int Bot::FindGoal (void) break; } } + + // forcing terrorist bot to not move to another bombspot + if (m_inBombZone && !m_hasProgressBar && m_hasC4) + return waypoints.FindNearest (pev->origin, 400.0f, FLAG_GOAL); } int tactic = 0; @@ -116,7 +120,7 @@ int Bot::FindGoal (void) if (m_personality != PERSONALITY_RUSHER) defensive += 10.0f; } - else if ((g_mapType & MAP_DE) && m_team == TERRORIST && g_timeRoundStart + 10.0f < GetWorldTime ()) + else if ((g_mapType & MAP_DE) && m_team == TERRORIST && g_timeRoundStart + 10.0f < engine.Time ()) { // send some terrorists to guard planted bomb if (!m_defendedBomb && g_bombPlanted && GetTaskId () != TASK_ESCAPEFROMBOMB && GetBombTimeleft () >= 15.0) @@ -167,7 +171,7 @@ TacticChoosen: else if (tactic == 3 && !waypoints.m_goalPoints.IsEmpty ()) // map goal waypoint { // force bomber to select closest goal, if round-start goal was reset by something - if (m_hasC4 && g_timeRoundStart + 10.0f < GetWorldTime ()) + if (m_hasC4 && g_timeRoundStart + 10.0f < engine.Time ()) { float minDist = 99999.0f; int count = 0; @@ -302,21 +306,21 @@ void Bot::IgnoreCollisionShortly (void) { ResetCollideState (); - m_lastCollTime = GetWorldTime () + 0.35f; + m_lastCollTime = engine.Time () + 0.35f; m_isStuck = false; m_checkTerrain = false; } void Bot::CheckCloseAvoidance (const Vector &dirNormal) { - if (m_seeEnemyTime + 1.5f < GetWorldTime ()) + if (m_seeEnemyTime + 1.5f < engine.Time ()) return; edict_t *nearest = NULL; float nearestDist = 99999.0f; int playerCount = 0; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Client *cl = &g_clients[i]; @@ -372,28 +376,26 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) // Standing still, no need to check? // FIXME: doesn't care for ladder movement (handled separately) should be included in some way - if ((m_moveSpeed >= 10.0f || m_strafeSpeed >= 10.0f) && m_lastCollTime < GetWorldTime () && m_seeEnemyTime + 0.8f < GetWorldTime () && GetTaskId () != TASK_ATTACK) + if ((m_moveSpeed >= 10.0f || m_strafeSpeed >= 10.0f) && m_lastCollTime < engine.Time () && m_seeEnemyTime + 0.8f < engine.Time () && GetTaskId () != TASK_ATTACK) { - bool cantMoveForward = false; - if (movedDistance < 2.0f && m_prevSpeed >= 20.0f) // didn't we move enough previously? { // Then consider being stuck - m_prevTime = GetWorldTime (); + m_prevTime = engine.Time (); m_isStuck = true; if (m_firstCollideTime == 0.0) - m_firstCollideTime = GetWorldTime () + 0.2f; + m_firstCollideTime = engine.Time () + 0.2f; } else // not stuck yet { // test if there's something ahead blocking the way - if ((cantMoveForward = CantMoveForward (dirNormal, &tr)) && !IsOnLadder ()) + if (CantMoveForward (dirNormal, &tr) && !IsOnLadder ()) { if (m_firstCollideTime == 0.0f) - m_firstCollideTime = GetWorldTime () + 0.2f; + m_firstCollideTime = engine.Time () + 0.2f; - else if (m_firstCollideTime <= GetWorldTime ()) + else if (m_firstCollideTime <= engine.Time ()) m_isStuck = true; } else @@ -402,7 +404,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) if (!m_isStuck) // not stuck? { - if (m_probeTime + 0.5f < GetWorldTime ()) + if (m_probeTime + 0.5f < engine.Time ()) ResetCollideState (); // reset collision memory if not being stuck for 0.5 secs else { @@ -427,7 +429,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) else if (IsInWater ()) bits |= (PROBE_JUMP | PROBE_STRAFE); else - bits |= (PROBE_STRAFE | (m_jumpStateTimer < GetWorldTime () ? PROBE_JUMP : 0)); + bits |= (PROBE_STRAFE | (m_jumpStateTimer < engine.Time () ? PROBE_JUMP : 0)); // collision check allowed if not flying through the air if (IsOnFloor () || IsOnLadder () || IsInWater ()) @@ -439,7 +441,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) state[i++] = COLLISION_STRAFELEFT; state[i++] = COLLISION_STRAFERIGHT; state[i++] = COLLISION_JUMP; - // state[i++] = COLLISION_DUCK; + state[i++] = COLLISION_DUCK; if (bits & PROBE_STRAFE) { @@ -468,7 +470,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) src = pev->origin + g_pGlobals->v_right * 32.0f; dst = src + testDir * 32.0f; - TraceHull (src, dst, true, head_hull, GetEntity (), &tr); + engine.TestHull (src, dst, TRACE_IGNORE_MONSTERS, head_hull, GetEntity (), &tr); if (tr.flFraction != 1.0f) blockedRight = true; @@ -476,7 +478,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) src = pev->origin - g_pGlobals->v_right * 32.0f; dst = src + testDir * 32.0f; - TraceHull (src, dst, true, head_hull, GetEntity (), &tr); + engine.TestHull (src, dst, TRACE_IGNORE_MONSTERS, head_hull, GetEntity (), &tr); if (tr.flFraction != 1.0f) blockedLeft = true; @@ -518,14 +520,14 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) src = EyePosition (); src = src + g_pGlobals->v_right * 15.0f; - TraceLine (src, m_destOrigin, true, true, GetEntity (), &tr); + engine.TestLine (src, m_destOrigin, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); if (tr.flFraction >= 1.0f) { src = EyePosition (); src = src - g_pGlobals->v_right * 15.0f; - TraceLine (src, m_destOrigin, true, true, GetEntity (), &tr); + engine.TestLine (src, m_destOrigin, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); if (tr.flFraction >= 1.0f) state[i] += 5; @@ -537,7 +539,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) src = pev->origin + Vector (0.0f, 0.0f, -17.0f); dst = src + dirNormal * 30.0f; - TraceLine (src, dst, true, true, GetEntity (), &tr); + engine.TestLine (src, dst, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); if (tr.flFraction != 1.0f) state[i] += 10; @@ -546,6 +548,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) state[i] = 0; i++; +#if 0 if (bits & PROBE_DUCK) { state[i] = 0; @@ -557,7 +560,8 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) state[i] += 5; } else - state[i] = 0; +#endif + state[i] = 0; i++; // weighted all possible moves, now sort them to start with most probable @@ -588,8 +592,8 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) for (i = 0; i < MAX_COLLIDE_MOVES; i++) m_collideMoves[i] = state[i]; - m_collideTime = GetWorldTime (); - m_probeTime = GetWorldTime () + 0.5f; + m_collideTime = engine.Time (); + m_probeTime = engine.Time () + 0.5f; m_collisionProbeBits = bits; m_collisionState = COLLISION_PROBING; m_collStateIndex = 0; @@ -598,14 +602,14 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) if (m_collisionState == COLLISION_PROBING) { - if (m_probeTime < GetWorldTime ()) + if (m_probeTime < engine.Time ()) { m_collStateIndex++; - m_probeTime = GetWorldTime () + 0.5f; + m_probeTime = engine.Time () + 0.5f; if (m_collStateIndex > MAX_COLLIDE_MOVES) { - m_navTimeset = GetWorldTime () - 5.0f; + m_navTimeset = engine.Time () - 5.0f; ResetCollideState (); } } @@ -660,7 +664,7 @@ bool Bot::DoWaypointNav (void) MakeVectors (Vector (pev->angles.x, AngleNormalize (pev->angles.y + Random.Float (-90.0f, 90.0f)), 0.0f)); m_waypointOrigin = m_waypointOrigin + g_pGlobals->v_forward * Random.Float (0, m_currentPath->radius); } - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); } if (pev->flags & FL_DUCKING) @@ -715,26 +719,26 @@ bool Bot::DoWaypointNav (void) bool liftClosedDoorExists = false; // update waypoint time set - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); // trace line to door - TraceLine (pev->origin, m_currentPath->origin, true, true, GetEntity (), &tr2); + engine.TestLine (pev->origin, m_currentPath->origin, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr2); if (tr2.flFraction < 1.0f && strcmp (STRING (tr2.pHit->v.classname), "func_door") == 0 && (m_liftState == LIFT_NO_NEARBY || m_liftState == LIFT_WAITING_FOR || m_liftState == LIFT_LOOKING_BUTTON_OUTSIDE) && pev->groundentity != tr2.pHit) { if (m_liftState == LIFT_NO_NEARBY) { m_liftState = LIFT_LOOKING_BUTTON_OUTSIDE; - m_liftUsageTime = GetWorldTime () + 7.0; + m_liftUsageTime = engine.Time () + 7.0; } liftClosedDoorExists = true; } // trace line down - TraceLine (m_currentPath->origin, m_currentPath->origin + Vector (0.0f, 0.0f, -50.0f), true, true, 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 (!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 (!engine.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) { @@ -743,13 +747,13 @@ bool Bot::DoWaypointNav (void) m_liftEntity = tr.pHit; m_liftState = LIFT_ENTERING_IN; m_liftTravelPos = m_currentPath->origin; - m_liftUsageTime = GetWorldTime () + 5.0f; + m_liftUsageTime = engine.Time () + 5.0f; } } else if (m_liftState == LIFT_TRAVELING_BY) { m_liftState = LIFT_LEAVING; - m_liftUsageTime = GetWorldTime () + 7.0f; + m_liftUsageTime = engine.Time () + 7.0f; } } else if (m_navNode != NULL) // no lift found at waypoint @@ -758,13 +762,13 @@ bool Bot::DoWaypointNav (void) { if (m_navNode->next->index >= 0 && m_navNode->next->index < g_numWaypoints && (waypoints.GetPath (m_navNode->next->index)->flags & FLAG_LIFT)) { - TraceLine (m_currentPath->origin, waypoints.GetPath (m_navNode->next->index)->origin, true, true, 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 (!engine.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_liftState = LIFT_LOOKING_BUTTON_OUTSIDE; - m_liftUsageTime = GetWorldTime () + 15.0f; + m_liftUsageTime = engine.Time () + 15.0f; } } @@ -779,7 +783,7 @@ bool Bot::DoWaypointNav (void) m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_aimFlags |= AIM_NAVPOINT; ResetCollideState (); @@ -788,14 +792,14 @@ bool Bot::DoWaypointNav (void) bool needWaitForTeammate = false; // if some bot is following a bot going into lift - he should take the same lift to go - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); if (bot == NULL || bot == this) continue; - if (!IsAlive (bot->GetEntity ()) || GetTeam (bot->GetEntity ()) != m_team || bot->m_targetEntity != GetEntity () || bot->GetTaskId () != TASK_FOLLOWUSER) + if (!bot->m_notKilled || bot->m_team != m_team || bot->m_targetEntity != GetEntity () || bot->GetTaskId () != TASK_FOLLOWUSER) continue; if (bot->pev->groundentity == m_liftEntity && bot->IsOnFloor ()) @@ -811,12 +815,12 @@ bool Bot::DoWaypointNav (void) if (needWaitForTeammate) { m_liftState = LIFT_WAIT_FOR_TEAMMATES; - m_liftUsageTime = GetWorldTime () + 8.0f; + m_liftUsageTime = engine.Time () + 8.0f; } else { m_liftState = LIFT_LOOKING_BUTTON_INSIDE; - m_liftUsageTime = GetWorldTime () + 10.0f; + m_liftUsageTime = engine.Time () + 10.0f; } } } @@ -827,14 +831,14 @@ bool Bot::DoWaypointNav (void) // need to wait our following teammate ? bool needWaitForTeammate = false; - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); if (bot == NULL) continue; // skip invalid bots - if (!IsAlive (bot->GetEntity ()) || GetTeam (bot->GetEntity ()) != m_team || bot->m_targetEntity != GetEntity () || bot->GetTaskId () != TASK_FOLLOWUSER || bot->m_liftEntity != m_liftEntity) + if (!bot->m_notKilled || bot->m_team != m_team || bot->m_targetEntity != GetEntity () || bot->GetTaskId () != TASK_FOLLOWUSER || bot->m_liftEntity != m_liftEntity) continue; if (bot->pev->groundentity == m_liftEntity || !bot->IsOnFloor ()) @@ -854,7 +858,7 @@ bool Bot::DoWaypointNav (void) m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_aimFlags |= AIM_NAVPOINT; ResetCollideState (); @@ -862,10 +866,10 @@ bool Bot::DoWaypointNav (void) } // else we need to look for button - if (!needWaitForTeammate || m_liftUsageTime < GetWorldTime ()) + if (!needWaitForTeammate || m_liftUsageTime < engine.Time ()) { m_liftState = LIFT_LOOKING_BUTTON_INSIDE; - m_liftUsageTime = GetWorldTime () + 10.0; + m_liftUsageTime = engine.Time () + 10.0; } } @@ -875,29 +879,29 @@ bool Bot::DoWaypointNav (void) edict_t *button = FindNearestButton (STRING (m_liftEntity->v.targetname)); // got a valid button entity ? - if (!IsEntityNull (button) && pev->groundentity == m_liftEntity && m_buttonPushTime + 1.0f < GetWorldTime () && m_liftEntity->v.velocity.z == 0.0f && IsOnFloor ()) + if (!engine.IsNullEntity (button) && pev->groundentity == m_liftEntity && m_buttonPushTime + 1.0f < engine.Time () && m_liftEntity->v.velocity.z == 0.0f && IsOnFloor ()) { m_pickupItem = button; m_pickupType = PICKUP_BUTTON; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); } } // 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 (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) || !engine.IsNullEntity (m_targetEntity))) { m_liftState = LIFT_TRAVELING_BY; - m_liftUsageTime = GetWorldTime () + 14.0f; + m_liftUsageTime = engine.Time () + 14.0f; if ((pev->origin - m_destOrigin).GetLengthSquared () < 225.0f) { m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_aimFlags |= AIM_NAVPOINT; ResetCollideState (); @@ -915,7 +919,7 @@ bool Bot::DoWaypointNav (void) m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_aimFlags |= AIM_NAVPOINT; ResetCollideState (); @@ -927,7 +931,7 @@ bool Bot::DoWaypointNav (void) { // button has been pressed, lift should come - if (m_buttonPushTime + 8.0f >= GetWorldTime ()) + if (m_buttonPushTime + 8.0f >= engine.Time ()) { if (m_prevWptIndex[0] >= 0 && m_prevWptIndex[0] < g_numWaypoints) m_destOrigin = waypoints.GetPath (m_prevWptIndex[0])->origin; @@ -939,26 +943,26 @@ bool Bot::DoWaypointNav (void) m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_aimFlags |= AIM_NAVPOINT; ResetCollideState (); } } - else if (!IsEntityNull(m_liftEntity)) + else if (!engine.IsNullEntity(m_liftEntity)) { edict_t *button = FindNearestButton (STRING (m_liftEntity->v.targetname)); // if we got a valid button entity - if (!IsEntityNull (button)) + if (!engine.IsNullEntity (button)) { // lift is already used ? bool liftUsed = false; // iterate though clients, and find if lift already used - for (int i = 0; i < GetMaxClients (); 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 () || engine.IsNullEntity (g_clients[i].ent->v.groundentity)) continue; if (g_clients[i].ent->v.groundentity == m_liftEntity) @@ -988,14 +992,14 @@ bool Bot::DoWaypointNav (void) m_pickupType = PICKUP_BUTTON; m_liftState = LIFT_WAITING_FOR; - m_navTimeset = GetWorldTime (); - m_liftUsageTime = GetWorldTime () + 20.0f; + m_navTimeset = engine.Time (); + m_liftUsageTime = engine.Time () + 20.0f; } } else { m_liftState = LIFT_WAITING_FOR; - m_liftUsageTime = GetWorldTime () + 15.0f; + m_liftUsageTime = engine.Time () + 15.0f; } } } @@ -1016,7 +1020,7 @@ bool Bot::DoWaypointNav (void) m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_aimFlags |= AIM_NAVPOINT; ResetCollideState (); @@ -1047,14 +1051,14 @@ bool Bot::DoWaypointNav (void) } } - if (!IsEntityNull (m_liftEntity) && !(m_currentPath->flags & FLAG_LIFT)) + if (!engine.IsNullEntity (m_liftEntity) && !(m_currentPath->flags & FLAG_LIFT)) { if (m_liftState == LIFT_TRAVELING_BY) { m_liftState = LIFT_LEAVING; - m_liftUsageTime = GetWorldTime () + 10.0f; + m_liftUsageTime = engine.Time () + 10.0f; } - if (m_liftState == LIFT_LEAVING && m_liftUsageTime < GetWorldTime () && pev->groundentity != m_liftEntity) + if (m_liftState == LIFT_LEAVING && m_liftUsageTime < engine.Time () && pev->groundentity != m_liftEntity) { m_liftState = LIFT_NO_NEARBY; m_liftUsageTime = 0.0f; @@ -1063,7 +1067,7 @@ bool Bot::DoWaypointNav (void) } } - if (m_liftUsageTime < GetWorldTime () && m_liftUsageTime != 0.0f) + if (m_liftUsageTime < engine.Time () && m_liftUsageTime != 0.0f) { m_liftEntity = NULL; m_liftState = LIFT_NO_NEARBY; @@ -1085,12 +1089,12 @@ bool Bot::DoWaypointNav (void) } // check if we are going through a door... - TraceLine (pev->origin, m_waypointOrigin, true, 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 (!engine.IsNullEntity (tr.pHit) && engine.IsNullEntity (m_liftEntity) && strncmp (STRING (tr.pHit->v.classname), "func_door", 9) == 0) { // if the door is near enough... - if ((GetEntityOrigin (tr.pHit) - pev->origin).GetLengthSquared () < 2500.0f) + if ((engine.GetAbsOrigin (tr.pHit) - pev->origin).GetLengthSquared () < 2500.0f) { IgnoreCollisionShortly (); // don't consider being stuck @@ -1104,39 +1108,39 @@ bool Bot::DoWaypointNav (void) edict_t *button = FindNearestButton (STRING (tr.pHit->v.targetname)); // check if we got valid button - if (!IsEntityNull (button)) + if (!engine.IsNullEntity (button)) { m_pickupItem = button; m_pickupType = PICKUP_BUTTON; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); } // if bot hits the door, then it opens, so wait a bit to let it open safely - if (pev->velocity.GetLength2D () < 2 && m_timeDoorOpen < GetWorldTime ()) + if (pev->velocity.GetLength2D () < 2 && m_timeDoorOpen < engine.Time ()) { - PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + 1, false); + PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, engine.Time () + 1, false); m_doorOpenAttempt++; - m_timeDoorOpen = GetWorldTime () + 1.0f; // retry in 1 sec until door is open + m_timeDoorOpen = engine.Time () + 1.0f; // retry in 1 sec until door is open edict_t *ent = NULL; - if (m_doorOpenAttempt > 2 && !IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, 256.0f))) + if (m_doorOpenAttempt > 2 && !engine.IsNullEntity (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, 512.0f))) { - if (IsValidPlayer (ent) && IsAlive (ent) && m_team != GetTeam (ent) && GetWeaponPenetrationPower (m_currentWeapon) > 0) + if (IsValidPlayer (ent) && IsAlive (ent) && m_team != engine.GetTeam (ent) && GetWeaponPenetrationPower (m_currentWeapon) > 0) { - m_seeEnemyTime = GetWorldTime (); + m_seeEnemyTime = engine.Time () - 0.5f; - m_states |= STATE_SUSPECT_ENEMY; - m_aimFlags |= AIM_LAST_ENEMY; + m_states |= STATE_SEEING_ENEMY; + m_aimFlags |= AIM_ENEMY; m_lastEnemy = ent; m_enemy = ent; m_lastEnemyOrigin = ent->v.origin; } - else if (IsValidPlayer (ent) && IsAlive (ent) && m_team == GetTeam (ent)) + else if (IsValidPlayer (ent) && IsAlive (ent) && m_team == engine.GetTeam (ent)) { DeleteSearchNodes (); ResetTasks (); @@ -1406,7 +1410,6 @@ public: } }; - float gfunctionKillsDistT (int currentIndex, int parentIndex) { // least kills and number of nodes to goal for a team @@ -1923,7 +1926,7 @@ bool Bot::FindWaypoint (void) waypointIndeces[i] = Random.Long (0, g_numWaypoints - 1); } - m_collideTime = GetWorldTime (); + m_collideTime = engine.Time (); ChangeWptIndex (waypointIndeces[i]); return true; @@ -1943,7 +1946,7 @@ void Bot::GetValidWaypoint (void) // FIXME: Do some error checks if we got a waypoint } - else if (m_navTimeset + GetEstimatedReachTime () < GetWorldTime () && IsEntityNull (m_enemy)) + else if (m_navTimeset + GetEstimatedReachTime () < engine.Time () && engine.IsNullEntity (m_enemy)) { if (m_team == TERRORIST) { @@ -2034,7 +2037,7 @@ int Bot::ChangeWptIndex(int waypointIndex) m_prevWptIndex[0] = m_currentWaypointIndex; m_currentWaypointIndex = waypointIndex; - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); m_currentPath = waypoints.GetPath (m_currentWaypointIndex); m_waypointFlags = m_currentPath->flags; @@ -2119,7 +2122,7 @@ int Bot::FindDefendWaypoint (const Vector &origin) if (distance > 512) continue; - TraceLine (waypoints.GetPath (i)->origin, waypoints.GetPath (posIndex)->origin, true, true, GetEntity (), &tr); + engine.TestLine (waypoints.GetPath (i)->origin, waypoints.GetPath (posIndex)->origin, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); // check if line not hit anything if (tr.flFraction != 1.0f) @@ -2331,7 +2334,7 @@ int Bot::FindCoverWaypoint (float maxDistance) { if (waypointIndex[i] != -1) { - TraceLine (m_lastEnemyOrigin + Vector (0.0f, 0.0f, 36.0f), waypoints.GetPath (waypointIndex[i])->origin, true, true, GetEntity (), &tr); + engine.TestLine (m_lastEnemyOrigin + Vector (0.0f, 0.0f, 36.0f), waypoints.GetPath (waypointIndex[i])->origin, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); if (tr.flFraction < 1.0f) return waypointIndex[i]; @@ -2400,7 +2403,7 @@ bool Bot::HeadTowardWaypoint (void) m_minSpeed = pev->maxspeed; // only if we in normal task and bomb is not planted - if (GetTaskId () == TASK_NORMAL && g_timeRoundMid + 5.0f < GetWorldTime () && m_timeCamping + 5.0f < GetWorldTime () && !g_bombPlanted && m_personality != PERSONALITY_RUSHER && !m_hasC4 && !m_isVIP && m_loosedBombWptIndex == -1 && !HasHostage ()) + if (GetTaskId () == TASK_NORMAL && g_timeRoundMid + 5.0f < engine.Time () && m_timeCamping + 5.0f < engine.Time () && !g_bombPlanted && m_personality != PERSONALITY_RUSHER && !m_hasC4 && !m_isVIP && m_loosedBombWptIndex == -1 && !HasHostage ()) { m_campButtons = 0; @@ -2413,7 +2416,7 @@ bool Bot::HeadTowardWaypoint (void) kills = (g_experienceData + (nextIndex * g_numWaypoints) + nextIndex)->team1Damage; // if damage done higher than one - if (kills > 1.0f && g_timeRoundMid > GetWorldTime ()) + if (kills > 1.0f && g_timeRoundMid > engine.Time ()) { switch (m_personality) { @@ -2428,8 +2431,8 @@ bool Bot::HeadTowardWaypoint (void) if (m_baseAgressionLevel < kills && HasPrimaryWeapon ()) { - PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (m_difficulty * 0.5f, m_difficulty) * 5.0f, true); - PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, FindDefendWaypoint (waypoints.GetPath (nextIndex)->origin), GetWorldTime () + Random.Float (3.0f, 10.0f), true); + PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (m_difficulty * 0.5f, m_difficulty) * 5.0f, true); + PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, FindDefendWaypoint (waypoints.GetPath (nextIndex)->origin), engine.Time () + Random.Float (3.0f, 10.0f), true); } } else if (g_botsCanPause && !IsOnLadder () && !IsInWater () && !m_currentTravelFlags && IsOnFloor ()) @@ -2490,21 +2493,21 @@ bool Bot::HeadTowardWaypoint (void) } // 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)) && engine.IsNullEntity (m_enemy)) SelectWeaponByName ("weapon_knife"); // draw out the knife if we needed // bot not already on ladder but will be soon? if ((waypoints.GetPath (destIndex)->flags & FLAG_LADDER) && !IsOnLadder ()) { // get ladder waypoints used by other (first moving) bots - for (int c = 0; c < GetMaxClients (); c++) + for (int c = 0; c < engine.MaxClients (); c++) { Bot *otherBot = bots.GetBot (c); // if another bot uses this ladder, wait 3 secs if (otherBot != NULL && otherBot != this && IsAlive (otherBot->GetEntity ()) && otherBot->m_currentWaypointIndex == m_navNode->index) { - PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + 3.0f, false); + PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, engine.Time () + 3.0f, false); return true; } } @@ -2524,12 +2527,12 @@ bool Bot::HeadTowardWaypoint (void) if (IsOnLadder ()) { - TraceLine (Vector (pev->origin.x, pev->origin.y, pev->absmin.z), m_waypointOrigin, true, true, GetEntity (), &tr); + engine.TestLine (Vector (pev->origin.x, pev->origin.y, pev->absmin.z), m_waypointOrigin, TRACE_IGNORE_EVERYTHING, GetEntity (), &tr); if (tr.flFraction < 1.0f) m_waypointOrigin = m_waypointOrigin + (pev->origin - m_waypointOrigin) * 0.5f + Vector (0.0f, 0.0f, 32.0f); } - m_navTimeset = GetWorldTime (); + m_navTimeset = engine.Time (); return true; } @@ -2547,7 +2550,7 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr) MakeVectors (Vector (0.0f, pev->angles.y, 0.0f)); // trace from the bot's eyes straight forward... - TraceLine (src, forward, true, GetEntity (), tr); + engine.TestLine (src, forward, TRACE_IGNORE_MONSTERS, GetEntity (), tr); // check if the trace hit something... if (tr->flFraction < 1.0f) @@ -2563,7 +2566,7 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr) src = EyePosition () + Vector (0.0f, 0.0f, -16.0f) - g_pGlobals->v_right * -16.0f; forward = EyePosition () + Vector (0.0f, 0.0f, -16.0f) + g_pGlobals->v_right * 16.0f + normal * 24.0f; - TraceLine (src, forward, true, GetEntity (), tr); + engine.TestLine (src, forward, TRACE_IGNORE_MONSTERS, GetEntity (), tr); // check if the trace hit something... if (tr->flFraction < 1.0f && strncmp ("func_door", STRING (tr->pHit->v.classname), 9) != 0) @@ -2574,7 +2577,7 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr) src = EyePosition () + Vector (0.0f, 0.0f, -16.0f) + g_pGlobals->v_right * 16.0f; forward = EyePosition () + Vector (0.0f, 0.0f, -16.0f) - g_pGlobals->v_right * -16.0f + normal * 24.0f; - TraceLine (src, forward, true, GetEntity (), tr); + engine.TestLine (src, forward, TRACE_IGNORE_MONSTERS, GetEntity (), tr); // check if the trace hit something... if (tr->flFraction < 1.0f && strncmp ("func_door", STRING (tr->pHit->v.classname), 9) != 0) @@ -2586,7 +2589,7 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr) src = pev->origin + Vector (0.0f, 0.0f, -19.0f + 19.0f); forward = src + Vector (0.0f, 0.0f, 10.0f) + normal * 24.0f; - TraceLine (src, forward, true, GetEntity (), tr); + engine.TestLine (src, forward, TRACE_IGNORE_MONSTERS, GetEntity (), tr); // check if the trace hit something... if (tr->flFraction < 1.0f && strncmp ("func_door", STRING (tr->pHit->v.classname), 9) != 0) @@ -2595,7 +2598,7 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr) src = pev->origin; forward = src + normal * 24.0f; - TraceLine (src, forward, true, GetEntity (), tr); + engine.TestLine (src, forward, TRACE_IGNORE_MONSTERS, GetEntity (), tr); // check if the trace hit something... if (tr->flFraction < 1.0f && strncmp ("func_door", STRING (tr->pHit->v.classname), 9) != 0) @@ -2608,7 +2611,7 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr) forward = pev->origin + Vector (0.0f, 0.0f, -17.0f) + g_pGlobals->v_right * 16.0f + normal * 24.0f; // trace from the bot's waist straight forward... - TraceLine (src, forward, true, GetEntity (), tr); + engine.TestLine (src, forward, TRACE_IGNORE_MONSTERS, GetEntity (), tr); // check if the trace hit something... if (tr->flFraction < 1.0f && strncmp ("func_door", STRING (tr->pHit->v.classname), 9) != 0) @@ -2618,7 +2621,7 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr) src = pev->origin + Vector (0.0f, 0.0f, -17.0f) + g_pGlobals->v_right * 16.0f; forward = pev->origin + Vector (0.0f, 0.0f, -17.0f) - g_pGlobals->v_right * -16.0f + normal * 24.0f; - TraceLine (src, forward, true, GetEntity (), tr); + engine.TestLine (src, forward, TRACE_IGNORE_MONSTERS, GetEntity (), tr); // check if the trace hit something... if (tr->flFraction < 1.0f && strncmp ("func_door", STRING (tr->pHit->v.classname), 9) != 0) @@ -2706,7 +2709,7 @@ bool Bot::CanJumpUp (const Vector &normal) Vector dest = src + normal * 32.0f; // trace a line forward at maximum jump height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); if (tr.flFraction < 1.0f) goto CheckDuckJump; @@ -2716,7 +2719,7 @@ bool Bot::CanJumpUp (const Vector &normal) src = dest; dest.z = dest.z + 37.0f; - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); if (tr.flFraction < 1.0f) return false; @@ -2727,7 +2730,7 @@ bool Bot::CanJumpUp (const Vector &normal) dest = src + normal * 32.0f; // trace a line forward at maximum jump height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false if (tr.flFraction < 1.0f) @@ -2737,7 +2740,7 @@ bool Bot::CanJumpUp (const Vector &normal) src = dest; dest.z = dest.z + 37.0f; - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false if (tr.flFraction < 1.0f) @@ -2748,7 +2751,7 @@ bool Bot::CanJumpUp (const Vector &normal) dest = src + normal * 32.0f; // trace a line forward at maximum jump height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false if (tr.flFraction < 1.0f) @@ -2758,7 +2761,7 @@ bool Bot::CanJumpUp (const Vector &normal) src = dest; dest.z = dest.z + 37.0f; - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false return tr.flFraction > 1.0f; @@ -2771,7 +2774,7 @@ CheckDuckJump: dest = src + normal * 32.0f; // trace a line forward at maximum jump height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); if (tr.flFraction < 1.0f) return false; @@ -2781,7 +2784,7 @@ CheckDuckJump: src = dest; dest.z = dest.z + 37.0f; - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, check duckjump if (tr.flFraction < 1.0f) @@ -2793,7 +2796,7 @@ CheckDuckJump: dest = src + normal * 32.0f; // trace a line forward at maximum jump height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false if (tr.flFraction < 1.0f) @@ -2803,7 +2806,7 @@ CheckDuckJump: src = dest; dest.z = dest.z + 37.0f; - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false if (tr.flFraction < 1.0f) @@ -2814,7 +2817,7 @@ CheckDuckJump: dest = src + normal * 32.0f; // trace a line forward at maximum jump height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false if (tr.flFraction < 1.0f) @@ -2824,7 +2827,7 @@ CheckDuckJump: src = dest; dest.z = dest.z + 37.0f; - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false return tr.flFraction > 1.0f; @@ -2850,7 +2853,7 @@ bool Bot::CanDuckUnder (const Vector &normal) Vector dest = src + normal * 32.0f; // trace a line forward at duck height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false if (tr.flFraction < 1.0f) @@ -2861,7 +2864,7 @@ bool Bot::CanDuckUnder (const Vector &normal) dest = src + normal * 32.0f; // trace a line forward at duck height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false if (tr.flFraction < 1.0f) @@ -2872,7 +2875,7 @@ bool Bot::CanDuckUnder (const Vector &normal) dest = src + normal * 32.0f; // trace a line forward at duck height... - TraceLine (src, dest, true, GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // if trace hit something, return false return tr.flFraction > 1.0f; @@ -2891,7 +2894,7 @@ bool Bot::IsBlockedLeft (void) MakeVectors (pev->angles); // do a trace to the left... - TraceLine (pev->origin, g_pGlobals->v_forward * direction - g_pGlobals->v_right * 48.0f, true, GetEntity (), &tr); + engine.TestLine (pev->origin, g_pGlobals->v_forward * direction - g_pGlobals->v_right * 48.0f, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // check if the trace hit something... if (tr.flFraction < 1.0f && strncmp ("func_door", STRING (tr.pHit->v.classname), 9) != 0) @@ -2911,7 +2914,7 @@ bool Bot::IsBlockedRight (void) MakeVectors (pev->angles); // do a trace to the right... - TraceLine (pev->origin, pev->origin + g_pGlobals->v_forward * direction + g_pGlobals->v_right * 48.0f, true, GetEntity (), &tr); + engine.TestLine (pev->origin, pev->origin + g_pGlobals->v_forward * direction + g_pGlobals->v_right * 48.0f, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // check if the trace hit something... if (tr.flFraction < 1.0f && (strncmp ("func_door", STRING (tr.pHit->v.classname), 9) != 0)) @@ -2927,7 +2930,7 @@ bool Bot::CheckWallOnLeft (void) TraceResult tr; MakeVectors (pev->angles); - TraceLine (pev->origin, pev->origin - g_pGlobals->v_right * 40.0f, true, GetEntity (), &tr); + engine.TestLine (pev->origin, pev->origin - g_pGlobals->v_right * 40.0f, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // check if the trace hit something... if (tr.flFraction < 1.0f) @@ -2942,7 +2945,7 @@ bool Bot::CheckWallOnRight (void) MakeVectors (pev->angles); // do a trace to the right... - TraceLine (pev->origin, pev->origin + g_pGlobals->v_right * 40.0f, true, GetEntity (), &tr); + engine.TestLine (pev->origin, pev->origin + g_pGlobals->v_right * 40.0f, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); // check if the trace hit something... if (tr.flFraction < 1.0f) @@ -2967,7 +2970,7 @@ bool Bot::IsDeadlyDrop (const Vector &to) down.z = down.z - 1000.0f; // straight down 1000 units - TraceHull (check, down, true, head_hull, GetEntity (), &tr); + engine.TestHull (check, down, TRACE_IGNORE_MONSTERS, head_hull, GetEntity (), &tr); if (tr.flFraction > 0.036f) // we're not on ground anymore? tr.flFraction = 0.036f; @@ -2983,7 +2986,7 @@ bool Bot::IsDeadlyDrop (const Vector &to) down = check; down.z = down.z - 1000.0f; // straight down 1000 units - TraceHull (check, down, true, head_hull, GetEntity (), &tr); + engine.TestHull (check, down, TRACE_IGNORE_MONSTERS, head_hull, GetEntity (), &tr); if (tr.fStartSolid) // Wall blocking? return false; @@ -3132,8 +3135,8 @@ void Bot::UpdateBodyAngles (void) void Bot::UpdateLookAngles (void) { - const float delta = Clamp (GetWorldTime () - m_lookUpdateTime, MATH_EQEPSILON, 0.05f); - m_lookUpdateTime = GetWorldTime (); + const float delta = Clamp (engine.Time () - m_lookUpdateTime, MATH_EQEPSILON, 0.05f); + m_lookUpdateTime = engine.Time (); // adjust all body and view angles to face an absolute vector Vector direction = (m_lookAt - EyePosition ()).ToAngles (); @@ -3226,7 +3229,7 @@ void Bot::UpdateLookAnglesLowSkill (const Vector &direction, const float delta) if (m_aimFlags & (AIM_ENEMY | AIM_ENTITY | AIM_GRENADE | AIM_LAST_ENEMY) || GetTaskId () == TASK_SHOOTBREAKABLE) { - m_playerTargetTime = GetWorldTime (); + m_playerTargetTime = engine.Time (); m_randomizedIdealAngles = m_idealAngles; stiffness = spring * (0.2f + (m_difficulty * 25) / 125.0f); @@ -3234,7 +3237,7 @@ void Bot::UpdateLookAnglesLowSkill (const Vector &direction, const float delta) else { // is it time for bot to randomize the aim direction again (more often where moving) ? - if (m_randomizeAnglesTime < GetWorldTime () && ((pev->velocity.GetLength () > 1.0f && m_angularDeviation.GetLength () < 5.0f) || m_angularDeviation.GetLength () < 1.0f)) + if (m_randomizeAnglesTime < engine.Time () && ((pev->velocity.GetLength () > 1.0f && m_angularDeviation.GetLength () < 5.0f) || m_angularDeviation.GetLength () < 1.0f)) { // is the bot standing still ? if (pev->velocity.GetLength () < 1.0f) @@ -3246,14 +3249,14 @@ void Bot::UpdateLookAnglesLowSkill (const Vector &direction, const float delta) m_randomizedIdealAngles = m_idealAngles + Vector (Random.Float (-randomize.x * 0.5f, randomize.x * 1.5f), Random.Float (-randomize.y, randomize.y), 0.0f); // set next time to do this - m_randomizeAnglesTime = GetWorldTime () + Random.Float (0.4f, offsetDelay); + m_randomizeAnglesTime = engine.Time () + Random.Float (0.4f, offsetDelay); } float stiffnessMultiplier = noTargetRatio; // take in account whether the bot was targeting someone in the last N seconds - if (GetWorldTime () - (m_playerTargetTime + offsetDelay) < noTargetRatio * 10.0f) + if (engine.Time () - (m_playerTargetTime + offsetDelay) < noTargetRatio * 10.0f) { - stiffnessMultiplier = 1.0f - (GetWorldTime () - m_timeLastFired) * 0.1f; + stiffnessMultiplier = 1.0f - (engine.Time () - m_timeLastFired) * 0.1f; // don't allow that stiffness multiplier less than zero if (stiffnessMultiplier < 0.0f) @@ -3310,11 +3313,11 @@ int Bot::FindPlantedBomb (void) edict_t *bombEntity = NULL; // temporaly pointer to bomb // search the bomb on the map - while (!IsEntityNull (bombEntity = FIND_ENTITY_BY_CLASSNAME (bombEntity, "grenade"))) + while (!engine.IsNullEntity (bombEntity = FIND_ENTITY_BY_CLASSNAME (bombEntity, "grenade"))) { if (strcmp (STRING (bombEntity->v.model) + 9, "c4.mdl") == 0) { - int nearestIndex = waypoints.FindNearest (GetEntityOrigin (bombEntity)); + int nearestIndex = waypoints.FindNearest (engine.GetAbsOrigin (bombEntity)); if (nearestIndex >= 0 && nearestIndex < g_numWaypoints) return nearestIndex; @@ -3331,7 +3334,7 @@ bool Bot::IsPointOccupied (int index) return true; // first check if current waypoint of one of the bots is index waypoint - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { Bot *bot = bots.GetBot (i); @@ -3341,7 +3344,7 @@ bool Bot::IsPointOccupied (int index) // check if this waypoint is already used // 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; @@ -3367,9 +3370,9 @@ edict_t *Bot::FindNearestButton (const char *targetName) edict_t *searchEntity = NULL, *foundEntity = NULL; // find the nearest button which can open our target - while (!IsEntityNull(searchEntity = FIND_ENTITY_BY_TARGET (searchEntity, targetName))) + while (!engine.IsNullEntity(searchEntity = FIND_ENTITY_BY_TARGET (searchEntity, targetName))) { - Vector entityOrign = GetEntityOrigin (searchEntity); + Vector entityOrign = engine.GetAbsOrigin (searchEntity); // check if this place safe if (!IsDeadlyDrop (entityOrign)) diff --git a/source/netmsg.cpp b/source/netmsg.cpp deleted file mode 100644 index c0d1b1f..0000000 --- a/source/netmsg.cpp +++ /dev/null @@ -1,499 +0,0 @@ -// -// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). -// Copyright (c) YaPB Development Team. -// -// This software is licensed under the BSD-style license. -// Additional exceptions apply. For full license details, see LICENSE.txt or visit: -// http://yapb.jeefo.net/license -// - -#include - -NetworkMsg::NetworkMsg (void) -{ - m_message = NETMSG_UNDEFINED; - m_state = 0; - m_bot = NULL; - - for (int i = 0; i < NETMSG_BOTVOICE; i++) - m_registerdMessages[i] = -1; -} - -void NetworkMsg::HandleMessageIfRequired (int messageType, int requiredType) -{ - if (messageType == m_registerdMessages[requiredType]) - SetMessage (requiredType); -} - -void NetworkMsg::Execute (void *p) -{ - if (m_message == NETMSG_UNDEFINED) - return; // no message or not for bot, return - - // some needed variables - static byte r, g, b; - static byte enabled; - - static int damageArmor, damageTaken, damageBits; - static int killerIndex, victimIndex, playerIndex; - static int index, numPlayers; - static int state, id, clip; - - static Vector damageOrigin; - static WeaponProperty weaponProp; - - // now starts of netmessage execution - switch (m_message) - { - case NETMSG_VGUI: - // this message is sent when a VGUI menu is displayed. - - if (m_state == 0) - { - switch (PTR_TO_INT (p)) - { - case VMS_TEAM: - m_bot->m_startAction = GSM_TEAM_SELECT; - break; - - case VMS_TF: - case VMS_CT: - m_bot->m_startAction = GSM_CLASS_SELECT; - break; - } - } - break; - - case NETMSG_SHOWMENU: - // this message is sent when a text menu is displayed. - - if (m_state < 3) // ignore first 3 fields of message - break; - - if (strcmp (PTR_TO_STR (p), "#Team_Select") == 0) // team select menu? - m_bot->m_startAction = GSM_TEAM_SELECT; - else if (strcmp (PTR_TO_STR (p), "#Team_Select_Spect") == 0) // team select menu? - m_bot->m_startAction = GSM_TEAM_SELECT; - else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select_Spect") == 0) // team select menu? - m_bot->m_startAction = GSM_TEAM_SELECT; - else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select") == 0) // team select menu? - m_bot->m_startAction = GSM_TEAM_SELECT; - else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select") == 0) // team select menu? - m_bot->m_startAction = GSM_TEAM_SELECT; - else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select_Spect") == 0) // team select menu? - m_bot->m_startAction = GSM_TEAM_SELECT; - else if (strcmp (PTR_TO_STR (p), "#Terrorist_Select") == 0) // T model select? - m_bot->m_startAction = GSM_CLASS_SELECT; - else if (strcmp (PTR_TO_STR (p), "#CT_Select") == 0) // CT model select menu? - m_bot->m_startAction = GSM_CLASS_SELECT; - - break; - - case NETMSG_WEAPONLIST: - // this message is sent when a client joins the game. All of the weapons are sent with the weapon ID and information about what ammo is used. - - switch (m_state) - { - case 0: - strncpy (weaponProp.className, PTR_TO_STR (p), SIZEOF_CHAR (weaponProp.className)); - break; - - case 1: - weaponProp.ammo1 = PTR_TO_INT (p); // ammo index 1 - break; - - case 2: - weaponProp.ammo1Max = PTR_TO_INT (p); // max ammo 1 - break; - - case 5: - weaponProp.slotID = PTR_TO_INT (p); // slot for this weapon - break; - - case 6: - weaponProp.position = PTR_TO_INT (p); // position in slot - break; - - case 7: - weaponProp.id = PTR_TO_INT (p); // weapon ID - break; - - case 8: - weaponProp.flags = PTR_TO_INT (p); // flags for weapon (WTF???) - g_weaponDefs[weaponProp.id] = weaponProp; // store away this weapon with it's ammo information... - break; - } - break; - - case NETMSG_CURWEAPON: - // this message is sent when a weapon is selected (either by the bot chosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased - - switch (m_state) - { - case 0: - state = PTR_TO_INT (p); // state of the current weapon (WTF???) - break; - - case 1: - id = PTR_TO_INT (p); // weapon ID of current weapon - break; - - case 2: - clip = PTR_TO_INT (p); // ammo currently in the clip for this weapon - - if (id <= 31) - { - if (state != 0) - m_bot->m_currentWeapon = id; - - // ammo amount decreased ? must have fired a bullet... - if (id == m_bot->m_currentWeapon && m_bot->m_ammoInClip[id] > clip) - m_bot->m_timeLastFired = GetWorldTime (); // remember the last bullet time - - m_bot->m_ammoInClip[id] = clip; - } - break; - } - break; - - case NETMSG_AMMOX: - // this message is sent whenever ammo amounts are adjusted (up or down). NOTE: Logging reveals that CS uses it very unreliable! - - switch (m_state) - { - case 0: - index = PTR_TO_INT (p); // ammo index (for type of ammo) - break; - - case 1: - m_bot->m_ammo[index] = PTR_TO_INT (p); // store it away - break; - } - break; - - case NETMSG_AMMOPICKUP: - // this message is sent when the bot picks up some ammo (AmmoX messages are also sent so this message is probably - // not really necessary except it allows the HUD to draw pictures of ammo that have been picked up. The bots - // don't really need pictures since they don't have any eyes anyway. - - switch (m_state) - { - case 0: - index = PTR_TO_INT (p); - break; - - case 1: - m_bot->m_ammo[index] = PTR_TO_INT (p); - break; - } - break; - - case NETMSG_DAMAGE: - // this message gets sent when the bots are getting damaged. - - switch (m_state) - { - case 0: - damageArmor = PTR_TO_INT (p); - break; - - case 1: - damageTaken = PTR_TO_INT (p); - break; - - case 2: - damageBits = PTR_TO_INT (p); - - if (m_bot != NULL && (damageArmor > 0 || damageTaken > 0)) - m_bot->TakeDamage (m_bot->pev->dmg_inflictor, damageTaken, damageArmor, damageBits); - break; - } - break; - - case NETMSG_MONEY: - // this message gets sent when the bots money amount changes - - if (m_state == 0) - m_bot->m_moneyAmount = PTR_TO_INT (p); // amount of money - break; - - case NETMSG_STATUSICON: - switch (m_state) - { - case 0: - enabled = PTR_TO_BYTE (p); - break; - - case 1: - if (strcmp (PTR_TO_STR (p), "defuser") == 0) - m_bot->m_hasDefuser = (enabled != 0); - else if (strcmp (PTR_TO_STR (p), "buyzone") == 0) - { - m_bot->m_inBuyZone = (enabled != 0); - - // try to equip in buyzone - m_bot->EquipInBuyzone (BUYSTATE_PRIMARY_WEAPON); - } - else if (strcmp (PTR_TO_STR (p), "vipsafety") == 0) - m_bot->m_inVIPZone = (enabled != 0); - else if (strcmp (PTR_TO_STR (p), "c4") == 0) - m_bot->m_inBombZone = (enabled == 2); - - break; - } - break; - - case NETMSG_DEATH: // this message sends on death - switch (m_state) - { - case 0: - killerIndex = PTR_TO_INT (p); - break; - - case 1: - victimIndex = PTR_TO_INT (p); - break; - - case 2: - bots.SetDeathMsgState (true); - - if (killerIndex != 0 && killerIndex != victimIndex) - { - edict_t *killer = EntityOfIndex (killerIndex); - edict_t *victim = EntityOfIndex (victimIndex); - - if (IsEntityNull (killer) || IsEntityNull (victim)) - break; - - if (yb_communication_type.GetInt () == 2) - { - // need to send congrats on well placed shot - for (int i = 0; i < GetMaxClients (); i++) - { - Bot *bot = bots.GetBot (i); - - if (bot != NULL && IsAlive (bot->GetEntity ()) && killer != bot->GetEntity () && bot->EntityIsVisible (victim->v.origin) && GetTeam (killer) == GetTeam (bot->GetEntity ()) && GetTeam (killer) != GetTeam (victim)) - { - if (killer == g_hostEntity) - bot->HandleChatterMessage ("#Bot_NiceShotCommander"); - else - bot->HandleChatterMessage ("#Bot_NiceShotPall"); - - break; - } - } - } - - // notice nearby to victim teammates, that attacker is near - for (int i = 0; i < GetMaxClients (); i++) - { - Bot *bot = bots.GetBot (i); - - if (bot != NULL && bot->m_seeEnemyTime + 2.0f < GetWorldTime () && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && IsEntityNull (bot->m_enemy) && GetTeam (killer) != GetTeam (victim)) - { - bot->m_actualReactionTime = 0.0f; - bot->m_seeEnemyTime = GetWorldTime (); - bot->m_enemy = killer; - bot->m_lastEnemy = killer; - bot->m_lastEnemyOrigin = killer->v.origin; - } - } - - Bot *bot = bots.GetBot (killer); - - // is this message about a bot who killed somebody? - if (bot != NULL) - bot->m_lastVictim = victim; - - else // did a human kill a bot on his team? - { - Bot *target = bots.GetBot (victim); - - if (target != NULL) - { - if (GetTeam (killer) == GetTeam (victim)) - target->m_voteKickIndex = killerIndex; - - target->m_notKilled = false; - } - } - } - break; - } - break; - - case NETMSG_SCREENFADE: // this message gets sent when the Screen fades (Flashbang) - switch (m_state) - { - case 3: - r = PTR_TO_BYTE (p); - break; - - case 4: - g = PTR_TO_BYTE (p); - break; - - case 5: - b = PTR_TO_BYTE (p); - break; - - case 6: - m_bot->TakeBlinded (Vector (r, g, b), PTR_TO_BYTE (p)); - break; - } - break; - - case NETMSG_HLTV: // round restart in steam cs - switch (m_state) - { - case 0: - numPlayers = PTR_TO_INT (p); - break; - - case 1: - if (numPlayers == 0 && PTR_TO_INT (p) == 0) - RoundInit (); - break; - } - break; - - - case NETMSG_RESETHUD: -#if 0 - if (m_bot != NULL) - m_bot->NewRound (); -#endif - break; - - case NETMSG_TEXTMSG: - if (m_state == 1) - { - if (FStrEq (PTR_TO_STR (p), "#CTs_Win") || - FStrEq (PTR_TO_STR (p), "#Bomb_Defused") || - FStrEq (PTR_TO_STR (p), "#Terrorists_Win") || - FStrEq (PTR_TO_STR (p), "#Round_Draw") || - FStrEq (PTR_TO_STR (p), "#All_Hostages_Rescued") || - FStrEq (PTR_TO_STR (p), "#Target_Saved") || - FStrEq (PTR_TO_STR (p), "#Hostages_Not_Rescued") || - FStrEq (PTR_TO_STR (p), "#Terrorists_Not_Escaped") || - FStrEq (PTR_TO_STR (p), "#VIP_Not_Escaped") || - FStrEq (PTR_TO_STR (p), "#Escaping_Terrorists_Neutralized") || - FStrEq (PTR_TO_STR (p), "#VIP_Assassinated") || - FStrEq (PTR_TO_STR (p), "#VIP_Escaped") || - FStrEq (PTR_TO_STR (p), "#Terrorists_Escaped") || - FStrEq (PTR_TO_STR (p), "#CTs_PreventEscape") || - FStrEq (PTR_TO_STR (p), "#Target_Bombed") || - FStrEq (PTR_TO_STR (p), "#Game_Commencing") || - FStrEq (PTR_TO_STR (p), "#Game_will_restart_in")) - { - g_roundEnded = true; - - if (FStrEq (PTR_TO_STR (p), "#Game_Commencing")) - g_isCommencing = true; - - if (FStrEq (PTR_TO_STR (p), "#CTs_Win")) - { - bots.SetLastWinner (CT); // update last winner for economics - - if (yb_communication_type.GetInt () == 2) - { - Bot *bot = bots.FindOneValidAliveBot (); - - if (bot != NULL && IsAlive (bot->GetEntity ())) - bot->HandleChatterMessage (PTR_TO_STR (p)); - } - } - - if (FStrEq (PTR_TO_STR (p), "#Game_will_restart_in")) - { - bots.CheckTeamEconomics (CT, true); - bots.CheckTeamEconomics (TERRORIST, true); - } - - if (FStrEq (PTR_TO_STR (p), "#Terrorists_Win")) - { - bots.SetLastWinner (TERRORIST); // update last winner for economics - - if (yb_communication_type.GetInt () == 2) - { - Bot *bot = bots.FindOneValidAliveBot (); - - if (bot != NULL && IsAlive (bot->GetEntity ())) - bot->HandleChatterMessage (PTR_TO_STR (p)); - } - } - waypoints.SetBombPosition (true); - } - else if (!g_bombPlanted && FStrEq (PTR_TO_STR (p), "#Bomb_Planted")) - { - waypoints.SetBombPosition (); - - g_bombPlanted = g_bombSayString = true; - g_timeBombPlanted = GetWorldTime (); - - for (int i = 0; i < GetMaxClients (); i++) - { - Bot *bot = bots.GetBot (i); - - if (bot != NULL && IsAlive (bot->GetEntity ())) - { - bot->DeleteSearchNodes (); - bot->ResetTasks (); - - if (yb_communication_type.GetInt () == 2 && Random.Long (0, 100) < 75 && GetTeam (bot->GetEntity ()) == CT) - bot->ChatterMessage (Chatter_WhereIsTheBomb); - } - } - } - else if (m_bot != NULL && FStrEq (PTR_TO_STR (p), "#Switch_To_BurstFire")) - m_bot->m_weaponBurstMode = BM_ON; - else if (m_bot != NULL && FStrEq (PTR_TO_STR (p), "#Switch_To_SemiAuto")) - m_bot->m_weaponBurstMode = BM_OFF; - } - break; - - case NETMSG_SCOREINFO: - switch (m_state) - { - case 0: - playerIndex = PTR_TO_INT (p); - break; - - case 4: - if (playerIndex >= 0 && playerIndex <= GetMaxClients ()) - { -#ifndef XASH_CSDM - Client &cl = g_clients[playerIndex - 1]; - - if (PTR_TO_INT (p) == 1) - cl.realTeam = TERRORIST; - else if (PTR_TO_INT (p) == 2) - cl.realTeam = CT; - else - cl.realTeam = SPECTATOR; - - if (yb_csdm_mode.GetInt () == 2) - cl.team = playerIndex; - else - cl.team = g_clients[playerIndex - 1].realTeam; -#endif - } - break; - } - break; - - case NETMSG_BARTIME: - if (m_state == 0) - { - if (PTR_TO_INT (p) > 0) - m_bot->m_hasProgressBar = true; // the progress bar on a hud - else if (PTR_TO_INT (p) == 0) - m_bot->m_hasProgressBar = false; // no progress bar or disappeared - } - break; - - default: - AddLogEntry (true, LL_FATAL, "Network message handler error. Call to unrecognized message id (%d).\n", m_message); - } - m_state++; // and finally update network message state -} diff --git a/source/support.cpp b/source/support.cpp index 988dde0..0115ee7 100644 --- a/source/support.cpp +++ b/source/support.cpp @@ -1,4 +1,4 @@ -// +// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // @@ -12,55 +12,7 @@ ConVar yb_display_menu_text ("yb_display_menu_text", "1"); ConVar mp_roundtime ("mp_roundtime", NULL, VT_NOREGISTER); - -#ifndef XASH_CSDM -ConVar mp_freezetime ("mp_freezetime", NULL, VT_NOREGISTER); -#else -ConVar mp_freezetime ("mp_freezetime", "0", VT_NOSERVER); -#endif - -void TraceLine (const Vector &start, const Vector &end, bool ignoreMonsters, bool ignoreGlass, edict_t *ignoreEntity, TraceResult *ptr) -{ - // this function traces a line dot by dot, starting from vecStart in the direction of vecEnd, - // ignoring or not monsters (depending on the value of IGNORE_MONSTERS, true or false), and stops - // at the first obstacle encountered, returning the results of the trace in the TraceResult structure - // ptr. Such results are (amongst others) the distance traced, the hit surface, the hit plane - // vector normal, etc. See the TraceResult structure for details. This function allows to specify - // whether the trace starts "inside" an entity's polygonal model, and if so, to specify that entity - // in ignoreEntity in order to ignore it as a possible obstacle. - // this is an overloaded prototype to add IGNORE_GLASS in the same way as IGNORE_MONSTERS work. - - (*g_engfuncs.pfnTraceLine) (start, end, (ignoreMonsters ? TRUE : FALSE) | (ignoreGlass ? 0x100 : 0), ignoreEntity, ptr); -} - -void TraceLine (const Vector &start, const Vector &end, bool ignoreMonsters, edict_t *ignoreEntity, TraceResult *ptr) -{ - // this function traces a line dot by dot, starting from vecStart in the direction of vecEnd, - // ignoring or not monsters (depending on the value of IGNORE_MONSTERS, true or false), and stops - // at the first obstacle encountered, returning the results of the trace in the TraceResult structure - // ptr. Such results are (amongst others) the distance traced, the hit surface, the hit plane - // vector normal, etc. See the TraceResult structure for details. This function allows to specify - // whether the trace starts "inside" an entity's polygonal model, and if so, to specify that entity - // in ignoreEntity in order to ignore it as a possible obstacle. - - (*g_engfuncs.pfnTraceLine) (start, end, ignoreMonsters ? TRUE : FALSE, ignoreEntity, ptr); -} - -void TraceHull (const Vector &start, const Vector &end, bool ignoreMonsters, int hullNumber, edict_t *ignoreEntity, TraceResult *ptr) -{ - // this function traces a hull dot by dot, starting from vecStart in the direction of vecEnd, - // ignoring or not monsters (depending on the value of IGNORE_MONSTERS, true or - // false), and stops at the first obstacle encountered, returning the results - // of the trace in the TraceResult structure ptr, just like TraceLine. Hulls that can be traced - // (by parameter hull_type) are point_hull (a line), head_hull (size of a crouching player), - // human_hull (a normal body size) and large_hull (for monsters?). Not all the hulls in the - // game can be traced here, this function is just useful to give a relative idea of spatial - // reachability (i.e. can a hostage pass through that tiny hole ?) Also like TraceLine, this - // function allows to specify whether the trace starts "inside" an entity's polygonal model, - // and if so, to specify that entity in ignoreEntity in order to ignore it as an obstacle. - - (*g_engfuncs.pfnTraceHull) (start, end, ignoreMonsters ? TRUE : FALSE, hullNumber, ignoreEntity, ptr); -} +ConVar mp_freezetime ("mp_freezetime", NULL, VT_NOREGISTER, true); uint16 FixedUnsigned16 (float value, float scale) { @@ -90,19 +42,25 @@ short FixedSigned16 (float value, float scale) const char *FormatBuffer (const char *format, ...) { - va_list ap; - static char staticBuffer[3072]; + static char strBuffer[2][MAX_PRINT_BUFFER]; + static int rotator = 0; + if (format == NULL) + return strBuffer[rotator]; + + static char *ptr = strBuffer[rotator ^= 1]; + + va_list ap; va_start (ap, format); - vsprintf (staticBuffer, format, ap); + vsnprintf (ptr, MAX_PRINT_BUFFER - 1, format, ap); va_end (ap); - return &staticBuffer[0]; + return ptr; } bool IsAlive (edict_t *ent) { - if (IsEntityNull (ent)) + if (engine.IsNullEntity (ent)) return false; return ent->v.deadflag == DEAD_NO && ent->v.health > 0 && ent->v.movetype != MOVETYPE_NOCLIP; @@ -129,11 +87,11 @@ bool IsInViewCone (const Vector &origin, edict_t *ent) bool IsVisible (const Vector &origin, edict_t *ent) { - if (IsEntityNull (ent)) + if (engine.IsNullEntity (ent)) return false; TraceResult tr; - TraceLine (ent->v.origin + ent->v.view_ofs, origin, true, true, ent, &tr); + engine.TestLine (ent->v.origin + ent->v.view_ofs, origin, TRACE_IGNORE_EVERYTHING, ent, &tr); if (tr.flFraction != 1.0f) return false; @@ -141,33 +99,19 @@ bool IsVisible (const Vector &origin, edict_t *ent) return true; } -Vector GetEntityOrigin (edict_t *ent) -{ - // 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. - - if (IsEntityNull (ent)) - return Vector::GetZero (); - - if (ent->v.origin.IsZero ()) - return ent->v.absmin + ent->v.size * 0.5f; - - return ent->v.origin; -} - void DisplayMenuToClient (edict_t *ent, MenuText *menu) { if (!IsValidPlayer (ent)) return; - int clientIndex = IndexOfEntity (ent) - 1; + int clientIndex = engine.IndexOfEntity (ent) - 1; if (menu != NULL) { String tempText = String (menu->menuText); tempText.Replace ("\v", "\n"); - char *text = locale.TranslateInput (tempText.GetBuffer ()); + const char *text = engine.TraslateMessage (tempText.GetBuffer ()); tempText = String (text); // make menu looks best @@ -177,11 +121,11 @@ void DisplayMenuToClient (edict_t *ent, MenuText *menu) if ((g_gameFlags & (GAME_XASH | GAME_MOBILITY)) && !yb_display_menu_text.GetBool ()) text = " "; else - text = (char *) tempText.GetBuffer (); + text = tempText.GetBuffer (); while (strlen (text) >= 64) { - MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, netmsg.GetId (NETMSG_SHOWMENU), NULL, ent); + MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, engine.FindMessageId (NETMSG_SHOWMENU), NULL, ent); WRITE_SHORT (menu->validSlots); WRITE_CHAR (-1); WRITE_BYTE (1); @@ -194,7 +138,7 @@ void DisplayMenuToClient (edict_t *ent, MenuText *menu) text += 64; } - MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, netmsg.GetId (NETMSG_SHOWMENU), NULL, ent); + MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, engine.FindMessageId (NETMSG_SHOWMENU), NULL, ent); WRITE_SHORT (menu->validSlots); WRITE_CHAR (-1); WRITE_BYTE (0); @@ -205,7 +149,7 @@ void DisplayMenuToClient (edict_t *ent, MenuText *menu) } else { - MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, netmsg.GetId (NETMSG_SHOWMENU), NULL, ent); + MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, engine.FindMessageId (NETMSG_SHOWMENU), NULL, ent); WRITE_SHORT (0); WRITE_CHAR (0); WRITE_BYTE (0); @@ -235,10 +179,10 @@ void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex) if (trace->flFraction == 1.0f) return; - if (!IsEntityNull (trace->pHit)) + if (!engine.IsNullEntity (trace->pHit)) { if (trace->pHit->v.solid == SOLID_BSP || trace->pHit->v.movetype == MOVETYPE_PUSHSTEP) - entityIndex = IndexOfEntity (trace->pHit); + entityIndex = engine.IndexOfEntity (trace->pHit); else return; } @@ -268,11 +212,11 @@ void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex) { MESSAGE_BEGIN (MSG_BROADCAST, SVC_TEMPENTITY); WRITE_BYTE (TE_PLAYERDECAL); - WRITE_BYTE (IndexOfEntity (ENT (pev))); + WRITE_BYTE (engine.IndexOfEntity (pev->pContainingEntity)); WRITE_COORD (trace->vecEndPos.x); WRITE_COORD (trace->vecEndPos.y); WRITE_COORD (trace->vecEndPos.z); - WRITE_SHORT (static_cast (IndexOfEntity (trace->pHit))); + WRITE_SHORT (static_cast (engine.IndexOfEntity (trace->pHit))); WRITE_BYTE (decalIndex); MESSAGE_END (); } @@ -296,321 +240,11 @@ void FreeLibraryMemory (void) { // this function free's all allocated memory waypoints.Init (); // frees waypoint data - locale.Destroy (); // clear language delete [] g_experienceData; 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; -} - -const char *GetModName (void) -{ - static char modName[256]; - - GET_GAME_DIR (modName); // ask the engine for the MOD directory path - int length = strlen (modName); // get the length of the returned string - - // format the returned string to get the last directory name - int stop = length - 1; - while ((modName[stop] == '\\' || modName[stop] == '/') && stop > 0) - stop--; // shift back any trailing separator - - int start = stop; - while (modName[start] != '\\' && modName[start] != '/' && start > 0) - start--; // shift back to the start of the last subdirectory name - - if (modName[start] == '\\' || modName[start] == '/') - start++; // if we reached a separator, step over it - - // now copy the formatted string back onto itself character per character - for (length = start; length <= stop; length++) - modName[length - start] = modName[length]; - - modName[length - start] = 0; // terminate the string - - return &modName[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 DrawLine (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, int red, int green, int blue, int brightness, int speed, int life) -{ - // this function draws a line visible from the client side of the player whose player entity - // is pointed to by ent, from the vector location start to the vector location end, - // which is supposed to last life tenths seconds, and having the color defined by RGB. - - if (!IsValidPlayer (ent)) - return; // reliability check - - MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, ent); - WRITE_BYTE (TE_BEAMPOINTS); - WRITE_COORD (start.x); - WRITE_COORD (start.y); - WRITE_COORD (start.z); - WRITE_COORD (end.x); - WRITE_COORD (end.y); - WRITE_COORD (end.z); - WRITE_SHORT (g_modelIndexLaser); - WRITE_BYTE (0); // framestart - WRITE_BYTE (10); // framerate - WRITE_BYTE (life); // life in 0.1's - WRITE_BYTE (width); // width - WRITE_BYTE (noise); // noise - - WRITE_BYTE (red); // r, g, b - WRITE_BYTE (green); // r, g, b - WRITE_BYTE (blue); // r, g, b - - WRITE_BYTE (brightness); // brightness - WRITE_BYTE (speed); // speed - MESSAGE_END (); -} - -void DrawArrow (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, int red, int green, int blue, int brightness, int speed, int life) -{ - // this function draws a arrow visible from the client side of the player whose player entity - // is pointed to by ent, from the vector location start to the vector location end, - // which is supposed to last life tenths seconds, and having the color defined by RGB. - - if (!IsValidPlayer (ent)) - return; // reliability check - - MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, ent); - WRITE_BYTE (TE_BEAMPOINTS); - WRITE_COORD (end.x); - WRITE_COORD (end.y); - WRITE_COORD (end.z); - WRITE_COORD (start.x); - WRITE_COORD (start.y); - WRITE_COORD (start.z); - WRITE_SHORT (g_modelIndexArrow); - WRITE_BYTE (0); // framestart - WRITE_BYTE (10); // framerate - WRITE_BYTE (life); // life in 0.1's - WRITE_BYTE (width); // width - WRITE_BYTE (noise); // noise - - WRITE_BYTE (red); // r, g, b - WRITE_BYTE (green); // r, g, b - WRITE_BYTE (blue); // r, g, b - - WRITE_BYTE (brightness); // brightness - WRITE_BYTE (speed); // speed - MESSAGE_END (); -} - void UpdateGlobalExperienceData (void) { // this function called after each end of the round to update knowledge about most dangerous waypoints for each team. @@ -725,8 +359,8 @@ void UpdateGlobalExperienceData (void) { for (int i = 0; i < g_numWaypoints; i++) { - (g_experienceData + (i * g_numWaypoints) + i)->team0Damage /= static_cast (GetMaxClients () * 0.5); - (g_experienceData + (i * g_numWaypoints) + i)->team1Damage /= static_cast (GetMaxClients () * 0.5); + (g_experienceData + (i * g_numWaypoints) + i)->team0Damage /= static_cast (engine.MaxClients () * 0.5); + (g_experienceData + (i * g_numWaypoints) + i)->team1Damage /= static_cast (engine.MaxClients () * 0.5); } g_highestKills = 1; } @@ -742,7 +376,7 @@ void RoundInit (void) bots.CheckTeamEconomics (TERRORIST); bots.CheckTeamEconomics (CT); - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (bots.GetBot (i)) bots.GetBot (i)->NewRound (); @@ -769,7 +403,7 @@ void RoundInit (void) UpdateGlobalExperienceData (); // update experience data on round start // calculate the round mid/end in world time - g_timeRoundStart = GetWorldTime () + mp_freezetime.GetFloat (); + g_timeRoundStart = engine.Time () + mp_freezetime.GetFloat (); g_timeRoundMid = g_timeRoundStart + mp_roundtime.GetFloat () * 60.0f * 0.5f; g_timeRoundEnd = g_timeRoundStart + mp_roundtime.GetFloat () * 60.0f; } @@ -790,10 +424,9 @@ int GetWeaponPenetrationPower (int id) return 0; } - bool IsValidPlayer (edict_t *ent) { - if (IsEntityNull (ent)) + if (engine.IsNullEntity (ent)) return false; if (ent->v.flags & FL_PROXY) @@ -818,141 +451,35 @@ bool IsPlayerVIP (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 || (!engine.IsNullEntity (ent) && (ent->v.flags & FL_FAKECLIENT))) return true; return false; } -bool IsDedicatedServer (void) -{ - // return true if server is dedicated server, false otherwise - - return (IS_DEDICATED_SERVER () > 0); // ask engine for this -} - -void ServerPrint (const char *format, ...) -{ - va_list ap; - char string[3072]; - - va_start (ap, format); - vsprintf (string, locale.TranslateInput (format), ap); - va_end (ap); - - SERVER_PRINT (string); - SERVER_PRINT ("\n"); -} - -void CenterPrint (const char *format, ...) -{ - va_list ap; - char string[2048]; - - va_start (ap, format); - vsprintf (string, locale.TranslateInput (format), ap); - va_end (ap); - - if (IsDedicatedServer ()) - { - ServerPrint (string); - return; - } - - MESSAGE_BEGIN (MSG_BROADCAST, netmsg.GetId (NETMSG_TEXTMSG)); - WRITE_BYTE (HUD_PRINTCENTER); - WRITE_STRING (FormatBuffer ("%s\n", string)); - MESSAGE_END (); -} - -void ChartPrint (const char *format, ...) -{ - va_list ap; - char string[2048]; - - va_start (ap, format); - vsprintf (string, locale.TranslateInput (format), ap); - va_end (ap); - - if (IsDedicatedServer ()) - { - ServerPrint (string); - return; - } - strcat (string, "\n"); - - MESSAGE_BEGIN (MSG_BROADCAST, netmsg.GetId (NETMSG_TEXTMSG)); - WRITE_BYTE (HUD_PRINTTALK); - WRITE_STRING (string); - MESSAGE_END (); -} - -void ClientPrint (edict_t *ent, int dest, const char *format, ...) -{ - va_list ap; - char string[2048]; - - va_start (ap, format); - vsprintf (string, locale.TranslateInput (format), ap); - va_end (ap); - - if (IsEntityNull (ent) || ent == g_hostEntity) - { - ServerPrint (string); - return; - } - strcat (string, "\n"); - (*g_engfuncs.pfnClientPrintf) (ent, static_cast (dest), string); - -} - -void ServerCommand (const char *format, ...) -{ - // this function asks the engine to execute a server command - - va_list ap; - static char string[1024]; - - // concatenate all the arguments in one string - va_start (ap, format); - vsprintf (string, format, ap); - va_end (ap); - - SERVER_COMMAND (const_cast (FormatBuffer ("%s\n", string))); // execute command -} - -const char *GetMapName (void) -{ - // this function gets the map name and store it in the map_name global string variable. - - static char mapName[256]; - strncpy (mapName, const_cast (g_pGlobals->pStringBase + static_cast (g_pGlobals->mapname)), SIZEOF_CHAR (mapName)); - - return &mapName[0]; // and return a pointer to it -} - -extern bool OpenConfig(const char *fileName, const char *errorIfNotExists, File *outFile, bool languageDependant /*= false*/) +bool OpenConfig (const char *fileName, const char *errorIfNotExists, MemoryFile *outFile, bool languageDependant /*= false*/) { if (outFile->IsValid ()) outFile->Close (); if (languageDependant) { + const char *mod = engine.GetModName (); extern ConVar yb_language; if (strcmp (fileName, "lang.cfg") == 0 && strcmp (yb_language.GetString (), "en") == 0) return false; - const char *languageDependantConfigFile = FormatBuffer ("%s/addons/yapb/conf/lang/%s_%s", GetModName (), yb_language.GetString (), fileName); + const char *languageDependantConfigFile = FormatBuffer ("%s/addons/yapb/conf/lang/%s_%s", mod, yb_language.GetString (), fileName); // check is file is exists for this language if (File::Accessible (languageDependantConfigFile)) - outFile->Open (languageDependantConfigFile, "rt"); + outFile->Open (languageDependantConfigFile); else - outFile->Open (FormatBuffer ("%s/addons/yapb/conf/lang/en_%s", GetModName (), fileName), "rt"); + outFile->Open (FormatBuffer ("%s/addons/yapb/conf/lang/en_%s", mod, fileName)); } else - outFile->Open (FormatBuffer ("%s/addons/yapb/conf/%s", GetModName (), fileName), "rt"); + outFile->Open (FormatBuffer ("%s/addons/yapb/conf/%s", engine.GetModName (), fileName)); if (!outFile->IsValid ()) { @@ -962,24 +489,6 @@ extern bool OpenConfig(const char *fileName, const char *errorIfNotExists, File return true; } -const char *GetWaypointDir (void) -{ - return FormatBuffer ("%s/addons/yapb/data/", GetModName ()); -} - -extern void RegisterCommand(const char *command, void funcPtr (void)) -{ - // this function tells the engine that a new server command is being declared, in addition - // to the standard ones, whose name is command_name. The engine is thus supposed to be aware - // that for every "command_name" server command it receives, it should call the function - // pointed to by "function" in order to handle it. - - if (IsNullString (command) || funcPtr == NULL) - return; // reliability check - - REG_SVR_COMMAND (const_cast (command), funcPtr); // ask the engine to register this new command -} - void CheckWelcomeMessage (void) { // the purpose of this function, is to send quick welcome message, to the listenserver entity. @@ -1014,14 +523,14 @@ void CheckWelcomeMessage (void) } if (IsAlive (g_hostEntity) && !alreadyReceived && receiveTime < 1.0 && (g_numWaypoints > 0 ? g_isCommencing : true)) - receiveTime = GetWorldTime () + 4.0f; // receive welcome message in four seconds after game has commencing + receiveTime = engine.Time () + 4.0f; // receive welcome message in four seconds after game has commencing - if (receiveTime > 0.0f && receiveTime < GetWorldTime () && !alreadyReceived && (g_numWaypoints > 0 ? g_isCommencing : true)) + if (receiveTime > 0.0f && receiveTime < engine.Time () && !alreadyReceived && (g_numWaypoints > 0 ? g_isCommencing : true)) { if (!(g_gameFlags & (GAME_MOBILITY | GAME_XASH))) - ServerCommand ("speak \"%s\"", const_cast (sentences.GetRandomElement ().GetBuffer ())); + engine.IssueCmd ("speak \"%s\"", const_cast (sentences.GetRandomElement ().GetBuffer ())); - ChartPrint ("----- %s v%s (Build: %u), {%s}, (c) 2016, by %s (%s)-----", PRODUCT_NAME, PRODUCT_VERSION, GenerateBuildNumber (), PRODUCT_DATE, PRODUCT_AUTHOR, PRODUCT_URL); + engine.ChatPrintf ("----- %s v%s (Build: %u), {%s}, (c) 2016, by %s (%s)-----", PRODUCT_NAME, PRODUCT_VERSION, GenerateBuildNumber (), PRODUCT_DATE, PRODUCT_AUTHOR, PRODUCT_URL); MESSAGE_BEGIN (MSG_ONE, SVC_TEMPENTITY, NULL, g_hostEntity); WRITE_BYTE (TE_TEXTMESSAGE); @@ -1062,7 +571,7 @@ void DetectCSVersion (void) } // counter-strike 1.6 or higher (plus detects for non-steam versions of 1.5) - byte *detection = (*g_engfuncs.pfnLoadFileForMe) ("events/galil.sc", NULL); + byte *detection = g_engfuncs.pfnLoadFileForMe ("events/galil.sc", NULL); if (detection != NULL) g_gameFlags |= GAME_CSTRIKE16; // just to be sure @@ -1071,49 +580,7 @@ void DetectCSVersion (void) // if we have loaded the file free it if (detection != NULL) - (*g_engfuncs.pfnFreeFile) (detection); -} - -void PlaySound (edict_t *ent, const char *name) -{ - // TODO: make this obsolete - EMIT_SOUND_DYN2 (ent, CHAN_WEAPON, name, 1.0f, ATTN_NORM, 0, 100.0f); - - return; -} - -float GetWaveLength (const char *fileName) -{ - WavHeader waveHdr; - memset (&waveHdr, 0, sizeof (waveHdr)); - - extern ConVar yb_chatter_path; - - File fp (FormatBuffer ("%s/%s/%s.wav", GetModName (), yb_chatter_path.GetString (), fileName), "rb"); - - // we're got valid handle? - if (!fp.IsValid ()) - return 0; - - if (fp.Read (&waveHdr, sizeof (WavHeader)) == 0) - { - AddLogEntry (true, LL_ERROR, "Wave File %s - has wrong or unsupported format", fileName); - return 0; - } - - if (strncmp (waveHdr.chunkID, "WAVE", 4) != 0) - { - AddLogEntry (true, LL_ERROR, "Wave File %s - has wrong wave chunk id", fileName); - return 0; - } - fp.Close (); - - if (waveHdr.dataChunkLength == 0) - { - AddLogEntry (true, LL_ERROR, "Wave File %s - has zero length!", fileName); - return 0; - } - return static_cast (waveHdr.dataChunkLength) / static_cast (waveHdr.bytesPerSecond); + g_engfuncs.pfnFreeFile (detection); } void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...) @@ -1121,33 +588,33 @@ void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...) // this function logs a message to the message log file root directory. va_list ap; - char buffer[512] = {0, }, levelString[32] = {0, }, logLine[1024] = {0, }; + char buffer[MAX_PRINT_BUFFER] = {0, }, levelString[32] = {0, }, logLine[MAX_PRINT_BUFFER] = {0, }; va_start (ap, format); - vsprintf (buffer, locale.TranslateInput (format), ap); + vsnprintf (buffer, SIZEOF_CHAR (buffer), format, ap); va_end (ap); switch (logLevel) { case LL_DEFAULT: - strcpy (levelString, "Log: "); + strcpy (levelString, "LOG: "); break; case LL_WARNING: - strcpy (levelString, "Warning: "); + strcpy (levelString, "WARN: "); break; case LL_ERROR: - strcpy (levelString, "Error: "); + strcpy (levelString, "ERROR: "); break; case LL_FATAL: - strcpy (levelString, "Critical: "); + strcpy (levelString, "FATAL: "); break; } if (outputToConsole) - ServerPrint ("%s%s", levelString, buffer); + engine.Printf ("%s%s", levelString, buffer); // now check if logging disabled if (!(logLevel & LL_IGNORE)) @@ -1199,61 +666,18 @@ void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...) } } -char *Localizer::TranslateInput (const char *input) -{ - if (IsDedicatedServer ()) - return const_cast (&input[0]); - - static char string[1024]; - const char *ptr = input + strlen (input) - 1; - - while (ptr > input && *ptr == '\n') - ptr--; - - if (ptr != input) - ptr++; - - strncpy (string, input, SIZEOF_CHAR (string)); - strtrim (string); - - FOR_EACH_AE (m_langTab, i) - { - if (strcmp (string, m_langTab[i].original) == 0) - { - strncpy (string, m_langTab[i].translated, SIZEOF_CHAR (string)); - - if (ptr != input) - strncat (string, ptr, 1024 - 1 - strlen (string)); - - return &string[0]; - } - } - return const_cast (&input[0]); // nothing found -} - -void Localizer::Destroy (void) -{ - FOR_EACH_AE (m_langTab, it) - { - delete[] m_langTab[it].original; - delete[] m_langTab[it].translated; - } - m_langTab.RemoveAll (); -} - - bool FindNearestPlayer (void **pvHolder, edict_t *to, float searchDistance, bool sameTeam, bool needBot, bool isAlive, bool needDrawn) { // this function finds nearest to to, player with set of parameters, like his // team, live status, search distance etc. if needBot is true, then pvHolder, will // be filled with bot pointer, else with edict pointer(!). - edict_t *survive = NULL; // pointer to temporaly & survive entity + edict_t *survive = NULL; // pointer to temporally & survive entity float nearestPlayer = 4096.0f; // nearest player - int toTeam = GetTeam (to); + int toTeam = engine.GetTeam (to); - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { edict_t *ent = g_clients[i].ent; @@ -1272,7 +696,7 @@ bool FindNearestPlayer (void **pvHolder, edict_t *to, float searchDistance, bool } } - if (IsEntityNull (survive)) + if (engine.IsNullEntity (survive)) return false; // nothing found // fill the holder @@ -1289,23 +713,23 @@ 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 // the array associated with the entity - if (IsEntityNull (ent) || IsNullString (sample)) - return; // reliability check + if (engine.IsNullEntity (ent) || IsNullString (sample)) + return; - const Vector &origin = GetEntityOrigin (ent); - int index = IndexOfEntity (ent) - 1; + const Vector &origin = engine.GetAbsOrigin (ent); + int index = engine.IndexOfEntity (ent) - 1; - if (index < 0 || index >= GetMaxClients ()) + if (index < 0 || index >= engine.MaxClients ()) { float nearestDistance = 99999.0f; // loop through all players - for (int i = 0; i < GetMaxClients (); i++) + for (int i = 0; i < engine.MaxClients (); i++) { if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE)) continue; - float distance = (g_clients[i].ent->v.origin - origin).GetLengthSquared (); + float distance = (g_clients[i].origin - origin).GetLength (); // now find nearest player if (distance < nearestDistance) @@ -1315,59 +739,61 @@ void SoundAttachToClients (edict_t *ent, const char *sample, float volume) } } } - Client *client = &g_clients[index]; - if (client == NULL) - return; + // in case of worst case + if (index < 0 || index >= engine.MaxClients ()) + index = 0; + + Client &client = g_clients[index]; if (strncmp ("player/bhit_flesh", sample, 17) == 0 || strncmp ("player/headshot", sample, 15) == 0) { // hit/fall sound? - client->hearingDistance = 768.0f * volume; - client->timeSoundLasting = GetWorldTime () + 0.5f; - client->soundPosition = origin; + client.hearingDistance = 768.0f * volume; + client.timeSoundLasting = engine.Time () + 0.5f; + client.soundPosition = origin; } else if (strncmp ("items/gunpickup", sample, 15) == 0) { // weapon pickup? - client->hearingDistance = 768.0f * volume; - client->timeSoundLasting = GetWorldTime () + 0.5f; - client->soundPosition = origin; + client.hearingDistance = 768.0f * volume; + client.timeSoundLasting = engine.Time () + 0.5f; + client.soundPosition = origin; } else if (strncmp ("weapons/zoom", sample, 12) == 0) { // sniper zooming? - client->hearingDistance = 512.0f * volume; - client->timeSoundLasting = GetWorldTime () + 0.1f; - client->soundPosition = origin; + client.hearingDistance = 512.0f * volume; + client.timeSoundLasting = engine.Time () + 0.1f; + client.soundPosition = origin; } else if (strncmp ("items/9mmclip", sample, 13) == 0) { // ammo pickup? - client->hearingDistance = 512.0f * volume; - client->timeSoundLasting = GetWorldTime () + 0.1f; - client->soundPosition = origin; + client.hearingDistance = 512.0f * volume; + client.timeSoundLasting = engine.Time () + 0.1f; + client.soundPosition = origin; } else if (strncmp ("hostage/hos", sample, 11) == 0) { // CT used hostage? - client->hearingDistance = 1024.0f * volume; - client->timeSoundLasting = GetWorldTime () + 5.0f; - client->soundPosition = origin; + client.hearingDistance = 1024.0f * volume; + client.timeSoundLasting = engine.Time () + 5.0f; + client.soundPosition = origin; } else if (strncmp ("debris/bustmetal", sample, 16) == 0 || strncmp ("debris/bustglass", sample, 16) == 0) { // broke something? - client->hearingDistance = 1024.0f * volume; - client->timeSoundLasting = GetWorldTime () + 2.0f; - client->soundPosition = origin; + client.hearingDistance = 1024.0f * volume; + client.timeSoundLasting = engine.Time () + 2.0f; + client.soundPosition = origin; } else if (strncmp ("doors/doormove", sample, 14) == 0) { // someone opened a door - client->hearingDistance = 1024.0f * volume; - client->timeSoundLasting = GetWorldTime () + 3.0f; - client->soundPosition = origin; + client.hearingDistance = 1024.0f * volume; + client.timeSoundLasting = engine.Time () + 3.0f; + client.soundPosition = origin; } } @@ -1376,35 +802,35 @@ void SoundSimulateUpdate (int playerIndex) // this function tries to simulate playing of sounds to let the bots hear sounds which aren't // captured through server sound hooking - if (playerIndex < 0 || playerIndex >= GetMaxClients ()) + if (playerIndex < 0 || playerIndex >= engine.MaxClients ()) return; // reliability check - Client *client = &g_clients[playerIndex]; + Client &client = g_clients[playerIndex]; float hearDistance = 0.0f; float timeSound = 0.0f; - if (client->ent->v.oldbuttons & IN_ATTACK) // pressed attack button? + if (client.ent->v.oldbuttons & IN_ATTACK) // pressed attack button? { hearDistance = 2048.0f; - timeSound = GetWorldTime () + 0.3f; + timeSound = engine.Time () + 0.3f; } - else if (client->ent->v.oldbuttons & IN_USE) // pressed used button? + else if (client.ent->v.oldbuttons & IN_USE) // pressed used button? { hearDistance = 512.0f; - timeSound = GetWorldTime () + 0.5f; + timeSound = engine.Time () + 0.5f; } - else if (client->ent->v.oldbuttons & IN_RELOAD) // pressed reload button? + else if (client.ent->v.oldbuttons & IN_RELOAD) // pressed reload button? { hearDistance = 512.0f; - timeSound = GetWorldTime () + 0.5f; + timeSound = engine.Time () + 0.5f; } - else if (client->ent->v.movetype == MOVETYPE_FLY) // uses ladder? + else if (client.ent->v.movetype == MOVETYPE_FLY) // uses ladder? { - if (fabsf (client->ent->v.velocity.z) > 50.0f) + if (fabsf (client.ent->v.velocity.z) > 50.0f) { hearDistance = 1024.0f; - timeSound = GetWorldTime () + 0.3f; + timeSound = engine.Time () + 0.3f; } } else @@ -1414,8 +840,8 @@ void SoundSimulateUpdate (int playerIndex) if (mp_footsteps.GetBool ()) { // moves fast enough? - hearDistance = 1280.0f * (client->ent->v.velocity.GetLength2D () / 260.0f); - timeSound = GetWorldTime () + 0.3f; + hearDistance = 1280.0f * (client.ent->v.velocity.GetLength2D () / 260.0f); + timeSound = engine.Time () + 0.3f; } } @@ -1423,30 +849,30 @@ void SoundSimulateUpdate (int playerIndex) return; // didn't issue sound? // some sound already associated - if (client->timeSoundLasting > GetWorldTime ()) + if (client.timeSoundLasting > engine.Time ()) { - if (client->hearingDistance <= hearDistance) + if (client.hearingDistance <= hearDistance) { // override it with new - client->hearingDistance = hearDistance; - client->timeSoundLasting = timeSound; - client->soundPosition = client->ent->v.origin; + client.hearingDistance = hearDistance; + client.timeSoundLasting = timeSound; + client.soundPosition = client.ent->v.origin; } } else { // just remember it - client->hearingDistance = hearDistance; - client->timeSoundLasting = timeSound; - client->soundPosition = client->ent->v.origin; + client.hearingDistance = hearDistance; + client.timeSoundLasting = timeSound; + client.soundPosition = client.ent->v.origin; } } -uint16 GenerateBuildNumber (void) +int GenerateBuildNumber (void) { // this function generates build number from the compiler date macros - static uint16 buildNumber = 0; + static int buildNumber = 0; if (buildNumber != 0) return buildNumber; diff --git a/source/waypoint.cpp b/source/waypoint.cpp index f930aa2..d0b9eea 100644 --- a/source/waypoint.cpp +++ b/source/waypoint.cpp @@ -1,4 +1,4 @@ -// +// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // @@ -17,6 +17,7 @@ ConVar yb_waypoint_autodl_enable ("yb_waypoint_autodl_enable", "1"); void Waypoint::Init (void) { // this function initialize the waypoint structures.. + m_loadTries = 0; m_learnVelocity.Zero (); m_learnPosition.Zero (); @@ -24,17 +25,21 @@ void Waypoint::Init (void) // have any waypoint path nodes been allocated yet? if (m_waypointPaths) - { - for (int i = 0; i < g_numWaypoints && m_paths[i] != NULL; i++) - { - delete m_paths[i]; - m_paths[i] = NULL; - } - } + CleanupPathMemory (); + g_numWaypoints = 0; } -void Waypoint::AddPath (short int addIndex, short int pathIndex, float distance) +void Waypoint::CleanupPathMemory (void) +{ + for (int i = 0; i < g_numWaypoints && m_paths[i] != NULL; i++) + { + delete m_paths[i]; + m_paths[i] = NULL; + } +} + +void Waypoint::AddPath (int addIndex, int pathIndex, float distance) { if (addIndex < 0 || addIndex >= g_numWaypoints || pathIndex < 0 || pathIndex >= g_numWaypoints || addIndex == pathIndex) return; @@ -143,7 +148,7 @@ void Waypoint::FindInRadius (Array &radiusHolder, float radius, const Vect void Waypoint::Add (int flags, const Vector &waypointOrigin) { - if (IsEntityNull (g_hostEntity)) + if (engine.IsNullEntity (g_hostEntity)) return; int index = -1, i; @@ -174,7 +179,7 @@ void Waypoint::Add (int flags, const Vector &waypointOrigin) if (!(path->flags & FLAG_CAMP)) { - CenterPrint ("This is not Camping Waypoint"); + engine.CenterPrintf ("This is not Camping Waypoint"); return; } @@ -185,7 +190,7 @@ void Waypoint::Add (int flags, const Vector &waypointOrigin) path->campEndY = forward.y; // play "done" sound... - PlaySound (g_hostEntity, "common/wpn_hudon.wav"); + engine.EmitSound (g_hostEntity, "common/wpn_hudon.wav"); } return; @@ -366,7 +371,7 @@ void Waypoint::Add (int flags, const Vector &waypointOrigin) if (m_paths[i]->flags & FLAG_LADDER) { // check if the waypoint is reachable from the new one - TraceLine (newOrigin, m_paths[i]->origin, true, g_hostEntity, &tr); + engine.TestLine (newOrigin, m_paths[i]->origin, TRACE_IGNORE_MONSTERS, g_hostEntity, &tr); if (tr.flFraction == 1.0f && fabs (newOrigin.x - m_paths[i]->origin.x) < 64.0f && fabs (newOrigin.y - m_paths[i]->origin.y) < 64.0f && fabs (newOrigin.z - m_paths[i]->origin.z) < g_autoPathDistance) { @@ -432,7 +437,7 @@ void Waypoint::Add (int flags, const Vector &waypointOrigin) } } } - PlaySound (g_hostEntity, "weapons/xbow_hit1.wav"); + engine.EmitSound (g_hostEntity, "weapons/xbow_hit1.wav"); CalculateWayzone (index); // calculate the wayzone of this waypoint } @@ -497,7 +502,7 @@ void Waypoint::Delete (void) g_numWaypoints--; m_waypointDisplayTime[index] = 0; - PlaySound (g_hostEntity, "weapons/mine_activate.wav"); + engine.EmitSound (g_hostEntity, "weapons/mine_activate.wav"); } void Waypoint::ToggleFlags (int toggleFlag) @@ -522,7 +527,7 @@ void Waypoint::ToggleFlags (int toggleFlag) } // play "done" sound... - PlaySound (g_hostEntity, "common/wpn_hudon.wav"); + engine.EmitSound (g_hostEntity, "common/wpn_hudon.wav"); } } @@ -537,7 +542,7 @@ void Waypoint::SetRadius (int radius) m_paths[index]->radius = static_cast (radius); // play "done" sound... - PlaySound (g_hostEntity, "common/wpn_hudon.wav"); + engine.EmitSound (g_hostEntity, "common/wpn_hudon.wav"); } } @@ -594,7 +599,7 @@ void Waypoint::CreatePath (char dir) if (nodeFrom == -1) { - CenterPrint ("Unable to find nearest waypoint in 50 units"); + engine.CenterPrintf ("Unable to find nearest waypoint in 50 units"); return; } int nodeTo = m_facingAtIndex; @@ -605,14 +610,14 @@ void Waypoint::CreatePath (char dir) nodeTo = m_cacheWaypointIndex; else { - CenterPrint ("Unable to find destination waypoint"); + engine.CenterPrintf ("Unable to find destination waypoint"); return; } } if (nodeTo == nodeFrom) { - CenterPrint ("Unable to connect waypoint with itself"); + engine.CenterPrintf ("Unable to connect waypoint with itself"); return; } @@ -628,7 +633,7 @@ void Waypoint::CreatePath (char dir) AddPath (nodeTo, nodeFrom, distance); } - PlaySound (g_hostEntity, "common/wpn_hudon.wav"); + engine.EmitSound (g_hostEntity, "common/wpn_hudon.wav"); g_waypointsChanged = true; } @@ -642,7 +647,7 @@ void Waypoint::DeletePath (void) if (nodeFrom == -1) { - CenterPrint ("Unable to find nearest waypoint in 50 units"); + engine.CenterPrintf ("Unable to find nearest waypoint in 50 units"); return; } int nodeTo = m_facingAtIndex; @@ -653,7 +658,7 @@ void Waypoint::DeletePath (void) nodeTo = m_cacheWaypointIndex; else { - CenterPrint ("Unable to find destination waypoint"); + engine.CenterPrintf ("Unable to find destination waypoint"); return; } } @@ -669,7 +674,7 @@ void Waypoint::DeletePath (void) m_paths[nodeFrom]->connectionFlags[index] = 0; m_paths[nodeFrom]->connectionVelocity[index].Zero (); - PlaySound (g_hostEntity, "weapons/mine_activate.wav"); + engine.EmitSound (g_hostEntity, "weapons/mine_activate.wav"); return; } } @@ -691,11 +696,11 @@ void Waypoint::DeletePath (void) m_paths[nodeFrom]->connectionFlags[index] = 0; m_paths[nodeFrom]->connectionVelocity[index].Zero (); - PlaySound (g_hostEntity, "weapons/mine_activate.wav"); + engine.EmitSound (g_hostEntity, "weapons/mine_activate.wav"); return; } } - CenterPrint ("There is already no path on this waypoint"); + engine.CenterPrintf ("There is already no path on this waypoint"); } void Waypoint::CacheWaypoint (void) @@ -705,12 +710,12 @@ void Waypoint::CacheWaypoint (void) if (node == -1) { m_cacheWaypointIndex = -1; - CenterPrint ("Cached waypoint cleared (nearby point not found in 50 units range)"); + engine.CenterPrintf ("Cached waypoint cleared (nearby point not found in 50 units range)"); return; } m_cacheWaypointIndex = node; - CenterPrint ("Waypoint #%d has been put into memory", m_cacheWaypointIndex); + engine.CenterPrintf ("Waypoint #%d has been put into memory", m_cacheWaypointIndex); } void Waypoint::CalculateWayzone (int index) @@ -755,11 +760,11 @@ void Waypoint::CalculateWayzone (int index) Vector radiusStart = start - g_pGlobals->v_forward * scanDistance; Vector radiusEnd = start + g_pGlobals->v_forward * scanDistance; - TraceHull (radiusStart, radiusEnd, true, head_hull, NULL, &tr); + engine.TestHull (radiusStart, radiusEnd, TRACE_IGNORE_MONSTERS, head_hull, NULL, &tr); if (tr.flFraction < 1.0f) { - TraceLine (radiusStart, radiusEnd, true, NULL, &tr); + engine.TestLine (radiusStart, radiusEnd, TRACE_IGNORE_MONSTERS, NULL, &tr); if (FClassnameIs (tr.pHit, "func_door") || FClassnameIs (tr.pHit, "func_door_rotating")) { @@ -778,7 +783,7 @@ void Waypoint::CalculateWayzone (int index) Vector dropStart = start + g_pGlobals->v_forward * scanDistance; Vector dropEnd = dropStart - Vector (0.0f, 0.0f, scanDistance + 60.0f); - TraceHull (dropStart, dropEnd, true, head_hull, NULL, &tr); + engine.TestHull (dropStart, dropEnd, TRACE_IGNORE_MONSTERS, head_hull, NULL, &tr); if (tr.flFraction >= 1.0f) { @@ -790,7 +795,7 @@ void Waypoint::CalculateWayzone (int index) dropStart = start - g_pGlobals->v_forward * scanDistance; dropEnd = dropStart - Vector (0.0f, 0.0f, scanDistance + 60.0f); - TraceHull (dropStart, dropEnd, true, head_hull, NULL, &tr); + engine.TestHull (dropStart, dropEnd, TRACE_IGNORE_MONSTERS, head_hull, NULL, &tr); if (tr.flFraction >= 1.0f) { @@ -800,7 +805,7 @@ void Waypoint::CalculateWayzone (int index) } radiusEnd.z += 34.0f; - TraceHull (radiusStart, radiusEnd, true, head_hull, NULL, &tr); + engine.TestHull (radiusStart, radiusEnd, TRACE_IGNORE_MONSTERS, head_hull, NULL, &tr); if (tr.flFraction < 1.0f) { @@ -846,7 +851,7 @@ void Waypoint::SaveExperienceTab (void) } } - int result = Compressor::Compress (FormatBuffer ("%slearned/%s.exp", GetWaypointDir (), 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; @@ -885,7 +890,7 @@ void Waypoint::InitExperienceTab (void) (g_experienceData + (i * g_numWaypoints) + j)->team1Value = 0; } } - File fp (FormatBuffer ("%slearned/%s.exp", GetWaypointDir (), GetMapName ()), "rb"); + File fp (FormatBuffer ("%slearned/%s.exp", GetDataDir (), engine.GetMapName ()), "rb"); // if file exists, read the experience data from it if (fp.IsValid ()) @@ -908,7 +913,7 @@ void Waypoint::InitExperienceTab (void) { ExperienceSave *experienceLoad = new ExperienceSave[g_numWaypoints * g_numWaypoints]; - Compressor::Uncompress (FormatBuffer ("%slearned/%s.exp", GetWaypointDir (), 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++) { @@ -958,7 +963,7 @@ void Waypoint::SaveVisibilityTab (void) header.fileVersion = FV_VISTABLE; header.pointNumber = g_numWaypoints; - File fp (FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), GetMapName ()), "wb"); + File fp (FormatBuffer ("%slearned/%s.vis", GetDataDir (), engine.GetMapName ()), "wb"); if (!fp.IsValid ()) { @@ -967,7 +972,7 @@ void Waypoint::SaveVisibilityTab (void) } fp.Close (); - Compressor::Compress (FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), 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 (unsigned char)); } void Waypoint::InitVisibilityTab (void) @@ -977,7 +982,7 @@ void Waypoint::InitVisibilityTab (void) ExtensionHeader header; - File fp (FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), GetMapName ()), "rb"); + File fp (FormatBuffer ("%slearned/%s.vis", GetDataDir (), engine.GetMapName ()), "rb"); m_redoneVisibility = false; if (!fp.IsValid ()) @@ -1008,7 +1013,7 @@ void Waypoint::InitVisibilityTab (void) return; } - int result = Compressor::Uncompress (FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), 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 (unsigned char)); if (result == -1) { @@ -1052,16 +1057,26 @@ void Waypoint::InitTypes (void) bool Waypoint::Load (void) { - File fp (CheckSubfolderFile (), "rb"); + if (m_loadTries++ > 3) + { + sprintf (m_infoBuffer, "Giving up loading waypoint file (%s). Something went wrong.", engine.GetMapName ()); + AddLogEntry (true, LL_ERROR, m_infoBuffer); + + return false; + } + MemoryFile fp (CheckSubfolderFile ()); WaypointHeader header; memset (&header, 0, sizeof (header)); + // save for faster access + const char *map = engine.GetMapName (); + if (fp.IsValid ()) { if (fp.Read (&header, sizeof (header)) == 0) { - sprintf (m_infoBuffer, "%s.pwf - damaged waypoint file (unable to read header)", GetMapName ()); + sprintf (m_infoBuffer, "%s.pwf - damaged waypoint file (unable to read header)", map); AddLogEntry (true, LL_ERROR, m_infoBuffer); fp.Close (); @@ -1072,15 +1087,15 @@ bool Waypoint::Load (void) { if (header.fileVersion != FV_WAYPOINT) { - sprintf (m_infoBuffer, "%s.pwf - incorrect waypoint file version (expected '%d' found '%ld')", GetMapName (), FV_WAYPOINT, header.fileVersion); + sprintf (m_infoBuffer, "%s.pwf - incorrect waypoint file version (expected '%d' found '%ld')", map, FV_WAYPOINT, header.fileVersion); AddLogEntry (true, LL_ERROR, m_infoBuffer); fp.Close (); return false; } - else if (stricmp (header.mapName, GetMapName ())) + else if (stricmp (header.mapName, map)) { - sprintf (m_infoBuffer, "%s.pwf - hacked waypoint file, file name doesn't match waypoint header information (mapname: '%s', header: '%s')", GetMapName (), GetMapName (), header.mapName); + sprintf (m_infoBuffer, "%s.pwf - hacked waypoint file, file name doesn't match waypoint header information (mapname: '%s', header: '%s')", map, map, header.mapName); AddLogEntry (true, LL_ERROR, m_infoBuffer); fp.Close (); @@ -1090,7 +1105,7 @@ bool Waypoint::Load (void) { if (header.pointNumber == 0 || header.pointNumber > MAX_WAYPOINTS) { - sprintf (m_infoBuffer, "%s.pwf - waypoint file contains illegal number of waypoints (mapname: '%s', header: '%s')", GetMapName (), GetMapName (), header.mapName); + sprintf (m_infoBuffer, "%s.pwf - waypoint file contains illegal number of waypoints (mapname: '%s', header: '%s')", map, map, header.mapName); AddLogEntry (true, LL_ERROR, m_infoBuffer); fp.Close (); @@ -1109,7 +1124,17 @@ bool Waypoint::Load (void) if (fp.Read (m_paths[i], sizeof (Path)) == 0) { - sprintf (m_infoBuffer, "%s.pwf - truncated waypoint file (count: %d, need: %d)", GetMapName (), i, g_numWaypoints); + sprintf (m_infoBuffer, "%s.pwf - truncated waypoint file (count: %d, need: %d)", map, i, g_numWaypoints); + AddLogEntry (true, LL_ERROR, m_infoBuffer); + + fp.Close (); + return false; + } + + // more checks of waypoint quality + if (m_paths[i]->pathNumber < 0 || m_paths[i]->pathNumber > g_numWaypoints) + { + sprintf (m_infoBuffer, "%s.pwf - bad waypoint file (path #%d index is out of bounds)", map, i); AddLogEntry (true, LL_ERROR, m_infoBuffer); fp.Close (); @@ -1121,7 +1146,7 @@ bool Waypoint::Load (void) } else { - sprintf (m_infoBuffer, "%s.pwf is not a yapb waypoint file (header found '%s' needed '%s'", GetMapName (), header.header, FH_WAYPOINT); + sprintf (m_infoBuffer, "%s.pwf is not a yapb waypoint file (header found '%s' needed '%s'", map, header.header, FH_WAYPOINT); AddLogEntry (true, LL_ERROR, m_infoBuffer); fp.Close (); @@ -1133,14 +1158,12 @@ bool Waypoint::Load (void) { if (yb_waypoint_autodl_enable.GetBool ()) { - AddLogEntry (true, LL_DEFAULT, "%s.pwf does not exist, trying to download from waypoint database", GetMapName ()); - - WaypointDownloader dl; - WaypointDownloadError status = dl.DoDownload (); + AddLogEntry (true, LL_DEFAULT, "%s.pwf does not exist, trying to download from waypoint database", map); + WaypointDownloadError status = RequestWaypoint (); if (status == WDE_SOCKET_ERROR) { - sprintf (m_infoBuffer, "%s.pwf does not exist. Can't autodownload. Socket error.", GetMapName ()); + sprintf (m_infoBuffer, "%s.pwf does not exist. Can't autodownload. Socket error.", map); AddLogEntry (true, LL_ERROR, m_infoBuffer); yb_waypoint_autodl_enable.SetInt (0); @@ -1149,7 +1172,7 @@ bool Waypoint::Load (void) } else if (status == WDE_CONNECT_ERROR) { - sprintf (m_infoBuffer, "%s.pwf does not exist. Can't autodownload. Connection problems.", GetMapName ()); + sprintf (m_infoBuffer, "%s.pwf does not exist. Can't autodownload. Connection problems.", map); AddLogEntry (true, LL_ERROR, m_infoBuffer); yb_waypoint_autodl_enable.SetInt (0); @@ -1158,18 +1181,18 @@ bool Waypoint::Load (void) } else if (status == WDE_NOTFOUND_ERROR) { - sprintf (m_infoBuffer, "%s.pwf does not exist. Can't autodownload. Waypoint not available.", GetMapName ()); + sprintf (m_infoBuffer, "%s.pwf does not exist. Can't autodownload. Waypoint not available.", map); AddLogEntry (true, LL_ERROR, m_infoBuffer); return false; } else { - AddLogEntry (true, LL_DEFAULT, "%s.pwf was downloaded from waypoint database. Trying to load...", GetMapName ()); + AddLogEntry (true, LL_DEFAULT, "%s.pwf was downloaded from waypoint database. Trying to load...", map); return Load (); } } - sprintf (m_infoBuffer, "%s.pwf does not exist", GetMapName ()); + sprintf (m_infoBuffer, "%s.pwf does not exist", map); AddLogEntry (true, LL_ERROR, m_infoBuffer); return false; @@ -1213,7 +1236,7 @@ void Waypoint::Save (void) strcpy (header.header, FH_WAYPOINT); strncpy (header.author, STRING (g_hostEntity->v.netname), SIZEOF_CHAR (header.author)); - strncpy (header.mapName, GetMapName (), SIZEOF_CHAR (header.mapName)); + strncpy (header.mapName, engine.GetMapName (), SIZEOF_CHAR (header.mapName)); header.mapName[31] = 0; header.fileVersion = FV_WAYPOINT; @@ -1234,7 +1257,7 @@ void Waypoint::Save (void) fp.Close (); } else - AddLogEntry (true, LL_ERROR, "Error writing '%s.pwf' waypoint file", GetMapName ()); + AddLogEntry (true, LL_ERROR, "Error writing '%s.pwf' waypoint file", engine.GetMapName ()); } String Waypoint::CheckSubfolderFile (void) @@ -1244,12 +1267,12 @@ String Waypoint::CheckSubfolderFile (void) if (!IsNullString (yb_wptsubfolder.GetString ())) returnFile += (String (yb_wptsubfolder.GetString ()) + "/"); - returnFile = FormatBuffer ("%s%s%s.pwf", GetWaypointDir (), returnFile.GetBuffer (), GetMapName ()); + returnFile = FormatBuffer ("%s%s%s.pwf", GetDataDir (), returnFile.GetBuffer (), engine.GetMapName ()); if (File::Accessible (returnFile)) return returnFile; - return FormatBuffer ("%s%s.pwf", GetWaypointDir (), GetMapName ()); + return FormatBuffer ("%s%s.pwf", GetDataDir (), engine.GetMapName ()); } float Waypoint::GetTravelTime (float maxSpeed, const Vector &src, const Vector &origin) @@ -1276,7 +1299,7 @@ bool Waypoint::Reachable (Bot *bot, int index) return false; TraceResult tr; - TraceLine (src, dest, true, bot->GetEntity (), &tr); + engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, bot->GetEntity (), &tr); // if waypoint is visible from current position (even behind head)... if (tr.flFraction >= 1.0f) @@ -1306,13 +1329,13 @@ bool Waypoint::IsNodeReachable (const Vector &src, const Vector &destination) return false; // check if we go through a func_illusionary, in which case return false - TraceHull (src, destination, 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 (!engine.IsNullEntity (tr.pHit) && strcmp ("func_illusionary", STRING (tr.pHit->v.classname)) == 0) return false; // don't add pathwaypoints through func_illusionaries // check if this waypoint is "visible"... - TraceLine (src, destination, ignore_monsters, g_hostEntity, &tr); + engine.TestLine (src, destination, TRACE_IGNORE_MONSTERS, g_hostEntity, &tr); // if waypoint is visible from current position (even behind head)... if (tr.flFraction >= 1.0f || strncmp ("func_door", STRING (tr.pHit->v.classname), 9) == 0) @@ -1320,7 +1343,7 @@ bool Waypoint::IsNodeReachable (const Vector &src, const Vector &destination) // if it's a door check if nothing blocks behind if (strncmp ("func_door", STRING (tr.pHit->v.classname), 9) == 0) { - TraceLine (tr.vecEndPos, destination, ignore_monsters, tr.pHit, &tr); + engine.TestLine (tr.vecEndPos, destination, TRACE_IGNORE_MONSTERS, tr.pHit, &tr); if (tr.flFraction < 1.0f) return false; @@ -1337,7 +1360,7 @@ bool Waypoint::IsNodeReachable (const Vector &src, const Vector &destination) Vector destinationNew = destination; destinationNew.z = destinationNew.z - 50.0f; // straight down 50 units - TraceLine (sourceNew, destinationNew, ignore_monsters, g_hostEntity, &tr); + engine.TestLine (sourceNew, destinationNew, TRACE_IGNORE_MONSTERS, g_hostEntity, &tr); // check if we didn't hit anything, if not then it's in mid-air if (tr.flFraction >= 1.0) @@ -1350,7 +1373,7 @@ bool Waypoint::IsNodeReachable (const Vector &src, const Vector &destination) down.z = down.z - 1000.0f; // straight down 1000 units - TraceLine (check, down, ignore_monsters, g_hostEntity, &tr); + engine.TestLine (check, down, TRACE_IGNORE_MONSTERS, g_hostEntity, &tr); float lastHeight = tr.flFraction * 1000.0f; // height from ground distance = (destination - check).GetLength (); // distance from goal @@ -1363,7 +1386,7 @@ bool Waypoint::IsNodeReachable (const Vector &src, const Vector &destination) down = check; down.z = down.z - 1000.0f; // straight down 1000 units - TraceLine (check, down, ignore_monsters, g_hostEntity, &tr); + engine.TestLine (check, down, TRACE_IGNORE_MONSTERS, g_hostEntity, &tr); float height = tr.flFraction * 1000.0f; // height from ground @@ -1409,7 +1432,7 @@ void Waypoint::InitializeVisibility (void) // first check ducked visibility Vector dest = m_paths[i]->origin; - TraceLine (sourceDuck, dest, true, NULL, &tr); + engine.TestLine (sourceDuck, dest, TRACE_IGNORE_MONSTERS, NULL, &tr); // check if line of sight to object is not blocked (i.e. visible) if (tr.flFraction != 1.0f || tr.fStartSolid) @@ -1419,7 +1442,7 @@ void Waypoint::InitializeVisibility (void) res <<= 1; - TraceLine (sourceStand, dest, true, NULL, &tr); + engine.TestLine (sourceStand, dest, TRACE_IGNORE_MONSTERS, NULL, &tr); // check if line of sight to object is not blocked (i.e. visible) if (tr.flFraction != 1.0f || tr.fStartSolid) @@ -1485,7 +1508,7 @@ const char *Waypoint::GetWaypointInfo(int id) jumpPoint = true; } - static char messageBuffer[1024]; + static char messageBuffer[MAX_PRINT_BUFFER]; sprintf (messageBuffer, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", (path->flags == 0 && !jumpPoint) ? " (none)" : "", (path->flags & FLAG_LIFT) ? " LIFT" : "", (path->flags & FLAG_CROUCH) ? " CROUCH" : "", (path->flags & FLAG_CROSSING) ? " CROSSING" : "", (path->flags & FLAG_CAMP) ? " CAMP" : "", (path->flags & FLAG_TF_ONLY) ? " TERRORIST" : "", (path->flags & FLAG_CF_ONLY) ? " CT" : "", (path->flags & FLAG_SNIPER) ? " SNIPER" : "", (path->flags & FLAG_GOAL) ? " GOAL" : "", (path->flags & FLAG_LADDER) ? " LADDER" : "", (path->flags & FLAG_RESCUE) ? " RESCUE" : "", (path->flags & FLAG_DOUBLEJUMP) ? " JUMPHELP" : "", (path->flags & FLAG_NOHOSTAGE) ? " NOHOSTAGE" : "", jumpPoint ? " JUMP" : ""); // return the message buffer @@ -1496,7 +1519,7 @@ void Waypoint::Think (void) { // this function executes frame of waypoint operation code. - if (IsEntityNull (g_hostEntity)) + if (engine.IsNullEntity (g_hostEntity)) return; // this function is only valid on listenserver, and in waypoint enabled mode. float nearestDistance = 99999.0f; @@ -1511,7 +1534,7 @@ void Waypoint::Think (void) { Add (9); - m_timeJumpStarted = GetWorldTime (); + m_timeJumpStarted = engine.Time (); m_endJumpPoint = true; } else @@ -1520,7 +1543,7 @@ void Waypoint::Think (void) m_learnPosition = g_hostEntity->v.origin; } } - else if (((g_hostEntity->v.flags & FL_ONGROUND) || g_hostEntity->v.movetype == MOVETYPE_FLY) && m_timeJumpStarted + 0.1 < GetWorldTime () && m_endJumpPoint) + else if (((g_hostEntity->v.flags & FL_ONGROUND) || g_hostEntity->v.movetype == MOVETYPE_FLY) && m_timeJumpStarted + 0.1 < engine.Time () && m_endJumpPoint) { Add (10); @@ -1574,7 +1597,7 @@ void Waypoint::Think (void) nearestDistance = distance; } - if (m_waypointDisplayTime[i] + 0.8f < GetWorldTime ()) + if (m_waypointDisplayTime[i] + 0.8f < engine.Time ()) { float nodeHeight = 0.0f; @@ -1616,13 +1639,13 @@ void Waypoint::Think (void) // draw node without additional flags if (nodeFlagColor.x == -1) - DrawLine (g_hostEntity, m_paths[i]->origin - Vector (0, 0, nodeHalfHeight), m_paths[i]->origin + Vector (0, 0, nodeHalfHeight), 15, 0, static_cast (nodeColor.x), static_cast (nodeColor.y), static_cast (nodeColor.z), 250, 0, 10); + engine.DrawLine (g_hostEntity, m_paths[i]->origin - Vector (0, 0, nodeHalfHeight), m_paths[i]->origin + Vector (0, 0, nodeHalfHeight), 15, 0, static_cast (nodeColor.x), static_cast (nodeColor.y), static_cast (nodeColor.z), 250, 0, 10); else // draw node with flags { - DrawLine (g_hostEntity, m_paths[i]->origin - Vector (0, 0, nodeHalfHeight), m_paths[i]->origin - Vector (0, 0, nodeHalfHeight - nodeHeight * 0.75), 14, 0, static_cast (nodeColor.x), static_cast (nodeColor.y), static_cast (nodeColor.z), 250, 0, 10); // draw basic path - DrawLine (g_hostEntity, m_paths[i]->origin - Vector (0, 0, nodeHalfHeight - nodeHeight * 0.75), m_paths[i]->origin + Vector (0, 0, nodeHalfHeight), 14, 0, static_cast (nodeFlagColor.x), static_cast (nodeFlagColor.y), static_cast (nodeFlagColor.z), 250, 0, 10); // draw additional path + engine.DrawLine (g_hostEntity, m_paths[i]->origin - Vector (0, 0, nodeHalfHeight), m_paths[i]->origin - Vector (0, 0, nodeHalfHeight - nodeHeight * 0.75), 14, 0, static_cast (nodeColor.x), static_cast (nodeColor.y), static_cast (nodeColor.z), 250, 0, 10); // draw basic path + engine.DrawLine (g_hostEntity, m_paths[i]->origin - Vector (0, 0, nodeHalfHeight - nodeHeight * 0.75), m_paths[i]->origin + Vector (0, 0, nodeHalfHeight), 14, 0, static_cast (nodeFlagColor.x), static_cast (nodeFlagColor.y), static_cast (nodeFlagColor.z), 250, 0, 10); // draw additional path } - m_waypointDisplayTime[i] = GetWorldTime (); + m_waypointDisplayTime[i] = engine.Time (); } } } @@ -1634,21 +1657,21 @@ void Waypoint::Think (void) if ((m_findWPIndex != -1 && m_findWPIndex < g_numWaypoints) || (m_cacheWaypointIndex != -1 && m_cacheWaypointIndex < g_numWaypoints) || (m_facingAtIndex != -1 && m_facingAtIndex < g_numWaypoints)) { // check for drawing code - if (m_arrowDisplayTime + 0.5f < GetWorldTime ()) + if (m_arrowDisplayTime + 0.5f < engine.Time ()) { // finding waypoint - pink arrow if (m_findWPIndex != -1) - DrawArrow (g_hostEntity, g_hostEntity->v.origin, m_paths[m_findWPIndex]->origin, 10, 0, 128, 0, 128, 200, 0, 5); + engine.DrawLine (g_hostEntity, g_hostEntity->v.origin, m_paths[m_findWPIndex]->origin, 10, 0, 128, 0, 128, 200, 0, 5, DRAW_ARROW); // cached waypoint - yellow arrow if (m_cacheWaypointIndex != -1) - DrawArrow (g_hostEntity, g_hostEntity->v.origin, m_paths[m_cacheWaypointIndex]->origin, 10, 0, 255, 255, 0, 200, 0, 5); + engine.DrawLine (g_hostEntity, g_hostEntity->v.origin, m_paths[m_cacheWaypointIndex]->origin, 10, 0, 255, 255, 0, 200, 0, 5, DRAW_ARROW); // waypoint user facing at - white arrow if (m_facingAtIndex != -1) - DrawArrow (g_hostEntity, g_hostEntity->v.origin, m_paths[m_facingAtIndex]->origin, 10, 0, 255, 255, 255, 200, 0, 5); + engine.DrawLine (g_hostEntity, g_hostEntity->v.origin, m_paths[m_facingAtIndex]->origin, 10, 0, 255, 255, 255, 200, 0, 5, DRAW_ARROW); - m_arrowDisplayTime = GetWorldTime (); + m_arrowDisplayTime = engine.Time (); } } @@ -1656,9 +1679,9 @@ void Waypoint::Think (void) Path *path = m_paths[nearestIndex]; // draw a paths, camplines and danger directions for nearest waypoint - if (nearestDistance <= 56.0f && m_pathDisplayTime <= GetWorldTime ()) + if (nearestDistance <= 56.0f && m_pathDisplayTime <= engine.Time ()) { - m_pathDisplayTime = GetWorldTime () + 1.0f; + m_pathDisplayTime = engine.Time () + 1.0f; // draw the camplines if (path->flags & FLAG_CAMP) @@ -1673,8 +1696,8 @@ void Waypoint::Think (void) Vector campEndOrigin = Vector (path->campEndX, path->campEndY, campSourceOrigin.z); // camp end // draw it now - DrawLine (g_hostEntity, campSourceOrigin, campStartOrigin, 10, 0, 255, 0, 0, 200, 0, 10); - DrawLine (g_hostEntity, campSourceOrigin, campEndOrigin, 10, 0, 255, 0, 0, 200, 0, 10); + engine.DrawLine (g_hostEntity, campSourceOrigin, campStartOrigin, 10, 0, 255, 0, 0, 200, 0, 10); + engine.DrawLine (g_hostEntity, campSourceOrigin, campEndOrigin, 10, 0, 255, 0, 0, 200, 0, 10); } // draw the connections @@ -1685,18 +1708,18 @@ void Waypoint::Think (void) // jump connection if (path->connectionFlags[i] & PATHFLAG_JUMP) - DrawLine (g_hostEntity, path->origin, m_paths[path->index[i]]->origin, 5, 0, 255, 0, 128, 200, 0, 10); + engine.DrawLine (g_hostEntity, path->origin, m_paths[path->index[i]]->origin, 5, 0, 255, 0, 128, 200, 0, 10); else if (IsConnected (path->index[i], nearestIndex)) // twoway connection - DrawLine (g_hostEntity, path->origin, m_paths[path->index[i]]->origin, 5, 0, 255, 255, 0, 200, 0, 10); + engine.DrawLine (g_hostEntity, path->origin, m_paths[path->index[i]]->origin, 5, 0, 255, 255, 0, 200, 0, 10); else // oneway connection - DrawLine (g_hostEntity, path->origin, m_paths[path->index[i]]->origin, 5, 0, 250, 250, 250, 200, 0, 10); + engine.DrawLine (g_hostEntity, path->origin, m_paths[path->index[i]]->origin, 5, 0, 250, 250, 250, 200, 0, 10); } // now look for oneway incoming connections for (int i = 0; i < g_numWaypoints; i++) { if (IsConnected (m_paths[i]->pathNumber, path->pathNumber) && !IsConnected (path->pathNumber, m_paths[i]->pathNumber)) - DrawLine (g_hostEntity, path->origin, m_paths[i]->origin, 5, 0, 0, 192, 96, 200, 0, 10); + engine.DrawLine (g_hostEntity, path->origin, m_paths[i]->origin, 5, 0, 0, 192, 96, 200, 0, 10); } // draw the radius circle @@ -1707,34 +1730,34 @@ void Waypoint::Think (void) { float squareRoot = sqrtf (path->radius * path->radius * 0.5f); - DrawLine (g_hostEntity, origin + Vector (path->radius, 0.0f, 0.0f), origin + Vector (squareRoot, -squareRoot, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); - DrawLine (g_hostEntity, origin + Vector (squareRoot, -squareRoot, 0.0f), origin + Vector (0.0f, -path->radius, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (path->radius, 0.0f, 0.0f), origin + Vector (squareRoot, -squareRoot, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (squareRoot, -squareRoot, 0.0f), origin + Vector (0.0f, -path->radius, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); - DrawLine (g_hostEntity, origin + Vector (0.0f, -path->radius, 0.0f), origin + Vector (-squareRoot, -squareRoot, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); - DrawLine (g_hostEntity, origin + Vector (-squareRoot, -squareRoot, 0.0f), origin + Vector (-path->radius, 0.0f, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (0.0f, -path->radius, 0.0f), origin + Vector (-squareRoot, -squareRoot, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (-squareRoot, -squareRoot, 0.0f), origin + Vector (-path->radius, 0.0f, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); - DrawLine (g_hostEntity, origin + Vector (-path->radius, 0.0f, 0.0f), origin + Vector (-squareRoot, squareRoot, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); - DrawLine (g_hostEntity, origin + Vector (-squareRoot, squareRoot, 0.0f), origin + Vector (0.0f, path->radius, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (-path->radius, 0.0f, 0.0f), origin + Vector (-squareRoot, squareRoot, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (-squareRoot, squareRoot, 0.0f), origin + Vector (0.0f, path->radius, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); - DrawLine (g_hostEntity, origin + Vector (0.0f, path->radius, 0.0f), origin + Vector (squareRoot, squareRoot, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); - DrawLine (g_hostEntity, origin + Vector (squareRoot, squareRoot, 0.0f), origin + Vector (path->radius, 0.0f, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (0.0f, path->radius, 0.0f), origin + Vector (squareRoot, squareRoot, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (squareRoot, squareRoot, 0.0f), origin + Vector (path->radius, 0.0f, 0.0f), 5, 0, 0, 0, 255, 200, 0, 10); } else { float squareRoot = sqrtf (32.0f); - DrawLine (g_hostEntity, origin + Vector (squareRoot, -squareRoot, 0.0f), origin + Vector (-squareRoot, squareRoot, 0.0f), 5, 0, 255, 0, 0, 200, 0, 10); - DrawLine (g_hostEntity, origin + Vector (-squareRoot, -squareRoot, 0.0f), origin + Vector (squareRoot, squareRoot, 0.0f), 5, 0, 255, 0, 0, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (squareRoot, -squareRoot, 0.0f), origin + Vector (-squareRoot, squareRoot, 0.0f), 5, 0, 255, 0, 0, 200, 0, 10); + engine.DrawLine (g_hostEntity, origin + Vector (-squareRoot, -squareRoot, 0.0f), origin + Vector (squareRoot, squareRoot, 0.0f), 5, 0, 255, 0, 0, 200, 0, 10); } // draw the danger directions if (!g_waypointsChanged) { - if ((g_experienceData + (nearestIndex * g_numWaypoints) + nearestIndex)->team0DangerIndex != -1 && GetTeam (g_hostEntity) == TERRORIST) - DrawArrow (g_hostEntity, path->origin, m_paths[(g_experienceData + (nearestIndex * g_numWaypoints) + nearestIndex)->team0DangerIndex]->origin, 15, 0, 255, 0, 0, 200, 0, 10); // draw a red arrow to this index's danger point + if ((g_experienceData + (nearestIndex * g_numWaypoints) + nearestIndex)->team0DangerIndex != -1 && engine.GetTeam (g_hostEntity) == TERRORIST) + engine.DrawLine (g_hostEntity, path->origin, m_paths[(g_experienceData + (nearestIndex * g_numWaypoints) + nearestIndex)->team0DangerIndex]->origin, 15, 0, 255, 0, 0, 200, 0, 10, DRAW_ARROW); // draw a red arrow to this index's danger point - if ((g_experienceData + (nearestIndex * g_numWaypoints) + nearestIndex)->team1DangerIndex != -1 && GetTeam (g_hostEntity) == CT) - DrawArrow (g_hostEntity, path->origin, m_paths[(g_experienceData + (nearestIndex * g_numWaypoints) + nearestIndex)->team1DangerIndex]->origin, 15, 0, 0, 0, 255, 200, 0, 10); // draw a blue arrow to this index's danger point + if ((g_experienceData + (nearestIndex * g_numWaypoints) + nearestIndex)->team1DangerIndex != -1 && engine.GetTeam (g_hostEntity) == CT) + engine.DrawLine (g_hostEntity, path->origin, m_paths[(g_experienceData + (nearestIndex * g_numWaypoints) + nearestIndex)->team1DangerIndex]->origin, 15, 0, 0, 0, 255, 200, 0, 10, DRAW_ARROW); // draw a blue arrow to this index's danger point } // display some information @@ -1889,7 +1912,7 @@ bool Waypoint::NodesValid (void) { AddLogEntry (true, LL_WARNING, "Waypoint %d - Pathindex %d points to itself!", i, k); - if (g_waypointOn && !IsDedicatedServer ()) + if (g_waypointOn && !engine.IsDedicatedServer ()) { (*g_engfuncs.pfnSetOrigin) (g_hostEntity, m_paths[i]->origin); @@ -1972,7 +1995,7 @@ bool Waypoint::NodesValid (void) { AddLogEntry (true, LL_WARNING, "Path broken from Waypoint #0 to Waypoint #%d!", i); - if (g_waypointOn && !IsDedicatedServer ()) + if (g_waypointOn && !engine.IsDedicatedServer ()) { (*g_engfuncs.pfnSetOrigin) (g_hostEntity, m_paths[i]->origin); @@ -2033,7 +2056,7 @@ bool Waypoint::NodesValid (void) { AddLogEntry (true, LL_WARNING, "Path broken from Waypoint #%d to Waypoint #0!", i); - if (g_waypointOn && !IsDedicatedServer ()) + if (g_waypointOn && !engine.IsDedicatedServer ()) { (*g_engfuncs.pfnSetOrigin) (g_hostEntity, m_paths[i]->origin); @@ -2107,7 +2130,7 @@ void Waypoint::InitPathMatrix (void) void Waypoint::SavePathMatrix (void) { - File fp (FormatBuffer ("%slearned/%s.pmt", GetWaypointDir (), GetMapName ()), "wb"); + File fp (FormatBuffer ("%slearned/%s.pmt", GetDataDir (), engine.GetMapName ()), "wb"); // unable to open file if (!fp.IsValid ()) @@ -2129,7 +2152,7 @@ void Waypoint::SavePathMatrix (void) bool Waypoint::LoadPathMatrix (void) { - File fp (FormatBuffer ("%slearned/%s.pmt", GetWaypointDir (), GetMapName ()), "rb"); + File fp (FormatBuffer ("%slearned/%s.pmt", GetDataDir (), engine.GetMapName ()), "rb"); // file doesn't exists return false if (!fp.IsValid ()) @@ -2208,7 +2231,7 @@ void Waypoint::CreateBasic (void) edict_t *ent = NULL; // first of all, if map contains ladder points, create it - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_ladder"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_ladder"))) { Vector ladderLeft = ent->v.absmin; Vector ladderRight = ent->v.absmax; @@ -2218,7 +2241,7 @@ void Waypoint::CreateBasic (void) Vector up, down, front, back; Vector diff = ((ladderLeft - ladderRight) ^ Vector (0.0f, 0.0f, 0.0f)).Normalize () * 15.0f; - front = back = GetEntityOrigin (ent); + front = back = engine.GetAbsOrigin (ent); front = front + diff; // front back = back - diff; // back @@ -2226,7 +2249,7 @@ void Waypoint::CreateBasic (void) up = down = front; down.z = ent->v.absmax.z; - TraceHull (down, up, true, point_hull, NULL, &tr); + engine.TestHull (down, up, TRACE_IGNORE_MONSTERS, point_hull, NULL, &tr); if (POINT_CONTENTS (up) == CONTENTS_SOLID || tr.flFraction != 1.0f) { @@ -2234,7 +2257,7 @@ void Waypoint::CreateBasic (void) down.z = ent->v.absmax.z; } - TraceHull (down, up - Vector (0.0f, 0.0f, 1000.0f), true, point_hull, NULL, &tr); + engine.TestHull (down, up - Vector (0.0f, 0.0f, 1000.0f), TRACE_IGNORE_MONSTERS, point_hull, NULL, &tr); up = tr.vecEndPos; Vector pointOrigin = up + Vector (0.0f, 0.0f, 39.0f); @@ -2257,103 +2280,103 @@ void Waypoint::CreateBasic (void) } // then terrortist spawnpoints - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_deathmatch"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_deathmatch"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (0, origin); } // then add ct spawnpoints - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_start"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_player_start"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (0, origin); } // then vip spawnpoint - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_vip_start"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_vip_start"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (0, origin); } // hostage rescue zone - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_hostage_rescue"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_hostage_rescue"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (4, origin); } // hostage rescue zone (same as above) - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_hostage_rescue"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_hostage_rescue"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (4, origin); } // bombspot zone - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_bomb_target"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_bomb_target"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (100, origin); } // bombspot zone (same as above) - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_bomb_target"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "info_bomb_target"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (100, origin); } // hostage entities - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "hostage_entity"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "hostage_entity"))) { // if already saved || moving skip it if ((ent->v.effects & EF_NODRAW) && ent->v.speed > 0.0f) continue; - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50) == -1) Add (100, origin); } // vip rescue (safety) zone - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_vip_safetyzone"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_vip_safetyzone"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (100, origin); } // terrorist escape zone - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_escapezone"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "func_escapezone"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (100, origin); } // weapons on the map ? - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "armoury_entity"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "armoury_entity"))) { - Vector origin = GetEntityOrigin (ent); + Vector origin = engine.GetAbsOrigin (ent); if (FindNearest (origin, 50.0f) == -1) Add (0, origin); @@ -2375,13 +2398,14 @@ void Waypoint::EraseFromHardDisk (void) // this function removes waypoint file from the hard disk String deleteList[5]; + const char *map = engine.GetMapName (); // if we're delete waypoint, delete all corresponding to it files - deleteList[0] = FormatBuffer ("%s%s.pwf", GetWaypointDir (), GetMapName ()); // waypoint itself - deleteList[1] = FormatBuffer ("%slearned/%s.exp", GetWaypointDir (), GetMapName ()); // corresponding to waypoint experience - deleteList[3] = FormatBuffer ("%slearned/%s.vis", GetWaypointDir (), GetMapName ()); // corresponding to waypoint vistable - deleteList[3] = FormatBuffer ("%slearned/%s.pmt", GetWaypointDir (), GetMapName ()); // corresponding to waypoint path matrix - deleteList[4] = FormatBuffer ("%slearned/%s.xml", GetWaypointDir (), GetMapName ()); // corresponding to waypoint xml database + deleteList[0] = FormatBuffer ("%s%s.pwf", GetDataDir (), map); // waypoint itself + deleteList[1] = FormatBuffer ("%slearned/%s.exp", GetDataDir (), map); // corresponding to waypoint experience + deleteList[3] = FormatBuffer ("%slearned/%s.vis", GetDataDir (), map); // corresponding to waypoint vistable + deleteList[3] = FormatBuffer ("%slearned/%s.pmt", GetDataDir (), map); // corresponding to waypoint path matrix + deleteList[4] = FormatBuffer ("%slearned/%s.xml", GetDataDir (), map); // corresponding to waypoint xml database for (int i = 0; i < 4; i++) { @@ -2396,6 +2420,11 @@ void Waypoint::EraseFromHardDisk (void) Init (); // reintialize points } +const char *Waypoint::GetDataDir (void) +{ + return FormatBuffer ("%s/addons/yapb/data/", engine.GetModName ()); +} + void Waypoint::SetBombPosition (bool shouldReset) { // this function stores the bomb position as a vector @@ -2407,14 +2436,13 @@ void Waypoint::SetBombPosition (bool shouldReset) return; } - edict_t *ent = NULL; - while (!IsEntityNull (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) + while (!engine.IsNullEntity (ent = FIND_ENTITY_BY_CLASSNAME (ent, "grenade"))) { if (strcmp (STRING (ent->v.model) + 9, "c4.mdl") == 0) { - m_foundBombOrigin = GetEntityOrigin (ent); + m_foundBombOrigin = engine.GetAbsOrigin (ent); break; } } @@ -2430,13 +2458,15 @@ void Waypoint::SetFindIndex (int index) m_findWPIndex = index; if (m_findWPIndex < g_numWaypoints) - ServerPrint ("Showing Direction to Waypoint #%d", m_findWPIndex); + engine.Printf ("Showing Direction to Waypoint #%d", m_findWPIndex); else m_findWPIndex = -1; } Waypoint::Waypoint (void) { + CleanupPathMemory (); + m_waypointPaths = false; m_endJumpPoint = false; m_redoneVisibility = false; @@ -2448,6 +2478,7 @@ Waypoint::Waypoint (void) m_findWPIndex = -1; m_facingAtIndex = -1; m_visibilityIndex = 0; + m_loadTries = 0; m_isOnLadder = false; @@ -2463,13 +2494,12 @@ Waypoint::Waypoint (void) m_distMatrix = NULL; m_pathMatrix = NULL; - - for (int i = 0; i < MAX_WAYPOINTS; i++) - m_paths[i] = NULL; } Waypoint::~Waypoint (void) { + CleanupPathMemory (); + delete [] m_distMatrix; delete [] m_pathMatrix; @@ -2477,7 +2507,7 @@ Waypoint::~Waypoint (void) m_pathMatrix = NULL; } -void WaypointDownloader::FreeSocket (int sock) +void Waypoint::CloseSocketHandle (int sock) { #if defined (PLATFORM_WIN32) if (sock != -1) @@ -2491,7 +2521,7 @@ void WaypointDownloader::FreeSocket (int sock) } -WaypointDownloadError WaypointDownloader::DoDownload (void) +WaypointDownloadError Waypoint::RequestWaypoint (void) { #if defined (PLATFORM_WIN32) WORD requestedVersion = MAKEWORD (1, 1); @@ -2512,7 +2542,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void) if (socketHandle < 0) { - FreeSocket (socketHandle); + CloseSocketHandle (socketHandle); return WDE_SOCKET_ERROR; } sockaddr_in dest; @@ -2525,14 +2555,14 @@ WaypointDownloadError WaypointDownloader::DoDownload (void) if (result < 0) { - FreeSocket (socketHandle); + CloseSocketHandle (socketHandle); return WDE_SOCKET_ERROR; } result = setsockopt (socketHandle, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof (timeout)); if (result < 0) { - FreeSocket (socketHandle); + CloseSocketHandle (socketHandle); return WDE_SOCKET_ERROR; } memset (&dest, 0, sizeof (dest)); @@ -2543,20 +2573,20 @@ WaypointDownloadError WaypointDownloader::DoDownload (void) if (connect (socketHandle, (struct sockaddr*) &dest, (int) sizeof (dest)) == -1) { - FreeSocket (socketHandle); + CloseSocketHandle (socketHandle); return WDE_CONNECT_ERROR; } String request; - request.AssignFormat ("GET /wpdb/%s.pwf HTTP/1.0\r\nAccept: */*\r\nUser-Agent: YaPB/%s\r\nHost: %s\r\n\r\n", GetMapName (), PRODUCT_VERSION, yb_waypoint_autodl_host.GetString ()); + request.AssignFormat ("GET /wpdb/%s.pwf HTTP/1.0\r\nAccept: */*\r\nUser-Agent: YaPB/%s\r\nHost: %s\r\n\r\n", engine.GetMapName (), PRODUCT_VERSION, yb_waypoint_autodl_host.GetString ()); if (send (socketHandle, request.GetBuffer (), request.GetLength () + 1, 0) < 1) { - FreeSocket (socketHandle); + CloseSocketHandle (socketHandle); return WDE_SOCKET_ERROR; } - const int ChunkSize = 1024; + const int ChunkSize = MAX_PRINT_BUFFER; char buffer[ChunkSize] = { 0, }; bool finished = false; @@ -2572,7 +2602,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void) // ugly, but whatever if (recvPosition > 2 && buffer[recvPosition - 2] == '4' && buffer[recvPosition - 1] == '0' && buffer[recvPosition] == '4') { - FreeSocket (socketHandle); + CloseSocketHandle (socketHandle); return WDE_NOTFOUND_ERROR; } @@ -2599,7 +2629,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void) if (!fp.IsValid ()) { - FreeSocket (socketHandle); + CloseSocketHandle (socketHandle); return WDE_SOCKET_ERROR; } @@ -2618,7 +2648,7 @@ WaypointDownloadError WaypointDownloader::DoDownload (void) } while (recvSize != 0); fp.Close (); - FreeSocket (socketHandle); + CloseSocketHandle (socketHandle); return WDE_NOERROR; } \ No newline at end of file