Merge pull request #40 from jeefo/develop

This commit is contained in:
jeefo 2016-12-09 22:13:36 +03:00 committed by GitHub
commit 66484293d5
9 changed files with 103 additions and 80 deletions

View file

@ -1313,7 +1313,7 @@ public:
int GetIndex (edict_t *ent);
Bot *GetBot (int index);
Bot *GetBot (edict_t *ent);
Bot *FindOneValidAliveBot (void);
Bot *GetAliveBot (void);
Bot *GetHighestFragsBot (int team);
int GetHumansNum (void);

View file

@ -30,7 +30,6 @@
#endif
#ifdef ENABLE_SSE_INTRINSICS
#include <xmmintrin.h>
#include <emmintrin.h>
#endif
@ -150,22 +149,23 @@ namespace Math
const float MATH_R2D = 180.0f / MATH_PI;
#ifdef ENABLE_SSE_INTRINSICS
//
// Function: mm_abs
// Function: sse_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);
};
//
// Function: mm_sine
// Function: sse_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 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_and_ps (val, pi2);
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));
__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_mul_ps (val, _mm_set1_ps (0.225f));
res = _mm_add_ps (val, res);
@ -196,7 +196,7 @@ namespace Math
static inline float A_sqrtf (float value)
{
#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
return sqrtf (value);
#endif
@ -210,7 +210,7 @@ namespace Math
static inline float A_sinf (float value)
{
#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
return sinf (value);
#endif
@ -224,7 +224,7 @@ namespace Math
static inline float A_cosf (float value)
{
#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
return cosf (value);
#endif
@ -238,7 +238,7 @@ namespace Math
static inline void A_sincosf (float rad, float *sine, float *cosine)
{
#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));
*sine = _mm_cvtss_f32 (m_sincos);

View file

@ -3025,7 +3025,7 @@ void Bot::RunTask_Normal (void)
}
// 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)
pev->button |= IN_ATTACK;
@ -3137,14 +3137,17 @@ void Bot::RunTask_Normal (void)
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);
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
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;
else
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_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;
else
m_campButtons &= ~IN_DUCK;
@ -3211,7 +3217,7 @@ void Bot::RunTask_Normal (void)
// do pathfinding if it's not the current waypoint
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
{
@ -5867,14 +5873,6 @@ bool Bot::OutOfBombTimer (void)
void Bot::ReactOnSound (void)
{
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;
// loop through all enemy clients to check for hearable stuff
@ -5890,9 +5888,6 @@ void Bot::ReactOnSound (void)
if (distance > client.hearingDistance)
continue;
if (!ENGINE_CHECK_VISIBILITY (client.ent, pas))
continue;
if (distance < minDistance)
{
hearEnemyIndex = i;

View file

@ -238,14 +238,6 @@ bool Bot::LookupEnemy (void)
// ignore shielded enemies, while we have real one
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...
for (int i = 0; i < engine.MaxClients (); i++)
{
@ -256,10 +248,6 @@ bool Bot::LookupEnemy (void)
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
if (m_blindRecognizeTime < engine.Time () && IsBehindSmokeClouds (player))
{

View file

@ -969,7 +969,7 @@ void Engine::ProcessMessageCapture (void *ptr)
if (yb_communication_type.GetInt () == 2)
{
Bot *notify = bots.FindOneValidAliveBot ();
Bot *notify = bots.GetAliveBot ();
if (notify != nullptr && notify->m_notKilled)
notify->HandleChatterMessage (strVal);
@ -988,7 +988,7 @@ void Engine::ProcessMessageCapture (void *ptr)
if (yb_communication_type.GetInt () == 2)
{
Bot *notify = bots.FindOneValidAliveBot ();
Bot *notify = bots.GetAliveBot ();
if (notify != nullptr && notify->m_notKilled)
notify->HandleChatterMessage (strVal);
@ -1069,6 +1069,7 @@ void Engine::ProcessMessageCapture (void *ptr)
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)
{
engine.PushVariableToStack (name, initval, type, regMissing, regVal, this);

View file

@ -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
// 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 (i);
Bot *bot = bots.GetBot (index);
// check if its a bot
if (bot != nullptr)
{
if (bot->pev == &ent->v)
if (bot != nullptr && bot->pev == &ent->v)
{
bot->EnableChatterIcon (false);
bots.Free (i);
}
bots.Free (index);
}
bots.AdjustQuota (false, ent);
if (g_gameFlags & GAME_METAMOD)
RETURN_META (MRES_IGNORED);

View file

@ -10,7 +10,7 @@
#include <core.h>
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_mode ("yb_quota_mode", "normal");
@ -275,7 +275,7 @@ Bot *BotManager::GetBot (edict_t *ent)
return GetBot (GetIndex (ent));
}
Bot *BotManager::FindOneValidAliveBot (void)
Bot *BotManager::GetAliveBot (void)
{
// 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);
}
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
if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || GetBot (ent))
if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || IsValidBot (ent))
return;
if (isPlayerConnection)
if (isPlayerConnecting)
{
if (yb_autovacate_smart_kick.GetBool ())
AddPlayerToCheckTeamQueue (ent);
@ -368,9 +368,11 @@ void BotManager::AdjustQuota (bool isPlayerConnection, edict_t *ent)
{
RemoveRandom ();
m_balanceCount--;
m_quotaMaintainTime = engine.Time () + 2.0f;
}
}
else if (m_balanceCount <= 0)
else if (m_balanceCount < 0)
{
AddRandom ();
m_balanceCount++;
@ -379,6 +381,9 @@ void BotManager::AdjustQuota (bool isPlayerConnection, edict_t *ent)
void BotManager::AddPlayerToCheckTeamQueue (edict_t *ent)
{
if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || IsValidBot (ent))
return;
// entity must be unique
bool hasFound = false;
@ -397,7 +402,7 @@ void BotManager::AddPlayerToCheckTeamQueue (edict_t *ent)
void BotManager::VerifyPlayersHasJoinedTeam (int &desiredCount)
{
if (m_trackedPlayers.IsEmpty ())
if (!engine.IsDedicatedServer () || !yb_autovacate.GetBool () || m_trackedPlayers.IsEmpty ())
return;
for (int i = 0; i < engine.MaxClients (); i++)
@ -472,21 +477,23 @@ void BotManager::MaintainBotQuota (void)
}
int numBots = GetBotsNum ();
int numHumans = yb_autovacate_smart_kick.GetBool () ? GetHumansNum () : GetHumansJoinedTeam ();
int numHumans = GetHumansNum ();
int desiredCount = yb_quota.GetInt ();
if (yb_join_after_player.GetBool () && !numHumans)
desiredCount = 0;
int numHumansOnTeam = yb_autovacate_smart_kick.GetBool () ? GetHumansJoinedTeam () : numHumans;
// quota mode
char mode = yb_quota_mode.GetString ()[0];
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
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)
VerifyPlayersHasJoinedTeam (desiredCount);
@ -1033,9 +1040,7 @@ Bot::~Bot (void)
{
// this is bot destructor
EnableChatterIcon (false);
ReleaseUsedName ();
DeleteSearchNodes ();
ResetTasks ();
}
@ -1082,7 +1087,7 @@ int BotManager::GetHumansJoinedTeam (void)
{
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++;
}
return count;
@ -1290,7 +1295,7 @@ void Bot::NewRound (void)
m_defendHostage = false;
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_lastChatTime = engine.Time ();
@ -1331,11 +1336,16 @@ void Bot::Kick (bool keepQuota)
{
// 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
pev->flags &= ~FL_FAKECLIENT;
engine.IssueCmd ("kick \"%s\"", STRING (pev->netname));
engine.CenterPrintf ("Bot '%s' kicked", STRING (pev->netname));
engine.IssueCmd ("kick \"%s\"", username);
engine.CenterPrintf ("Bot '%s' kicked", username);
// keep quota number up to date
if (!keepQuota)

View file

@ -626,7 +626,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal)
if (IsOnFloor () || IsInWater ())
{
pev->button |= IN_JUMP;
m_jumpStateTimer = Random.Float (1.0f, 2.0f);
m_jumpStateTimer = Random.Float (2.0f, 3.0f);
}
break;
@ -1150,7 +1150,6 @@ bool Bot::DoWaypointNav (void)
m_lastEnemy = ent;
m_enemy = ent;
m_lastEnemyOrigin = ent->v.origin;
}
else if (IsValidPlayer (ent) && IsAlive (ent) && m_team == engine.GetTeam (ent))
{
@ -1193,7 +1192,7 @@ bool Bot::DoWaypointNav (void)
if (waypointDistance < desiredDistance)
{
// Did we reach a destination Waypoint?
// did we reach a destination waypoint?
if (GetTask ()->data == m_currentWaypointIndex)
{
// add goal values
@ -1247,7 +1246,7 @@ bool Bot::DoWaypointNav (void)
{
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))
RadioMessage (Radio_SectorClear);
@ -2427,8 +2426,10 @@ bool Bot::HeadTowardWaypoint (void)
GetBestNextWaypoint ();
m_minSpeed = pev->maxspeed;
TaskID taskID = GetTaskId ();
// 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;
@ -2467,6 +2468,24 @@ bool Bot::HeadTowardWaypoint (void)
else if (Random.Int (1, 100) > m_difficulty * 25)
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)
{
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;
if (index == occupyId)
return true;
// length check
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;
}
}

View file

@ -722,6 +722,10 @@ void SoundAttachToClients (edict_t *ent, const char *sample, float volume)
return;
const Vector &origin = engine.GetAbsOrigin (ent);
if (origin.IsZero ())
return;
int index = engine.IndexOfEntity (ent) - 1;
if (index < 0 || index >= engine.MaxClients ())