some combat behavior tweaks
This commit is contained in:
parent
c12437689c
commit
d0a8cb727a
4 changed files with 70 additions and 63 deletions
|
|
@ -961,7 +961,7 @@ private:
|
||||||
void BotAI (void);
|
void BotAI (void);
|
||||||
void CheckSpawnTimeConditions (void);
|
void CheckSpawnTimeConditions (void);
|
||||||
bool IsMorePowerfulWeaponCanBeBought (void);
|
bool IsMorePowerfulWeaponCanBeBought (void);
|
||||||
void PerformWeaponPurchase (void);
|
void PurchaseWeapons (void);
|
||||||
|
|
||||||
bool CanDuckUnder (const Vector &normal);
|
bool CanDuckUnder (const Vector &normal);
|
||||||
bool CanJumpUp (const Vector &normal);
|
bool CanJumpUp (const Vector &normal);
|
||||||
|
|
@ -1070,7 +1070,7 @@ private:
|
||||||
|
|
||||||
void SelectBestWeapon (void);
|
void SelectBestWeapon (void);
|
||||||
void SelectPistol (void);
|
void SelectPistol (void);
|
||||||
bool IsFriendInLineOfFire (void);
|
bool IsFriendInLineOfFire (float distance);
|
||||||
bool IsGroupOfEnemies (const Vector &location, int numEnemies = 1, int radius = 256);
|
bool IsGroupOfEnemies (const Vector &location, int numEnemies = 1, int radius = 256);
|
||||||
|
|
||||||
bool IsShootableThruObstacle (const Vector &dest);
|
bool IsShootableThruObstacle (const Vector &dest);
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,6 @@ ConVar yb_freeze_bots ("yb_freeze_bots", "0");
|
||||||
ConVar yb_spraypaints ("yb_spraypaints", "1");
|
ConVar yb_spraypaints ("yb_spraypaints", "1");
|
||||||
ConVar yb_botbuy ("yb_botbuy", "1");
|
ConVar yb_botbuy ("yb_botbuy", "1");
|
||||||
|
|
||||||
ConVar yb_timersound ("yb_timersound", "0.5", VT_NOSERVER);
|
|
||||||
ConVar yb_timerpickup ("yb_timerpickup", "0.5", VT_NOSERVER);
|
|
||||||
ConVar yb_timergrenade ("yb_timergrenade", "0.5", VT_NOSERVER);
|
|
||||||
|
|
||||||
ConVar yb_chatter_path ("yb_chatter_path", "sound/radio/bot", VT_NOSERVER);
|
ConVar yb_chatter_path ("yb_chatter_path", "sound/radio/bot", VT_NOSERVER);
|
||||||
ConVar yb_restricted_weapons ("yb_restricted_weapons", "");
|
ConVar yb_restricted_weapons ("yb_restricted_weapons", "");
|
||||||
|
|
||||||
|
|
@ -205,10 +201,10 @@ bool Bot::IsEnemyViewable (edict_t *player)
|
||||||
|
|
||||||
bool forceTrueIfVisible = false;
|
bool forceTrueIfVisible = false;
|
||||||
|
|
||||||
if (IsValidPlayer (pev->dmg_inflictor) && GetTeam (pev->dmg_inflictor) != m_team && ::IsInViewCone (EyePosition (), pev->dmg_inflictor))
|
if (IsValidPlayer (pev->dmg_inflictor) && GetTeam (pev->dmg_inflictor) != m_team)
|
||||||
forceTrueIfVisible = true;
|
forceTrueIfVisible = true;
|
||||||
|
|
||||||
if (CheckVisibility (player, &m_enemyOrigin, &m_visibility) && (IsInViewCone (player->v.origin + Vector (0, 0, 14)) || forceTrueIfVisible))
|
if (CheckVisibility (player, &m_enemyOrigin, &m_visibility) && (IsInViewCone (player->v.origin + pev->view_ofs) || forceTrueIfVisible))
|
||||||
{
|
{
|
||||||
m_seeEnemyTime = GetWorldTime ();
|
m_seeEnemyTime = GetWorldTime ();
|
||||||
m_lastEnemy = player;
|
m_lastEnemy = player;
|
||||||
|
|
@ -262,7 +258,7 @@ void Bot::CheckGrenadeThrow (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check again in some seconds
|
// check again in some seconds
|
||||||
m_grenadeCheckTime = GetWorldTime () + yb_timergrenade.GetFloat ();
|
m_grenadeCheckTime = GetWorldTime () + 0.5f;
|
||||||
|
|
||||||
// check if we have grenades to throw
|
// check if we have grenades to throw
|
||||||
int grenadeToThrow = CheckGrenades ();
|
int grenadeToThrow = CheckGrenades ();
|
||||||
|
|
@ -998,8 +994,9 @@ void Bot::FindItem (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pickupOrigin.z > EyePosition ().z + (m_pickupType == PICKUP_HOSTAGE ? 40.0f : 15.0f)|| IsDeadlyDrop (pickupOrigin)) // check if item is too high to reach, check if getting the item would hurt bot
|
if (pickupOrigin.z > EyePosition ().z + (m_pickupType == PICKUP_HOSTAGE ? 40.0f : 15.0f) || IsDeadlyDrop (pickupOrigin)) // check if item is too high to reach, check if getting the item would hurt bot
|
||||||
{
|
{
|
||||||
|
m_itemIgnore = m_pickupItem;
|
||||||
m_pickupItem = NULL;
|
m_pickupItem = NULL;
|
||||||
m_pickupType = PICKUP_NONE;
|
m_pickupType = PICKUP_NONE;
|
||||||
|
|
||||||
|
|
@ -1261,7 +1258,7 @@ void Bot::CheckMessageQueue (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
PushMessageQueue (GSM_IDLE);
|
PushMessageQueue (GSM_IDLE);
|
||||||
PerformWeaponPurchase ();
|
PurchaseWeapons ();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1503,7 +1500,7 @@ bool Bot::IsMorePowerfulWeaponCanBeBought (void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::PerformWeaponPurchase (void)
|
void Bot::PurchaseWeapons (void)
|
||||||
{
|
{
|
||||||
// this function does all the work in selecting correct buy menus for most weapons/items
|
// this function does all the work in selecting correct buy menus for most weapons/items
|
||||||
|
|
||||||
|
|
@ -1998,7 +1995,7 @@ void Bot::SetConditions (void)
|
||||||
if (!yb_ignore_enemies.GetBool () && m_soundUpdateTime <= GetWorldTime () && m_blindTime < GetWorldTime ())
|
if (!yb_ignore_enemies.GetBool () && m_soundUpdateTime <= GetWorldTime () && m_blindTime < GetWorldTime ())
|
||||||
{
|
{
|
||||||
ReactOnSound ();
|
ReactOnSound ();
|
||||||
m_soundUpdateTime = GetWorldTime () + yb_timersound.GetFloat ();
|
m_soundUpdateTime = GetWorldTime () + 0.25f;
|
||||||
}
|
}
|
||||||
else if (m_heardSoundTime < GetWorldTime ())
|
else if (m_heardSoundTime < GetWorldTime ())
|
||||||
m_states &= ~STATE_HEARING_ENEMY;
|
m_states &= ~STATE_HEARING_ENEMY;
|
||||||
|
|
@ -2021,7 +2018,7 @@ void Bot::SetConditions (void)
|
||||||
// check if there are items needing to be used/collected
|
// check if there are items needing to be used/collected
|
||||||
if (m_itemCheckTime < GetWorldTime () || !IsEntityNull (m_pickupItem))
|
if (m_itemCheckTime < GetWorldTime () || !IsEntityNull (m_pickupItem))
|
||||||
{
|
{
|
||||||
m_itemCheckTime = GetWorldTime () + yb_timerpickup.GetFloat ();
|
m_itemCheckTime = GetWorldTime () + 0.4f;
|
||||||
FindItem ();
|
FindItem ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2103,7 +2100,7 @@ void Bot::SetConditions (void)
|
||||||
if (g_bombPlanted || m_isStuck)
|
if (g_bombPlanted || m_isStuck)
|
||||||
ratio /= 3; // reduce the seek cover desire if bomb is planted
|
ratio /= 3; // reduce the seek cover desire if bomb is planted
|
||||||
else if (m_isVIP || m_isReloading)
|
else if (m_isVIP || m_isReloading)
|
||||||
ratio *= 2; // triple the seek cover desire if bot is VIP or reloading
|
ratio *= 3; // triple the seek cover desire if bot is VIP or reloading
|
||||||
|
|
||||||
if (distance > 500.0)
|
if (distance > 500.0)
|
||||||
g_taskFilters[TASK_SEEKCOVER].desire = retreatLevel * ratio;
|
g_taskFilters[TASK_SEEKCOVER].desire = retreatLevel * ratio;
|
||||||
|
|
@ -3632,9 +3629,11 @@ void Bot::RunTask (void)
|
||||||
|
|
||||||
if (!IsEntityNull (m_enemy))
|
if (!IsEntityNull (m_enemy))
|
||||||
{
|
{
|
||||||
|
m_lastCollTime = GetWorldTime () + 0.5f;
|
||||||
|
|
||||||
if (IsOnLadder ())
|
if (IsOnLadder ())
|
||||||
{
|
{
|
||||||
pev->button |= IN_DUCK;
|
pev->button |= IN_JUMP;
|
||||||
DeleteSearchNodes ();
|
DeleteSearchNodes ();
|
||||||
}
|
}
|
||||||
CombatFight ();
|
CombatFight ();
|
||||||
|
|
@ -5660,7 +5659,7 @@ void Bot::ResetDoubleJumpState (void)
|
||||||
|
|
||||||
void Bot::DebugMsg (const char *format, ...)
|
void Bot::DebugMsg (const char *format, ...)
|
||||||
{
|
{
|
||||||
if (yb_debug.GetInt () < 2)
|
if (yb_debug.GetInt () <= 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
@ -5670,9 +5669,10 @@ void Bot::DebugMsg (const char *format, ...)
|
||||||
vsprintf (buffer, format, ap);
|
vsprintf (buffer, format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
ServerPrint ("%s: %s", STRING (pev->netname), buffer);
|
if (yb_debug.GetInt () == 3 && !IsEntityNull (g_hostEntity) && g_hostEntity->v.iuser2 == IndexOfEntity (GetEntity ()))
|
||||||
|
ServerPrint ("%s: %s", STRING (pev->netname), buffer);
|
||||||
|
|
||||||
if (yb_debug.GetInt () >= 3)
|
if (yb_debug.GetInt () > 3)
|
||||||
AddLogEntry (false, LL_DEFAULT, "%s: %s", STRING (pev->netname), buffer);
|
AddLogEntry (false, LL_DEFAULT, "%s: %s", STRING (pev->netname), buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,13 +49,12 @@ bool Bot::LookupEnemy (void)
|
||||||
{
|
{
|
||||||
// this function tries to find the best suitable enemy for the bot
|
// this function tries to find the best suitable enemy for the bot
|
||||||
|
|
||||||
m_visibility = 0;
|
|
||||||
|
|
||||||
// do not search for enemies while we're blinded, or shooting disabled by user
|
// do not search for enemies while we're blinded, or shooting disabled by user
|
||||||
if (m_blindTime > GetWorldTime () || yb_ignore_enemies.GetBool ())
|
if (m_blindTime > GetWorldTime () || yb_ignore_enemies.GetBool ())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// do not check for new enemy too fast
|
// do not check for new enemy too fast
|
||||||
|
#if 0
|
||||||
if (!IsEntityNull (m_enemy) && m_enemyUpdateTime + 2.5f > GetWorldTime () && !(m_states & STATE_SUSPECT_ENEMY))
|
if (!IsEntityNull (m_enemy) && m_enemyUpdateTime + 2.5f > GetWorldTime () && !(m_states & STATE_SUSPECT_ENEMY))
|
||||||
{
|
{
|
||||||
m_aimFlags |= AIM_ENEMY;
|
m_aimFlags |= AIM_ENEMY;
|
||||||
|
|
@ -63,6 +62,7 @@ bool Bot::LookupEnemy (void)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
edict_t *player, *newEnemy = NULL;
|
edict_t *player, *newEnemy = NULL;
|
||||||
|
|
||||||
float nearestDistance = m_viewDistance;
|
float nearestDistance = m_viewDistance;
|
||||||
|
|
@ -76,10 +76,10 @@ bool Bot::LookupEnemy (void)
|
||||||
byte *pvs = ENGINE_SET_PVS (reinterpret_cast <float *> (&potentialVisibility));
|
byte *pvs = ENGINE_SET_PVS (reinterpret_cast <float *> (&potentialVisibility));
|
||||||
|
|
||||||
// clear suspected flag
|
// clear suspected flag
|
||||||
if (m_seeEnemyTime + 4.0 < GetWorldTime ())
|
if (m_seeEnemyTime + 3.0f < GetWorldTime ())
|
||||||
m_states &= ~STATE_SUSPECT_ENEMY;
|
m_states &= ~STATE_SUSPECT_ENEMY;
|
||||||
|
|
||||||
if (!IsEntityNull (m_enemy))
|
if (!IsEntityNull (m_enemy) && m_enemyUpdateTime > GetWorldTime ())
|
||||||
{
|
{
|
||||||
player = m_enemy;
|
player = m_enemy;
|
||||||
|
|
||||||
|
|
@ -91,7 +91,10 @@ bool Bot::LookupEnemy (void)
|
||||||
// the old enemy is no longer visible or
|
// the old enemy is no longer visible or
|
||||||
if (IsEntityNull (newEnemy))
|
if (IsEntityNull (newEnemy))
|
||||||
{
|
{
|
||||||
m_enemyUpdateTime = GetWorldTime () + 0.25;
|
m_enemyUpdateTime = GetWorldTime () + 0.5f;
|
||||||
|
|
||||||
|
// ignore shielded enemies, while we have real one
|
||||||
|
edict_t *shieldEnemy = NULL;
|
||||||
|
|
||||||
// search the world for players...
|
// search the world for players...
|
||||||
for (int i = 0; i < GetMaxClients (); i++)
|
for (int i = 0; i < GetMaxClients (); i++)
|
||||||
|
|
@ -124,6 +127,11 @@ bool Bot::LookupEnemy (void)
|
||||||
// see if bot can see the player...
|
// see if bot can see the player...
|
||||||
if (m_blindRecognizeTime < GetWorldTime () && IsEnemyViewable (player))
|
if (m_blindRecognizeTime < GetWorldTime () && IsEnemyViewable (player))
|
||||||
{
|
{
|
||||||
|
if (IsEnemyProtectedByShield (player))
|
||||||
|
{
|
||||||
|
shieldEnemy = player;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
float distance = (player->v.origin - pev->origin).GetLength ();
|
float distance = (player->v.origin - pev->origin).GetLength ();
|
||||||
|
|
||||||
if (distance < nearestDistance)
|
if (distance < nearestDistance)
|
||||||
|
|
@ -137,12 +145,17 @@ bool Bot::LookupEnemy (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsEntityNull (newEnemy) && !IsEntityNull (shieldEnemy))
|
||||||
|
newEnemy = shieldEnemy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsValidPlayer (newEnemy))
|
if (IsValidPlayer (newEnemy))
|
||||||
{
|
{
|
||||||
g_botsCanPause = true;
|
g_botsCanPause = true;
|
||||||
|
|
||||||
m_aimFlags |= AIM_ENEMY;
|
m_aimFlags |= AIM_ENEMY;
|
||||||
|
m_states |= STATE_SEEING_ENEMY;
|
||||||
|
|
||||||
if (newEnemy == m_enemy)
|
if (newEnemy == m_enemy)
|
||||||
{
|
{
|
||||||
|
|
@ -164,7 +177,7 @@ bool Bot::LookupEnemy (void)
|
||||||
m_targetEntity = NULL; // stop following when we see an enemy...
|
m_targetEntity = NULL; // stop following when we see an enemy...
|
||||||
|
|
||||||
if (Random.Long (0, 100) < m_difficulty * 25)
|
if (Random.Long (0, 100) < m_difficulty * 25)
|
||||||
m_enemySurpriseTime = GetWorldTime () + m_actualReactionTime / 3;
|
m_enemySurpriseTime = GetWorldTime () + m_actualReactionTime * 0.5f;
|
||||||
else
|
else
|
||||||
m_enemySurpriseTime = GetWorldTime () + m_actualReactionTime;
|
m_enemySurpriseTime = GetWorldTime () + m_actualReactionTime;
|
||||||
|
|
||||||
|
|
@ -212,11 +225,11 @@ bool Bot::LookupEnemy (void)
|
||||||
m_enemy = NULL;
|
m_enemy = NULL;
|
||||||
|
|
||||||
// shoot at dying players if no new enemy to give some more human-like illusion
|
// shoot at dying players if no new enemy to give some more human-like illusion
|
||||||
if (m_seeEnemyTime + 0.1 > GetWorldTime ())
|
if (m_seeEnemyTime + 0.1f > GetWorldTime ())
|
||||||
{
|
{
|
||||||
if (!UsesSniper ())
|
if (!UsesSniper ())
|
||||||
{
|
{
|
||||||
m_shootAtDeadTime = GetWorldTime () + 0.2;
|
m_shootAtDeadTime = GetWorldTime () + 0.4f;
|
||||||
m_actualReactionTime = 0.0;
|
m_actualReactionTime = 0.0;
|
||||||
m_states |= STATE_SUSPECT_ENEMY;
|
m_states |= STATE_SUSPECT_ENEMY;
|
||||||
|
|
||||||
|
|
@ -237,7 +250,7 @@ bool Bot::LookupEnemy (void)
|
||||||
// if no enemy visible check if last one shoot able through wall
|
// if no enemy visible check if last one shoot able through wall
|
||||||
if (yb_shoots_thru_walls.GetBool () && m_difficulty >= 2 && IsShootableThruObstacle (newEnemy->v.origin))
|
if (yb_shoots_thru_walls.GetBool () && m_difficulty >= 2 && IsShootableThruObstacle (newEnemy->v.origin))
|
||||||
{
|
{
|
||||||
m_seeEnemyTime = GetWorldTime () - 0.35f;
|
m_seeEnemyTime = GetWorldTime ();
|
||||||
|
|
||||||
m_states |= STATE_SUSPECT_ENEMY;
|
m_states |= STATE_SUSPECT_ENEMY;
|
||||||
m_aimFlags |= AIM_LAST_ENEMY;
|
m_aimFlags |= AIM_LAST_ENEMY;
|
||||||
|
|
@ -293,7 +306,7 @@ const Vector &Bot::GetAimPosition (void)
|
||||||
// now take in account different parts of enemy body
|
// now take in account different parts of enemy body
|
||||||
if (m_visibility & (VISIBLE_HEAD | VISIBLE_BODY)) // visible head & body
|
if (m_visibility & (VISIBLE_HEAD | VISIBLE_BODY)) // visible head & body
|
||||||
{
|
{
|
||||||
int headshotFreq[5] = { 20, 40, 60, 90, 100 };
|
int headshotFreq[5] = { 20, 40, 60, 80, 100 };
|
||||||
|
|
||||||
// now check is our skill match to aim at head, else aim at enemy body
|
// now check is our skill match to aim at head, else aim at enemy body
|
||||||
if ((Random.Long (1, 100) < headshotFreq[m_difficulty]) || UsesPistol ())
|
if ((Random.Long (1, 100) < headshotFreq[m_difficulty]) || UsesPistol ())
|
||||||
|
|
@ -316,7 +329,7 @@ const Vector &Bot::GetAimPosition (void)
|
||||||
}
|
}
|
||||||
m_lastEnemyOrigin = targetOrigin;
|
m_lastEnemyOrigin = targetOrigin;
|
||||||
}
|
}
|
||||||
const Vector &velocity = UsesSniper () ? nullvec : (1.0f * m_frameInterval * m_enemy->v.velocity - 1.0 * m_frameInterval * pev->velocity).SkipZ ();
|
const Vector &velocity = UsesSniper () ? nullvec : ((1.0f * m_frameInterval * m_enemy->v.velocity - 1.0 * m_frameInterval * pev->velocity) * m_frameInterval).SkipZ ();
|
||||||
|
|
||||||
if (m_difficulty < 3 && randomize != nullvec)
|
if (m_difficulty < 3 && randomize != nullvec)
|
||||||
{
|
{
|
||||||
|
|
@ -333,7 +346,7 @@ const Vector &Bot::GetAimPosition (void)
|
||||||
m_enemyOrigin = divOffs * randomize + velocity;
|
m_enemyOrigin = divOffs * randomize + velocity;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_enemyOrigin = targetOrigin;
|
m_enemyOrigin = targetOrigin + velocity;
|
||||||
|
|
||||||
return m_enemyOrigin;
|
return m_enemyOrigin;
|
||||||
}
|
}
|
||||||
|
|
@ -389,7 +402,7 @@ float Bot::GetZOffset (float distance)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::IsFriendInLineOfFire (void)
|
bool Bot::IsFriendInLineOfFire (float distance)
|
||||||
{
|
{
|
||||||
// bot can't hurt teammates, if friendly fire is not enabled...
|
// bot can't hurt teammates, if friendly fire is not enabled...
|
||||||
if (!mp_friendlyfire.GetBool () || yb_csdm_mode.GetInt () > 0)
|
if (!mp_friendlyfire.GetBool () || yb_csdm_mode.GetInt () > 0)
|
||||||
|
|
@ -409,9 +422,7 @@ bool Bot::IsFriendInLineOfFire (void)
|
||||||
if (playerIndex >= 0 && playerIndex < GetMaxClients () && g_clients[playerIndex].team == m_team && (g_clients[playerIndex].flags & CF_ALIVE))
|
if (playerIndex >= 0 && playerIndex < GetMaxClients () && g_clients[playerIndex].team == m_team && (g_clients[playerIndex].flags & CF_ALIVE))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// search the world for players
|
// search the world for players
|
||||||
for (int i = 0; i < GetMaxClients (); i++)
|
for (int i = 0; i < GetMaxClients (); i++)
|
||||||
{
|
{
|
||||||
|
|
@ -427,7 +438,6 @@ bool Bot::IsFriendInLineOfFire (void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::IsShootableThruObstacle (const Vector &dest)
|
bool Bot::IsShootableThruObstacle (const Vector &dest)
|
||||||
|
|
@ -591,7 +601,7 @@ void Bot::FireWeapon (void)
|
||||||
// or if friend in line of fire, stop this too but do not update shoot time
|
// or if friend in line of fire, stop this too but do not update shoot time
|
||||||
if (!IsEntityNull (m_enemy))
|
if (!IsEntityNull (m_enemy))
|
||||||
{
|
{
|
||||||
if (IsFriendInLineOfFire ())
|
if (IsFriendInLineOfFire (distance))
|
||||||
{
|
{
|
||||||
m_fightStyle = 1;
|
m_fightStyle = 1;
|
||||||
m_lastFightStyleCheck = GetWorldTime ();
|
m_lastFightStyleCheck = GetWorldTime ();
|
||||||
|
|
@ -663,6 +673,7 @@ void Bot::FireWeapon (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
WeaponSelectEnd:
|
WeaponSelectEnd:
|
||||||
|
|
||||||
// we want to fire weapon, don't reload now
|
// we want to fire weapon, don't reload now
|
||||||
if (!m_isReloading)
|
if (!m_isReloading)
|
||||||
{
|
{
|
||||||
|
|
@ -733,7 +744,7 @@ WeaponSelectEnd:
|
||||||
m_navTimeset = GetWorldTime ();
|
m_navTimeset = GetWorldTime ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (UsesZoomableRifle () && m_zoomCheckTime < GetWorldTime () && m_difficulty <= 3) // else is the bot holding a zoomable rifle?
|
else if (m_difficulty <= 3 && UsesZoomableRifle () && m_zoomCheckTime < GetWorldTime ()) // else is the bot holding a zoomable rifle?
|
||||||
{
|
{
|
||||||
if (distance > 800 && pev->fov >= 90) // should the bot switch to zoomed mode?
|
if (distance > 800 && pev->fov >= 90) // should the bot switch to zoomed mode?
|
||||||
pev->button |= IN_ATTACK2;
|
pev->button |= IN_ATTACK2;
|
||||||
|
|
@ -744,7 +755,7 @@ WeaponSelectEnd:
|
||||||
m_zoomCheckTime = GetWorldTime ();
|
m_zoomCheckTime = GetWorldTime ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasPrimaryWeapon () && GetAmmoInClip () <= 0)
|
if (selectId != WEAPON_KNIFE && HasPrimaryWeapon () && GetAmmoInClip () <= 0)
|
||||||
{
|
{
|
||||||
if (GetAmmo () <= 0 && !(m_states &= ~(STATE_THROW_HE | STATE_THROW_FB | STATE_THROW_SG)))
|
if (GetAmmo () <= 0 && !(m_states &= ~(STATE_THROW_HE | STATE_THROW_FB | STATE_THROW_SG)))
|
||||||
SelectPistol();
|
SelectPistol();
|
||||||
|
|
@ -754,7 +765,6 @@ WeaponSelectEnd:
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float baseDelay = delay[chosenWeaponIndex].primaryBaseDelay;
|
const float baseDelay = delay[chosenWeaponIndex].primaryBaseDelay;
|
||||||
|
|
||||||
const float minDelay = delay[chosenWeaponIndex].primaryMinDelay[abs (m_difficulty - 4)];
|
const float minDelay = delay[chosenWeaponIndex].primaryMinDelay[abs (m_difficulty - 4)];
|
||||||
|
|
@ -775,7 +785,7 @@ WeaponSelectEnd:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LookupEnemy ();
|
LookupEnemy ();
|
||||||
|
|
||||||
if (selectTab[chosenWeaponIndex].primaryFireHold && m_ammo[g_weaponDefs[selectTab[selectIndex].id].ammo1] >= selectTab[selectIndex].minPrimaryAmmo) // if automatic weapon, just press attack
|
if (selectTab[chosenWeaponIndex].primaryFireHold && m_ammo[g_weaponDefs[selectTab[selectIndex].id].ammo1] >= selectTab[selectIndex].minPrimaryAmmo) // if automatic weapon, just press attack
|
||||||
pev->button |= IN_ATTACK;
|
pev->button |= IN_ATTACK;
|
||||||
|
|
@ -785,9 +795,7 @@ WeaponSelectEnd:
|
||||||
pev->button |= IN_ATTACK;
|
pev->button |= IN_ATTACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_shootTime = GetWorldTime ();
|
||||||
if (pev->button & IN_ATTACK)
|
|
||||||
m_shootTime = GetWorldTime ();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -796,7 +804,10 @@ WeaponSelectEnd:
|
||||||
|
|
||||||
// don't attack with knife over long distance
|
// don't attack with knife over long distance
|
||||||
if (selectId == WEAPON_KNIFE)
|
if (selectId == WEAPON_KNIFE)
|
||||||
|
{
|
||||||
|
m_shootTime = GetWorldTime ();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (selectTab[chosenWeaponIndex].primaryFireHold)
|
if (selectTab[chosenWeaponIndex].primaryFireHold)
|
||||||
{
|
{
|
||||||
|
|
@ -853,7 +864,7 @@ void Bot::FocusEnemy (void)
|
||||||
|
|
||||||
float distance = enemyOrigin.GetLength (); // how far away is the enemy scum?
|
float distance = enemyOrigin.GetLength (); // how far away is the enemy scum?
|
||||||
|
|
||||||
if (distance < 256.0f)
|
if (distance < 128.0f)
|
||||||
{
|
{
|
||||||
if (m_currentWeapon == WEAPON_KNIFE)
|
if (m_currentWeapon == WEAPON_KNIFE)
|
||||||
{
|
{
|
||||||
|
|
@ -865,29 +876,25 @@ void Bot::FocusEnemy (void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_currentWeapon == WEAPON_KNIFE)
|
float dot = GetShootingConeDeviation (GetEntity (), &m_enemyOrigin);
|
||||||
m_wantsToFire = true;
|
|
||||||
|
if (dot < 0.90f)
|
||||||
|
m_wantsToFire = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float dot = GetShootingConeDeviation (GetEntity (), &m_enemyOrigin);
|
float enemyDot = GetShootingConeDeviation (m_enemy, &pev->origin);
|
||||||
|
|
||||||
if (dot < 0.90)
|
// enemy faces bot?
|
||||||
m_wantsToFire = false;
|
if (enemyDot >= 0.90f)
|
||||||
|
m_wantsToFire = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float enemyDot = GetShootingConeDeviation (m_enemy, &pev->origin);
|
if (dot > 0.99f)
|
||||||
|
|
||||||
// enemy faces bot?
|
|
||||||
if (enemyDot >= 0.90)
|
|
||||||
m_wantsToFire = true;
|
m_wantsToFire = true;
|
||||||
else
|
else
|
||||||
{
|
m_wantsToFire = false;
|
||||||
if (dot > 0.99)
|
|
||||||
m_wantsToFire = true;
|
|
||||||
else
|
|
||||||
m_wantsToFire = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1065,7 +1065,7 @@ bool Bot::DoWaypointNav (void)
|
||||||
|
|
||||||
edict_t *ent = NULL;
|
edict_t *ent = NULL;
|
||||||
|
|
||||||
if (m_doorOpenAttempt > 2 && !IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, 100)))
|
if (m_doorOpenAttempt > 2 && !IsEntityNull (ent = FIND_ENTITY_IN_SPHERE (ent, pev->origin, 256.0f)))
|
||||||
{
|
{
|
||||||
if (IsValidPlayer (ent) && IsAlive (ent) && m_team != GetTeam (ent) && GetWeaponPenetrationPower (m_currentWeapon) > 0)
|
if (IsValidPlayer (ent) && IsAlive (ent) && m_team != GetTeam (ent) && GetWeaponPenetrationPower (m_currentWeapon) > 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue