Merge pull request #35 from jeefo/testing

Merge changes
This commit is contained in:
jeefo 2016-07-04 13:28:22 +03:00 committed by GitHub
commit 9cb73aaa66
11 changed files with 234 additions and 254 deletions

View file

@ -636,6 +636,7 @@ struct ExperienceSave
// bot creation tab // bot creation tab
struct CreateQueue struct CreateQueue
{ {
bool console;
int difficulty; int difficulty;
int team; int team;
int member; int member;
@ -1203,9 +1204,8 @@ public:
void TryHeadTowardRadioEntity (void); void TryHeadTowardRadioEntity (void);
void Kill (void); void Kill (void);
void Kick (void); void Kick (bool keepQuota = false);
void ResetDoubleJumpState (void); void ResetDoubleJumpState (void);
void MoveToVector (const Vector &to);
int FindPlantedBomb(void); int FindPlantedBomb(void);
bool HasHostage (void); bool HasHostage (void);
@ -1248,7 +1248,7 @@ private:
edict_t *m_killerEntity; // killer entity for bots edict_t *m_killerEntity; // killer entity for bots
protected: protected:
int CreateBot (const String &name, int difficulty, int personality, int team, int member); int CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd);
public: public:
BotManager (void); BotManager (void);
@ -1280,13 +1280,13 @@ public:
void Free (void); void Free (void);
void Free (int index); void Free (int index);
void AddRandom (void) { AddBot ("", -1, -1, -1, -1); } void AddRandom (bool isConsoleCmd = true) { AddBot ("", -1, -1, -1, -1, isConsoleCmd); }
void AddBot (const String &name, int difficulty, int personality, int team, int member); void AddBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd = true);
void AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member); void AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member, bool isConsoleCmd = true);
void FillServer (int selection, int personality = PERSONALITY_NORMAL, int difficulty = -1, int numToAdd = -1); void FillServer (int selection, int personality = PERSONALITY_NORMAL, int difficulty = -1, int numToAdd = -1);
void RemoveAll (bool zeroQuota = true); void RemoveAll (void);
void RemoveRandom (void); void RemoveRandom (bool keepQuota = false);
void RemoveFromTeam (Team team, bool removeAll = false); void RemoveFromTeam (Team team, bool removeAll = false);
void RemoveMenu (edict_t *ent, int selection); void RemoveMenu (edict_t *ent, int selection);
void KillAll (int team = -1); void KillAll (int team = -1);
@ -1469,7 +1469,6 @@ extern bool FindNearestPlayer (void **holder, edict_t *to, float searchDistance
extern void FreeLibraryMemory (void); extern void FreeLibraryMemory (void);
extern void RoundInit (void); extern void RoundInit (void);
extern void CheckWelcomeMessage (void); extern void CheckWelcomeMessage (void);
extern void DetectCSVersion (void);
extern void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...); extern void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...);
extern void DisplayMenuToClient (edict_t *ent, MenuText *menu); extern void DisplayMenuToClient (edict_t *ent, MenuText *menu);
extern void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex); extern void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex);

View file

@ -318,7 +318,7 @@ public:
FORCEINLINE int GetInt (void) { return static_cast <int> (m_eptr->value); } FORCEINLINE int GetInt (void) { return static_cast <int> (m_eptr->value); }
FORCEINLINE float GetFloat (void) { return m_eptr->value; } FORCEINLINE float GetFloat (void) { return m_eptr->value; }
FORCEINLINE const char *GetString (void) { return m_eptr->string; } FORCEINLINE const char *GetString (void) { return m_eptr->string; }
FORCEINLINE void SetFloat (float val) { m_eptr->value = val; } FORCEINLINE void SetFloat (float val) { g_engfuncs.pfnCVarSetFloat (m_eptr->name, val); }
FORCEINLINE void SetInt (int val) { SetFloat (static_cast <float> (val)); } FORCEINLINE void SetInt (int val) { SetFloat (static_cast <float> (val)); }
FORCEINLINE void SetString (const char *val) { g_engfuncs.pfnCvar_DirectSet (m_eptr, const_cast <char *> (val)); } FORCEINLINE void SetString (const char *val) { g_engfuncs.pfnCvar_DirectSet (m_eptr, const_cast <char *> (val)); }
}; };

View file

@ -20,7 +20,6 @@ extern bool g_autoWaypoint;
extern bool g_botsCanPause; extern bool g_botsCanPause;
extern bool g_editNoclip; extern bool g_editNoclip;
extern bool g_isMetamod; extern bool g_isMetamod;
extern bool g_sendAudioFinished;
extern bool g_isCommencing; extern bool g_isCommencing;
extern bool g_leaderChoosen[2]; extern bool g_leaderChoosen[2];

View file

@ -62,7 +62,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc> <UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140_xp</PlatformToolset> <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">

View file

@ -984,7 +984,7 @@ void Bot::InstantChatterMessage (int type)
{ {
// this function sends instant chatter messages. // this function sends instant chatter messages.
if (yb_communication_type.GetInt () != 2 || g_chatterFactory[type].IsEmpty () || (g_gameFlags & GAME_LEGACY) || !g_sendAudioFinished) if (yb_communication_type.GetInt () != 2 || g_chatterFactory[type].IsEmpty () || (g_gameFlags & GAME_LEGACY))
return; return;
if (m_notKilled) if (m_notKilled)
@ -1009,8 +1009,6 @@ void Bot::InstantChatterMessage (int type)
if (!IsValidPlayer (ent) || IsValidBot (ent) || engine.GetTeam (ent) != m_team) if (!IsValidPlayer (ent) || IsValidBot (ent) || engine.GetTeam (ent) != m_team)
continue; continue;
g_sendAudioFinished = false;
MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_SENDAUDIO), NULL, ent); // begin message MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_SENDAUDIO), NULL, ent); // begin message
WRITE_BYTE (GetIndex ()); WRITE_BYTE (GetIndex ());
@ -1021,8 +1019,6 @@ void Bot::InstantChatterMessage (int type)
WRITE_SHORT (m_voicePitch); WRITE_SHORT (m_voicePitch);
MESSAGE_END (); MESSAGE_END ();
g_sendAudioFinished = true;
} }
} }
@ -2511,7 +2507,9 @@ void Bot::CheckRadioCommands (void)
SelectWeaponByName ("weapon_knife"); SelectWeaponByName ("weapon_knife");
DeleteSearchNodes (); DeleteSearchNodes ();
MoveToVector (waypoints.GetBombPosition ());
m_position = waypoints.GetBombPosition ();
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0f, true);
RadioMessage (Radio_Affirmative); RadioMessage (Radio_Affirmative);
} }
@ -2961,40 +2959,6 @@ void Bot::ThinkFrame (void)
engine.IssueBotCommand (GetEntity (), "votemap %d", m_voteMap); engine.IssueBotCommand (GetEntity (), "votemap %d", m_voteMap);
m_voteMap = 0; m_voteMap = 0;
} }
extern ConVar yb_chat;
if (yb_chat.GetBool () && !RepliesToPlayer () && m_lastChatTime + 10.0 < engine.Time () && g_lastChatTime + 5.0f < engine.Time ()) // bot chatting turned on?
{
// say a text every now and then
if (Random.Long (1, 1500) < 2)
{
m_lastChatTime = engine.Time ();
g_lastChatTime = engine.Time ();
char *pickedPhrase = const_cast <char *> (g_chatFactory[CHAT_DEAD].GetRandomElement ().GetBuffer ());
bool sayBufferExists = false;
// search for last messages, sayed
FOR_EACH_AE (m_sayTextBuffer.lastUsedSentences, i)
{
if (strncmp (m_sayTextBuffer.lastUsedSentences[i].GetBuffer (), pickedPhrase, m_sayTextBuffer.lastUsedSentences[i].GetLength ()) == 0)
sayBufferExists = true;
}
if (!sayBufferExists)
{
PrepareChatMessage (pickedPhrase);
PushMessageQueue (GSM_SAY);
// add to ignore list
m_sayTextBuffer.lastUsedSentences.Push (pickedPhrase);
}
// clear the used line buffer every now and then
if (m_sayTextBuffer.lastUsedSentences.GetElementNumber () > Random.Long (4, 6))
m_sayTextBuffer.lastUsedSentences.RemoveAll ();
}
}
} }
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 ())
botMovement = true; botMovement = true;
@ -3007,7 +2971,7 @@ void Bot::ThinkFrame (void)
CheckMessageQueue (); // check for pending messages CheckMessageQueue (); // check for pending messages
// remove voice icon // remove voice icon
if (g_lastRadioTime[g_clients[engine.IndexOfEntity (GetEntity ()) - 1].team2] + Random.Float (0.8f, 2.1f) < engine.Time ()) if (!(g_gameFlags & GAME_LEGACY) && g_lastRadioTime[g_clients[GetIndex () - 1].team2] + Random.Float (0.8f, 2.1f) < engine.Time ())
SwitchChatterIcon (false); // hide icon SwitchChatterIcon (false); // hide icon
if (botMovement) if (botMovement)
@ -3031,6 +2995,41 @@ void Bot::PeriodicThink (void)
CheckSpawnTimeConditions (); CheckSpawnTimeConditions ();
extern ConVar yb_chat;
if (m_notKilled && yb_chat.GetBool () && m_lastChatTime + 10.0 < engine.Time () && g_lastChatTime + 5.0f < engine.Time () && !RepliesToPlayer ()) // bot chatting turned on?
{
// say a text every now and then
if (Random.Long (1, 1500) < 2)
{
m_lastChatTime = engine.Time ();
g_lastChatTime = engine.Time ();
char *pickedPhrase = const_cast <char *> (g_chatFactory[CHAT_DEAD].GetRandomElement ().GetBuffer ());
bool sayBufferExists = false;
// search for last messages, sayed
FOR_EACH_AE (m_sayTextBuffer.lastUsedSentences, i)
{
if (strncmp (m_sayTextBuffer.lastUsedSentences[i].GetBuffer (), pickedPhrase, m_sayTextBuffer.lastUsedSentences[i].GetLength ()) == 0)
sayBufferExists = true;
}
if (!sayBufferExists)
{
PrepareChatMessage (pickedPhrase);
PushMessageQueue (GSM_SAY);
// add to ignore list
m_sayTextBuffer.lastUsedSentences.Push (pickedPhrase);
}
// clear the used line buffer every now and then
if (m_sayTextBuffer.lastUsedSentences.GetElementNumber () > Random.Long (4, 6))
m_sayTextBuffer.lastUsedSentences.RemoveAll ();
}
}
// clear enemy far away // clear enemy far away
if (!m_lastEnemyOrigin.IsZero () && !engine.IsNullEntity (m_lastEnemy) && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0f) if (!m_lastEnemyOrigin.IsZero () && !engine.IsNullEntity (m_lastEnemy) && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0f)
{ {
@ -4374,6 +4373,15 @@ void Bot::RunTask_EscapeFromBomb (void)
if (lastSelectedGoal < 0) if (lastSelectedGoal < 0)
lastSelectedGoal = waypoints.FindFarest (pev->origin, safeRadius); lastSelectedGoal = waypoints.FindFarest (pev->origin, safeRadius);
// still no luck?
if (lastSelectedGoal < 0)
{
TaskComplete (); // we're done
// we have no destination point, so just sit down and camp
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + 10.0f, true);
return;
}
m_prevGoalIndex = lastSelectedGoal; m_prevGoalIndex = lastSelectedGoal;
GetTask ()->data = lastSelectedGoal; GetTask ()->data = lastSelectedGoal;
@ -4984,7 +4992,7 @@ void Bot::DisplayDebugOverlay (void)
{ {
bool displayDebugOverlay = false; bool displayDebugOverlay = false;
if (g_hostEntity->v.iuser2 == engine.IndexOfEntity (GetEntity ())) if (g_hostEntity->v.iuser2 == GetIndex ())
displayDebugOverlay = true; displayDebugOverlay = true;
if (!displayDebugOverlay && yb_debug.GetInt () >= 2) if (!displayDebugOverlay && yb_debug.GetInt () >= 2)
@ -5590,7 +5598,7 @@ void Bot::DebugMsg (const char *format, ...)
bool playMessage = false; bool playMessage = false;
if (level == 3 && !engine.IsNullEntity (g_hostEntity) && g_hostEntity->v.iuser2 == engine.IndexOfEntity (GetEntity ())) if (level == 3 && !engine.IsNullEntity (g_hostEntity) && g_hostEntity->v.iuser2 == GetIndex ())
playMessage = true; playMessage = true;
else if (level != 3) else if (level != 3)
playMessage = true; playMessage = true;
@ -5731,14 +5739,6 @@ Vector Bot::CheckBombAudible (void)
return Vector::GetZero (); return Vector::GetZero ();
} }
void Bot::MoveToVector (const Vector &to)
{
if (to.IsZero ())
return;
FindPath (m_currentWaypointIndex, waypoints.FindNearest (to), SEARCH_PATH_FASTEST);
}
byte Bot::ThrottledMsec (void) byte Bot::ThrottledMsec (void)
{ {
// estimate msec to use for this command based on time passed from the previous command // estimate msec to use for this command based on time passed from the previous command

View file

@ -66,7 +66,7 @@ bool Bot::IsEnemyHiddenByRendering (edict_t *enemy)
{ {
if (v.renderfx == kRenderFxGlowShell) if (v.renderfx == kRenderFxGlowShell)
{ {
if (v.renderamt <= 20.0f && v.rendercolor.x <= 20.0f && v.rendercolor.y <= 20.f && v.rendercolor.z <= 20.f) if (v.renderamt <= 20.0f && v.rendercolor.x <= 20.0f && v.rendercolor.y <= 20.0f && v.rendercolor.z <= 20.0f)
{ {
if (!enemyGunfire || !enemyHasGun) if (!enemyGunfire || !enemyHasGun)
return true; return true;

View file

@ -9,19 +9,11 @@
#include <core.h> #include <core.h>
// forward for super-globals
//NetworkMsg netmsg;
//Localizer locale;
//Waypoint waypoints;
//BotManager bots;
//Engine engine;
bool g_canSayBombPlanted = true; bool g_canSayBombPlanted = true;
bool g_isMetamod = false; bool g_isMetamod = false;
bool g_radioInsteadVoice = false; bool g_radioInsteadVoice = false;
bool g_roundEnded = true; bool g_roundEnded = true;
bool g_botsCanPause = false; bool g_botsCanPause = false;
bool g_sendAudioFinished = true;
bool g_bombPlanted = false; bool g_bombPlanted = false;
bool g_bombSayString = false; bool g_bombSayString = false;
bool g_isCommencing = false; bool g_isCommencing = false;
@ -53,7 +45,6 @@ int g_highestDamageCT = 1;
int g_highestDamageT = 1; int g_highestDamageT = 1;
int g_highestKills = 1; int g_highestKills = 1;
Array <Array <String> > g_chatFactory; Array <Array <String> > g_chatFactory;
Array <Array <ChatterItem> > g_chatterFactory; Array <Array <ChatterItem> > g_chatterFactory;
Array <BotName> g_botNames; Array <BotName> g_botNames;

View file

@ -928,31 +928,7 @@ void GameDLLInit (void)
// server is enabled. Here is a good place to do our own game session initialization, and // server is enabled. Here is a good place to do our own game session initialization, and
// to register by the engine side the server commands we need to administrate our bots. // to register by the engine side the server commands we need to administrate our bots.
DetectCSVersion ();
{
// print game detection info
String gameVersionStr;
if (g_gameFlags & GAME_LEGACY)
gameVersionStr.Assign ("Legacy");
else if (g_gameFlags & GAME_CZERO)
gameVersionStr.Assign ("Condition Zero");
else if (g_gameFlags & GAME_CSTRIKE16)
gameVersionStr.Assign ("v1.6");
if (g_gameFlags & GAME_XASH)
{
gameVersionStr.Append (" @ Xash3D Engine");
if (g_gameFlags & GAME_MOBILITY)
gameVersionStr.Append (" Mobile");
gameVersionStr.Replace ("Legacy", "1.6 Limited");
}
engine.Printf ("YaPB Bot has detect game version as Counter-Strike: %s", gameVersionStr.GetBuffer ());
}
// register server command(s) // register server command(s)
engine.RegisterCmd ("yapb", CommandHandler); engine.RegisterCmd ("yapb", CommandHandler);
@ -1103,7 +1079,7 @@ void UpdateClientData (const struct edict_s *ent, int sendweapons, struct client
{ {
extern ConVar yb_latency_display; extern ConVar yb_latency_display;
if (yb_latency_display.GetInt () == 2) if (!(g_gameFlags & GAME_LEGACY) && yb_latency_display.GetInt () == 2)
bots.SendPingDataOffsets (const_cast <edict_t *> (ent)); bots.SendPingDataOffsets (const_cast <edict_t *> (ent));
if (g_isMetamod) if (g_isMetamod)
@ -2452,7 +2428,6 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed
// is this message for a bot? // is this message for a bot?
if (index != -1 && !(ed->v.flags & FL_DORMANT)) if (index != -1 && !(ed->v.flags & FL_DORMANT))
{ {
engine.ResetMessageCapture ();
engine.SetOngoingMessageReceiver (index); engine.SetOngoingMessageReceiver (index);
// message handling is done in usermsg.cpp // message handling is done in usermsg.cpp
@ -2471,8 +2446,6 @@ void pfnMessageBegin (int msgDest, int msgType, const float *origin, edict_t *ed
} }
else if (msgDest == MSG_ALL) else if (msgDest == MSG_ALL)
{ {
engine.ResetMessageCapture ();
engine.TryCaptureMessage (msgType, NETMSG_SCOREINFO); engine.TryCaptureMessage (msgType, NETMSG_SCOREINFO);
engine.TryCaptureMessage (msgType, NETMSG_DEATH); engine.TryCaptureMessage (msgType, NETMSG_DEATH);
engine.TryCaptureMessage (msgType, NETMSG_TEXTMSG); engine.TryCaptureMessage (msgType, NETMSG_TEXTMSG);
@ -2786,8 +2759,10 @@ void pfnAlertMessage (ALERT_TYPE alertType, char *format, ...)
if (bot != NULL && bot->m_team == TERRORIST && bot->m_notKilled) if (bot != NULL && bot->m_team == TERRORIST && bot->m_notKilled)
{ {
bot->ResetTasks (); bot->DeleteSearchNodes ();
bot->MoveToVector (waypoints.GetBombPosition ());
bot->m_position = waypoints.GetBombPosition ();
bot->PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0f, true);
} }
} }
} }
@ -2982,6 +2957,84 @@ SHARED_LIBRARAY_EXPORT void Meta_Init (void)
g_isMetamod = true; g_isMetamod = true;
} }
Library *LoadCSBinary (void)
{
const char *modname = engine.GetModName ();
if (!modname)
return NULL;
#if defined (PLATFORM_WIN32)
const char *libs[] = { "mp.dll", "cs.dll" };
#elif defined (PLATFORM_LINUX)
const char *libs[] = { "cs.so", "cs_i386.so" };
#elif defined (PLATFORM_OSX)
const char *libs[] = { "cs.dylib" };
#endif
// search the libraries inside game dlls directory
for (int i = 0; i < ARRAYSIZE_HLSDK (libs); i++)
{
char path[256];
sprintf (path, "%s/dlls/%s", modname, libs[i]);
// if we can't read file, skip it
if (!File::Accessible (path))
continue;
// special case, czero is always detected first, as it's has custom directory
if (strcmp (modname, "czero") == 0)
{
g_gameFlags |= GAME_CZERO;
if (g_isMetamod)
return NULL;
return new Library (path);
}
else
{
Library *game = new Library (path);
// try to load gamedll
if (!game->IsLoaded ())
{
AddLogEntry (true, LL_FATAL | LL_IGNORE, "Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", libs[i], modname);
return NULL;
}
// detect xash engine
if (g_engfuncs.pfnCVarGetPointer ("build") != NULL)
{
g_gameFlags |= (GAME_LEGACY | GAME_XASH);
if (g_isMetamod)
{
delete game;
return NULL;
}
return game;
}
// detect if we're running modern game
EntityPtr_t entity = game->GetFuncAddr <EntityPtr_t> ("weapon_famas");
if (entity != NULL)
g_gameFlags |= GAME_CSTRIKE16;
else
g_gameFlags |= GAME_LEGACY;
if (g_isMetamod)
{
delete game;
return NULL;
}
return game;
}
}
return NULL;
}
DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t *pGlobals) DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t *pGlobals)
{ {
// this is the very first function that is called in the game DLL by the engine. Its purpose // this is the very first function that is called in the game DLL by the engine. Its purpose
@ -3031,71 +3084,40 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *functionTable, globalvars_t
if (!g_gameLib->IsLoaded ()) if (!g_gameLib->IsLoaded ())
AddLogEntry (true, LL_FATAL | LL_IGNORE, "Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", gameDLLName, engine.GetModName ()); AddLogEntry (true, LL_FATAL | LL_IGNORE, "Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", gameDLLName, engine.GetModName ());
#else #else
static struct ModSupport g_gameLib = LoadCSBinary ();
{ {
char name[10]; if (g_gameLib == NULL && !g_isMetamod)
char linuxLib[12];
char osxLib[9];
char winLib[8];
char desc[39];
int modType;
} s_supportedMods[] =
{
{ "cstrike", "cs_i386.so", "cs.dylib", "mp.dll", "Counter-Strike v1.6", GAME_CSTRIKE16 },
{ "cstrike", "cs.so", "cs.dylib", "mp.dll", "Counter-Strike v1.6 (Newer)", GAME_CSTRIKE16 },
{ "czero", "cs_i386.so", "cs.dylib", "mp.dll", "Counter-Strike: Condition Zero", GAME_CZERO },
{ "czero", "cs.so", "cs.dylib", "mp.dll", "Counter-Strike: Condition Zero (Newer)", GAME_CZERO },
{ "csv15", "cs_i386.so", "cs.dylib", "mp.dll", "CS 1.5 for Steam", GAME_LEGACY },
{ "csdm", "cs_i386.so", "cs.dylib", "mp.dll", "CSDM for Windows", GAME_LEGACY },
{ "cs13", "cs_i386.so", "cs.dylib", "mp.dll", "Counter-Strike v1.3", GAME_LEGACY }, // assume cs13 = cs15
};
ModSupport *knownMod = NULL;
for (int i = 0; i < ARRAYSIZE_HLSDK (s_supportedMods); i++)
{
ModSupport *mod = &s_supportedMods[i];
if (strcmp (mod->name, engine.GetModName ()) == 0 && File::Accessible (FormatBuffer ("%s/dlls/%s", mod->name,
#if defined (PLATFORM_WIN32)
mod->winLib
#elif defined (PLATFORM_LINUX)
mod->linuxLib
#elif defined (PLATFORM_OSX)
mod->osxLib
#endif
)))
{ {
knownMod = mod; AddLogEntry (true, LL_FATAL | LL_IGNORE, "Mod that you has started, not supported by this bot (gamedir: %s)", engine.GetModName ());
break; return;
} }
}
if (knownMod != NULL) // print game detection info
{ String gameVersionStr;
g_gameFlags |= knownMod->modType;
if (g_gameFlags & GAME_LEGACY)
gameVersionStr.Assign ("Legacy");
else if (g_gameFlags & GAME_CZERO)
gameVersionStr.Assign ("Condition Zero");
else if (g_gameFlags & GAME_CSTRIKE16)
gameVersionStr.Assign ("v1.6");
if (g_gameFlags & GAME_XASH)
{
gameVersionStr.Append (" @ Xash3D Engine");
if (g_gameFlags & GAME_MOBILITY)
gameVersionStr.Append (" Mobile");
gameVersionStr.Replace ("Legacy", "1.6 Limited");
}
engine.Printf ("YaPB Bot has detect game version as Counter-Strike: %s", gameVersionStr.GetBuffer ());
if (g_isMetamod) if (g_isMetamod)
return; // we should stop the attempt for loading the real gamedll, since metamod handle this for us return;
char gameDLLName[256];
sprintf (gameDLLName, "%s/dlls/%s", knownMod->name,
#if defined (PLATFORM_WIN32)
knownMod->winLib
#elif defined (PLATFORM_LINUX)
knownMod->linuxLib
#elif defined (PLATFORM_OSX)
knownMod->osxLib
#endif
);
g_gameLib = new Library (gameDLLName);
if (!g_gameLib->IsLoaded ())
AddLogEntry (true, LL_FATAL | LL_IGNORE, "Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", gameDLLName, engine.GetModName ());
} }
else
AddLogEntry (true, LL_FATAL | LL_IGNORE, "Mod that you has started, not supported by this bot (gamedir: %s)", engine.GetModName ());
#endif #endif
g_funcPointers = g_gameLib->GetFuncAddr <FuncPointers_t> ("GiveFnptrsToDll"); g_funcPointers = g_gameLib->GetFuncAddr <FuncPointers_t> ("GiveFnptrsToDll");

View file

@ -10,7 +10,7 @@
#include <core.h> #include <core.h>
ConVar yb_autovacate ("yb_autovacate", "0"); ConVar yb_autovacate ("yb_autovacate", "0");
ConVar yb_autovacate_smart_kick ("yb_autovacate_smart_kick", "1"); ConVar yb_autovacate_smart_kick ("yb_autovacate_smart_kick", "0");
ConVar yb_quota ("yb_quota", "0", VT_NORMAL); ConVar yb_quota ("yb_quota", "0", VT_NORMAL);
ConVar yb_quota_mode ("yb_quota_mode", "normal"); ConVar yb_quota_mode ("yb_quota_mode", "normal");
@ -108,12 +108,11 @@ void BotManager::CallGameEntity (entvars_t *vars)
player (vars); player (vars);
} }
int BotManager::CreateBot (const String &name, int difficulty, int personality, int team, int member) int BotManager::CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd)
{ {
// this function completely prepares bot entity (edict) for creation, creates team, difficulty, sets name etc, and // this function completely prepares bot entity (edict) for creation, creates team, difficulty, sets name etc, and
// then sends result to bot constructor // then sends result to bot constructor
edict_t *bot = NULL; edict_t *bot = NULL;
char outputName[33]; char outputName[33];
@ -195,8 +194,9 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality,
if (!IsNullString (prefixedName)) if (!IsNullString (prefixedName))
strcpy (outputName, prefixedName); strcpy (outputName, prefixedName);
} }
bot = g_engfuncs.pfnCreateFakeClient (outputName);
if (engine.IsNullEntity ((bot = (*g_engfuncs.pfnCreateFakeClient) (outputName)))) if (engine.IsNullEntity (bot))
{ {
engine.CenterPrintf ("Maximum players reached (%d/%d). Unable to create Bot.", engine.MaxClients (), engine.MaxClients ()); engine.CenterPrintf ("Maximum players reached (%d/%d). Unable to create Bot.", engine.MaxClients (), engine.MaxClients ());
return 2; return 2;
@ -213,6 +213,9 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality,
engine.Printf ("Connecting Bot..."); engine.Printf ("Connecting Bot...");
if (isConsoleCmd)
yb_quota.SetInt (yb_quota.GetInt () + 1);
return 1; return 1;
} }
@ -296,7 +299,7 @@ void BotManager::PeriodicThink (void)
} }
} }
void BotManager::AddBot (const String &name, int difficulty, int personality, int team, int member) void BotManager::AddBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd)
{ {
// this function putting bot creation process to queue to prevent engine crashes // this function putting bot creation process to queue to prevent engine crashes
@ -308,12 +311,13 @@ void BotManager::AddBot (const String &name, int difficulty, int personality, in
bot.personality = personality; bot.personality = personality;
bot.team = team; bot.team = team;
bot.member = member; bot.member = member;
bot.console = isConsoleCmd;
// put to queue // put to queue
m_creationTab.Push (bot); m_creationTab.Push (bot);
} }
void BotManager::AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member) void BotManager::AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member, bool isConsoleCmd)
{ {
// this function is same as the function above, but accept as parameters string instead of integers // this function is same as the function above, but accept as parameters string instead of integers
@ -325,6 +329,7 @@ void BotManager::AddBot (const String &name, const String &difficulty, const Str
bot.team = (team.IsEmpty () || team == any) ? -1 : team.ToInt (); bot.team = (team.IsEmpty () || team == any) ? -1 : team.ToInt ();
bot.member = (member.IsEmpty () || member == any) ? -1 : member.ToInt (); bot.member = (member.IsEmpty () || member == any) ? -1 : member.ToInt ();
bot.personality = (personality.IsEmpty () || personality == any) ? -1 : personality.ToInt (); bot.personality = (personality.IsEmpty () || personality == any) ? -1 : personality.ToInt ();
bot.console = isConsoleCmd;
m_creationTab.Push (bot); m_creationTab.Push (bot);
} }
@ -380,20 +385,20 @@ void BotManager::VerifyPlayersHasJoinedTeam (int &desiredCount)
{ {
Client &cl = g_clients[i]; Client &cl = g_clients[i];
if ((cl.flags & CF_USED) && cl.team != SPECTATOR && !IsValidBot (cl.ent)) if (!(cl.flags & CF_USED) || cl.team == SPECTATOR || IsValidBot (cl.ent))
continue;
FOR_EACH_AE (m_trackedPlayers, it)
{ {
FOR_EACH_AE (m_trackedPlayers, it) if (cl.ent != m_trackedPlayers[it])
{ continue;
if (cl.ent != m_trackedPlayers[it])
continue;
m_balanceCount--; m_balanceCount--;
desiredCount--; desiredCount--;
m_trackedPlayers.RemoveAt (it); m_trackedPlayers.RemoveAt (it);
break; break;
}
} }
} }
} }
@ -410,7 +415,7 @@ void BotManager::MaintainBotQuota (void)
if (!m_creationTab.IsEmpty () && m_maintainTime < engine.Time ()) if (!m_creationTab.IsEmpty () && m_maintainTime < engine.Time ())
{ {
CreateQueue last = m_creationTab.Pop (); CreateQueue last = m_creationTab.Pop ();
int resultOfCall = CreateBot (last.name, last.difficulty, last.personality, last.team, last.member); int resultOfCall = CreateBot (last.name, last.difficulty, last.personality, last.team, last.member, last.console);
// check the result of creation // check the result of creation
if (resultOfCall == 0) if (resultOfCall == 0)
@ -429,15 +434,20 @@ void BotManager::MaintainBotQuota (void)
// now keep bot number up to date // now keep bot number up to date
if (m_quotaMaintainTime < engine.Time ()) if (m_quotaMaintainTime < engine.Time ())
{ {
// don't allow that quota is below zero // keep the quota number in valid ranges
if (yb_quota.GetInt () < 0) {
yb_quota.SetInt (0); if (yb_quota.GetInt () < 0)
yb_quota.SetInt (0);
if (yb_quota.GetInt () > engine.MaxClients ())
yb_quota.SetInt (engine.MaxClients ());
}
int numBots = GetBotsNum (); int numBots = GetBotsNum ();
int numHumans = GetHumansJoinedTeam (); int numHumans = yb_autovacate_smart_kick.GetBool () ? GetHumansNum () : GetHumansJoinedTeam ();
int desiredCount = yb_quota.GetInt (); int desiredCount = yb_quota.GetInt ();
if (yb_join_after_player.GetInt () > 0 && !numHumans) if (yb_join_after_player.GetBool () && !numHumans)
desiredCount = 0; desiredCount = 0;
// quota mode // quota mode
@ -448,20 +458,17 @@ void BotManager::MaintainBotQuota (void)
else if (mode == 'm') // match else if (mode == 'm') // match
desiredCount = max (0, yb_quota.GetInt () * numHumans); desiredCount = max (0, yb_quota.GetInt () * numHumans);
if (yb_autovacate.GetBool ()) desiredCount = min (desiredCount, engine.MaxClients () - (numHumans + (yb_autovacate.GetBool () ? 1 : 0)));
desiredCount = min (desiredCount, engine.MaxClients () - (numHumans + 1));
else
desiredCount = min (desiredCount, engine.MaxClients () - numHumans);
if (yb_autovacate_smart_kick.GetBool () && numBots > 1 && desiredCount > 1) if (yb_autovacate_smart_kick.GetBool () && numBots > 1 && desiredCount > 1)
VerifyPlayersHasJoinedTeam (desiredCount); VerifyPlayersHasJoinedTeam (desiredCount);
if (desiredCount > numBots) if (desiredCount > numBots)
AddRandom (); AddRandom (false);
else if (desiredCount < numBots) else if (desiredCount < numBots)
RemoveRandom (); RemoveRandom (true);
m_quotaMaintainTime = engine.Time () + 0.90f; m_quotaMaintainTime = engine.Time () + 0.40f;
} }
} }
@ -506,30 +513,17 @@ void BotManager::FillServer (int selection, int personality, int difficulty, int
for (int i = 0; i <= toAdd; i++) for (int i = 0; i <= toAdd; i++)
AddBot ("", difficulty, personality, selection, -1); AddBot ("", difficulty, personality, selection, -1);
yb_quota.SetInt (toAdd);
engine.CenterPrintf ("Fill Server with %s bots...", &teamDesc[selection][0]); engine.CenterPrintf ("Fill Server with %s bots...", &teamDesc[selection][0]);
} }
void BotManager::RemoveAll (bool zeroQuota) void BotManager::RemoveAll (void)
{ {
// this function drops all bot clients from server (this function removes only yapb's)`q // this function drops all bot clients from server (this function removes only yapb's)`q
if (zeroQuota) engine.CenterPrintf ("Bots are removed from server.");
engine.CenterPrintf ("Bots are removed from server.");
for (int i = 0; i < engine.MaxClients (); i++)
{
if (m_bots[i] != NULL) // is this slot used?
m_bots[i]->Kick ();
}
m_creationTab.RemoveAll (); m_creationTab.RemoveAll ();
yb_quota.SetInt (0);
// reset cvars
if (zeroQuota)
{
yb_quota.SetInt (0);
yb_autovacate.SetInt (0);
}
} }
void BotManager::RemoveFromTeam (Team team, bool removeAll) void BotManager::RemoveFromTeam (Team team, bool removeAll)
@ -625,19 +619,18 @@ void BotManager::KillAll (int team)
engine.CenterPrintf ("All Bots died !"); engine.CenterPrintf ("All Bots died !");
} }
void BotManager::RemoveRandom (void) void BotManager::RemoveRandom (bool keepQuota)
{ {
// this function removes random bot from server (only yapb's) // this function removes random bot from server (only yapb's)
bool deadBotFound = false; bool deadBotFound = false;
// first try to kick the bot that is currently dead // first try to kick the bot that is currently dead
for (int i = 0; i < engine.MaxClients (); i++) for (int i = 0; i < engine.MaxClients (); i++)
{ {
if (m_bots[i] != NULL && !m_bots[i]->m_notKilled) // is this slot used? if (m_bots[i] != NULL && !m_bots[i]->m_notKilled) // is this slot used?
{ {
m_bots[i]->Kick (); m_bots[i]->Kick (keepQuota);
deadBotFound = true; deadBotFound = true;
break; break;
@ -666,7 +659,7 @@ void BotManager::RemoveRandom (void)
// if found some bots // if found some bots
if (index != 0) if (index != 0)
{ {
m_bots[index]->Kick (); m_bots[index]->Kick (keepQuota);
return; return;
} }
@ -675,7 +668,7 @@ void BotManager::RemoveRandom (void)
{ {
if (m_bots[i] != NULL) // is this slot used? if (m_bots[i] != NULL) // is this slot used?
{ {
m_bots[i]->Kick (); m_bots[i]->Kick (keepQuota);
break; break;
} }
} }
@ -887,6 +880,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c
engine.IssueCmd ("kick \"%s\"", STRING (bot->v.netname)); // kick the bot player if the server refused it engine.IssueCmd ("kick \"%s\"", STRING (bot->v.netname)); // kick the bot player if the server refused it
bot->v.flags |= FL_KILLME; bot->v.flags |= FL_KILLME;
return;
} }
MDLL_ClientPutInServer (bot); MDLL_ClientPutInServer (bot);
@ -957,12 +951,6 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member, c
m_wantedTeam = team; m_wantedTeam = team;
m_wantedClass = member; m_wantedClass = member;
int newBotsNum = bots.GetBotsNum () + 1;
// keep quota number up to date
if (newBotsNum < engine.MaxClients () && newBotsNum > yb_quota.GetInt ())
yb_quota.SetInt (newBotsNum);
NewRound (); NewRound ();
} }
@ -1246,12 +1234,7 @@ void Bot::NewRound (void)
if (Random.Long (0, 100) < 50) if (Random.Long (0, 100) < 50)
ChatterMessage (Chatter_NewRound); ChatterMessage (Chatter_NewRound);
const float interval = (1.0f / 30.0f) * Random.Float (0.95f, 1.05f); m_thinkInterval = (g_gameFlags & GAME_LEGACY) ? 0.0f : (1.0f / 30.0f) * Random.Float (0.95f, 1.05f);
if (g_gameFlags & GAME_LEGACY)
m_thinkInterval = 0.0f;
else
m_thinkInterval = interval;
} }
void Bot::Kill (void) void Bot::Kill (void)
@ -1262,18 +1245,16 @@ void Bot::Kill (void)
bots.TouchWithKillerEntity (this); bots.TouchWithKillerEntity (this);
} }
void Bot::Kick (void) void Bot::Kick (bool keepQuota)
{ {
// this function kick off one bot from the server. // this function kick off one bot from the server.
engine.IssueCmd ("kick \"%s\"", STRING (pev->netname)); engine.IssueCmd ("kick \"%s\"", STRING (pev->netname));
engine.CenterPrintf ("Bot '%s' kicked", STRING (pev->netname)); engine.CenterPrintf ("Bot '%s' kicked", STRING (pev->netname));
int newBotsNum = bots.GetBotsNum () - 1;
// keep quota number up to date // keep quota number up to date
if (newBotsNum < engine.MaxClients () && newBotsNum < yb_quota.GetInt ()) if (!keepQuota)
yb_quota.SetInt (newBotsNum); yb_quota.SetInt (Clamp <int> (yb_quota.GetInt () - 1, 0, yb_quota.GetInt ()));
} }
void Bot::StartGame (void) void Bot::StartGame (void)

View file

@ -1264,6 +1264,18 @@ void Bot::FindShortestPath (int srcIndex, int destIndex)
{ {
// this function finds the shortest path from source index to destination index // this function finds the shortest path from source index to destination index
if (srcIndex > g_numWaypoints - 1 || srcIndex < 0)
{
AddLogEntry (true, LL_ERROR, "Pathfinder source path index not valid (%d)", srcIndex);
return;
}
if (destIndex > g_numWaypoints - 1 || destIndex < 0)
{
AddLogEntry (true, LL_ERROR, "Pathfinder destination path index not valid (%d)", destIndex);
return;
}
DeleteSearchNodes (); DeleteSearchNodes ();
m_chosenGoalIndex = srcIndex; m_chosenGoalIndex = srcIndex;

View file

@ -569,30 +569,6 @@ void CheckWelcomeMessage (void)
} }
} }
void DetectCSVersion (void)
{
if (g_gameFlags & GAME_CZERO)
return;
// detect xash engine
if (g_engfuncs.pfnCVarGetPointer ("build") != NULL)
{
g_gameFlags |= (GAME_LEGACY | GAME_XASH);
return;
}
// counter-strike 1.6 or higher (plus detects for non-steam versions of 1.5)
byte *detection = g_engfuncs.pfnLoadFileForMe ("events/galil.sc", NULL);
if (detection != NULL)
g_gameFlags |= GAME_CSTRIKE16; // just to be sure
else if (detection == NULL)
g_gameFlags |= GAME_LEGACY; // reset it to WON
// if we have loaded the file free it
if (detection != NULL)
g_engfuncs.pfnFreeFile (detection);
}
void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...) void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...)
{ {