bot: return of the cheat cvar yb_whose_your_daddy (resolved #513)

combat: resolve strafe movement issues
combat: resolve bots always standing still with pistols and shotguns
vision: take a look at recent victim for some time before changing view angles
control: allow bots to be killed silently (ref #514) via commands
control: bots that are killed with auto kill timer are now killed silently
This commit is contained in:
jeefo 2024-01-29 08:08:07 +03:00
commit d82124e595
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
14 changed files with 150 additions and 62 deletions

View file

@ -218,8 +218,13 @@ bool Bot::seesEnemy (edict_t *player) {
if (game.isNullEntity (player)) {
return false;
}
bool ignoreFieldOfView = false;
if (isInViewCone (player->v.origin) && frustum.check (m_viewFrustum, player) && checkBodyParts (player)) {
if (cv_whose_your_daddy.bool_ () && util.isPlayer (pev->dmg_inflictor) && game.getTeam (pev->dmg_inflictor) != m_team) {
ignoreFieldOfView = true;
}
if ((ignoreFieldOfView || isInViewCone (player->v.origin)) && frustum.check (m_viewFrustum, player) && checkBodyParts (player)) {
m_seeEnemyTime = game.time ();
m_lastEnemy = player;
m_lastEnemyOrigin = m_enemyOrigin;
@ -314,6 +319,11 @@ bool Bot::lookupEnemies () {
continue;
}
// extra skill player can see thru smoke... if beeing attacked
if (cv_whose_your_daddy.bool_ () && (player->v.button & (IN_ATTACK | IN_ATTACK2)) && m_viewDistance < m_maxViewDistance) {
nearestDistanceSq = cr::sqrf (m_maxViewDistance);
}
// see if bot can see the player...
if (seesEnemy (player)) {
if (isEnemyBehindShield (player)) {
@ -362,7 +372,13 @@ bool Bot::lookupEnemies () {
pushRadioMessage (Radio::EnemySpotted);
}
m_targetEntity = nullptr; // stop following when we see an enemy...
m_enemySurpriseTime = game.time () + m_actualReactionTime;
if (cv_whose_your_daddy.bool_ ()) {
m_enemySurpriseTime = m_actualReactionTime * 0.5f;
}
else {
m_enemySurpriseTime = m_actualReactionTime;
}
// zero out reaction time
m_actualReactionTime = 0.0f;
@ -976,8 +992,12 @@ void Bot::fireWeapons () {
// or if friend in line of fire, stop this too but do not update shoot time
if (isFriendInLineOfFire (distance)) {
m_fireHurtsFriend = true;
return;
}
else {
m_fireHurtsFriend = false;
}
int selectId = Weapon::Knife, selectIndex = 0, choosenWeapon = 0;
const auto tab = conf.getRawWeapons ();
@ -1148,7 +1168,7 @@ void Bot::attackMovement () {
}
auto approach = 0;
const auto distance = m_lookAt.distance2d (getEyesPos ()); // how far away is the enemy scum?
const auto distance = m_lookAt.distance (getEyesPos ()); // how far away is the enemy scum?
if (usesKnife ()) {
approach = 100;
@ -1168,15 +1188,17 @@ void Bot::attackMovement () {
}
// only take cover when bomb is not planted and enemy can see the bot or the bot is VIP
if (!game.is (GameFlags::CSDM) && (m_states & Sense::SeeingEnemy) && approach < 30 && !bots.isBombPlanted () && (isInViewCone (m_enemy->v.origin) || m_isVIP)) {
m_moveSpeed = -pev->maxspeed;
startTask (Task::SeekCover, TaskPri::SeekCover, kInvalidNodeIndex, 0.0f, true);
}
else if (approach < 50) {
m_moveSpeed = 0.0f;
}
else {
m_moveSpeed = pev->maxspeed;
if (!game.is (GameFlags::CSDM)) {
if ((m_states & Sense::SeeingEnemy) && approach < 30 && !bots.isBombPlanted () && (isInViewCone (m_enemy->v.origin) || m_isVIP)) {
m_moveSpeed = -pev->maxspeed;
startTask (Task::SeekCover, TaskPri::SeekCover, kInvalidNodeIndex, 0.0f, true);
}
else if (approach < 50) {
m_moveSpeed = 0.0f;
}
else {
m_moveSpeed = pev->maxspeed;
}
}
if (m_lastFightStyleCheck + 3.0f < game.time ()) {
@ -1215,9 +1237,6 @@ void Bot::attackMovement () {
else if (usesKnife ()) {
m_fightStyle = Fight::Strafe;
}
else if (usesKnife () && isInViewCone (m_enemy->v.origin) && game.is (GameFlags::CSDM) && !isInNarrowPlace ()) {
m_fightStyle = Fight::Strafe;
}
else {
m_fightStyle = Fight::Stay;
}
@ -1226,6 +1245,14 @@ void Bot::attackMovement () {
if (isDucking () || isInNarrowPlace ()) {
m_fightStyle = Fight::Stay;
}
const auto pistolStrafeDistance = game.is (GameFlags::CSDM) ? kDoubleSprayDistance * 3.0f : kDoubleSprayDistance;
// fire hurts friend value here is from previous frame, but acceptable, and saves us alot of cpu cycles
if (m_fireHurtsFriend || ((usesPistol () || usesShotgun ())
&& distance < pistolStrafeDistance
&& isInViewCone (m_enemyOrigin))) {
m_fightStyle = Fight::Strafe;
}
m_lastFightStyleCheck = game.time ();
}
@ -1252,10 +1279,10 @@ void Bot::attackMovement () {
const auto &rightSide = m_enemy->v.v_angle.right ().normalize2d_apx ();
if ((dirToPoint | rightSide) < 0.0f) {
m_combatStrafeDir = Dodge::Left;
m_combatStrafeDir = Dodge::Right;
}
else {
m_combatStrafeDir = Dodge::Right;
m_combatStrafeDir = Dodge::Left;
}
if (rg.chance (30)) {
@ -1267,14 +1294,14 @@ void Bot::attackMovement () {
const bool wallOnRight = checkWallOnRight ();
const bool wallOnLeft = checkWallOnLeft ();
if (m_combatStrafeDir == Dodge::Right) {
if (m_combatStrafeDir == Dodge::Left) {
if (!wallOnLeft) {
m_strafeSpeed = -pev->maxspeed;
}
else if (!wallOnRight) {
swapStrafeCombatDir ();
m_strafeSetTime = strafeUpdateTime ();
m_strafeSetTime = strafeUpdateTime ();
m_strafeSpeed = pev->maxspeed;
}
else {
@ -1288,8 +1315,8 @@ void Bot::attackMovement () {
}
else if (!wallOnLeft) {
swapStrafeCombatDir ();
m_strafeSetTime = strafeUpdateTime ();
m_strafeSetTime = strafeUpdateTime ();
m_strafeSpeed = -pev->maxspeed;
}
else {
@ -1298,14 +1325,12 @@ void Bot::attackMovement () {
}
}
// we're setting strafe speed regardless of move angles, so not resetting forward move here cause bots to behave strange
m_moveSpeed = 0.0f;
if (m_difficulty >= Difficulty::Normal && (m_jumpTime + 5.0f < game.time () && isOnFloor () && rg.get (0, 1000) < (m_isReloading ? 8 : 2) && pev->velocity.length2d () > 150.0f) && !usesSniper ()) {
pev->button |= IN_JUMP;
}
// do not move forward/backward is too far
if (distance > 1024.0f) {
m_moveSpeed = 0.0f;
}
}
else if (m_fightStyle == Fight::Stay) {
const bool alreadyDucking = m_duckTime > game.time () || isDucking ();
@ -1649,16 +1674,18 @@ void Bot::updateTeamCommands () {
bool Bot::isGroupOfEnemies (const Vector &location, int numEnemies, float radius) {
int numPlayers = 0;
// needs a square radius
const float radiusSq = cr::sqrf (radius);
// search the world for enemy players...
for (const auto &client : util.getClients ()) {
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.ent == ent ()) {
continue;
}
if (client.ent->v.origin.distanceSq (location) < cr::sqrf (radius)) {
// don't target our teammates...
if (client.ent->v.origin.distanceSq (location) < radiusSq) {
if (client.team == m_team) {
return false;
return false; // don't target our teammates...
}
if (numPlayers++ > numEnemies) {
@ -1877,16 +1904,16 @@ void Bot::checkGrenadesThrow () {
};
// check if throwing a grenade is a good thing to do...
auto throwingCondition = game.mapIs(MapFlags::GrenadeWar)
const auto throwingCondition = game.mapIs (MapFlags::GrenadeWar)
? false
: (preventibleTasks
|| isInNarrowPlace()
|| cv_ignore_enemies.bool_()
|| isInNarrowPlace ()
|| cv_ignore_enemies.bool_ ()
|| m_isUsingGrenade
|| m_grenadeRequested
|| m_isReloading
|| (isKnifeMode() && !bots.isBombPlanted())
|| m_grenadeCheckTime >= game.time());
|| (isKnifeMode () && !bots.isBombPlanted ())
|| m_grenadeCheckTime >= game.time ());
if (throwingCondition) {
clearThrowStates (m_states);
@ -1896,7 +1923,8 @@ void Bot::checkGrenadesThrow () {
// check again in some seconds
m_grenadeCheckTime = game.time () + kGrenadeCheckTime;
auto senseCondition = game.mapIs(MapFlags::GrenadeWar) ? false : !(m_states & (Sense::SuspectEnemy | Sense::HearingEnemy));
const auto senseCondition = game.mapIs (MapFlags::GrenadeWar) ? false : !(m_states & (Sense::SuspectEnemy | Sense::HearingEnemy));
if (!util.isAlive (m_lastEnemy) || senseCondition) {
clearThrowStates (m_states);
return;
@ -1939,7 +1967,7 @@ void Bot::checkGrenadesThrow () {
}
// enemy within a good throw distance?
auto grenadeToThrowCondition = game.mapIs(MapFlags::GrenadeWar)
const auto grenadeToThrowCondition = game.mapIs (MapFlags::GrenadeWar)
? 100.0f
: grenadeToThrow == Weapon::Smoke ? 200.0f : 400.0f;