diff --git a/include/core.h b/include/core.h index 2e609e1..88544ca 100644 --- a/include/core.h +++ b/include/core.h @@ -66,6 +66,34 @@ enum GameFlags GAME_METAMOD = (1 << 6) }; +// bot menu ids +enum MenuId +{ + BOT_MENU_IVALID = -1, + BOT_MENU_MAIN, + BOT_MENU_FEATURES, + BOT_MENU_CONTROL, + BOT_MENU_WEAPON_MODE, + BOT_MENU_PERSONALITY, + BOT_MENU_DIFFICULTY, + BOT_MENU_TEAM_SELECT, + BOT_MENU_TERRORIST_SELECT, + BOT_MENU_CT_SELECT, + BOT_MENU_COMMANDS, + BOT_MENU_WAYPOINT_MAIN_PAGE1, + BOT_MENU_WAYPOINT_MAIN_PAGE2, + BOT_MENU_WAYPOINT_RADIUS, + BOT_MENU_WAYPOINT_TYPE, + BOT_MENU_WAYPOINT_FLAG, + BOT_MENU_WAYPOINT_AUTOPATH, + BOT_MENU_WAYPOINT_PATH, + BOT_MENU_KICK_PAGE_1, + BOT_MENU_KICK_PAGE_2, + BOT_MENU_KICK_PAGE_3, + BOT_MENU_KICK_PAGE_4, + BOT_MENU_TOTAL_MENUS +}; + // log levels enum LogLevel { @@ -601,14 +629,15 @@ struct WeaponSelect // struct for menus struct MenuText { - int validSlots; // ored together bits for valid keys - const char *menuText; // ptr to actual string + MenuId id; // actual menu id + int slots; // together bits for valid keys + String text; // ptr to actual string }; // array of clients struct struct Client { - MenuText *menu; // pointer to opened bot menu + MenuId menu; // id to opened bot menu edict_t *ent; // pointer to actual edict Vector origin; // position in the world Vector soundPosition; // position sound was played @@ -619,6 +648,8 @@ struct Client float hearingDistance; // distance this sound is heared float timeSoundLasting; // time sound is played/heared + + Client (void) : menu (BOT_MENU_IVALID) { } }; // experience data hold in memory while playing @@ -1184,7 +1215,7 @@ public: bool FindWaypoint (void); bool EntityIsVisible (const Vector &dest, bool fromBody = false); - void SwitchChatterIcon (bool show); + void EnableChatterIcon (bool show); void DeleteSearchNodes (void); void VerifyBreakable (edict_t *touch); @@ -1455,6 +1486,11 @@ public: WaypointDownloadError RequestWaypoint (void); }; +class BotMenu +{ + +}; + #include // expose bot super-globals @@ -1482,7 +1518,7 @@ extern void FreeLibraryMemory (void); extern void RoundInit (void); extern void CheckWelcomeMessage (void); extern void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...); -extern void DisplayMenuToClient (edict_t *ent, MenuText *menu); +extern void DisplayMenuToClient (edict_t *ent, MenuId 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); diff --git a/include/corelib.h b/include/corelib.h index 698a45a..1ee22b9 100644 --- a/include/corelib.h +++ b/include/corelib.h @@ -2429,7 +2429,7 @@ public: // Returns: // Length of string, 0 in case of error. // - int GetLength (void) + int GetLength (void) const { if (m_bufferPtr == NULL) return 0; diff --git a/include/globals.h b/include/globals.h index 6b53b07..e5223ed 100644 --- a/include/globals.h +++ b/include/globals.h @@ -17,7 +17,7 @@ extern bool g_waypointOn; extern bool g_autoWaypoint; extern bool g_botsCanPause; extern bool g_editNoclip; -extern bool g_isCommencing; +extern bool g_gameWelcomeSent; extern float g_autoPathDistance; extern float g_timeBombPlanted; @@ -57,7 +57,7 @@ extern WeaponSelect g_weaponSelect[NUM_WEAPONS + 1]; extern WeaponProperty g_weaponDefs[MAX_WEAPONS + 1]; extern Client g_clients[MAX_ENGINE_PLAYERS]; -extern MenuText g_menus[21]; +extern MenuText g_menus[BOT_MENU_TOTAL_MENUS]; extern TaskItem g_taskFilters[]; extern Experience *g_experienceData; diff --git a/project/makefile b/project/makefile index 114b821..f6e6d45 100644 --- a/project/makefile +++ b/project/makefile @@ -52,7 +52,7 @@ endif LINK += -m32 -lm -ldl -CFLAGS += -std=c++11 -DHAVE_STDINT_H -D__extern_always_inline=inline -D_strdup=strdup -Dstricmp=strcasecmp -Dstrcmpi=strcasecmp -fno-strict-aliasing -m32 -Wall -Werror -Wextra +CFLAGS += -msse2 -std=c++11 -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) diff --git a/source/basecode.cpp b/source/basecode.cpp index ea91e75..273bc17 100644 --- a/source/basecode.cpp +++ b/source/basecode.cpp @@ -963,7 +963,7 @@ void Bot::GetCampDirection (Vector *dest) } } -void Bot::SwitchChatterIcon (bool show) +void Bot::EnableChatterIcon (bool show) { // this function depending on show boolen, shows/remove chatter, icon, on the head of bot. @@ -988,11 +988,11 @@ void Bot::InstantChatterMessage (int type) { // this function sends instant chatter messages. - if (yb_communication_type.GetInt () != 2 || g_chatterFactory[type].IsEmpty () || (g_gameFlags & GAME_LEGACY)) + if ((g_gameFlags & GAME_LEGACY) || yb_communication_type.GetInt () != 2 || g_chatterFactory[type].IsEmpty ()) return; if (m_notKilled) - SwitchChatterIcon (true); + EnableChatterIcon (true); // delay only reportteam if (type == Radio_ReportTeam) @@ -1003,17 +1003,17 @@ void Bot::InstantChatterMessage (int type) 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; + const String &defaultSound = g_chatterFactory[type].GetRandomElement ().name; + const String &painSound = g_chatterFactory[Chatter_DiePain].GetRandomElement ().name; for (int i = 0; i < engine.MaxClients (); i++) { - edict_t *ent = engine.EntityOfIndex (i); + const Client &client = g_clients[i]; - if (!IsValidPlayer (ent) || IsValidBot (ent) || engine.GetTeam (ent) != m_team) + if (!(client.flags & CF_USED) || (client.ent->v.flags & FL_FAKECLIENT) || client.team != m_team) continue; - MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_SENDAUDIO), nullptr, ent); // begin message + MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_SENDAUDIO), nullptr, client.ent); // begin message WRITE_BYTE (GetIndex ()); if (pev->deadflag & DEAD_DYING) @@ -1033,7 +1033,7 @@ void Bot::RadioMessage (int message) if (yb_communication_type.GetInt () == 0 || m_numFriendsLeft == 0) return; - if (g_chatterFactory[message].IsEmpty () || (g_gameFlags & GAME_LEGACY) || yb_communication_type.GetInt () != 2) + if ((g_gameFlags & GAME_LEGACY) || g_chatterFactory[message].IsEmpty () || yb_communication_type.GetInt () != 2) m_forceRadio = true; // use radio instead voice else m_forceRadio = false; @@ -2922,7 +2922,7 @@ void Bot::ThinkFrame (void) // remove voice icon if (!(g_gameFlags & GAME_LEGACY) && g_lastRadioTime[g_clients[GetIndex () - 1].team2] + Random.Float (0.8f, 2.1f) < engine.Time ()) - SwitchChatterIcon (false); // hide icon + EnableChatterIcon (false); // hide icon if (botMovement) BotAI (); // execute main code @@ -5980,7 +5980,7 @@ void Bot::EquipInBuyzone (int buyState) if (mp_buytime.m_eptr != nullptr) 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 < engine.Time () && m_lastEquipTime + 15.0f < engine.Time () && m_inBuyZone && checkBuyTime && !g_bombPlanted && m_moneyAmount > g_botBuyEconomyTable[0]) { diff --git a/source/engine.cpp b/source/engine.cpp index 8cb0a3b..de07455 100644 --- a/source/engine.cpp +++ b/source/engine.cpp @@ -948,7 +948,7 @@ void Engine::ProcessMessageCapture (void *ptr) g_roundEnded = true; if (FStrEq (strVal, "#Game_Commencing")) - g_isCommencing = true; + g_gameWelcomeSent = true; if (FStrEq (strVal, "#CTs_Win")) { diff --git a/source/globals.cpp b/source/globals.cpp index 8b2c5b0..5868d88 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -9,37 +9,12 @@ #include -class Chat -{ -public: -}; - -class Globals -{ -public: -}; - -class Practice -{ -public: -}; - -class GameState -{ -public: -}; - -class MenuManager -{ -public: -}; - bool g_canSayBombPlanted = true; bool g_roundEnded = true; bool g_botsCanPause = false; bool g_bombPlanted = false; bool g_bombSayString = false; -bool g_isCommencing = false; +bool g_gameWelcomeSent = false; bool g_editNoclip = false; bool g_waypointOn = false; @@ -183,10 +158,11 @@ WeaponSelect g_weaponSelect[NUM_WEAPONS + 1] = }; // bot menus -MenuText g_menus[21] = +MenuText g_menus[BOT_MENU_TOTAL_MENUS] = { // main menu { + BOT_MENU_MAIN, 0x2ff, "\\yMain Menu\\w\v\v" "1. Control Bots\v" @@ -198,6 +174,7 @@ MenuText g_menus[21] = // bot features menu { + BOT_MENU_FEATURES, 0x25f, "\\yBots Features\\w\v\v" "1. Weapon Mode Menu\v" @@ -210,6 +187,7 @@ MenuText g_menus[21] = // bot control menu { + BOT_MENU_CONTROL, 0x2ff, "\\yBots Control Menu\\w\v\v" "1. Add a Bot, Quick\v" @@ -222,6 +200,7 @@ MenuText g_menus[21] = // weapon mode select menu { + BOT_MENU_WEAPON_MODE, 0x27f, "\\yBots Weapon Mode\\w\v\v" "1. Knives only\v" @@ -236,6 +215,7 @@ MenuText g_menus[21] = // personality select menu { + BOT_MENU_PERSONALITY, 0x20f, "\\yBots Personality\\w\v\v" "1. Random\v" @@ -247,6 +227,7 @@ MenuText g_menus[21] = // difficulty select menu { + BOT_MENU_DIFFICULTY, 0x23f, "\\yBots Difficulty Level\\w\v\v" "1. Newbie\v" @@ -259,6 +240,7 @@ MenuText g_menus[21] = // team select menu { + BOT_MENU_TEAM_SELECT, 0x213, "\\ySelect a team\\w\v\v" "1. Terrorist Force\v" @@ -269,6 +251,7 @@ MenuText g_menus[21] = // terrorist model select menu { + BOT_MENU_TERRORIST_SELECT, 0x21f, "\\ySelect an appearance\\w\v\v" "1. Phoenix Connexion\v" @@ -279,8 +262,9 @@ MenuText g_menus[21] = "0. Exit" }, - // counter-terrirust model select menu + // counter-terrorist model select menu { + BOT_MENU_CT_SELECT, 0x21f, "\\ySelect an appearance\\w\v\v" "1. Seal Team 6 (DEVGRU)\v" @@ -291,8 +275,21 @@ MenuText g_menus[21] = "0. Exit" }, + // command menu + { + BOT_MENU_COMMANDS, + 0x23f, + "\\yBot Command Menu\\w\v\v" + "1. Make Double Jump\v" + "2. Finish Double Jump\v\v" + "3. Drop the C4 Bomb\v" + "4. Drop the Weapon\v\v" + "0. Exit" + }, + // main waypoint menu { + BOT_MENU_WAYPOINT_MAIN_PAGE1, 0x3ff, "\\yWaypoint Operations (Page 1)\\w\v\v" "1. Show/Hide waypoints\v" @@ -309,6 +306,7 @@ MenuText g_menus[21] = // main waypoint menu (page 2) { + BOT_MENU_WAYPOINT_MAIN_PAGE2, 0x3ff, "\\yWaypoint Operations (Page 2)\\w\v\v" "1. Waypoint stats\v" @@ -325,6 +323,7 @@ MenuText g_menus[21] = // select waypoint radius menu { + BOT_MENU_WAYPOINT_RADIUS, 0x3ff, "\\yWaypoint Radius\\w\v\v" "1. SetRadius 0\v" @@ -341,6 +340,7 @@ MenuText g_menus[21] = // waypoint add menu { + BOT_MENU_WAYPOINT_TYPE, 0x3ff, "\\yWaypoint Type\\w\v\v" "1. Normal\v" @@ -357,6 +357,7 @@ MenuText g_menus[21] = // set waypoint flag menu { + BOT_MENU_WAYPOINT_FLAG, 0x2ff, "\\yToggle Waypoint Flags\\w\v\v" "1. Block with Hostage\v" @@ -367,43 +368,9 @@ MenuText g_menus[21] = "0. Exit" }, - // kickmenu #1 - { - 0x0, - nullptr, - }, - - // kickmenu #2 - { - 0x0, - nullptr, - }, - - // kickmenu #3 - { - 0x0, - nullptr, - }, - - // kickmenu #4 - { - 0x0, - nullptr, - }, - - // command menu - { - 0x23f, - "\\yBot Command Menu\\w\v\v" - "1. Make Double Jump\v" - "2. Finish Double Jump\v\v" - "3. Drop the C4 Bomb\v" - "4. Drop the Weapon\v\v" - "0. Exit" - }, - // auto-path max distance { + BOT_MENU_WAYPOINT_AUTOPATH, 0x27f, "\\yAutoPath Distance\\w\v\v" "1. Distance 0\v" @@ -418,11 +385,40 @@ MenuText g_menus[21] = // path connections { + BOT_MENU_WAYPOINT_PATH, 0x207, "\\yCreate Path (Choose Direction)\\w\v\v" "1. Outgoing Path\v" "2. Incoming Path\v" "3. Bidirectional (Both Ways)\v\v" "0. Exit" + }, + + // kickmenu #1 + { + BOT_MENU_KICK_PAGE_1, + 0x0, + nullptr, + }, + + // kickmenu #2 + { + BOT_MENU_KICK_PAGE_2, + 0x0, + nullptr, + }, + + // kickmenu #3 + { + BOT_MENU_KICK_PAGE_3, + 0x0, + nullptr, + }, + + // kickmenu #4 + { + BOT_MENU_KICK_PAGE_4, + 0x0, + nullptr, } }; diff --git a/source/interface.cpp b/source/interface.cpp index 10d071c..c9b30a7 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -188,16 +188,16 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c // displays main bot menu else if (stricmp (arg0, "botmenu") == 0 || stricmp (arg0, "menu") == 0) - DisplayMenuToClient (ent, &g_menus[0]); + DisplayMenuToClient (ent, BOT_MENU_MAIN); // display command menu else if (stricmp (arg0, "cmdmenu") == 0 || stricmp (arg0, "cmenu") == 0) { if (IsAlive (ent)) - DisplayMenuToClient (ent, &g_menus[18]); + DisplayMenuToClient (ent, BOT_MENU_COMMANDS); else { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display engine.CenterPrintf ("You're dead, and have no access to this menu"); } } @@ -280,7 +280,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c else if (stricmp (arg1, "add") == 0) { g_waypointOn = true; // turn waypoints on - DisplayMenuToClient (g_hostEntity, &g_menus[12]); + DisplayMenuToClient (g_hostEntity, BOT_MENU_WAYPOINT_TYPE); } // creates basic waypoints on the map (ladder/spawn points/goals) @@ -334,7 +334,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c // opens menu for setting (removing) waypoint flags else if (stricmp (arg1, "flags") == 0) - DisplayMenuToClient (g_hostEntity, &g_menus[13]); + DisplayMenuToClient (g_hostEntity, BOT_MENU_WAYPOINT_FLAG); // setting waypoint radius else if (stricmp (arg1, "setradius") == 0) @@ -363,7 +363,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c // displays waypoint menu else if (stricmp (arg1, "menu") == 0) - DisplayMenuToClient (g_hostEntity, &g_menus[9]); + DisplayMenuToClient (g_hostEntity, BOT_MENU_WAYPOINT_MAIN_PAGE1); // otherwise display waypoint current status else @@ -378,7 +378,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c // opens path creation menu if (stricmp (arg1, "create") == 0) - DisplayMenuToClient (g_hostEntity, &g_menus[20]); + DisplayMenuToClient (g_hostEntity, BOT_MENU_WAYPOINT_PATH); // creates incoming path from the cached waypoint else if (stricmp (arg1, "create_in") == 0) @@ -398,7 +398,7 @@ int BotCommandHandler (edict_t *ent, const char *arg0, const char *arg1, const c // sets auto path maximum distance else if (stricmp (arg1, "autodistance") == 0) - DisplayMenuToClient (g_hostEntity, &g_menus[19]); + DisplayMenuToClient (g_hostEntity, BOT_MENU_WAYPOINT_AUTOPATH); } // automatic waypoint handling (supported only on listen server) @@ -905,19 +905,6 @@ void InitConfig (void) g_timePerSecondUpdate = 0.0f; } -void CommandHandler_NotMM (void) -{ - // this function is the dedicated server command handler for the new yapb server command we - // registered at game start. It will be called by the engine each time a server command that - // starts with "meta" is entered in the server console. It works exactly the same way as - // ClientCommand() does, using the CmdArgc() and CmdArgv() facilities of the engine. Argv(0) - // is the server command itself (here "meta") and the next ones are its arguments. Just like - // 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. - - -} - void GameDLLInit (void) { // this function is a one-time call, and appears to be the second function called in the @@ -1151,7 +1138,7 @@ void ClientDisconnect (edict_t *ent) { if (bot->pev == &ent->v) { - bot->SwitchChatterIcon (false); + bot->EnableChatterIcon (false); bot->ReleaseUsedName (); bots.Free (i); @@ -1237,14 +1224,14 @@ void ClientCommand (edict_t *ent) return; } - else if (stricmp (command, "menuselect") == 0 && !IsNullString (arg1) && g_clients[issuerPlayerIndex].menu != nullptr) + else if (stricmp (command, "menuselect") == 0 && !IsNullString (arg1) && g_clients[issuerPlayerIndex].menu != BOT_MENU_IVALID) { Client *client = &g_clients[issuerPlayerIndex]; int selection = atoi (arg1); - if (client->menu == &g_menus[12]) + if (client->menu == BOT_MENU_WAYPOINT_TYPE) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1267,7 +1254,7 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1275,9 +1262,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[13]) + else if (client->menu == BOT_MENU_WAYPOINT_FLAG) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1306,9 +1293,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[9]) + else if (client->menu == BOT_MENU_WAYPOINT_MAIN_PAGE1) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1326,7 +1313,7 @@ void ClientCommand (edict_t *ent) case 3: g_waypointOn = true; - DisplayMenuToClient (ent, &g_menus[20]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_PATH); break; case 4: @@ -1336,7 +1323,7 @@ void ClientCommand (edict_t *ent) case 5: g_waypointOn = true; - DisplayMenuToClient (ent, &g_menus[12]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_TYPE); break; case 6: @@ -1346,20 +1333,20 @@ void ClientCommand (edict_t *ent) case 7: g_waypointOn = true; - DisplayMenuToClient (ent, &g_menus[19]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_AUTOPATH); break; case 8: g_waypointOn = true; - DisplayMenuToClient (ent, &g_menus[11]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_RADIUS); break; case 9: - DisplayMenuToClient (ent, &g_menus[10]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE2); break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1367,9 +1354,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[10]) + else if (client->menu == BOT_MENU_WAYPOINT_MAIN_PAGE2) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1425,7 +1412,7 @@ void ClientCommand (edict_t *ent) case 3: g_waypointOn = true; - DisplayMenuToClient (ent, &g_menus[13]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_FLAG); break; case 4: @@ -1455,7 +1442,7 @@ void ClientCommand (edict_t *ent) break; case 9: - DisplayMenuToClient (ent, &g_menus[9]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE1); break; } if (g_gameFlags & GAME_METAMOD) @@ -1463,9 +1450,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[11]) + else if (client->menu == BOT_MENU_WAYPOINT_RADIUS) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display g_waypointOn = true; // turn waypoints on in case @@ -1479,24 +1466,24 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[0]) + else if (client->menu == BOT_MENU_MAIN) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { case 1: fillCommand = false; - DisplayMenuToClient (ent, &g_menus[2]); + DisplayMenuToClient (ent, BOT_MENU_CONTROL); break; case 2: - DisplayMenuToClient (ent, &g_menus[1]); + DisplayMenuToClient (ent, BOT_MENU_FEATURES); break; case 3: fillCommand = true; - DisplayMenuToClient (ent, &g_menus[6]); + DisplayMenuToClient (ent, BOT_MENU_TEAM_SELECT); break; case 4: @@ -1504,7 +1491,7 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } @@ -1513,9 +1500,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[2]) + else if (client->menu == BOT_MENU_CONTROL) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1524,7 +1511,7 @@ void ClientCommand (edict_t *ent) break; case 2: - DisplayMenuToClient (ent, &g_menus[5]); + DisplayMenuToClient (ent, BOT_MENU_DIFFICULTY); break; case 3: @@ -1540,7 +1527,7 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1548,22 +1535,22 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[1]) + else if (client->menu == BOT_MENU_FEATURES) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { case 1: - DisplayMenuToClient (ent, &g_menus[3]); + DisplayMenuToClient (ent, BOT_MENU_WEAPON_MODE); break; case 2: - DisplayMenuToClient (ent, &g_menus[9]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE1); break; case 3: - DisplayMenuToClient (ent, &g_menus[4]); + DisplayMenuToClient (ent, BOT_MENU_PERSONALITY); break; case 4: @@ -1574,16 +1561,16 @@ void ClientCommand (edict_t *ent) case 5: if (IsAlive (ent)) - DisplayMenuToClient (ent, &g_menus[18]); + DisplayMenuToClient (ent, BOT_MENU_COMMANDS); else { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display engine.CenterPrintf ("You're dead, and have no access to this menu"); } break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1591,9 +1578,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[18]) + else if (client->menu == BOT_MENU_COMMANDS) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display Bot *bot = nullptr; switch (selection) @@ -1616,6 +1603,7 @@ void ClientCommand (edict_t *ent) } else if (selection == 2) bot->ResetDoubleJumpState (); + break; } } @@ -1628,7 +1616,7 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } @@ -1637,9 +1625,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[19]) + else if (client->menu ==BOT_MENU_WAYPOINT_AUTOPATH) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display const float autoDistanceValue[] = {0.0f, 100.0f, 130.0f, 160.0f, 190.0f, 220.0f, 250.0f }; @@ -1656,9 +1644,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[20]) + else if (client->menu == BOT_MENU_WAYPOINT_PATH) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1675,7 +1663,7 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } @@ -1684,11 +1672,11 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[5]) + else if (client->menu == BOT_MENU_DIFFICULTY) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display - client->menu = &g_menus[4]; + client->menu = BOT_MENU_PERSONALITY; switch (selection) { @@ -1713,21 +1701,21 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } - if (client->menu == &g_menus[4]) - DisplayMenuToClient (ent, &g_menus[4]); + if (client->menu == BOT_MENU_PERSONALITY) + DisplayMenuToClient (ent, BOT_MENU_PERSONALITY); if (g_gameFlags & GAME_METAMOD) RETURN_META (MRES_SUPERCEDE); return; } - else if (client->menu == &g_menus[6] && fillCommand) + else if (client->menu == BOT_MENU_TEAM_SELECT && fillCommand) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1739,11 +1727,11 @@ void ClientCommand (edict_t *ent) case 5: fillServerTeam = selection; - DisplayMenuToClient (ent, &g_menus[5]); + DisplayMenuToClient (ent, BOT_MENU_DIFFICULTY); break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1751,9 +1739,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[4] && fillCommand) + else if (client->menu == BOT_MENU_PERSONALITY && fillCommand) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1764,7 +1752,7 @@ void ClientCommand (edict_t *ent) bots.FillServer (fillServerTeam, selection - 2, g_storeAddbotVars[0]); case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1772,9 +1760,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[6]) + else if (client->menu == BOT_MENU_TEAM_SELECT) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1790,14 +1778,14 @@ void ClientCommand (edict_t *ent) else { if (selection == 1) - DisplayMenuToClient (ent, &g_menus[7]); + DisplayMenuToClient (ent, BOT_MENU_TERRORIST_SELECT); else - DisplayMenuToClient (ent, &g_menus[8]); + DisplayMenuToClient (ent, BOT_MENU_CT_SELECT); } break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1805,9 +1793,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[4]) + else if (client->menu == BOT_MENU_PERSONALITY) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1816,11 +1804,11 @@ void ClientCommand (edict_t *ent) case 3: case 4: g_storeAddbotVars[3] = selection - 2; - DisplayMenuToClient (ent, &g_menus[6]); + DisplayMenuToClient (ent, BOT_MENU_TEAM_SELECT); break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1828,9 +1816,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[7] || client->menu == &g_menus[8]) + else if (client->menu == BOT_MENU_TERRORIST_SELECT || client->menu == BOT_MENU_CT_SELECT) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1844,7 +1832,7 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1852,9 +1840,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[3]) + else if (client->menu == BOT_MENU_WEAPON_MODE) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1869,7 +1857,7 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, nullptr); + DisplayMenuToClient (ent, BOT_MENU_IVALID); break; } if (g_gameFlags & GAME_METAMOD) @@ -1877,9 +1865,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[14]) + else if (client->menu == BOT_MENU_KICK_PAGE_1) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1899,7 +1887,7 @@ void ClientCommand (edict_t *ent) break; case 10: - DisplayMenuToClient (ent, &g_menus[2]); + DisplayMenuToClient (ent, BOT_MENU_CONTROL); break; } if (g_gameFlags & GAME_METAMOD) @@ -1907,9 +1895,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[15]) + else if (client->menu == BOT_MENU_KICK_PAGE_2) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1937,9 +1925,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[16]) + else if (client->menu == BOT_MENU_KICK_PAGE_3) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { @@ -1967,9 +1955,9 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu == &g_menus[17]) + else if (client->menu == BOT_MENU_KICK_PAGE_4) { - DisplayMenuToClient (ent, nullptr); // reset menu display + DisplayMenuToClient (ent, BOT_MENU_IVALID); // reset menu display switch (selection) { diff --git a/source/manager.cpp b/source/manager.cpp index 52ae81c..7324f50 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -9,7 +9,7 @@ #include -ConVar yb_autovacate ("yb_autovacate", "0"); +ConVar yb_autovacate ("yb_autovacate", "1"); ConVar yb_autovacate_smart_kick ("yb_autovacate_smart_kick", "0"); ConVar yb_quota ("yb_quota", "0", VT_NORMAL); @@ -439,8 +439,11 @@ void BotManager::MaintainBotQuota (void) if (yb_quota.GetInt () < 0) yb_quota.SetInt (0); - if (yb_quota.GetInt () > engine.MaxClients ()) - yb_quota.SetInt (engine.MaxClients ()); + // always keep one slot + int maxClients = yb_autovacate.GetBool () ? engine.MaxClients () - 1 - GetHumansNum () : engine.MaxClients (); + + if (yb_quota.GetInt () > maxClients) + yb_quota.SetInt (maxClients); } int numBots = GetBotsNum (); @@ -487,7 +490,10 @@ void BotManager::FillServer (int selection, int personality, int difficulty, int { // this function fill server with bots, with specified team & personality - if (GetBotsNum () >= engine.MaxClients () - GetHumansNum ()) + // always keep one slot + int maxClients = yb_autovacate.GetBool () ? engine.MaxClients () - 1 - GetHumansNum () : engine.MaxClients (); + + if (GetBotsNum () >= maxClients - GetHumansNum ()) return; if (selection == 1 || selection == 2) @@ -498,7 +504,7 @@ void BotManager::FillServer (int selection, int personality, int difficulty, int else selection = 5; - char teamDesc[6][12] = + char teams[6][12] = { "", {"Terrorists"}, @@ -508,12 +514,12 @@ void BotManager::FillServer (int selection, int personality, int difficulty, int {"Random"}, }; - int toAdd = numToAdd == -1 ? engine.MaxClients () - (GetHumansNum () + GetBotsNum ()) : numToAdd; + int toAdd = numToAdd == -1 ? maxClients - (GetHumansNum () + GetBotsNum ()) : numToAdd; for (int i = 0; i <= toAdd; i++) AddBot ("", difficulty, personality, selection, -1); - engine.CenterPrintf ("Fill Server with %s bots...", &teamDesc[selection][0]); + engine.CenterPrintf ("Fill Server with %s bots...", &teams[selection][0]); } void BotManager::RemoveAll (void) @@ -573,31 +579,31 @@ void BotManager::RemoveMenu (edict_t *ent, int selection) switch (selection) { case 1: - g_menus[14].validSlots = validSlots & static_cast (-1); - g_menus[14].menuText = tempBuffer; + g_menus[BOT_MENU_KICK_PAGE_1].slots = validSlots & static_cast (-1); + g_menus[14].text = tempBuffer; - DisplayMenuToClient (ent, &g_menus[14]); + DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_1); break; case 2: - g_menus[15].validSlots = validSlots & static_cast (-1); - g_menus[15].menuText = tempBuffer; + g_menus[BOT_MENU_KICK_PAGE_2].slots = validSlots & static_cast (-1); + g_menus[BOT_MENU_KICK_PAGE_2].text = tempBuffer; - DisplayMenuToClient (ent, &g_menus[15]); + DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_2); break; case 3: - g_menus[16].validSlots = validSlots & static_cast (-1); - g_menus[16].menuText = tempBuffer; + g_menus[BOT_MENU_KICK_PAGE_3].slots = validSlots & static_cast (-1); + g_menus[BOT_MENU_KICK_PAGE_3].text = tempBuffer; - DisplayMenuToClient (ent, &g_menus[16]); + DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_3); break; case 4: - g_menus[17].validSlots = validSlots & static_cast (-1); - g_menus[17].menuText = tempBuffer; + g_menus[BOT_MENU_KICK_PAGE_4].slots = validSlots & static_cast (-1); + g_menus[BOT_MENU_KICK_PAGE_4].text = tempBuffer; - DisplayMenuToClient (ent, &g_menus[17]); + DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_4); break; } } diff --git a/source/navigate.cpp b/source/navigate.cpp index de14f57..576143f 100644 --- a/source/navigate.cpp +++ b/source/navigate.cpp @@ -1105,7 +1105,13 @@ bool Bot::DoWaypointNav (void) IgnoreCollisionShortly (); // don't consider being stuck if (Random.Int (1, 100) < 50) - MDLL_Use (tr.pHit, GetEntity ()); // also 'use' the door randomly + { + // do not use door directrly under xash, or we will get failed assert in gamedll code + if (g_gameFlags & GAME_XASH) + pev->button |= IN_USE; + else + MDLL_Use (tr.pHit, GetEntity ()); // also 'use' the door randomly + } } // make sure we are always facing the door when going through it diff --git a/source/support.cpp b/source/support.cpp index 6498e63..c168e4d 100644 --- a/source/support.cpp +++ b/source/support.cpp @@ -99,65 +99,80 @@ bool IsVisible (const Vector &origin, edict_t *ent) return true; } -void DisplayMenuToClient (edict_t *ent, MenuText *menu) +void DisplayMenuToClient (edict_t *ent, MenuId menu) { + static bool s_menusParsed = false; + + // make menus looks like we need only once + if (!s_menusParsed) + { + for (int i = 0; i < ARRAYSIZE_HLSDK (g_menus); i++) + { + auto parsed = &g_menus[i]; + + // translate all the things + parsed->text.Replace ("\v", "\n"); + parsed->text.Assign (engine.TraslateMessage (parsed->text.GetBuffer ())); + + // make menu looks best + for (int j = 0; j < 10; j++) + parsed->text.Replace (FormatBuffer ("%d.", j), FormatBuffer ("\\r%d.\\w", j)); + } + s_menusParsed = true; + } + if (!IsValidPlayer (ent)) return; - int clientIndex = engine.IndexOfEntity (ent) - 1; + Client &client = g_clients[engine.IndexOfEntity (ent) - 1]; - if (menu != nullptr) - { - String tempText = String (menu->menuText); - tempText.Replace ("\v", "\n"); - - const char *text = engine.TraslateMessage (tempText.GetBuffer ()); - tempText = String (text); - - // make menu looks best - for (int i = 0; i <= 9; i++) - tempText.Replace (FormatBuffer ("%d.", i), FormatBuffer ("\\r%d.\\w", i)); - - if ((g_gameFlags & (GAME_XASH | GAME_MOBILITY)) && !yb_display_menu_text.GetBool ()) - text = " "; - else - text = tempText.GetBuffer (); - - while (strlen (text) >= 64) - { - MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, engine.FindMessageId (NETMSG_SHOWMENU), nullptr, ent); - WRITE_SHORT (menu->validSlots); - WRITE_CHAR (-1); - WRITE_BYTE (1); - - for (int i = 0; i <= 63; i++) - WRITE_CHAR (text[i]); - - MESSAGE_END (); - - text += 64; - } - - MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, engine.FindMessageId (NETMSG_SHOWMENU), nullptr, ent); - WRITE_SHORT (menu->validSlots); - WRITE_CHAR (-1); - WRITE_BYTE (0); - WRITE_STRING (text); - MESSAGE_END(); - - g_clients[clientIndex].menu = menu; - } - else + if (menu == BOT_MENU_IVALID) { MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, engine.FindMessageId (NETMSG_SHOWMENU), nullptr, ent); WRITE_SHORT (0); WRITE_CHAR (0); WRITE_BYTE (0); WRITE_STRING (""); - MESSAGE_END(); + MESSAGE_END (); - g_clients[clientIndex].menu = nullptr; + client.menu = BOT_MENU_IVALID; + return; } + + MenuText *menuPtr = nullptr; + + for (int i = 0; i < ARRAYSIZE_HLSDK (g_menus); i++) + { + if (g_menus[i].id == menu) + { + menuPtr = &g_menus[i]; + break; + } + } + char *displayText = (g_gameFlags & (GAME_XASH | GAME_MOBILITY)) && !yb_display_menu_text.GetBool () ? " " : menuPtr->text.GetBuffer (); + + while (strlen (displayText) >= 64) + { + MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, engine.FindMessageId (NETMSG_SHOWMENU), nullptr, ent); + WRITE_SHORT (menuPtr->slots); + WRITE_CHAR (-1); + WRITE_BYTE (1); + + for (int i = 0; i <= 63; i++) + WRITE_CHAR (displayText[i]); + + MESSAGE_END (); + displayText += 64; + } + + MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, engine.FindMessageId (NETMSG_SHOWMENU), nullptr, ent); + WRITE_SHORT (menuPtr->slots); + WRITE_CHAR (-1); + WRITE_BYTE (0); + WRITE_STRING (displayText); + MESSAGE_END(); + + client.menu = menu; CLIENT_COMMAND (ent, "speak \"player/geiger1\"\n"); // Stops others from hearing menu sounds.. } @@ -534,10 +549,10 @@ void CheckWelcomeMessage (void) sentences.Push ("warning, medical attention required"); } - if (IsAlive (g_hostEntity) && !alreadyReceived && receiveTime < 1.0 && (g_numWaypoints > 0 ? g_isCommencing : true)) + if (IsAlive (g_hostEntity) && !alreadyReceived && receiveTime < 1.0 && (g_numWaypoints > 0 ? g_gameWelcomeSent : true)) receiveTime = engine.Time () + 4.0f; // receive welcome message in four seconds after game has commencing - if (receiveTime > 0.0f && receiveTime < engine.Time () && !alreadyReceived && (g_numWaypoints > 0 ? g_isCommencing : true)) + if (receiveTime > 0.0f && receiveTime < engine.Time () && !alreadyReceived && (g_numWaypoints > 0 ? g_gameWelcomeSent : true)) { if (!(g_gameFlags & (GAME_MOBILITY | GAME_XASH))) engine.IssueCmd ("speak \"%s\"", const_cast (sentences.GetRandomElement ().GetBuffer ()));