Merge pull request #40 from jeefo/develop
This commit is contained in:
commit
66484293d5
9 changed files with 103 additions and 80 deletions
|
|
@ -1313,7 +1313,7 @@ public:
|
||||||
int GetIndex (edict_t *ent);
|
int GetIndex (edict_t *ent);
|
||||||
Bot *GetBot (int index);
|
Bot *GetBot (int index);
|
||||||
Bot *GetBot (edict_t *ent);
|
Bot *GetBot (edict_t *ent);
|
||||||
Bot *FindOneValidAliveBot (void);
|
Bot *GetAliveBot (void);
|
||||||
Bot *GetHighestFragsBot (int team);
|
Bot *GetHighestFragsBot (int team);
|
||||||
|
|
||||||
int GetHumansNum (void);
|
int GetHumansNum (void);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_SSE_INTRINSICS
|
#ifdef ENABLE_SSE_INTRINSICS
|
||||||
#include <xmmintrin.h>
|
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -150,22 +149,23 @@ namespace Math
|
||||||
const float MATH_R2D = 180.0f / MATH_PI;
|
const float MATH_R2D = 180.0f / MATH_PI;
|
||||||
|
|
||||||
#ifdef ENABLE_SSE_INTRINSICS
|
#ifdef ENABLE_SSE_INTRINSICS
|
||||||
|
|
||||||
//
|
//
|
||||||
// Function: mm_abs
|
// Function: sse_abs
|
||||||
//
|
//
|
||||||
// mm version if abs
|
// mm version if abs
|
||||||
//
|
//
|
||||||
static inline __m128 mm_abs (__m128 val)
|
static inline __m128 sse_abs (__m128 val)
|
||||||
{
|
{
|
||||||
return _mm_andnot_ps (_mm_castsi128_ps (_mm_set1_epi32 (0x80000000)), val);
|
return _mm_andnot_ps (_mm_castsi128_ps (_mm_set1_epi32 (0x80000000)), val);
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Function: mm_sine
|
// Function: sse_sine
|
||||||
//
|
//
|
||||||
// mm version if sine
|
// mm version if sine
|
||||||
//
|
//
|
||||||
static inline __m128 mm_sine (__m128 inp)
|
static inline __m128 sse_sine (__m128 inp)
|
||||||
{
|
{
|
||||||
__m128 pi2 = _mm_set1_ps (MATH_PI * 2);
|
__m128 pi2 = _mm_set1_ps (MATH_PI * 2);
|
||||||
__m128 val = _mm_cmpnlt_ps (inp, _mm_set1_ps (MATH_PI));
|
__m128 val = _mm_cmpnlt_ps (inp, _mm_set1_ps (MATH_PI));
|
||||||
|
|
@ -175,12 +175,12 @@ namespace Math
|
||||||
val = _mm_cmpngt_ps (inp, _mm_set1_ps (-MATH_PI));
|
val = _mm_cmpngt_ps (inp, _mm_set1_ps (-MATH_PI));
|
||||||
val = _mm_and_ps (val, pi2);
|
val = _mm_and_ps (val, pi2);
|
||||||
inp = _mm_add_ps (inp, val);
|
inp = _mm_add_ps (inp, val);
|
||||||
val = _mm_mul_ps (mm_abs (inp), _mm_set1_ps (-4.0f / (MATH_PI * MATH_PI)));
|
val = _mm_mul_ps (sse_abs (inp), _mm_set1_ps (-4.0f / (MATH_PI * MATH_PI)));
|
||||||
val = _mm_add_ps (val, _mm_set1_ps (4.0f / MATH_PI));
|
val = _mm_add_ps (val, _mm_set1_ps (4.0f / MATH_PI));
|
||||||
|
|
||||||
__m128 res = _mm_mul_ps (val, inp);
|
__m128 res = _mm_mul_ps (val, inp);
|
||||||
|
|
||||||
val = _mm_mul_ps (mm_abs (res), res);
|
val = _mm_mul_ps (sse_abs (res), res);
|
||||||
val = _mm_sub_ps (val, res);
|
val = _mm_sub_ps (val, res);
|
||||||
val = _mm_mul_ps (val, _mm_set1_ps (0.225f));
|
val = _mm_mul_ps (val, _mm_set1_ps (0.225f));
|
||||||
res = _mm_add_ps (val, res);
|
res = _mm_add_ps (val, res);
|
||||||
|
|
@ -196,7 +196,7 @@ namespace Math
|
||||||
static inline float A_sqrtf (float value)
|
static inline float A_sqrtf (float value)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SSE_INTRINSICS
|
#ifdef ENABLE_SSE_INTRINSICS
|
||||||
return _mm_cvtss_f32 (_mm_sqrt_ss (_mm_load_ss (&value)));
|
return _mm_cvtss_f32 (_mm_sqrt_ss (_mm_set1_ps (value)));
|
||||||
#else
|
#else
|
||||||
return sqrtf (value);
|
return sqrtf (value);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -210,7 +210,7 @@ namespace Math
|
||||||
static inline float A_sinf (float value)
|
static inline float A_sinf (float value)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SSE_INTRINSICS
|
#ifdef ENABLE_SSE_INTRINSICS
|
||||||
return _mm_cvtss_f32 (mm_sine (_mm_set1_ps (value)));
|
return _mm_cvtss_f32 (sse_sine (_mm_set1_ps (value)));
|
||||||
#else
|
#else
|
||||||
return sinf (value);
|
return sinf (value);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -224,7 +224,7 @@ namespace Math
|
||||||
static inline float A_cosf (float value)
|
static inline float A_cosf (float value)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SSE_INTRINSICS
|
#ifdef ENABLE_SSE_INTRINSICS
|
||||||
return _mm_cvtss_f32 (mm_sine (_mm_set1_ps (value + MATH_PI / 2.0f)));
|
return _mm_cvtss_f32 (sse_sine (_mm_set1_ps (value + MATH_PI / 2.0f)));
|
||||||
#else
|
#else
|
||||||
return cosf (value);
|
return cosf (value);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -238,7 +238,7 @@ namespace Math
|
||||||
static inline void A_sincosf (float rad, float *sine, float *cosine)
|
static inline void A_sincosf (float rad, float *sine, float *cosine)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SSE_INTRINSICS
|
#ifdef ENABLE_SSE_INTRINSICS
|
||||||
__m128 m_sincos = mm_sine (_mm_set_ps (0.0f, 0.0f, rad + MATH_PI / 2.f, rad));
|
__m128 m_sincos = sse_sine (_mm_set_ps (0.0f, 0.0f, rad + MATH_PI / 2.f, rad));
|
||||||
__m128 m_cos = _mm_shuffle_ps (m_sincos, m_sincos, _MM_SHUFFLE (0, 0, 0, 1));
|
__m128 m_cos = _mm_shuffle_ps (m_sincos, m_sincos, _MM_SHUFFLE (0, 0, 0, 1));
|
||||||
|
|
||||||
*sine = _mm_cvtss_f32 (m_sincos);
|
*sine = _mm_cvtss_f32 (m_sincos);
|
||||||
|
|
|
||||||
|
|
@ -3025,7 +3025,7 @@ void Bot::RunTask_Normal (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bots rushing with knife, when have no enemy (thanks for idea to nicebot project)
|
// bots rushing with knife, when have no enemy (thanks for idea to nicebot project)
|
||||||
if (m_currentWeapon == WEAPON_KNIFE && (engine.IsNullEntity (m_lastEnemy) || !IsAlive (m_lastEnemy)) && engine.IsNullEntity (m_enemy) && m_knifeAttackTime < engine.Time () && !HasShield () && GetNearbyFriendsNearPosition (pev->origin, 96) == 0)
|
if (m_currentWeapon == WEAPON_KNIFE && (engine.IsNullEntity (m_lastEnemy) || !IsAlive (m_lastEnemy)) && engine.IsNullEntity (m_enemy) && m_knifeAttackTime < engine.Time () && !HasShield () && GetNearbyFriendsNearPosition (pev->origin, 96.0f) == 0)
|
||||||
{
|
{
|
||||||
if (Random.Int (0, 100) < 40)
|
if (Random.Int (0, 100) < 40)
|
||||||
pev->button |= IN_ATTACK;
|
pev->button |= IN_ATTACK;
|
||||||
|
|
@ -3137,14 +3137,17 @@ void Bot::RunTask_Normal (void)
|
||||||
m_hostages[i] = nullptr; // clear array of hostage pointers
|
m_hostages[i] = nullptr; // clear array of hostage pointers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_team == TERRORIST && Random.Int (0, 100) < 80)
|
else if (m_team == TERRORIST && Random.Int (0, 100) < 75)
|
||||||
{
|
{
|
||||||
int index = FindDefendWaypoint (m_currentPath->origin);
|
int index = FindDefendWaypoint (m_currentPath->origin);
|
||||||
|
|
||||||
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (60.0f, 120.0f), true); // push camp task on to stack
|
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (60.0f, 120.0f), true); // push camp task on to stack
|
||||||
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (5.0f, 10.0f), true); // push move command
|
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (5.0f, 10.0f), true); // push move command
|
||||||
|
|
||||||
if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand)
|
auto path = waypoints.GetPath (index);
|
||||||
|
|
||||||
|
// decide to duck or not to duck
|
||||||
|
if (path->vis.crouch <= path->vis.stand)
|
||||||
m_campButtons |= IN_DUCK;
|
m_campButtons |= IN_DUCK;
|
||||||
else
|
else
|
||||||
m_campButtons &= ~IN_DUCK;
|
m_campButtons &= ~IN_DUCK;
|
||||||
|
|
@ -3183,7 +3186,10 @@ void Bot::RunTask_Normal (void)
|
||||||
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + campTime, true); // push camp task on to stack
|
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + campTime, true); // push camp task on to stack
|
||||||
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (5.0f, 11.0f), true); // push move command
|
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (5.0f, 11.0f), true); // push move command
|
||||||
|
|
||||||
if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand)
|
auto path = waypoints.GetPath (index);
|
||||||
|
|
||||||
|
// decide to duck or not to duck
|
||||||
|
if (path->vis.crouch <= path->vis.stand)
|
||||||
m_campButtons |= IN_DUCK;
|
m_campButtons |= IN_DUCK;
|
||||||
else
|
else
|
||||||
m_campButtons &= ~IN_DUCK;
|
m_campButtons &= ~IN_DUCK;
|
||||||
|
|
@ -3211,7 +3217,7 @@ void Bot::RunTask_Normal (void)
|
||||||
|
|
||||||
// do pathfinding if it's not the current waypoint
|
// do pathfinding if it's not the current waypoint
|
||||||
if (destIndex != m_currentWaypointIndex)
|
if (destIndex != m_currentWaypointIndex)
|
||||||
FindPath (m_currentWaypointIndex, destIndex, ((g_bombPlanted && m_team == CT) || yb_debug_goal.GetInt () != -1) ? SEARCH_PATH_FASTEST : m_pathType);
|
FindPath (m_currentWaypointIndex, destIndex, m_pathType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -5867,14 +5873,6 @@ bool Bot::OutOfBombTimer (void)
|
||||||
void Bot::ReactOnSound (void)
|
void Bot::ReactOnSound (void)
|
||||||
{
|
{
|
||||||
int hearEnemyIndex = -1;
|
int hearEnemyIndex = -1;
|
||||||
|
|
||||||
Vector pasOrg = EyePosition ();
|
|
||||||
|
|
||||||
if (pev->flags & FL_DUCKING)
|
|
||||||
pasOrg = pasOrg + (VEC_HULL_MIN - VEC_DUCK_HULL_MIN);
|
|
||||||
|
|
||||||
uint8 *pas = ENGINE_SET_PAS (reinterpret_cast <float *> (&pasOrg));
|
|
||||||
|
|
||||||
float minDistance = 99999.0f;
|
float minDistance = 99999.0f;
|
||||||
|
|
||||||
// loop through all enemy clients to check for hearable stuff
|
// loop through all enemy clients to check for hearable stuff
|
||||||
|
|
@ -5890,9 +5888,6 @@ void Bot::ReactOnSound (void)
|
||||||
if (distance > client.hearingDistance)
|
if (distance > client.hearingDistance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!ENGINE_CHECK_VISIBILITY (client.ent, pas))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (distance < minDistance)
|
if (distance < minDistance)
|
||||||
{
|
{
|
||||||
hearEnemyIndex = i;
|
hearEnemyIndex = i;
|
||||||
|
|
|
||||||
|
|
@ -238,14 +238,6 @@ bool Bot::LookupEnemy (void)
|
||||||
// ignore shielded enemies, while we have real one
|
// ignore shielded enemies, while we have real one
|
||||||
edict_t *shieldEnemy = nullptr;
|
edict_t *shieldEnemy = nullptr;
|
||||||
|
|
||||||
// setup potentially visible set for this bot
|
|
||||||
Vector potentialVisibility = EyePosition ();
|
|
||||||
|
|
||||||
if (pev->flags & FL_DUCKING)
|
|
||||||
potentialVisibility = potentialVisibility + (VEC_HULL_MIN - VEC_DUCK_HULL_MIN);
|
|
||||||
|
|
||||||
uint8 *pvs = ENGINE_SET_PVS (reinterpret_cast <float *> (&potentialVisibility));
|
|
||||||
|
|
||||||
// search the world for players...
|
// search the world for players...
|
||||||
for (int i = 0; i < engine.MaxClients (); i++)
|
for (int i = 0; i < engine.MaxClients (); i++)
|
||||||
{
|
{
|
||||||
|
|
@ -256,10 +248,6 @@ bool Bot::LookupEnemy (void)
|
||||||
|
|
||||||
player = client.ent;
|
player = client.ent;
|
||||||
|
|
||||||
// let the engine check if this player is potentially visible
|
|
||||||
if (!ENGINE_CHECK_VISIBILITY (player, pvs))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// do some blind by smoke grenade
|
// do some blind by smoke grenade
|
||||||
if (m_blindRecognizeTime < engine.Time () && IsBehindSmokeClouds (player))
|
if (m_blindRecognizeTime < engine.Time () && IsBehindSmokeClouds (player))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -969,7 +969,7 @@ void Engine::ProcessMessageCapture (void *ptr)
|
||||||
|
|
||||||
if (yb_communication_type.GetInt () == 2)
|
if (yb_communication_type.GetInt () == 2)
|
||||||
{
|
{
|
||||||
Bot *notify = bots.FindOneValidAliveBot ();
|
Bot *notify = bots.GetAliveBot ();
|
||||||
|
|
||||||
if (notify != nullptr && notify->m_notKilled)
|
if (notify != nullptr && notify->m_notKilled)
|
||||||
notify->HandleChatterMessage (strVal);
|
notify->HandleChatterMessage (strVal);
|
||||||
|
|
@ -988,7 +988,7 @@ void Engine::ProcessMessageCapture (void *ptr)
|
||||||
|
|
||||||
if (yb_communication_type.GetInt () == 2)
|
if (yb_communication_type.GetInt () == 2)
|
||||||
{
|
{
|
||||||
Bot *notify = bots.FindOneValidAliveBot ();
|
Bot *notify = bots.GetAliveBot ();
|
||||||
|
|
||||||
if (notify != nullptr && notify->m_notKilled)
|
if (notify != nullptr && notify->m_notKilled)
|
||||||
notify->HandleChatterMessage (strVal);
|
notify->HandleChatterMessage (strVal);
|
||||||
|
|
@ -1069,6 +1069,7 @@ void Engine::ProcessMessageCapture (void *ptr)
|
||||||
m_msgBlock.state++; // and finally update network message state
|
m_msgBlock.state++; // and finally update network message state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// console var registrator
|
||||||
ConVar::ConVar (const char *name, const char *initval, VarType type, bool regMissing, const char *regVal) : m_eptr (nullptr)
|
ConVar::ConVar (const char *name, const char *initval, VarType type, bool regMissing, const char *regVal) : m_eptr (nullptr)
|
||||||
{
|
{
|
||||||
engine.PushVariableToStack (name, initval, type, regMissing, regVal, this);
|
engine.PushVariableToStack (name, initval, type, regMissing, regVal, this);
|
||||||
|
|
|
||||||
|
|
@ -1119,24 +1119,21 @@ void ClientDisconnect (edict_t *ent)
|
||||||
// to reset his entity pointer for safety. There are still a few server frames to go once a
|
// to reset his entity pointer for safety. There are still a few server frames to go once a
|
||||||
// listen server client disconnects, and we don't want to send him any sort of message then.
|
// listen server client disconnects, and we don't want to send him any sort of message then.
|
||||||
|
|
||||||
bots.AdjustQuota (false, ent);
|
int index = engine.IndexOfEntity (ent) - 1;
|
||||||
|
|
||||||
int i = engine.IndexOfEntity (ent) - 1;
|
InternalAssert (index >= 0 && index < MAX_ENGINE_PLAYERS);
|
||||||
|
|
||||||
InternalAssert (i >= 0 && i < MAX_ENGINE_PLAYERS);
|
Bot *bot = bots.GetBot (index);
|
||||||
|
|
||||||
Bot *bot = bots.GetBot (i);
|
|
||||||
|
|
||||||
// check if its a bot
|
// check if its a bot
|
||||||
if (bot != nullptr)
|
if (bot != nullptr && bot->pev == &ent->v)
|
||||||
{
|
|
||||||
if (bot->pev == &ent->v)
|
|
||||||
{
|
{
|
||||||
bot->EnableChatterIcon (false);
|
bot->EnableChatterIcon (false);
|
||||||
bots.Free (i);
|
bots.Free (index);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bots.AdjustQuota (false, ent);
|
||||||
|
|
||||||
if (g_gameFlags & GAME_METAMOD)
|
if (g_gameFlags & GAME_METAMOD)
|
||||||
RETURN_META (MRES_IGNORED);
|
RETURN_META (MRES_IGNORED);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include <core.h>
|
#include <core.h>
|
||||||
|
|
||||||
ConVar yb_autovacate ("yb_autovacate", "1");
|
ConVar yb_autovacate ("yb_autovacate", "1");
|
||||||
ConVar yb_autovacate_smart_kick ("yb_autovacate_smart_kick", "0");
|
ConVar yb_autovacate_smart_kick ("yb_autovacate_smart_kick", "1");
|
||||||
|
|
||||||
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");
|
||||||
|
|
@ -275,7 +275,7 @@ Bot *BotManager::GetBot (edict_t *ent)
|
||||||
return GetBot (GetIndex (ent));
|
return GetBot (GetIndex (ent));
|
||||||
}
|
}
|
||||||
|
|
||||||
Bot *BotManager::FindOneValidAliveBot (void)
|
Bot *BotManager::GetAliveBot (void)
|
||||||
{
|
{
|
||||||
// this function finds one bot, alive bot :)
|
// this function finds one bot, alive bot :)
|
||||||
|
|
||||||
|
|
@ -353,14 +353,14 @@ void BotManager::AddBot (const String &name, const String &difficulty, const Str
|
||||||
m_creationTab.Push (bot);
|
m_creationTab.Push (bot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotManager::AdjustQuota (bool isPlayerConnection, edict_t *ent)
|
void BotManager::AdjustQuota (bool isPlayerConnecting, edict_t *ent)
|
||||||
{
|
{
|
||||||
// this function increases or decreases bot quota amount depending on auto vacate variables
|
// this function increases or decreases bot quota amount depending on auto vacate variables
|
||||||
|
|
||||||
if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || GetBot (ent))
|
if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || IsValidBot (ent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (isPlayerConnection)
|
if (isPlayerConnecting)
|
||||||
{
|
{
|
||||||
if (yb_autovacate_smart_kick.GetBool ())
|
if (yb_autovacate_smart_kick.GetBool ())
|
||||||
AddPlayerToCheckTeamQueue (ent);
|
AddPlayerToCheckTeamQueue (ent);
|
||||||
|
|
@ -368,9 +368,11 @@ void BotManager::AdjustQuota (bool isPlayerConnection, edict_t *ent)
|
||||||
{
|
{
|
||||||
RemoveRandom ();
|
RemoveRandom ();
|
||||||
m_balanceCount--;
|
m_balanceCount--;
|
||||||
|
|
||||||
|
m_quotaMaintainTime = engine.Time () + 2.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_balanceCount <= 0)
|
else if (m_balanceCount < 0)
|
||||||
{
|
{
|
||||||
AddRandom ();
|
AddRandom ();
|
||||||
m_balanceCount++;
|
m_balanceCount++;
|
||||||
|
|
@ -379,6 +381,9 @@ void BotManager::AdjustQuota (bool isPlayerConnection, edict_t *ent)
|
||||||
|
|
||||||
void BotManager::AddPlayerToCheckTeamQueue (edict_t *ent)
|
void BotManager::AddPlayerToCheckTeamQueue (edict_t *ent)
|
||||||
{
|
{
|
||||||
|
if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || IsValidBot (ent))
|
||||||
|
return;
|
||||||
|
|
||||||
// entity must be unique
|
// entity must be unique
|
||||||
bool hasFound = false;
|
bool hasFound = false;
|
||||||
|
|
||||||
|
|
@ -397,7 +402,7 @@ void BotManager::AddPlayerToCheckTeamQueue (edict_t *ent)
|
||||||
|
|
||||||
void BotManager::VerifyPlayersHasJoinedTeam (int &desiredCount)
|
void BotManager::VerifyPlayersHasJoinedTeam (int &desiredCount)
|
||||||
{
|
{
|
||||||
if (m_trackedPlayers.IsEmpty ())
|
if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || m_trackedPlayers.IsEmpty ())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < engine.MaxClients (); i++)
|
for (int i = 0; i < engine.MaxClients (); i++)
|
||||||
|
|
@ -472,21 +477,23 @@ void BotManager::MaintainBotQuota (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int numBots = GetBotsNum ();
|
int numBots = GetBotsNum ();
|
||||||
int numHumans = yb_autovacate_smart_kick.GetBool () ? GetHumansNum () : GetHumansJoinedTeam ();
|
int numHumans = GetHumansNum ();
|
||||||
int desiredCount = yb_quota.GetInt ();
|
int desiredCount = yb_quota.GetInt ();
|
||||||
|
|
||||||
if (yb_join_after_player.GetBool () && !numHumans)
|
if (yb_join_after_player.GetBool () && !numHumans)
|
||||||
desiredCount = 0;
|
desiredCount = 0;
|
||||||
|
|
||||||
|
int numHumansOnTeam = yb_autovacate_smart_kick.GetBool () ? GetHumansJoinedTeam () : numHumans;
|
||||||
|
|
||||||
// quota mode
|
// quota mode
|
||||||
char mode = yb_quota_mode.GetString ()[0];
|
char mode = yb_quota_mode.GetString ()[0];
|
||||||
|
|
||||||
if (mode == 'f' || mode == 'F') // fill
|
if (mode == 'f' || mode == 'F') // fill
|
||||||
desiredCount = A_max (0, desiredCount - numHumans);
|
desiredCount = A_max (0, desiredCount - numHumansOnTeam);
|
||||||
else if (mode == 'm' || mode == 'M') // match
|
else if (mode == 'm' || mode == 'M') // match
|
||||||
desiredCount = A_max (0, yb_quota.GetInt () * numHumans);
|
desiredCount = A_max (0, yb_quota.GetInt () * numHumansOnTeam);
|
||||||
|
|
||||||
desiredCount = A_min (desiredCount, engine.MaxClients () - (numHumans + (yb_autovacate.GetBool () ? 1 : 0)));
|
desiredCount = A_min (desiredCount, engine.MaxClients () - (numHumansOnTeam + (yb_autovacate.GetBool () ? 1 : 0)));
|
||||||
|
|
||||||
if (yb_autovacate_smart_kick.GetBool () && numBots > 1 && desiredCount > 1)
|
if (yb_autovacate_smart_kick.GetBool () && numBots > 1 && desiredCount > 1)
|
||||||
VerifyPlayersHasJoinedTeam (desiredCount);
|
VerifyPlayersHasJoinedTeam (desiredCount);
|
||||||
|
|
@ -1033,9 +1040,7 @@ Bot::~Bot (void)
|
||||||
{
|
{
|
||||||
// this is bot destructor
|
// this is bot destructor
|
||||||
|
|
||||||
EnableChatterIcon (false);
|
|
||||||
ReleaseUsedName ();
|
ReleaseUsedName ();
|
||||||
|
|
||||||
DeleteSearchNodes ();
|
DeleteSearchNodes ();
|
||||||
ResetTasks ();
|
ResetTasks ();
|
||||||
}
|
}
|
||||||
|
|
@ -1082,7 +1087,7 @@ int BotManager::GetHumansJoinedTeam (void)
|
||||||
{
|
{
|
||||||
const Client &client = g_clients[i];
|
const Client &client = g_clients[i];
|
||||||
|
|
||||||
if ((client.flags & (CF_USED | CF_ALIVE)) && m_bots[i] == nullptr && client.team != SPECTATOR && !(client.ent->v.flags & FL_FAKECLIENT) && client.ent->v.movetype != MOVETYPE_FLY)
|
if ((client.flags & (CF_USED | CF_ALIVE)) && m_bots[i] == nullptr && client.team != SPECTATOR && !(client.ent->v.flags & FL_FAKECLIENT))
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
|
@ -1290,7 +1295,7 @@ void Bot::NewRound (void)
|
||||||
m_defendHostage = false;
|
m_defendHostage = false;
|
||||||
m_headedTime = 0.0f;
|
m_headedTime = 0.0f;
|
||||||
|
|
||||||
m_timeLogoSpray = engine.Time () + Random.Float (0.5f, 2.0f);
|
m_timeLogoSpray = engine.Time () + Random.Float (5.0f, 30.0f);
|
||||||
m_spawnTime = engine.Time ();
|
m_spawnTime = engine.Time ();
|
||||||
m_lastChatTime = engine.Time ();
|
m_lastChatTime = engine.Time ();
|
||||||
|
|
||||||
|
|
@ -1331,11 +1336,16 @@ void Bot::Kick (bool keepQuota)
|
||||||
{
|
{
|
||||||
// this function kick off one bot from the server.
|
// this function kick off one bot from the server.
|
||||||
|
|
||||||
|
auto username = STRING (pev->netname);
|
||||||
|
|
||||||
|
if (!(pev->flags & FL_FAKECLIENT) || IsNullString (username))
|
||||||
|
return;
|
||||||
|
|
||||||
// clear fakeclient bit immediately
|
// clear fakeclient bit immediately
|
||||||
pev->flags &= ~FL_FAKECLIENT;
|
pev->flags &= ~FL_FAKECLIENT;
|
||||||
|
|
||||||
engine.IssueCmd ("kick \"%s\"", STRING (pev->netname));
|
engine.IssueCmd ("kick \"%s\"", username);
|
||||||
engine.CenterPrintf ("Bot '%s' kicked", STRING (pev->netname));
|
engine.CenterPrintf ("Bot '%s' kicked", username);
|
||||||
|
|
||||||
// keep quota number up to date
|
// keep quota number up to date
|
||||||
if (!keepQuota)
|
if (!keepQuota)
|
||||||
|
|
|
||||||
|
|
@ -626,7 +626,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal)
|
||||||
if (IsOnFloor () || IsInWater ())
|
if (IsOnFloor () || IsInWater ())
|
||||||
{
|
{
|
||||||
pev->button |= IN_JUMP;
|
pev->button |= IN_JUMP;
|
||||||
m_jumpStateTimer = Random.Float (1.0f, 2.0f);
|
m_jumpStateTimer = Random.Float (2.0f, 3.0f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1150,7 +1150,6 @@ bool Bot::DoWaypointNav (void)
|
||||||
m_lastEnemy = ent;
|
m_lastEnemy = ent;
|
||||||
m_enemy = ent;
|
m_enemy = ent;
|
||||||
m_lastEnemyOrigin = ent->v.origin;
|
m_lastEnemyOrigin = ent->v.origin;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (IsValidPlayer (ent) && IsAlive (ent) && m_team == engine.GetTeam (ent))
|
else if (IsValidPlayer (ent) && IsAlive (ent) && m_team == engine.GetTeam (ent))
|
||||||
{
|
{
|
||||||
|
|
@ -1193,7 +1192,7 @@ bool Bot::DoWaypointNav (void)
|
||||||
|
|
||||||
if (waypointDistance < desiredDistance)
|
if (waypointDistance < desiredDistance)
|
||||||
{
|
{
|
||||||
// Did we reach a destination Waypoint?
|
// did we reach a destination waypoint?
|
||||||
if (GetTask ()->data == m_currentWaypointIndex)
|
if (GetTask ()->data == m_currentWaypointIndex)
|
||||||
{
|
{
|
||||||
// add goal values
|
// add goal values
|
||||||
|
|
@ -1247,7 +1246,7 @@ bool Bot::DoWaypointNav (void)
|
||||||
{
|
{
|
||||||
float distance = (bombOrigin - waypoints.GetPath (taskTarget)->origin).GetLength ();
|
float distance = (bombOrigin - waypoints.GetPath (taskTarget)->origin).GetLength ();
|
||||||
|
|
||||||
if (distance > 512.0)
|
if (distance > 512.0f)
|
||||||
{
|
{
|
||||||
if (Random.Int (0, 100) < 50 && !waypoints.IsGoalVisited (taskTarget))
|
if (Random.Int (0, 100) < 50 && !waypoints.IsGoalVisited (taskTarget))
|
||||||
RadioMessage (Radio_SectorClear);
|
RadioMessage (Radio_SectorClear);
|
||||||
|
|
@ -2427,8 +2426,10 @@ bool Bot::HeadTowardWaypoint (void)
|
||||||
GetBestNextWaypoint ();
|
GetBestNextWaypoint ();
|
||||||
m_minSpeed = pev->maxspeed;
|
m_minSpeed = pev->maxspeed;
|
||||||
|
|
||||||
|
TaskID taskID = GetTaskId ();
|
||||||
|
|
||||||
// only if we in normal task and bomb is not planted
|
// only if we in normal task and bomb is not planted
|
||||||
if (GetTaskId () == TASK_NORMAL && g_timeRoundMid + 5.0f < engine.Time () && m_timeCamping + 5.0f < engine.Time () && !g_bombPlanted && m_personality != PERSONALITY_RUSHER && !m_hasC4 && !m_isVIP && m_loosedBombWptIndex == -1 && !HasHostage ())
|
if (taskID == TASK_NORMAL && g_timeRoundMid + 5.0f < engine.Time () && m_timeCamping + 5.0f < engine.Time () && !g_bombPlanted && m_personality != PERSONALITY_RUSHER && !m_hasC4 && !m_isVIP && m_loosedBombWptIndex == -1 && !HasHostage ())
|
||||||
{
|
{
|
||||||
m_campButtons = 0;
|
m_campButtons = 0;
|
||||||
|
|
||||||
|
|
@ -2467,6 +2468,24 @@ bool Bot::HeadTowardWaypoint (void)
|
||||||
else if (Random.Int (1, 100) > m_difficulty * 25)
|
else if (Random.Int (1, 100) > m_difficulty * 25)
|
||||||
m_minSpeed = GetWalkSpeed ();
|
m_minSpeed = GetWalkSpeed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// force terrorist bot to plant bomb
|
||||||
|
if (taskID == TASK_NORMAL && m_inBombZone && !m_hasProgressBar && m_hasC4)
|
||||||
|
{
|
||||||
|
int newGoal = FindGoal ();
|
||||||
|
|
||||||
|
m_prevGoalIndex = newGoal;
|
||||||
|
m_chosenGoalIndex = newGoal;
|
||||||
|
|
||||||
|
// remember index
|
||||||
|
GetTask ()->data = newGoal;
|
||||||
|
|
||||||
|
// do path finding if it's not the current waypoint
|
||||||
|
if (newGoal != m_currentWaypointIndex)
|
||||||
|
FindPath (m_currentWaypointIndex, newGoal, m_pathType);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3373,12 +3392,21 @@ bool Bot::IsPointOccupied (int index)
|
||||||
|
|
||||||
if (bot->m_notKilled && m_currentWaypointIndex != -1 && bot->m_prevWptIndex[0] != -1)
|
if (bot->m_notKilled && m_currentWaypointIndex != -1 && bot->m_prevWptIndex[0] != -1)
|
||||||
{
|
{
|
||||||
|
int targetId = bot->GetTask ()->data;
|
||||||
|
|
||||||
|
if (index == targetId)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// check bot's current waypoint
|
||||||
int occupyId = GetShootingConeDeviation (bot->GetEntity (), &pev->origin) >= 0.7f ? bot->m_prevWptIndex[0] : m_currentWaypointIndex;
|
int occupyId = GetShootingConeDeviation (bot->GetEntity (), &pev->origin) >= 0.7f ? bot->m_prevWptIndex[0] : m_currentWaypointIndex;
|
||||||
|
|
||||||
|
if (index == occupyId)
|
||||||
|
return true;
|
||||||
|
|
||||||
// length check
|
// length check
|
||||||
float length = (waypoints.GetPath (occupyId)->origin - waypoints.GetPath (index)->origin).GetLengthSquared ();
|
float length = (waypoints.GetPath (occupyId)->origin - waypoints.GetPath (index)->origin).GetLengthSquared ();
|
||||||
|
|
||||||
if (occupyId == index || bot->GetTask ()->data == index || length < GET_SQUARE (64.0f))
|
if (length < GET_SQUARE (128.0f))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -722,6 +722,10 @@ void SoundAttachToClients (edict_t *ent, const char *sample, float volume)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Vector &origin = engine.GetAbsOrigin (ent);
|
const Vector &origin = engine.GetAbsOrigin (ent);
|
||||||
|
|
||||||
|
if (origin.IsZero ())
|
||||||
|
return;
|
||||||
|
|
||||||
int index = engine.IndexOfEntity (ent) - 1;
|
int index = engine.IndexOfEntity (ent) - 1;
|
||||||
|
|
||||||
if (index < 0 || index >= engine.MaxClients ())
|
if (index < 0 || index >= engine.MaxClients ())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue