diff --git a/.gitignore b/.gitignore index fba712e..62c4af6 100644 --- a/.gitignore +++ b/.gitignore @@ -61,5 +61,3 @@ project/yapb.vcxproj.user *.enc *.xml /project/#Verone/incremental_index -*.lastcodeanalysissucceeded -/project/hlds160301.vsp diff --git a/include/core.h b/include/core.h index bd6bc72..37ecafd 100644 --- a/include/core.h +++ b/include/core.h @@ -63,8 +63,7 @@ enum GameFlags GAME_CZERO = (1 << 2), // Counter-Strike: Condition Zero GAME_LEGACY = (1 << 3), // Counter-Strike 1.3-1.5 with/without Steam GAME_MOBILITY = (1 << 4), // additional flag that bot is running on android (additional flag) - GAME_OFFICIAL_CSBOT = (1 << 5), // additional flag that indicates official cs bots are in game - GAME_METAMOD = (1 << 6) + GAME_OFFICIAL_CSBOT = (1 << 5) // additional flag that indicates official cs bots are in game }; // log levels @@ -126,14 +125,6 @@ enum ClientFlags CF_ADMIN = (1 << 2) }; -// bot create status -enum BotCreationResult -{ - BOT_RESULT_CREATED, - BOT_RESULT_MAX_PLAYERS_REACHED, - BOT_RESULT_NAV_ERROR -}; - // radio messages enum RadioMessage_t { @@ -811,7 +802,6 @@ private: bool m_moveToGoal; // bot currently moving to goal?? bool m_isStuck; // bot is stuck bool m_isReloading; // bot is reloading a gun - bool m_forceRadio; // should bot use radio anyway? int m_reloadState; // current reload state int m_voicePitch; // bot voice pitch @@ -998,6 +988,7 @@ private: int ChangeWptIndex (int waypointIndex); bool IsDeadlyDrop (const Vector &to); bool OutOfBombTimer (void); + void SelectLeaderEachTeam (int team); Vector CheckThrow (const Vector &start, const Vector &stop); Vector CheckToss (const Vector &start, const Vector &stop); @@ -1248,9 +1239,8 @@ private: int m_lastWinner; // the team who won previous round int m_balanceCount; // limit of bots to add - bool m_leaderChoosen[SPECTATOR]; // is team leader choose theese round - bool m_economicsGood[SPECTATOR]; // is team able to buy anything - bool m_deathMsgSent; // for fake ping + 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 @@ -1258,13 +1248,13 @@ private: edict_t *m_killerEntity; // killer entity for bots protected: - BotCreationResult CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd); + int CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd); public: BotManager (void); ~BotManager (void); - bool IsEcoValid (int team) { return m_economicsGood[team]; } + bool EconomicsValid (int team) { return m_economicsGood[team]; } int GetLastWinner (void) const { return m_lastWinner; } void SetLastWinner (int winner) { m_lastWinner = winner; } @@ -1306,7 +1296,6 @@ public: void AddPlayerToCheckTeamQueue (edict_t *ent); void VerifyPlayersHasJoinedTeam (int &desiredCount); - void SelectLeaderEachTeam (int team, bool reset); void ListBots (void); void SetWeaponMode (int selection); @@ -1333,6 +1322,7 @@ public: void SendDeathMsgFix (void); }; + // waypoint operation class class Waypoint : public Singleton { @@ -1345,7 +1335,6 @@ private: bool m_isOnLadder; bool m_endJumpPoint; bool m_learnJumpWaypoint; - bool m_waypointsChanged; float m_timeJumpStarted; Vector m_learnVelocity; @@ -1432,9 +1421,7 @@ public: int GetPathDistance (int srcIndex, int destIndex); Path *GetPath (int id); const char *GetWaypointInfo (int id); - char *GetInfo (void) { return m_infoBuffer; } - bool HasChanged (void) { return m_waypointsChanged; } void SetFindIndex (int index); void SetLearnJumpWaypoint (void); diff --git a/include/globals.h b/include/globals.h index 38cdef3..ca8f776 100644 --- a/include/globals.h +++ b/include/globals.h @@ -13,11 +13,15 @@ extern bool g_canSayBombPlanted; extern bool g_bombPlanted; extern bool g_bombSayString; extern bool g_roundEnded; +extern bool g_radioInsteadVoice; extern bool g_waypointOn; +extern bool g_waypointsChanged; extern bool g_autoWaypoint; extern bool g_botsCanPause; extern bool g_editNoclip; +extern bool g_isMetamod; extern bool g_isCommencing; +extern bool g_leaderChoosen[2]; extern float g_autoPathDistance; extern float g_timeBombPlanted; @@ -25,6 +29,7 @@ extern float g_timeNextBombUpdate; extern float g_lastChatTime; extern float g_timeRoundEnd; extern float g_timeRoundMid; +extern float g_timeNextBombUpdate; extern float g_timeRoundStart; extern float g_timePerSecondUpdate; extern float g_lastRadioTime[2]; @@ -66,6 +71,10 @@ extern edict_t *g_hostEntity; extern Library *g_gameLib; extern gamefuncs_t g_functionTable; +extern EntityAPI_t g_entityAPI; +extern FuncPointers_t g_funcPointers; +extern NewEntityAPI_t g_getNewEntityAPI; +extern BlendAPI_t g_serverBlendingAPI; static inline bool IsNullString (const char *input) { diff --git a/include/resource.h b/include/resource.h index 850bca5..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.8" +#define PRODUCT_VERSION "2.73" #define PRODUCT_AUTHOR "YaPB Dev Team" -#define PRODUCT_URL "https://yapb.jeefo.net/" +#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 © 1999-2017, 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,8 +#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/yapb.sln b/project/yapb.sln index c13e67c..4265017 100644 --- a/project/yapb.sln +++ b/project/yapb.sln @@ -1,14 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yapb", "yapb.vcxproj", "{C232645A-3B99-48F4-A1F3-F20CF0A9568B}" EndProject Global - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 diff --git a/project/yapb.vcxproj b/project/yapb.vcxproj index 3d9d590..6005c14 100644 --- a/project/yapb.vcxproj +++ b/project/yapb.vcxproj @@ -62,7 +62,7 @@ DynamicLibrary false - v140_xp + v120_xp diff --git a/source/basecode.cpp b/source/basecode.cpp index bd1aa7b..2eb63e2 100644 --- a/source/basecode.cpp +++ b/source/basecode.cpp @@ -4,7 +4,7 @@ // // This software is licensed under the BSD-style license. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: -// https://yapb.ru/license +// http://yapb.jeefo.net/license // #include @@ -968,7 +968,7 @@ void Bot::SwitchChatterIcon (bool show) for (int i = 0; i < engine.MaxClients (); i++) { - const Client &client = g_clients[i]; + Client &client = g_clients[i]; if (!(client.flags & CF_USED) || (client.ent->v.flags & FL_FAKECLIENT) || client.team != m_team) continue; @@ -1030,9 +1030,7 @@ void Bot::RadioMessage (int message) return; if (g_chatterFactory[message].IsEmpty () || (g_gameFlags & GAME_LEGACY) || yb_communication_type.GetInt () != 2) - m_forceRadio = true; // use radio instead voice - else - m_forceRadio = false; + g_radioInsteadVoice = true; // use radio instead voice m_radioSelect = message; PushMessageQueue (GSM_RADIO); @@ -1243,7 +1241,7 @@ void Bot::CheckMessageQueue (void) } } - if ((m_radioSelect != Radio_ReportingIn && m_forceRadio) || yb_communication_type.GetInt () != 2 || g_chatterFactory[m_radioSelect].IsEmpty () || (g_gameFlags & GAME_LEGACY)) + if ((m_radioSelect != Radio_ReportingIn && g_radioInsteadVoice) || yb_communication_type.GetInt () != 2 || g_chatterFactory[m_radioSelect].IsEmpty () || (g_gameFlags & GAME_LEGACY)) { if (m_radioSelect < Radio_GoGoGo) engine.IssueBotCommand (GetEntity (), "radio1"); @@ -1264,7 +1262,7 @@ void Bot::CheckMessageQueue (void) else if (m_radioSelect != -1 && m_radioSelect != Radio_ReportingIn) InstantChatterMessage (m_radioSelect); - m_forceRadio = false; // reset radio to voice + g_radioInsteadVoice = false; // reset radio to voice g_lastRadioTime[m_team] = engine.Time (); // store last radio usage } else @@ -1406,7 +1404,7 @@ void Bot::PurchaseWeapons (void) int *ptr = g_weaponPrefs[m_personality] + NUM_WEAPONS; bool isPistolMode = g_weaponSelect[25].teamStandard == -1 && g_weaponSelect[3].teamStandard == 2; - bool teamEcoValid = bots.IsEcoValid (m_team); + bool teamEcoValid = bots.EconomicsValid (m_team); // do this, because xash engine is not capable to run all the features goldsrc, but we have cs 1.6 on it, so buy table must be the same bool isOldGame = (g_gameFlags & GAME_LEGACY) && !(g_gameFlags & GAME_XASH); @@ -2582,12 +2580,10 @@ void Bot::CheckRadioCommands (void) // take nearest enemy to ordering player for (int i = 0; i < engine.MaxClients (); i++) { - const Client &client = g_clients[i]; - - if (!(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.team == m_team) + if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team == m_team) continue; - edict_t *enemy = client.ent; + edict_t *enemy = g_clients[i].ent; float curDist = (m_radioEntity->v.origin - enemy->v.origin).GetLengthSquared (); if (curDist < nearestDistance) @@ -2678,12 +2674,10 @@ void Bot::CheckRadioCommands (void) // take nearest enemy to ordering player for (int i = 0; i < engine.MaxClients (); i++) { - const Client &client = g_clients[i]; - - if (!(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.team == m_team) + if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team == m_team) continue; - edict_t *enemy = client.ent; + edict_t *enemy = g_clients[i].ent; float dist = (m_radioEntity->v.origin - enemy->v.origin).GetLengthSquared (); if (dist < nearestDistance) @@ -2734,6 +2728,98 @@ void Bot::TryHeadTowardRadioEntity (void) } } +void Bot::SelectLeaderEachTeam (int team) +{ + if (g_mapType & MAP_AS) + { + if (m_isVIP && !g_leaderChoosen[CT]) + { + // vip bot is the leader + m_isLeader = true; + + if (Random.Long (1, 100) < 50) + { + RadioMessage (Radio_FollowMe); + m_campButtons = 0; + } + g_leaderChoosen[CT] = true; + } + else if (team == TERRORIST && !g_leaderChoosen[TERRORIST]) + { + Bot *botLeader = bots.GetHighestFragsBot(team); + + if (botLeader != NULL && botLeader->m_notKilled) + { + botLeader->m_isLeader = true; + + if (Random.Long (1, 100) < 45) + botLeader->RadioMessage (Radio_FollowMe); + } + g_leaderChoosen[TERRORIST] = true; + } + } + else if (g_mapType & MAP_DE) + { + if (team == TERRORIST && !g_leaderChoosen[TERRORIST]) + { + if (m_hasC4) + { + // bot carrying the bomb is the leader + m_isLeader = true; + + // terrorist carrying a bomb needs to have some company + if (Random.Long (1, 100) < 80) + { + if (yb_communication_type.GetInt () == 2) + ChatterMessage (Chatter_GoingToPlantBomb); + else + ChatterMessage (Radio_FollowMe); + + m_campButtons = 0; + } + g_leaderChoosen[TERRORIST] = true; + } + } + else if (!g_leaderChoosen[CT]) + { + Bot *botLeader = bots.GetHighestFragsBot(team); + + if (botLeader != NULL) + { + botLeader->m_isLeader = true; + + if (Random.Long (1, 100) < 30) + botLeader->RadioMessage (Radio_FollowMe); + } + g_leaderChoosen[CT] = true; + } + } + else if (g_mapType & (MAP_ES | MAP_KA | MAP_FY)) + { + Bot *botLeader = bots.GetHighestFragsBot (team); + + if (botLeader != NULL) + { + botLeader->m_isLeader = true; + + if (Random.Long (1, 100) < 30) + botLeader->RadioMessage (Radio_FollowMe); + } + } + else + { + Bot *botLeader = bots.GetHighestFragsBot(team); + + if (botLeader != NULL) + { + botLeader->m_isLeader = true; + + if (Random.Long (1, 100) < (team == TERRORIST ? 30 : 40)) + botLeader->RadioMessage (Radio_FollowMe); + } + } +} + void Bot::ChooseAimDirection (void) { unsigned int flags = m_aimFlags; @@ -4698,6 +4784,9 @@ void Bot::CheckSpawnTimeConditions (void) break; } } + + // select a leader bot for this team + SelectLeaderEachTeam (m_team); m_checkWeaponSwitch = false; } } @@ -5291,7 +5380,7 @@ void Bot::CollectGoalExperience (int damage, int team) // gets called each time a bot gets damaged by some enemy. tries to achieve a statistic about most/less dangerous // waypoints for a destination goal used for pathfinding - if (g_numWaypoints < 1 || waypoints.HasChanged () || m_chosenGoalIndex < 0 || m_prevGoalIndex < 0) + if (g_numWaypoints < 1 || g_waypointsChanged || m_chosenGoalIndex < 0 || m_prevGoalIndex < 0) return; // only rate goal waypoint if bot died because of the damage @@ -5830,17 +5919,15 @@ void Bot::ReactOnSound (void) // loop through all enemy clients to check for hearable stuff for (int i = 0; i < engine.MaxClients (); i++) { - const Client &client = g_clients[i]; - - if (!(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.ent == GetEntity () || client.team == m_team || client.timeSoundLasting < engine.Time ()) + 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 = (client.soundPosition - pev->origin).GetLength (); + float distance = (g_clients[i].soundPosition - pev->origin).GetLength (); - if (distance > client.hearingDistance) + if (distance > g_clients[i].hearingDistance) continue; - if (!ENGINE_CHECK_VISIBILITY (client.ent, pas)) + if (!ENGINE_CHECK_VISIBILITY (g_clients[i].ent, pas)) continue; if (distance < minDistance) @@ -5983,13 +6070,13 @@ bool Bot::IsBombDefusing (const Vector &bombOrigin) defusingInProgress = true; break; } - const Client &client = g_clients[i]; + Client *client = &g_clients[i]; // take in account peoples too - if (defusingInProgress || !(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.team != m_team || IsValidBot (client.ent)) + if (defusingInProgress || !(client->flags & CF_USED) || !(client->flags & CF_ALIVE) || client->team != m_team || IsValidBot (g_clients[i].ent)) continue; - if ((client.ent->v.origin - bombOrigin).GetLength () < 140.0f && ((client.ent->v.button | client.ent->v.oldbuttons) & IN_USE)) + if ((client->ent->v.origin - bombOrigin).GetLength () < 140.0f && ((client->ent->v.button | client->ent->v.oldbuttons) & IN_USE)) { defusingInProgress = true; break; diff --git a/source/combat.cpp b/source/combat.cpp index e891a2d..0fc85a6 100644 --- a/source/combat.cpp +++ b/source/combat.cpp @@ -22,12 +22,10 @@ int Bot::GetNearbyFriendsNearPosition(const Vector &origin, float radius) for (int i = 0; i < engine.MaxClients (); i++) { - const Client &client = g_clients[i]; - - if (!(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.team != m_team || client.ent == GetEntity ()) + 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; - if ((client.origin - origin).GetLengthSquared () < GET_SQUARE (radius)) + if ((g_clients[i].origin - origin).GetLengthSquared () < GET_SQUARE (radius)) count++; } return count; @@ -39,12 +37,10 @@ int Bot::GetNearbyEnemiesNearPosition(const Vector &origin, float radius) for (int i = 0; i < engine.MaxClients (); i++) { - const Client &client = g_clients[i]; - - if (!(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.team == m_team) + if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team == m_team) continue; - if ((client.origin - origin).GetLengthSquared () < GET_SQUARE (radius)) + if ((g_clients[i].origin - origin).GetLengthSquared () < GET_SQUARE (radius)) count++; } return count; @@ -250,12 +246,10 @@ bool Bot::LookupEnemy (void) // search the world for players... for (int i = 0; i < engine.MaxClients (); i++) { - const Client &client = g_clients[i]; - - if (!(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.team == m_team || client.ent == GetEntity ()) + 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; - player = client.ent; + player = g_clients[i].ent; // let the engine check if this player is potentially visible if (!ENGINE_CHECK_VISIBILITY (player, pvs)) @@ -346,20 +340,18 @@ bool Bot::LookupEnemy (void) // 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 < engine.MaxClients (); j++) { - const Client &client = g_clients[j]; - - if (!(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.team != m_team || client.ent == GetEntity ()) + 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 *other = bots.GetBot (client.ent); + Bot *friendBot = bots.GetBot (g_clients[j].ent); - if (other != NULL && other->m_seeEnemyTime + 2.0f < engine.Time () && engine.IsNullEntity (other->m_lastEnemy) && IsVisible (pev->origin, other->GetEntity ()) && other->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)) { - other->m_lastEnemy = newEnemy; - other->m_lastEnemyOrigin = m_lastEnemyOrigin; - other->m_seeEnemyTime = engine.Time (); - other->m_states |= (STATE_SUSPECT_ENEMY | STATE_HEARING_ENEMY); - other->m_aimFlags |= AIM_LAST_ENEMY; + friendBot->m_lastEnemy = newEnemy; + friendBot->m_lastEnemyOrigin = m_lastEnemyOrigin; + friendBot->m_seeEnemyTime = engine.Time (); + friendBot->m_states |= (STATE_SUSPECT_ENEMY | STATE_HEARING_ENEMY); + friendBot->m_aimFlags |= AIM_LAST_ENEMY; } } return true; @@ -1437,24 +1429,22 @@ void Bot::SelectWeaponbyNumber (int num) void Bot::AttachToUser (void) { // this function forces bot to follow user - Array users; + Array foundUsers; // search friends near us for (int i = 0; i < engine.MaxClients (); i++) { - const Client &client = g_clients[i]; - - if (!(client.flags & CF_USED) || !(client.flags & CF_ALIVE) || client.team != m_team || client.ent == GetEntity ()) + 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; - if (EntityIsVisible (client.origin) && !IsValidBot (client.ent)) - users.Push (client.ent); + if (EntityIsVisible (g_clients[i].origin) && !IsValidBot (g_clients[i].ent)) + foundUsers.Push (g_clients[i].ent); } - if (users.IsEmpty ()) + if (foundUsers.IsEmpty ()) return; - m_targetEntity = users.GetRandomElement (); + m_targetEntity = foundUsers.GetRandomElement (); ChatterMessage (Chatter_LeadOnSir); PushTask (TASK_FOLLOWUSER, TASKPRI_FOLLOWUSER, -1, 0.0f, true); diff --git a/source/globals.cpp b/source/globals.cpp index 1e0441e..6d8341d 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -9,41 +9,20 @@ #include -class Chat -{ -public: -}; - -class Globals -{ -public: -}; - -class Practice -{ -public: -}; - -class GameState -{ -public: -}; - -class MenuManager -{ -public: -}; - bool g_canSayBombPlanted = true; +bool g_isMetamod = false; +bool g_radioInsteadVoice = false; bool g_roundEnded = true; bool g_botsCanPause = false; bool g_bombPlanted = false; bool g_bombSayString = false; bool g_isCommencing = false; - bool g_editNoclip = false; bool g_waypointOn = false; +bool g_waypointsChanged = true; bool g_autoWaypoint = false; +bool g_bLearnJumpWaypoint = false; +bool g_leaderChoosen[2] = {false, false}; float g_lastChatTime = 0.0f; float g_timeRoundStart = 0.0f; @@ -78,6 +57,10 @@ gamedll_funcs_t *gpGamedllFuncs = NULL; mutil_funcs_t *gpMetaUtilFuncs = NULL; gamefuncs_t g_functionTable; +EntityAPI_t g_entityAPI = NULL; +NewEntityAPI_t g_getNewEntityAPI = NULL; +BlendAPI_t g_serverBlendingAPI = NULL; +FuncPointers_t g_funcPointers = NULL; enginefuncs_t g_engfuncs; Client g_clients[MAX_ENGINE_PLAYERS]; diff --git a/source/interface.cpp b/source/interface.cpp index 8cdb76b..863a66c 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -915,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. - + engine.Printf ("You're launched standalone version of yapb. Metamod is not installed or not enabled!"); } void GameDLLInit (void) @@ -928,6 +928,8 @@ void GameDLLInit (void) // server is enabled. Here is a good place to do our own game session initialization, and // to register by the engine side the server commands we need to administrate our bots. + + // register server command(s) engine.RegisterCmd ("yapb", CommandHandler); engine.RegisterCmd ("yb", CommandHandler); @@ -939,15 +941,10 @@ void GameDLLInit (void) 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_gameFlags & GAME_METAMOD)) - { - engine.RegisterCmd ("meta", [] (void) - { - engine.Printf ("You're launched standalone version of yapb. Metamod is not installed or not enabled!"); - }); - } + if (!g_isMetamod) + engine.RegisterCmd ("meta", CommandHandler_NotMM); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnGameInit) (); @@ -973,7 +970,7 @@ void Touch (edict_t *pentTouched, edict_t *pentOther) if (bot != NULL) bot->VerifyBreakable (pentTouched); } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnTouch) (pentTouched, pentOther); @@ -1016,7 +1013,7 @@ int Spawn (edict_t *ent) { REMOVE_ENTITY (ent); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_SUPERCEDE, 0); return 0; @@ -1067,7 +1064,7 @@ int Spawn (edict_t *ent) else if (strncmp (engine.GetMapName (), "ka_", 3) == 0) // knife arena map g_mapType |= MAP_KA; - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_IGNORED, 0); int result = (*g_functionTable.pfnSpawn) (ent); // get result @@ -1085,7 +1082,7 @@ void UpdateClientData (const struct edict_s *ent, int sendweapons, struct client if (!(g_gameFlags & GAME_LEGACY) && yb_latency_display.GetInt () == 2) bots.SendPingDataOffsets (const_cast (ent)); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnUpdateClientData) (ent, sendweapons, cd); @@ -1119,7 +1116,7 @@ int ClientConnect (edict_t *ent, const char *name, const char *addr, char reject bots.AdjustQuota (true, ent); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_IGNORED, 0); return (*g_functionTable.pfnClientConnect) (ent, name, addr, rejectReason); @@ -1158,7 +1155,7 @@ void ClientDisconnect (edict_t *ent) } } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnClientDisconnect) (ent); @@ -1187,7 +1184,7 @@ void ClientUserInfoChanged (edict_t *ent, char *infobuffer) } } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnClientUserInfoChanged) (ent, infobuffer); @@ -1230,7 +1227,7 @@ void ClientCommand (edict_t *ent) engine.ClientPrintf (ent, "Command %s, can only be executed from server console.", arg1); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1268,7 +1265,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1299,7 +1296,7 @@ void ClientCommand (edict_t *ent) waypoints.ToggleFlags (FLAG_SNIPER); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1360,7 +1357,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1456,7 +1453,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, &g_menus[9]); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1472,7 +1469,7 @@ void ClientCommand (edict_t *ent) if ((selection >= 1) && (selection <= 9)) waypoints.SetRadius (radiusValue[selection - 1]); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1506,7 +1503,7 @@ void ClientCommand (edict_t *ent) break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1541,7 +1538,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1584,7 +1581,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1630,7 +1627,7 @@ void ClientCommand (edict_t *ent) break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1649,7 +1646,7 @@ void ClientCommand (edict_t *ent) else engine.CenterPrintf ("AutoPath maximum distance set to %f", g_autoPathDistance); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1677,7 +1674,7 @@ void ClientCommand (edict_t *ent) break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1718,7 +1715,7 @@ void ClientCommand (edict_t *ent) if (client->menu == &g_menus[4]) DisplayMenuToClient (ent, &g_menus[4]); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1744,7 +1741,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1765,7 +1762,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1798,7 +1795,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1821,7 +1818,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1845,7 +1842,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1870,7 +1867,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, NULL); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1900,7 +1897,7 @@ void ClientCommand (edict_t *ent) DisplayMenuToClient (ent, &g_menus[2]); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1930,7 +1927,7 @@ void ClientCommand (edict_t *ent) bots.RemoveMenu (ent, 1); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1960,7 +1957,7 @@ void ClientCommand (edict_t *ent) bots.RemoveMenu (ent, 2); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -1986,7 +1983,7 @@ void ClientCommand (edict_t *ent) bots.RemoveMenu (ent, 3); break; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; @@ -2063,7 +2060,7 @@ void ClientCommand (edict_t *ent) else if (strncmp (command, "radio", 5) == 0) g_radioSelect[clientIndex] = atoi (&command[5]); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnClientCommand) (ent); @@ -2098,7 +2095,7 @@ void ServerActivate (edict_t *pentEdictList, int edictCount, int clientMax) } bots.InitQuota (); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnServerActivate) (pentEdictList, edictCount, clientMax); @@ -2127,7 +2124,7 @@ void ServerDeactivate (void) FreeLibraryMemory (); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnServerDeactivate) (); @@ -2220,11 +2217,7 @@ void StartFrame (void) } bots.CalculatePingOffsets (); - // select the leader each team - for (int team = TERRORIST; team < SPECTATOR; team++) - bots.SelectLeaderEachTeam (team, false); - - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) { static cvar_t *csdm_active; static cvar_t *mp_freeforall; @@ -2247,7 +2240,7 @@ void StartFrame (void) // keep bot number up to date bots.MaintainBotQuota (); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_functionTable.pfnStartFrame) (); @@ -2317,7 +2310,7 @@ void pfnChangeLevel (char *s1, char *s2) waypoints.SaveExperienceTab (); waypoints.SaveVisibilityTab (); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); CHANGE_LEVEL (s1, s2); @@ -2329,7 +2322,7 @@ edict_t *pfnFindEntityByString (edict_t *edictStartSearchAfter, const char *fiel if (strcmp (value, "info_map_parameters") == 0) RoundInit (); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_IGNORED, 0); return FIND_ENTITY_BY_STRING (edictStartSearchAfter, field, value); @@ -2349,7 +2342,7 @@ void pfnEmitSound (edict_t *entity, int channel, const char *sample, float volum SoundAttachToClients (entity, sample, volume); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_engfuncs.pfnEmitSound) (entity, channel, sample, volume, attenuation, flags, pitch); @@ -2381,13 +2374,13 @@ void pfnClientCommand (edict_t *ent, char const *format, ...) // is the target entity an official bot, or a third party bot ? if (ent->v.flags & FL_FAKECLIENT) { - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); // prevent bots to be forced to issue client commands return; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); CLIENT_COMMAND (ent, buffer); @@ -2398,7 +2391,7 @@ 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_gameFlags & GAME_METAMOD) && engine.FindMessageId (NETMSG_MONEY) == -1) + if (g_isMetamod && engine.FindMessageId (NETMSG_MONEY) == -1) { engine.AssignMessageId (NETMSG_VGUI, GET_USER_MSG_ID (PLID, "VGUIMenu", NULL)); engine.AssignMessageId (NETMSG_SHOWMENU, GET_USER_MSG_ID (PLID, "ShowMenu", NULL)); @@ -2469,7 +2462,7 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed } } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); MESSAGE_BEGIN (msgDest, msgType, origin, ed); @@ -2479,7 +2472,7 @@ void pfnMessageEnd (void) { engine.ResetMessageCapture (); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); MESSAGE_END (); @@ -2501,7 +2494,7 @@ void pfnWriteByte (int value) // if this message is for a bot, call the client message function... engine.ProcessMessageCapture ((void *) &value); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); WRITE_BYTE (value); @@ -2512,7 +2505,7 @@ void pfnWriteChar (int value) // if this message is for a bot, call the client message function... engine.ProcessMessageCapture ((void *) &value); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); WRITE_CHAR (value); @@ -2523,7 +2516,7 @@ void pfnWriteShort (int value) // if this message is for a bot, call the client message function... engine.ProcessMessageCapture ((void *) &value); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); WRITE_SHORT (value); @@ -2534,7 +2527,7 @@ void pfnWriteLong (int value) // if this message is for a bot, call the client message function... engine.ProcessMessageCapture ((void *) &value); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); WRITE_LONG (value); @@ -2545,7 +2538,7 @@ void pfnWriteAngle (float value) // if this message is for a bot, call the client message function... engine.ProcessMessageCapture ((void *) &value); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); WRITE_ANGLE (value); @@ -2556,7 +2549,7 @@ void pfnWriteCoord (float value) // if this message is for a bot, call the client message function... engine.ProcessMessageCapture ((void *) &value); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); WRITE_COORD (value); @@ -2567,7 +2560,7 @@ void pfnWriteString (const char *sz) // if this message is for a bot, call the client message function... engine.ProcessMessageCapture ((void *) sz); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); WRITE_STRING (sz); @@ -2578,7 +2571,7 @@ void pfnWriteEntity (int value) // if this message is for a bot, call the client message function... engine.ProcessMessageCapture ((void *) &value); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); WRITE_ENTITY (value); @@ -2596,13 +2589,13 @@ int pfnCmd_Argc (void) // is this a bot issuing that client command? if (engine.IsBotCommand ()) { - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_SUPERCEDE, engine.GetOverrideArgc ()); return engine.GetOverrideArgc (); // if so, then return the argument count we know } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_IGNORED, 0); return CMD_ARGC (); // ask the engine how many arguments there are @@ -2620,13 +2613,13 @@ const char *pfnCmd_Args (void) // is this a bot issuing that client command? if (engine.IsBotCommand ()) { - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_SUPERCEDE, engine.GetOverrideArgs ()); return engine.GetOverrideArgs (); // else return the whole bot client command string we know } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_IGNORED, NULL); return CMD_ARGS (); // ask the client command string to the engine @@ -2644,12 +2637,12 @@ const char *pfnCmd_Argv (int argc) // is this a bot issuing that client command? if (engine.IsBotCommand ()) { - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_SUPERCEDE, engine.GetOverrideArgv (argc)); return engine.GetOverrideArgv (argc); // if so, then return the wanted argument we know } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_IGNORED, NULL); return CMD_ARGV (argc); // ask the argument number "argc" to the engine @@ -2665,13 +2658,13 @@ void pfnClientPrintf (edict_t *ent, PRINT_TYPE printType, const char *message) if (IsValidBot (ent)) { - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_SUPERCEDE); return; } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); CLIENT_PRINTF (ent, printType, message); @@ -2685,7 +2678,7 @@ void pfnSetClientMaxspeed (const edict_t *ent, float newMaxspeed) if (bot != NULL) bot->pev->maxspeed = newMaxspeed; - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_engfuncs.pfnSetClientMaxspeed) (ent, newMaxspeed); @@ -2703,7 +2696,7 @@ int pfnRegUserMsg (const char *name, int size) // using pfnMessageBegin (), it will know what message ID number to send, and the engine will // know what to do, only for non-metamod version - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META_VALUE (MRES_IGNORED, 0); int message = REG_USER_MSG (name, size); @@ -2774,7 +2767,7 @@ void pfnAlertMessage (ALERT_TYPE alertType, char *format, ...) } } - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) RETURN_META (MRES_IGNORED); (*g_engfuncs.pfnAlertMessage) (alertType, buffer); @@ -2796,16 +2789,14 @@ SHARED_LIBRARAY_EXPORT int GetEntityAPI2 (gamefuncs_t *functionTable, int *) memset (functionTable, 0, sizeof (gamefuncs_t)); - if (!(g_gameFlags & GAME_METAMOD)) + if (!g_isMetamod) { - auto api_GetEntityAPI = g_gameLib->GetFuncAddr ("GetEntityAPI"); - // pass other DLLs engine callbacks to function table... - if (api_GetEntityAPI (&g_functionTable, INTERFACE_VERSION) == 0) - { - AddLogEntry (true, LL_FATAL, "GetEntityAPI2: ERROR - Not Initialized."); - return FALSE; // error initializing function table!!! - } + if ((*g_entityAPI) (&g_functionTable, INTERFACE_VERSION) == 0) + { + AddLogEntry (true, LL_FATAL, "GetEntityAPI2: ERROR - Not Initialized."); + return FALSE; // error initializing function table!!! + } gameDLLFunc.dllapi_table = &g_functionTable; gpGamedllFuncs = &gameDLLFunc; @@ -2857,12 +2848,10 @@ SHARED_LIBRARAY_EXPORT int GetNewDLLFunctions (newgamefuncs_t *functionTable, in // pass them too, else the DLL interfacing wouldn't be complete and the game possibly wouldn't // run properly. - auto api_GetNewDLLFunctions = g_gameLib->GetFuncAddr ("GetNewDLLFunctions"); - - if (api_GetNewDLLFunctions == NULL) + if (g_getNewEntityAPI == NULL) return FALSE; - if (!api_GetNewDLLFunctions (functionTable, interfaceVersion)) + if (!(*g_getNewEntityAPI) (functionTable, interfaceVersion)) { AddLogEntry (true, LL_FATAL, "GetNewDLLFunctions: ERROR - Not Initialized."); return FALSE; @@ -2874,7 +2863,7 @@ SHARED_LIBRARAY_EXPORT int GetNewDLLFunctions (newgamefuncs_t *functionTable, in SHARED_LIBRARAY_EXPORT int GetEngineFunctions (enginefuncs_t *functionTable, int *) { - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) memset (functionTable, 0, sizeof (enginefuncs_t)); functionTable->pfnChangeLevel = pfnChangeLevel; @@ -2917,12 +2906,10 @@ SHARED_LIBRARAY_EXPORT int Server_GetBlendingInterface (int version, void **ppin // of the body move, which bones, which hitboxes and how) between the server and the game DLL. // some MODs can be using a different hitbox scheme than the standard one. - auto api_GetBlendingInterface = g_gameLib->GetFuncAddr ("Server_GetBlendingInterface"); - - if (api_GetBlendingInterface == NULL) + if (g_serverBlendingAPI == NULL) return FALSE; - return api_GetBlendingInterface (version, ppinterface, pstudio, rotationmatrix, bonetransform); + return (*g_serverBlendingAPI) (version, ppinterface, pstudio, rotationmatrix, bonetransform); } SHARED_LIBRARAY_EXPORT int Meta_Query (char *, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs) @@ -2967,7 +2954,7 @@ 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. - g_gameFlags |= GAME_METAMOD; + g_isMetamod = true; } Library *LoadCSBinary (void) @@ -3000,7 +2987,7 @@ Library *LoadCSBinary (void) { g_gameFlags |= GAME_CZERO; - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) return NULL; return new Library (path); @@ -3021,7 +3008,7 @@ Library *LoadCSBinary (void) { g_gameFlags |= (GAME_LEGACY | GAME_XASH); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) { delete game; return NULL; @@ -3037,7 +3024,7 @@ Library *LoadCSBinary (void) else g_gameFlags |= GAME_LEGACY; - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) { delete game; return NULL; @@ -3080,7 +3067,7 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t #ifdef PLATFORM_ANDROID g_gameFlags |= (GAME_LEGACY | GAME_XASH | GAME_MOBILITY); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) return; // we should stop the attempt for loading the real gamedll, since metamod handle this for us #ifdef LOAD_HARDFP @@ -3099,7 +3086,7 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t #else g_gameLib = LoadCSBinary (); { - if (g_gameLib == NULL && !(g_gameFlags & GAME_METAMOD)) + if (g_gameLib == NULL && !g_isMetamod) { AddLogEntry (true, LL_FATAL | LL_IGNORE, "Mod that you has started, not supported by this bot (gamedir: %s)", engine.GetModName ()); return; @@ -3128,20 +3115,23 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t } engine.Printf ("YaPB Bot has detect game version as Counter-Strike: %s", gameVersionStr.GetBuffer ()); - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) return; } #endif - auto api_GiveFnptrsToDll = g_gameLib->GetFuncAddr ("GiveFnptrsToDll"); + g_funcPointers = g_gameLib->GetFuncAddr ("GiveFnptrsToDll"); + g_entityAPI = g_gameLib->GetFuncAddr ("GetEntityAPI"); + g_getNewEntityAPI = g_gameLib->GetFuncAddr ("GetNewDLLFunctions"); + g_serverBlendingAPI = g_gameLib->GetFuncAddr ("Server_GetBlendingInterface"); - if (!api_GiveFnptrsToDll) + if (!g_funcPointers || !g_entityAPI) TerminateOnMalloc (); GetEngineFunctions (functionTable, NULL); // give the engine functions to the other DLL... - api_GiveFnptrsToDll (functionTable, pGlobals); + (*g_funcPointers) (functionTable, pGlobals); } DLL_ENTRYPOINT diff --git a/source/manager.cpp b/source/manager.cpp index b4aee0e..6baecce 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -100,7 +100,7 @@ void BotManager::CallGameEntity (entvars_t *vars) { // this function calls gamedll player() function, in case to create player entity in game - if (g_gameFlags & GAME_METAMOD) + if (g_isMetamod) { CALL_GAME_ENTITY (PLID, "player", vars); return; @@ -108,7 +108,7 @@ void BotManager::CallGameEntity (entvars_t *vars) player (vars); } -BotCreationResult BotManager::CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd) +int BotManager::CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd) { // this function completely prepares bot entity (edict) for creation, creates team, difficulty, sets name etc, and // then sends result to bot constructor @@ -119,12 +119,12 @@ BotCreationResult BotManager::CreateBot (const String &name, int difficulty, int if (g_numWaypoints < 1) // don't allow creating bots with no waypoints loaded { engine.CenterPrintf ("Map is not waypointed. Cannot create bot"); - return BOT_RESULT_NAV_ERROR; + return 0; } - else if (waypoints.HasChanged ()) // don't allow creating bots with changed waypoints (distance tables are messed up) + else if (g_waypointsChanged) // don't allow creating bots with changed waypoints (distance tables are messed up) { engine.CenterPrintf ("Waypoints have been changed. Load waypoints again..."); - return BOT_RESULT_NAV_ERROR; + return 0; } if (difficulty < 0 || difficulty > 4) @@ -199,7 +199,7 @@ BotCreationResult BotManager::CreateBot (const String &name, int difficulty, int if (engine.IsNullEntity (bot)) { engine.CenterPrintf ("Maximum players reached (%d/%d). Unable to create Bot.", engine.MaxClients (), engine.MaxClients ()); - return BOT_RESULT_MAX_PLAYERS_REACHED; + return 2; } int index = engine.IndexOfEntity (bot) - 1; @@ -216,7 +216,7 @@ BotCreationResult BotManager::CreateBot (const String &name, int difficulty, int if (isConsoleCmd) yb_quota.SetInt (yb_quota.GetInt () + 1); - return BOT_RESULT_CREATED; + return 1; } int BotManager::GetIndex (edict_t *ent) @@ -260,19 +260,19 @@ Bot *BotManager::FindOneValidAliveBot (void) { // this function finds one bot, alive bot :) - Array result; + Array foundBots; for (int i = 0; i < engine.MaxClients (); i++) { - if (result.GetSize () > 4) + if (foundBots.GetSize () > 4) break; if (m_bots[i] != NULL && IsAlive (m_bots[i]->GetEntity ())) - result.Push (i); + foundBots.Push (i); } - if (!result.IsEmpty ()) - return m_bots[result.GetRandomElement ()]; + if (!foundBots.IsEmpty ()) + return m_bots[foundBots.GetRandomElement ()]; return NULL; } @@ -408,22 +408,22 @@ void BotManager::MaintainBotQuota (void) // this function keeps number of bots up to date, and don't allow to maintain bot creation // while creation process in process. - if (g_numWaypoints < 1 || waypoints.HasChanged ()) + if (g_numWaypoints < 1 || g_waypointsChanged) return; // bot's creation update if (!m_creationTab.IsEmpty () && m_maintainTime < engine.Time ()) { - const CreateQueue &last = m_creationTab.Pop (); - const BotCreationResult callResult = CreateBot (last.name, last.difficulty, last.personality, last.team, last.member, last.console); + CreateQueue last = m_creationTab.Pop (); + int resultOfCall = CreateBot (last.name, last.difficulty, last.personality, last.team, last.member, last.console); // check the result of creation - if (callResult == BOT_RESULT_NAV_ERROR) + if (resultOfCall == 0) { m_creationTab.RemoveAll (); // something wrong with waypoints, reset tab of creation yb_quota.SetInt (0); // reset quota } - else if (callResult == BOT_RESULT_MAX_PLAYERS_REACHED) + else if (resultOfCall == 2) { m_creationTab.RemoveAll (); // maximum players reached, so set quota to maximum players yb_quota.SetInt (GetBotsNum ()); @@ -888,7 +888,6 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c // initialize all the variables for this bot... m_notStarted = true; // hasn't joined game yet - m_forceRadio = false; m_startAction = GSM_IDLE; m_moneyAmount = 0; @@ -1029,6 +1028,7 @@ void Bot::NewRound (void) { // this function initializes a bot after creation & at the start of each round + g_canSayBombPlanted = true; int i = 0; // delete all allocated path nodes @@ -1478,108 +1478,3 @@ const Array &BotManager::GetActiveGrenades (void) { return m_activeGrenades; } - -void BotManager::SelectLeaderEachTeam (int team, bool reset) -{ - if (reset) - { - m_leaderChoosen[team] = false; - return; - } - - if (g_mapType & MAP_AS) - { - if (team == CT && !m_leaderChoosen[CT]) - { - for (int i = 0; i < engine.MaxClients (); i++) - { - auto bot = m_bots[i]; - - if (bot != NULL && bot->m_isVIP) - { - // vip bot is the leader - bot->m_isLeader = true; - - if (Random.Long (1, 100) < 50) - { - bot->RadioMessage (Radio_FollowMe); - bot->m_campButtons = 0; - } - } - } - m_leaderChoosen[CT] = true; - } - else if (team == TERRORIST && !m_leaderChoosen[TERRORIST]) - { - auto bot = bots.GetHighestFragsBot (team); - - if (bot != NULL && bot->m_notKilled) - { - bot->m_isLeader = true; - - if (Random.Long (1, 100) < 45) - bot->RadioMessage (Radio_FollowMe); - } - m_leaderChoosen[TERRORIST] = true; - } - } - else if (g_mapType & MAP_DE) - { - if (team == TERRORIST && !m_leaderChoosen[TERRORIST]) - { - for (int i = 0; i < engine.MaxClients (); i++) - { - auto bot = m_bots[i]; - - if (bot != NULL && bot->m_hasC4) - { - // bot carrying the bomb is the leader - bot->m_isLeader = true; - - // terrorist carrying a bomb needs to have some company - if (Random.Long (1, 100) < 80) - { - if (yb_communication_type.GetInt () == 2) - bot->ChatterMessage (Chatter_GoingToPlantBomb); - else - bot->ChatterMessage (Radio_FollowMe); - - bot->m_campButtons = 0; - } - } - m_leaderChoosen[TERRORIST] = true; - } - } - else if (!m_leaderChoosen[CT]) - { - if (auto bot = bots.GetHighestFragsBot (team)) - { - bot->m_isLeader = true; - - if (Random.Long (1, 100) < 30) - bot->RadioMessage (Radio_FollowMe); - } - m_leaderChoosen[CT] = true; - } - } - else if (g_mapType & (MAP_ES | MAP_KA | MAP_FY)) - { - if (auto bot = bots.GetHighestFragsBot (team)) - { - bot->m_isLeader = true; - - if (Random.Long (1, 100) < 30) - bot->RadioMessage (Radio_FollowMe); - } - } - else - { - if (auto bot = bots.GetHighestFragsBot (team)) - { - bot->m_isLeader = true; - - if (Random.Long (1, 100) < (team == TERRORIST ? 30 : 40)) - bot->RadioMessage (Radio_FollowMe); - } - } -} \ No newline at end of file diff --git a/source/support.cpp b/source/support.cpp index fe1e691..e08a810 100644 --- a/source/support.cpp +++ b/source/support.cpp @@ -250,7 +250,7 @@ void UpdateGlobalExperienceData (void) // this function called after each end of the round to update knowledge about most dangerous waypoints for each team. // no waypoints, no experience used or waypoints edited or being edited? - if (g_numWaypoints < 1 || waypoints.HasChanged ()) + if (g_numWaypoints < 1 || g_waypointsChanged) return; // no action unsigned short maxDamage; // maximum damage @@ -371,14 +371,10 @@ void RoundInit (void) // this is called at the start of each round g_roundEnded = false; - g_canSayBombPlanted = true; // check team economics - for (int team = TERRORIST; team < SPECTATOR; team++) - { - bots.CheckTeamEconomics (team); - bots.SelectLeaderEachTeam (team, true); - } + bots.CheckTeamEconomics (TERRORIST); + bots.CheckTeamEconomics (CT); for (int i = 0; i < engine.MaxClients (); i++) { @@ -394,6 +390,9 @@ void RoundInit (void) g_timeBombPlanted = 0.0f; g_timeNextBombUpdate = 0.0f; + g_leaderChoosen[CT] = false; + g_leaderChoosen[TERRORIST] = false; + g_lastRadioTime[0] = 0.0f; g_lastRadioTime[1] = 0.0f; g_botsCanPause = false; diff --git a/source/waypoint.cpp b/source/waypoint.cpp index 7166d3a..b4b8a90 100644 --- a/source/waypoint.cpp +++ b/source/waypoint.cpp @@ -166,7 +166,7 @@ void Waypoint::Add (int flags, const Vector &waypointOrigin) if (bots.GetBotsNum () > 0) bots.RemoveAll (); - m_waypointsChanged = true; + g_waypointsChanged = true; switch (flags) { @@ -443,7 +443,7 @@ void Waypoint::Add (int flags, const Vector &waypointOrigin) void Waypoint::Delete (void) { - m_waypointsChanged = true; + g_waypointsChanged = true; if (g_numWaypoints < 1) return; @@ -634,9 +634,10 @@ void Waypoint::CreatePath (char dir) } engine.EmitSound (g_hostEntity, "common/wpn_hudon.wav"); - m_waypointsChanged = true; + g_waypointsChanged = true; } + void Waypoint::DeletePath (void) { // this function allow player to manually remove a path from one waypoint to another @@ -666,7 +667,7 @@ void Waypoint::DeletePath (void) { if (m_paths[nodeFrom]->index[index] == nodeTo) { - m_waypointsChanged = true; + g_waypointsChanged = true; m_paths[nodeFrom]->index[index] = -1; // unassigns this path m_paths[nodeFrom]->distances[index] = 0; @@ -687,7 +688,7 @@ void Waypoint::DeletePath (void) { if (m_paths[nodeFrom]->index[index] == nodeTo) { - m_waypointsChanged = true; + g_waypointsChanged = true; m_paths[nodeFrom]->index[index] = -1; // unassign this path m_paths[nodeFrom]->distances[index] = 0; @@ -828,7 +829,7 @@ void Waypoint::SaveExperienceTab (void) { ExtensionHeader header; - if (g_numWaypoints < 1 || m_waypointsChanged) + if ((g_numWaypoints <= 0) || g_waypointsChanged) return; memset (header.header, 0, sizeof (header.header)); @@ -1208,7 +1209,7 @@ bool Waypoint::Load (void) InitPathMatrix (); InitTypes (); - m_waypointsChanged = false; + g_waypointsChanged = false; g_highestKills = 1; m_pathDisplayTime = 0.0f; @@ -1750,7 +1751,7 @@ void Waypoint::Think (void) } // draw the danger directions - if (!m_waypointsChanged) + if (!g_waypointsChanged) { 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 @@ -1769,7 +1770,7 @@ void Waypoint::Think (void) // if waypoint is not changed display experience also - if (!m_waypointsChanged) + if (!g_waypointsChanged) { int dangerIndexCT = (g_experienceData + nearestIndex * g_numWaypoints + nearestIndex)->team1DangerIndex; int dangerIndexT = (g_experienceData + nearestIndex * g_numWaypoints + nearestIndex)->team0DangerIndex; @@ -2477,7 +2478,6 @@ Waypoint::Waypoint (void) m_endJumpPoint = false; m_redoneVisibility = false; m_learnJumpWaypoint = false; - m_waypointsChanged = false; m_timeJumpStarted = 0.0f; m_lastJumpWaypoint = -1;