fixed crashes on door open on xash3d

workaround bug with svc_bad after adding bots
reworked a little how bot menus works
some more source cleanup
This commit is contained in:
jeefo 2016-09-13 19:09:20 +03:00
commit 0f97db33db
11 changed files with 304 additions and 257 deletions

View file

@ -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 <engine.h>
// 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);

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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])
{

View file

@ -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"))
{

View file

@ -9,37 +9,12 @@
#include <core.h>
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,
}
};

View file

@ -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)
{

View file

@ -9,7 +9,7 @@
#include <core.h>
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 <unsigned int> (-1);
g_menus[14].menuText = tempBuffer;
g_menus[BOT_MENU_KICK_PAGE_1].slots = validSlots & static_cast <unsigned int> (-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 <unsigned int> (-1);
g_menus[15].menuText = tempBuffer;
g_menus[BOT_MENU_KICK_PAGE_2].slots = validSlots & static_cast <unsigned int> (-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 <unsigned int> (-1);
g_menus[16].menuText = tempBuffer;
g_menus[BOT_MENU_KICK_PAGE_3].slots = validSlots & static_cast <unsigned int> (-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 <unsigned int> (-1);
g_menus[17].menuText = tempBuffer;
g_menus[BOT_MENU_KICK_PAGE_4].slots = validSlots & static_cast <unsigned int> (-1);
g_menus[BOT_MENU_KICK_PAGE_4].text = tempBuffer;
DisplayMenuToClient (ent, &g_menus[17]);
DisplayMenuToClient (ent, BOT_MENU_KICK_PAGE_4);
break;
}
}

View file

@ -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

View file

@ -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 <char *> (sentences.GetRandomElement ().GetBuffer ()));