bot: disrupt bot vision in dark areas
This commit is contained in:
parent
d05b6c8507
commit
3d0bb4d7da
5 changed files with 60 additions and 7 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit a518be32e2ccf8e2ddb073fe237d1652cd8b185a
|
Subproject commit c0d1357bcd6b638368f345489c1a0dc70b4a9b38
|
||||||
|
|
@ -435,6 +435,7 @@ private:
|
||||||
bool isEnemyHidden (edict_t *enemy);
|
bool isEnemyHidden (edict_t *enemy);
|
||||||
bool isEnemyInvincible (edict_t *enemy);
|
bool isEnemyInvincible (edict_t *enemy);
|
||||||
bool isEnemyNoTarget (edict_t *enemy);
|
bool isEnemyNoTarget (edict_t *enemy);
|
||||||
|
bool isEnemyInDarkArea (edict_t *enemy);
|
||||||
bool isFriendInLineOfFire (float distance);
|
bool isFriendInLineOfFire (float distance);
|
||||||
bool isGroupOfEnemies (const Vector &location, int numEnemies = 1, float radius = 256.0f);
|
bool isGroupOfEnemies (const Vector &location, int numEnemies = 1, float radius = 256.0f);
|
||||||
bool isPenetrableObstacle (const Vector &dest);
|
bool isPenetrableObstacle (const Vector &dest);
|
||||||
|
|
@ -925,6 +926,7 @@ extern ConVar cv_ignore_enemies_after_spawn_time;
|
||||||
extern ConVar cv_camping_time_min;
|
extern ConVar cv_camping_time_min;
|
||||||
extern ConVar cv_camping_time_max;
|
extern ConVar cv_camping_time_max;
|
||||||
extern ConVar cv_smoke_grenade_checks;
|
extern ConVar cv_smoke_grenade_checks;
|
||||||
|
extern ConVar cv_check_darkness;
|
||||||
|
|
||||||
extern ConVar mp_freezetime;
|
extern ConVar mp_freezetime;
|
||||||
extern ConVar mp_roundtime;
|
extern ConVar mp_roundtime;
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ void Bot::avoidGrenades () {
|
||||||
|
|
||||||
if (m_preventFlashing < game.time ()
|
if (m_preventFlashing < game.time ()
|
||||||
&& m_personality == Personality::Rusher
|
&& m_personality == Personality::Rusher
|
||||||
&& m_difficulty == Difficulty::Expert
|
&& cv_whose_your_daddy
|
||||||
&& model == kFlashbangModelName) {
|
&& model == kFlashbangModelName) {
|
||||||
|
|
||||||
// don't look at flash bang
|
// don't look at flash bang
|
||||||
|
|
|
||||||
|
|
@ -128,10 +128,49 @@ bool Bot::isEnemyNoTarget (edict_t *enemy) {
|
||||||
return !!(enemy->v.flags & FL_NOTARGET);
|
return !!(enemy->v.flags & FL_NOTARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Bot::isEnemyInDarkArea (edict_t *enemy) {
|
||||||
|
if (!cv_check_darkness && game.isNullEntity (enemy)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto scolor = illum.getSkyColor ();
|
||||||
|
|
||||||
|
// check if node near the enemy have a degraded light level
|
||||||
|
const auto enemyNodeIndex = graph.getNearest (m_enemy->v.origin);
|
||||||
|
|
||||||
|
if (!graph.exists (enemyNodeIndex)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto llevel = graph[enemyNodeIndex].light;
|
||||||
|
|
||||||
|
// if light level is higher than 30, do not bother with further tests
|
||||||
|
if (llevel > 30.0f) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool enemySemiTransparent = false;
|
||||||
|
|
||||||
|
const bool enemyHasGun = (enemy->v.weapons & kPrimaryWeaponMask) || (enemy->v.weapons & kSecondaryWeaponMask);
|
||||||
|
const bool enemyHasFlashlightEnabled = !!(enemy->v.effects & EF_DIMLIGHT);
|
||||||
|
const bool enemyIsAttacking = !!(enemy->v.oldbuttons & IN_ATTACK);
|
||||||
|
|
||||||
|
if (!m_usesNVG && ((llevel < 3.0f && scolor > 50.0f) || (llevel < 25.0f && scolor <= 50.0f))
|
||||||
|
&& !enemyHasFlashlightEnabled && (!enemyIsAttacking || !enemyHasGun)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (((llevel < 10.0f && scolor > 50.0f) || (llevel < 30.0f && scolor <= 50.0f)
|
||||||
|
|| (enemyIsAttacking && enemyHasGun))
|
||||||
|
&& !m_usesNVG && !enemyHasFlashlightEnabled) {
|
||||||
|
enemySemiTransparent = true;
|
||||||
|
}
|
||||||
|
TraceResult result {};
|
||||||
|
game.testLine (getEyesPos (), enemy->v.origin, m_isCreature ? TraceIgnore::None : TraceIgnore::Everything, ent (), &result);
|
||||||
|
|
||||||
|
return (result.flFraction <= 1.0f && result.pHit == enemy && (m_usesNVG || !enemySemiTransparent));
|
||||||
|
}
|
||||||
|
|
||||||
bool Bot::checkBodyParts (edict_t *target) {
|
bool Bot::checkBodyParts (edict_t *target) {
|
||||||
// this function checks visibility of a bot target.
|
// this function checks visibility of a bot target.
|
||||||
|
|
||||||
if (isEnemyHidden (target) || isEnemyInvincible (target) || isEnemyNoTarget (target)) {
|
if (isEnemyHidden (target) || isEnemyInvincible (target) || isEnemyNoTarget (target) || isEnemyInDarkArea (target)) {
|
||||||
m_enemyParts = Visibility::None;
|
m_enemyParts = Visibility::None;
|
||||||
m_enemyOrigin.clear ();
|
m_enemyOrigin.clear ();
|
||||||
|
|
||||||
|
|
@ -336,6 +375,9 @@ void Bot::trackEnemies () {
|
||||||
bool Bot::lookupEnemies () {
|
bool Bot::lookupEnemies () {
|
||||||
// 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_enemyParts = Visibility::None;
|
||||||
|
m_enemyOrigin.clear ();
|
||||||
|
|
||||||
// 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_enemyIgnoreTimer > game.time () || m_blindTime > game.time () || cv_ignore_enemies) {
|
if (m_enemyIgnoreTimer > game.time () || m_blindTime > game.time () || cv_ignore_enemies) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -359,8 +401,6 @@ bool Bot::lookupEnemies () {
|
||||||
m_aimFlags |= AimFlags::LastEnemy;
|
m_aimFlags |= AimFlags::LastEnemy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_enemyParts = Visibility::None;
|
|
||||||
m_enemyOrigin.clear ();
|
|
||||||
|
|
||||||
if (!game.isNullEntity (m_enemy)) {
|
if (!game.isNullEntity (m_enemy)) {
|
||||||
player = m_enemy;
|
player = m_enemy;
|
||||||
|
|
|
||||||
|
|
@ -559,8 +559,19 @@ void Bot::blind_ () {
|
||||||
m_navTimeset = game.time ();
|
m_navTimeset = game.time ();
|
||||||
|
|
||||||
// if bot remembers last enemy position
|
// if bot remembers last enemy position
|
||||||
if (m_difficulty >= Difficulty::Normal && !m_lastEnemyOrigin.empty () && util.isPlayer (m_lastEnemy) && !usesSniper ()) {
|
if (rg.chance (50)
|
||||||
m_lookAt = m_lastEnemyOrigin; // face last enemy
|
&& m_difficulty >= Difficulty::Normal
|
||||||
|
&& !m_lastEnemyOrigin.empty ()
|
||||||
|
&& util.isPlayer (m_lastEnemy)
|
||||||
|
&& !usesSniper ()) {
|
||||||
|
|
||||||
|
auto error = kSprayDistance * cr::powf (m_lastEnemyOrigin.distance (pev->origin), 0.5f) / 2048.0f;
|
||||||
|
auto origin = m_lastEnemyOrigin;
|
||||||
|
|
||||||
|
origin.x = origin.x + rg (-error, error);
|
||||||
|
origin.y = origin.y + rg (-error, error);
|
||||||
|
|
||||||
|
m_lookAt = origin; // face last enemy
|
||||||
m_wantsToFire = true; // and shoot it
|
m_wantsToFire = true; // and shoot it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue