diff --git a/.travis.yml b/.travis.yml index 3fb6455..3703fc4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ before_script: - export PATH=$PATH:/tmp/osxcross/target/bin - wget https://yapb.jeefo.net/ci/scripts/gitrev.sh && chmod a+x ./gitrev.sh && ./gitrev.sh script: - - cd project && make all + - cd project && CC=clang-3.8 make all after_success: - curl --ftp-create-dirs -T ./release/yapb.so -u $FTP_USER:$FTP_PASS ftp://$FTP_HOST/project/release/yapb.so - curl --ftp-create-dirs -T ./debug/yapb.so -u $FTP_USER:$FTP_PASS ftp://$FTP_HOST/project/debug/yapb.so diff --git a/project/makefile b/project/makefile index d8045fe..f621e8f 100644 --- a/project/makefile +++ b/project/makefile @@ -6,123 +6,105 @@ # Additional exceptions apply. For full license details, see LICENSE.txt or visit: # https://yapb.jeefo.net/license # -# Based on Makefile written by David "BAILOPAN" Anderson. -# PROJECT = yapb -SRC_DIR = ../source -OBJECTS = $(SRC_DIR)/basecode.cpp \ - $(SRC_DIR)/manager.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)/support.cpp \ - $(SRC_DIR)/waypoint.cpp \ +SOURCES = ../source +OBJECTS = $(wildcard $(SOURCES)/*.cpp) -C_OPT_FLAGS = -Ofast -DNDEBUG -pipe -fno-strict-aliasing -mtune=generic -C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3 +COMPILER_FLAGS = -std=c++11 -m32 -Wall -Werror -Wextra -fno-exceptions -fno-rtti +LINKER_FLAGS = -m32 -lm -ldl -C_GCC_FLAGS = -fvisibility=hidden -CPP_GCC_FLAGS = -fvisibility-inlines-hidden - -CPP = clang-3.8 -CPP_MAC = o32-clang - -LINK = -INCLUDE = -I../include -I../include/engine - -ifeq "$(MAC)" "true" - OS = Darwin - CPP_MAC = o32-clang +ifeq "$(SSE_VERSION)" "" + COMPILER_SSE_VERSION = 2 else - OS := $(shell uname -s) + COMPILER_SSE_VERSION = $(SSE_VERSION) endif -ifeq "$(OS)" "Darwin" - CPP = $(CPP_MAC) - LIB_EXT = dylib - CFLAGS += -DOSX -D_OSX -DPOSIX - LINK += -dynamiclib -lstdc++ -mmacosx-version-min=10.5 -arch i386 -else - LIB_EXT = so - CFLAGS += -DLINUX -D_LINUX -DPOSIX - LINK += -shared -lsupc++ -endif - -LINK += -m32 -lm -ldl - -CFLAGS += -msse2 -std=c++11 -m32 -Wall -Werror -Wextra -CPPFLAGS += -fno-exceptions -fno-rtti - -BINARY = $(PROJECT).$(LIB_EXT) - ifeq "$(DEBUG)" "true" - BIN_DIR = debug - CFLAGS += $(C_DEBUG_FLAGS) + COMPILER_FLAGS += -D_DEBUG -DDEBUG -g3 + BINARY_DIR = debug else - BIN_DIR = release - CFLAGS += $(C_OPT_FLAGS) + COMPILER_FLAGS += -DNDEBUG -pipe -Ofast -msse$(COMPILER_SSE_VERSION) -funroll-loops -fomit-frame-pointer -fno-stack-protector -fvisibility=hidden -fvisibility-inlines-hidden + BINARY_DIR = release +endif - ifneq "$(OS)" "Darwin" - LINK += -s +INCLUDE = -I../include -I../include/engine +COMPILER = $(CC) + +ifeq "$(shell uname -s)" "Darwin" + MACOS = true +else + ifeq "$(MACOS)" "true" + COMPILER = o32-clang endif endif -IS_CLANG := $(shell $(CPP) --version | head -1 | grep clang > /dev/null && echo "1" || echo "0") - -ifeq "$(IS_CLANG)" "1" - CFLAGS += $(C_GCC_FLAGS) -D__extern_always_inline="extern __always_inline" - CPPFLAGS += $(CPP_GCC_FLAGS) +ifeq "$(MACOS)" "true" + LIBRARY_EXT = dylib + COMPILER_FLAGS += -DOSX -D_OSX -DPOSIX + LINKER_FLAGS += -s -dynamiclib -lstdc++ -mmacosx-version-min=10.5 -arch i386 +else + LIBRARY_EXT = so + COMPILER_FLAGS += -DLINUX -D_LINUX -DPOSIX + LINKER_FLAGS += -shared -lsupc++ endif -# OS is Linux and not using clang -ifeq "$(shell expr $(OS) \= Linux \& $(IS_CLANG) \= 0)" "1" - LINK += -static-libgcc +BINARY_OUTPUT = $(PROJECT).$(LIBRARY_EXT) + +ifeq ($(findstring clang,$(COMPILER)),clang) + COMPILER_FLAGS += -D__extern_always_inline="extern __always_inline" + ifeq "$(MACOS)" "false" + LINKER_FLAGS += -lgcc_eh + endif +else ifeq ($(findstring gcc,$(COMPILER)),gcc) + ifneq "$(MACOS)" "false" + LINKER_FLAGS += -static-libgcc + COMPILER_FLAGS += -funroll-all-loops + endif +else ifeq ($(findstring icpc,$(COMPILER)),icpc) + COMPILER_FLAGS += -funroll-all-loops -no-prec-div -no-inline-min-size -no-inline-max-size -wd11076 -wd11074 + LINKER_FLAGS += -static-intel -no-intel-extensions +else + $(error Compiler unrecognized. Specify CC.) endif -# OS is Linux and using clang -ifeq "$(shell expr $(OS) \= Linux \& $(IS_CLANG) \= 1)" "1" - LINK += -lgcc_eh -endif +OBJECTS_BIN := $(OBJECTS:%.cpp=$(BINARY_DIR)/%.o) -OBJ_BIN := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) +$(BINARY_DIR)/%.o: %.cpp + $(COMPILER) $(INCLUDE) $(COMPILER_FLAGS) -o $(subst $(SOURCES)/,,$@) -c $< -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $(subst $(SRC_DIR)/,,$@) -c $< - -main: - mkdir -p release - mkdir -p debug +compile: + mkdir -p $(BINARY_DIR) $(MAKE) $(PROJECT) -$(PROJECT): $(OBJ_BIN) - $(CPP) $(INCLUDE) $(subst $(SRC_DIR)/,,$(OBJ_BIN)) $(LINK) -o $(BIN_DIR)/$(BINARY) - -debug: - mkdir -p debug - $(MAKE) main DEBUG=true +$(PROJECT): $(OBJECTS_BIN) + $(COMPILER) $(INCLUDE) $(subst $(SOURCES)/,,$(OBJECTS_BIN)) $(LINKER_FLAGS) -o $(BINARY_DIR)/$(BINARY_OUTPUT) release: - mkdir -p release - $(MAKE) main DEBUG=false + $(MAKE) compile DEBUG=false -release_osx: - mkdir -p release - $(MAKE) main OSX=true DEBUG=false +debug: + $(MAKE) compile DEBUG=true -debug_osx: - mkdir -p debug - $(MAKE) main OSX=true DEBUG=true +release_macos: + $(MAKE) compile MACOS=true DEBUG=false -all_linux: release debug -all_osx: release_osx debug_osx -all: all_linux all_osx +debug_macos: + $(MAKE) compile MACOS=true DEBUG=true -default: all +all_linux: + $(MAKE) compile DEBUG=true + $(MAKE) compile DEBUG=false + +all_macos: + $(MAKE) compile MACOS=true DEBUG=false + $(MAKE) compile MACOS=true DEBUG=true + +all: all_linux all_macos +default: all_linux clean: - rm -rf release - rm -rf debug + rm -rf release/*.o + rm -rf release/$(BINARY_OUTPUT) + rm -rf debug/*.o + rm -rf debug/$(BINARY_OUTPUT) \ No newline at end of file diff --git a/source/basecode.cpp b/source/basecode.cpp index a506152..eb51c20 100644 --- a/source/basecode.cpp +++ b/source/basecode.cpp @@ -1712,7 +1712,7 @@ void Bot::PurchaseWeapons (void) else // steam cs buy menu is different from old one { - if (engine.GetTeam (GetEntity ()) == TERRORIST) + if (m_team == TERRORIST) engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectT); else engine.IssueBotCommand (GetEntity (), "menuselect %d", selectedWeapon->newBuySelectCT); @@ -2929,7 +2929,7 @@ void Bot::ThinkFrame (void) m_voteMap = 0; } } - else if (m_notKilled && m_buyingFinished && !(pev->maxspeed < 10.0f && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB) && !yb_freeze_bots.GetBool ()) + else if (m_notKilled && m_buyingFinished && !(pev->maxspeed < 10.0f && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB) && !yb_freeze_bots.GetBool () && !waypoints.HasChanged ()) botMovement = true; #ifdef XASH_CSDM @@ -2955,9 +2955,13 @@ void Bot::PeriodicThink (void) m_numFriendsLeft = GetNearbyFriendsNearPosition (pev->origin, 99999.0f); m_numEnemiesLeft = GetNearbyEnemiesNearPosition (pev->origin, 99999.0f); - if (g_bombPlanted && m_team == CT && (pev->origin - waypoints.GetBombPosition ()).GetLength () < 700 && !IsBombDefusing (waypoints.GetBombPosition ()) && !m_hasProgressBar && GetTaskId () != TASK_ESCAPEFROMBOMB) - ResetTasks (); + if (g_bombPlanted && m_team == CT) + { + const Vector &bombPosition = waypoints.GetBombPosition (); + if (!m_hasProgressBar && GetTaskId () != TASK_ESCAPEFROMBOMB && (pev->origin - bombPosition).GetLength () < 700 && !IsBombDefusing ()) + ResetTasks (); + } CheckSpawnTimeConditions (); extern ConVar yb_chat; @@ -3559,10 +3563,10 @@ void Bot::RunTask_Camp (void) dest.z = 0.0f; // find a visible waypoint to this direction... - // i know this is ugly hack, but i just don't want to break compatiability :) + // i know this is ugly hack, but i just don't want to break compatibility :) int numFoundPoints = 0; - int foundPoints[3]; - int distanceTab[3]; + int campPoints[3] = { 0, }; + int distances[3] = { 0, }; const Vector &dotA = (dest - pev->origin).Normalize2D (); @@ -3574,7 +3578,7 @@ void Bot::RunTask_Camp (void) const Vector &dotB = (waypoints.GetPath (i)->origin - pev->origin).Normalize2D (); - if ((dotA | dotB) > 0.9) + if ((dotA | dotB) > 0.9f) { int distance = static_cast ((pev->origin - waypoints.GetPath (i)->origin).GetLength ()); @@ -3582,10 +3586,10 @@ void Bot::RunTask_Camp (void) { for (int j = 0; j < 3; j++) { - if (distance > distanceTab[j]) + if (distance > distances[j]) { - distanceTab[j] = distance; - foundPoints[j] = i; + distances[j] = distance; + campPoints[j] = i; break; } @@ -3593,8 +3597,8 @@ void Bot::RunTask_Camp (void) } else { - foundPoints[numFoundPoints] = i; - distanceTab[numFoundPoints] = distance; + campPoints[numFoundPoints] = i; + distances[numFoundPoints] = distance; numFoundPoints++; } @@ -3602,7 +3606,7 @@ void Bot::RunTask_Camp (void) } if (--numFoundPoints >= 0) - m_camp = waypoints.GetPath (foundPoints[Random.Int (0, numFoundPoints)])->origin; + m_camp = waypoints.GetPath (campPoints[Random.Int (0, numFoundPoints)])->origin; else m_camp = waypoints.GetPath (GetCampAimingWaypoint ())->origin; } diff --git a/source/globals.cpp b/source/globals.cpp index 5868d88..236f039 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -157,25 +157,26 @@ WeaponSelect g_weaponSelect[NUM_WEAPONS + 1] = {0, "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, false} }; -// bot menus -MenuText g_menus[BOT_MENU_TOTAL_MENUS] = +void SetupBotMenus (void) { - // main menu + int counter = 0; + + // bots main menu + g_menus[counter] = { - BOT_MENU_MAIN, - 0x2ff, + BOT_MENU_MAIN, 0x2ff, "\\yMain Menu\\w\v\v" "1. Control Bots\v" "2. Features\v\v" "3. Fill Server\v" "4. End Round\v\v" "0. Exit" - }, + }; - // bot features menu + // bots features menu + g_menus[++counter] = { - BOT_MENU_FEATURES, - 0x25f, + BOT_MENU_FEATURES, 0x25f, "\\yBots Features\\w\v\v" "1. Weapon Mode Menu\v" "2. Waypoint Menu\v" @@ -183,12 +184,12 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "4. Toggle Debug Mode\v" "5. Command Menu\v\v" "0. Exit" - }, + }; // bot control menu + g_menus[++counter] = { - BOT_MENU_CONTROL, - 0x2ff, + BOT_MENU_CONTROL, 0x2ff, "\\yBots Control Menu\\w\v\v" "1. Add a Bot, Quick\v" "2. Add a Bot, Specified\v\v" @@ -196,12 +197,12 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "4. Remove All Bots\v\v" "5. Remove Bot Menu\v\v" "0. Exit" - }, + }; // weapon mode select menu + g_menus[++counter] = { - BOT_MENU_WEAPON_MODE, - 0x27f, + BOT_MENU_WEAPON_MODE, 0x27f, "\\yBots Weapon Mode\\w\v\v" "1. Knives only\v" "2. Pistols only\v" @@ -211,24 +212,24 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "6. Sniper Weapons only\v" "7. All Weapons\v\v" "0. Exit" - }, + }; // personality select menu + g_menus[++counter] = { - BOT_MENU_PERSONALITY, - 0x20f, + BOT_MENU_PERSONALITY, 0x20f, "\\yBots Personality\\w\v\v" "1. Random\v" "2. Normal\v" "3. Aggressive\v" "4. Careful\v\v" "0. Exit" - }, + }; // difficulty select menu + g_menus[++counter] = { - BOT_MENU_DIFFICULTY, - 0x23f, + BOT_MENU_DIFFICULTY, 0x23f, "\\yBots Difficulty Level\\w\v\v" "1. Newbie\v" "2. Average\v" @@ -236,23 +237,23 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "4. Professional\v" "5. Godlike\v\v" "0. Exit" - }, + }; // team select menu + g_menus[++counter] = { - BOT_MENU_TEAM_SELECT, - 0x213, + BOT_MENU_TEAM_SELECT, 0x213, "\\ySelect a team\\w\v\v" "1. Terrorist Force\v" "2. Counter-Terrorist Force\v\v" "5. Auto-select\v\v" "0. Exit" - }, + }; // terrorist model select menu + g_menus[++counter] = { - BOT_MENU_TERRORIST_SELECT, - 0x21f, + BOT_MENU_TERRORIST_SELECT, 0x21f, "\\ySelect an appearance\\w\v\v" "1. Phoenix Connexion\v" "2. L337 Krew\v" @@ -260,12 +261,12 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "4. Guerilla Warfare\v\v" "5. Auto-select\v\v" "0. Exit" - }, + }; // counter-terrorist model select menu + g_menus[++counter] = { - BOT_MENU_CT_SELECT, - 0x21f, + BOT_MENU_CT_SELECT, 0x21f, "\\ySelect an appearance\\w\v\v" "1. Seal Team 6 (DEVGRU)\v" "2. German GSG-9\v" @@ -273,24 +274,24 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "4. French GIGN\v\v" "5. Auto-select\v\v" "0. Exit" - }, + }; // command menu + g_menus[++counter] = { - BOT_MENU_COMMANDS, - 0x23f, + 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 + g_menus[++counter] = { - BOT_MENU_WAYPOINT_MAIN_PAGE1, - 0x3ff, + BOT_MENU_WAYPOINT_MAIN_PAGE1, 0x3ff, "\\yWaypoint Operations (Page 1)\\w\v\v" "1. Show/Hide waypoints\v" "2. Cache waypoint\v" @@ -302,12 +303,12 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "8. Set Radius\v\v" "9. Next...\v\v" "0. Exit" - }, + }; // main waypoint menu (page 2) + g_menus[++counter] = { - BOT_MENU_WAYPOINT_MAIN_PAGE2, - 0x3ff, + BOT_MENU_WAYPOINT_MAIN_PAGE2, 0x3ff, "\\yWaypoint Operations (Page 2)\\w\v\v" "1. Waypoint stats\v" "2. Autowaypoint on/off\v" @@ -319,12 +320,12 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "8. Noclip cheat on/off\v\v" "9. Previous...\v\v" "0. Exit" - }, + }; // select waypoint radius menu + g_menus[++counter] = { - BOT_MENU_WAYPOINT_RADIUS, - 0x3ff, + BOT_MENU_WAYPOINT_RADIUS, 0x3ff, "\\yWaypoint Radius\\w\v\v" "1. SetRadius 0\v" "2. SetRadius 8\v" @@ -336,12 +337,12 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "8. SetRadius 96\v" "9. SetRadius 128\v\v" "0. Exit" - }, + }; // waypoint add menu + g_menus[++counter] = { - BOT_MENU_WAYPOINT_TYPE, - 0x3ff, + BOT_MENU_WAYPOINT_TYPE, 0x3ff, "\\yWaypoint Type\\w\v\v" "1. Normal\v" "\\r2. Terrorist Important\v" @@ -353,12 +354,12 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "\\r8. Map Goal\v" "\\w9. Jump\v\v" "0. Exit" - }, + }; // set waypoint flag menu + g_menus[++counter] = { - BOT_MENU_WAYPOINT_FLAG, - 0x2ff, + BOT_MENU_WAYPOINT_FLAG, 0x2ff, "\\yToggle Waypoint Flags\\w\v\v" "1. Block with Hostage\v" "2. Terrorists Specific\v" @@ -366,9 +367,10 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "4. Use Elevator\v" "5. Sniper Point (\\yFor Camp Points Only!\\w)\v\v" "0. Exit" - }, + }; // auto-path max distance + g_menus[++counter] = { BOT_MENU_WAYPOINT_AUTOPATH, 0x27f, @@ -381,9 +383,10 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "6. Distance 220\v" "7. Distance 250 (Default)\v\v" "0. Exit" - }, + }; // path connections + g_menus[++counter] = { BOT_MENU_WAYPOINT_PATH, 0x207, @@ -392,33 +395,16 @@ MenuText g_menus[BOT_MENU_TOTAL_MENUS] = "2. Incoming Path\v" "3. Bidirectional (Both Ways)\v\v" "0. Exit" - }, + }; - // kickmenu #1 - { - BOT_MENU_KICK_PAGE_1, - 0x0, - nullptr, - }, + const String &empty = ""; - // kickmenu #2 - { - BOT_MENU_KICK_PAGE_2, - 0x0, - nullptr, - }, + // kick menus + g_menus[++counter] = { BOT_MENU_KICK_PAGE_1, 0x0, empty, }; + g_menus[++counter] = { BOT_MENU_KICK_PAGE_2, 0x0, empty, }; + g_menus[++counter] = { BOT_MENU_KICK_PAGE_3, 0x0, empty, }; + g_menus[++counter] = { BOT_MENU_KICK_PAGE_4, 0x0, empty, }; +} - // kickmenu #3 - { - BOT_MENU_KICK_PAGE_3, - 0x0, - nullptr, - }, - - // kickmenu #4 - { - BOT_MENU_KICK_PAGE_4, - 0x0, - nullptr, - } -}; +// bot menus +MenuText g_menus[BOT_MENU_TOTAL_MENUS]; diff --git a/source/interface.cpp b/source/interface.cpp index 6849687..f3c8efa 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -1236,14 +1236,20 @@ void ClientCommand (edict_t *ent) case 6: case 7: waypoints.Add (selection - 1); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_TYPE); + break; case 8: waypoints.Add (100); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_TYPE); + break; case 9: waypoints.SetLearnJumpWaypoint (); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_TYPE); + break; case 10: @@ -1263,22 +1269,27 @@ void ClientCommand (edict_t *ent) { case 1: waypoints.ToggleFlags (FLAG_NOHOSTAGE); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_FLAG); break; case 2: waypoints.ToggleFlags (FLAG_TF_ONLY); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_FLAG); break; case 3: waypoints.ToggleFlags (FLAG_CF_ONLY); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_FLAG); break; case 4: waypoints.ToggleFlags (FLAG_LIFT); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_FLAG); break; case 5: waypoints.ToggleFlags (FLAG_SNIPER); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_FLAG); break; } if (g_gameFlags & GAME_METAMOD) @@ -1297,11 +1308,15 @@ void ClientCommand (edict_t *ent) engine.IssueCmd ("yapb waypoint off"); else engine.IssueCmd ("yapb waypoint on"); + + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE1); break; case 2: g_waypointOn = true; waypoints.CacheWaypoint (); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE1); + break; case 3: @@ -1312,6 +1327,8 @@ void ClientCommand (edict_t *ent) case 4: g_waypointOn = true; waypoints.DeletePath (); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE1); + break; case 5: @@ -1322,6 +1339,8 @@ void ClientCommand (edict_t *ent) case 6: g_waypointOn = true; waypoints.Delete (); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE1); + break; case 7: @@ -1392,6 +1411,8 @@ void ClientCommand (edict_t *ent) "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); + + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE2); } break; @@ -1401,6 +1422,8 @@ void ClientCommand (edict_t *ent) g_autoWaypoint ^= 1; engine.CenterPrintf ("Auto-Waypoint %s", g_autoWaypoint ? "Enabled" : "Disabled"); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE2); + break; case 3: @@ -1413,14 +1436,18 @@ void ClientCommand (edict_t *ent) waypoints.Save (); else engine.CenterPrintf ("Waypoint not saved\nThere are errors, see console"); + + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE2); break; case 5: waypoints.Save (); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE2); break; case 6: waypoints.Load (); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE2); break; case 7: @@ -1428,10 +1455,13 @@ void ClientCommand (edict_t *ent) engine.CenterPrintf ("Nodes works fine"); else engine.CenterPrintf ("There are errors, see console"); + + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE2); break; case 8: engine.IssueCmd ("yapb wp on noclip"); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_MAIN_PAGE2); break; case 9: @@ -1454,6 +1484,8 @@ void ClientCommand (edict_t *ent) if ((selection >= 1) && (selection <= 9)) waypoints.SetRadius (radiusValue[selection - 1]); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_RADIUS); + if (g_gameFlags & GAME_METAMOD) RETURN_META (MRES_SUPERCEDE); @@ -1481,6 +1513,7 @@ void ClientCommand (edict_t *ent) case 4: bots.KillAll (); + DisplayMenuToClient (ent, BOT_MENU_MAIN); break; case 10: @@ -1501,6 +1534,7 @@ void ClientCommand (edict_t *ent) { case 1: bots.AddRandom (); + DisplayMenuToClient (ent, BOT_MENU_CONTROL); break; case 2: @@ -1509,10 +1543,12 @@ void ClientCommand (edict_t *ent) case 3: bots.RemoveRandom (); + DisplayMenuToClient (ent, BOT_MENU_CONTROL); break; case 4: bots.RemoveAll (); + DisplayMenuToClient (ent, BOT_MENU_CONTROL); break; case 5: @@ -1550,6 +1586,7 @@ void ClientCommand (edict_t *ent) extern ConVar yb_debug; yb_debug.SetInt (yb_debug.GetInt () ^ 1); + DisplayMenuToClient (ent, BOT_MENU_FEATURES); break; case 5: @@ -1596,16 +1633,17 @@ void ClientCommand (edict_t *ent) } else if (selection == 2) bot->ResetDoubleJumpState (); - - break; } } + DisplayMenuToClient (ent, BOT_MENU_COMMANDS); break; case 3: case 4: if (FindNearestPlayer (reinterpret_cast (&bot), ent, 300.0f, true, true, true)) bot->DiscardWeaponForUser (ent, selection == 4 ? false : true); + + DisplayMenuToClient (ent, BOT_MENU_COMMANDS); break; case 10: @@ -1618,7 +1656,7 @@ void ClientCommand (edict_t *ent) return; } - else if (client->menu ==BOT_MENU_WAYPOINT_AUTOPATH) + else if (client->menu == BOT_MENU_WAYPOINT_AUTOPATH) { DisplayMenuToClient (ent, BOT_MENU_INVALID); // reset menu display @@ -1632,6 +1670,8 @@ void ClientCommand (edict_t *ent) else engine.CenterPrintf ("AutoPath maximum distance set to %.2f", g_autoPathDistance); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_AUTOPATH); + if (g_gameFlags & GAME_METAMOD) RETURN_META (MRES_SUPERCEDE); @@ -1645,14 +1685,17 @@ void ClientCommand (edict_t *ent) { case 1: waypoints.CreatePath (CONNECTION_OUTGOING); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_PATH); break; case 2: waypoints.CreatePath (CONNECTION_INCOMING); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_PATH); break; case 3: waypoints.CreatePath (CONNECTION_BOTHWAYS); + DisplayMenuToClient (ent, BOT_MENU_WAYPOINT_PATH); break; case 10: @@ -1847,6 +1890,7 @@ void ClientCommand (edict_t *ent) case 6: case 7: bots.SetWeaponMode (selection); + DisplayMenuToClient (ent, BOT_MENU_WEAPON_MODE); break; case 10: @@ -1873,6 +1917,7 @@ void ClientCommand (edict_t *ent) case 7: case 8: bots.GetBot (selection - 1)->Kick (); + bots.RemoveMenu (ent, 1); break; case 9: @@ -1903,6 +1948,7 @@ void ClientCommand (edict_t *ent) case 7: case 8: bots.GetBot (selection + 8 - 1)->Kick (); + bots.RemoveMenu (ent, 2); break; case 9: @@ -1933,6 +1979,7 @@ void ClientCommand (edict_t *ent) case 7: case 8: bots.GetBot (selection + 16 - 1)->Kick (); + bots.RemoveMenu (ent, 3); break; case 9: @@ -1963,6 +2010,7 @@ void ClientCommand (edict_t *ent) case 7: case 8: bots.GetBot (selection + 24 - 1)->Kick (); + bots.RemoveMenu (ent, 4); break; case 10: diff --git a/source/manager.cpp b/source/manager.cpp index a5f1197..6ff1d79 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -572,12 +572,14 @@ void BotManager::RemoveMenu (edict_t *ent, int selection) int validSlots = (selection == 4) ? (1 << 9) : ((1 << 8) | (1 << 9)); - for (int i = ((selection - 1) * 8); i < selection * 8; i++) + for (int i = (selection - 1) * 8; i < selection * 8; i++) { - if (m_bots[i] != nullptr && !engine.IsNullEntity (m_bots[i]->GetEntity ())) + const Bot *bot = GetBot (i); + + if (bot != nullptr && (bot->pev->flags & FL_FAKECLIENT)) { 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), engine.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 (bot->pev->netname), bot->m_team == 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); @@ -585,32 +587,58 @@ void BotManager::RemoveMenu (edict_t *ent, int selection) sprintf (tempBuffer, "\\yBots Remove Menu (%d/4):\\w\n\n%s\n%s 0. Back", selection, buffer, (selection == 4) ? "" : " 9. More...\n"); + // force to clear current menu + DisplayMenuToClient (ent, BOT_MENU_INVALID); + + auto FindMenu = [] (MenuId id) + { + int menuIndex = 0; + + for (; menuIndex < ARRAYSIZE_HLSDK (g_menus); menuIndex++) + { + if (g_menus[menuIndex].id == id) + break; + } + return &g_menus[menuIndex]; + }; + + MenuText *menu = nullptr; + const unsigned int slots = validSlots & static_cast (-1); + switch (selection) { case 1: - g_menus[BOT_MENU_KICK_PAGE_1].slots = validSlots & static_cast (-1); - g_menus[14].text = tempBuffer; + menu = FindMenu (BOT_MENU_KICK_PAGE_1); + + menu->slots = slots; + menu->text = tempBuffer; DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_1); break; case 2: - g_menus[BOT_MENU_KICK_PAGE_2].slots = validSlots & static_cast (-1); - g_menus[BOT_MENU_KICK_PAGE_2].text = tempBuffer; + menu = FindMenu (BOT_MENU_KICK_PAGE_2); + + menu->slots = slots; + menu->text = tempBuffer; DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_2); break; case 3: - g_menus[BOT_MENU_KICK_PAGE_3].slots = validSlots & static_cast (-1); - g_menus[BOT_MENU_KICK_PAGE_3].text = tempBuffer; + menu = FindMenu (BOT_MENU_KICK_PAGE_3); + + menu->slots = slots; + menu->text = tempBuffer; DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_3); break; case 4: - g_menus[BOT_MENU_KICK_PAGE_4].slots = validSlots & static_cast (-1); - g_menus[BOT_MENU_KICK_PAGE_4].text = tempBuffer; + menu = FindMenu (BOT_MENU_KICK_PAGE_4); + + menu->slots = slots; + menu->text = tempBuffer; DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_4); break; @@ -1265,6 +1293,9 @@ void Bot::Kick (bool keepQuota) { // this function kick off one bot from the server. + // clear fakeclient bit immediately + pev->flags &= ~FL_FAKECLIENT; + engine.IssueCmd ("kick \"%s\"", STRING (pev->netname)); engine.CenterPrintf ("Bot '%s' kicked", STRING (pev->netname)); diff --git a/source/support.cpp b/source/support.cpp index c115a29..8c7d93c 100644 --- a/source/support.cpp +++ b/source/support.cpp @@ -106,6 +106,9 @@ void DisplayMenuToClient (edict_t *ent, MenuId menu) // make menus looks like we need only once if (!s_menusParsed) { + extern void SetupBotMenus (void); + SetupBotMenus (); + for (int i = 0; i < ARRAYSIZE_HLSDK (g_menus); i++) { auto parsed = &g_menus[i];