made lower difficulty bots a bit easier
This commit is contained in:
parent
533cd8a93c
commit
4256d15bf1
5 changed files with 121 additions and 23 deletions
|
|
@ -893,8 +893,10 @@ private:
|
||||||
edict_t *m_targetEntity; // the entity that the bot is trying to reach
|
edict_t *m_targetEntity; // the entity that the bot is trying to reach
|
||||||
edict_t *m_hostages[MAX_HOSTAGES]; // pointer to used hostage entities
|
edict_t *m_hostages[MAX_HOSTAGES]; // pointer to used hostage entities
|
||||||
|
|
||||||
|
bool m_moveToGoal; // bot currently moving to goal??
|
||||||
bool m_isStuck; // bot is stuck
|
bool m_isStuck; // bot is stuck
|
||||||
bool m_isReloading; // bot is reloading a gun
|
bool m_isReloading; // bot is reloading a gun
|
||||||
|
|
||||||
int m_reloadState; // current reload state
|
int m_reloadState; // current reload state
|
||||||
int m_voicePitch; // bot voice pitch
|
int m_voicePitch; // bot voice pitch
|
||||||
|
|
||||||
|
|
@ -946,13 +948,19 @@ private:
|
||||||
float m_lookPitchVel; // look pitch velocity
|
float m_lookPitchVel; // look pitch velocity
|
||||||
float m_lookUpdateTime; // lookangles update time
|
float m_lookUpdateTime; // lookangles update time
|
||||||
|
|
||||||
bool m_moveToGoal; // bot currently moving to goal??
|
Vector m_randomizedIdealAngles; // angle wanted with noise
|
||||||
|
Vector m_angularDeviation; // angular deviation from current to ideal angles
|
||||||
|
Vector m_aimSpeed; // aim speed calculated
|
||||||
|
|
||||||
|
float m_randomizeAnglesTime; // time last randomized location
|
||||||
|
float m_playerTargetTime; // time last targeting
|
||||||
|
|
||||||
void InstantChatterMessage (int type);
|
void InstantChatterMessage (int type);
|
||||||
void BotAI (void);
|
void BotAI (void);
|
||||||
void CheckSpawnTimeConditions (void);
|
void CheckSpawnTimeConditions (void);
|
||||||
bool IsMorePowerfulWeaponCanBeBought (void);
|
|
||||||
void PurchaseWeapons (void);
|
void PurchaseWeapons (void);
|
||||||
|
|
||||||
|
bool IsMorePowerfulWeaponCanBeBought (void);
|
||||||
int PickBestFromRandom (int *random, int count);
|
int PickBestFromRandom (int *random, int count);
|
||||||
|
|
||||||
bool CanDuckUnder (const Vector &normal);
|
bool CanDuckUnder (const Vector &normal);
|
||||||
|
|
@ -1009,6 +1017,7 @@ private:
|
||||||
bool EnemyIsThreat (void);
|
bool EnemyIsThreat (void);
|
||||||
void UpdateLookAngles (void);
|
void UpdateLookAngles (void);
|
||||||
void UpdateBodyAngles (void);
|
void UpdateBodyAngles (void);
|
||||||
|
void UpdateLookAnglesLowSkill (const Vector &direction, const float delta);
|
||||||
void SetIdealReactionTimes (bool actual = false);
|
void SetIdealReactionTimes (bool actual = false);
|
||||||
bool IsRestricted (int weaponIndex);
|
bool IsRestricted (int weaponIndex);
|
||||||
bool IsRestrictedAMX (int weaponIndex);
|
bool IsRestrictedAMX (int weaponIndex);
|
||||||
|
|
|
||||||
|
|
@ -5229,7 +5229,7 @@ void Bot::TakeDamage (edict_t *inflictor, int damage, int armor, int bits)
|
||||||
|
|
||||||
if (IsValidPlayer (inflictor))
|
if (IsValidPlayer (inflictor))
|
||||||
{
|
{
|
||||||
if (m_seeEnemyTime + 4.0f < GetWorldTime () && yb_tkpunish.GetBool () && GetTeam (inflictor) == m_team && !bots.GetBot (inflictor))
|
if (yb_tkpunish.GetBool () && GetTeam (inflictor) == m_team && !IsValidBot (inflictor))
|
||||||
{
|
{
|
||||||
// alright, die you teamkiller!!!
|
// alright, die you teamkiller!!!
|
||||||
m_actualReactionTime = 0.0f;
|
m_actualReactionTime = 0.0f;
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart)
|
||||||
*bodyPart |= VISIBLE_HEAD;
|
*bodyPart |= VISIBLE_HEAD;
|
||||||
*origin = target->v.origin + target->v.view_ofs;
|
*origin = target->v.origin + target->v.view_ofs;
|
||||||
|
|
||||||
if (m_difficulty == 4)
|
if (m_difficulty > 3)
|
||||||
origin->z += 1.0f;
|
origin->z += 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -509,7 +509,7 @@ const Vector &Bot::GetAimPosition (void)
|
||||||
else
|
else
|
||||||
m_enemyOrigin = targetOrigin;
|
m_enemyOrigin = targetOrigin;
|
||||||
|
|
||||||
if (distance >= 256.0f)
|
if (distance >= 256.0f && m_difficulty < 4)
|
||||||
m_enemyOrigin += velocity;
|
m_enemyOrigin += velocity;
|
||||||
|
|
||||||
return m_enemyOrigin;
|
return m_enemyOrigin;
|
||||||
|
|
@ -517,7 +517,8 @@ const Vector &Bot::GetAimPosition (void)
|
||||||
|
|
||||||
float Bot::GetZOffset (float distance)
|
float Bot::GetZOffset (float distance)
|
||||||
{
|
{
|
||||||
// got it from pbmm
|
if (m_difficulty < 3)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
bool sniper = UsesSniper ();
|
bool sniper = UsesSniper ();
|
||||||
bool pistol = UsesPistol ();
|
bool pistol = UsesPistol ();
|
||||||
|
|
@ -977,6 +978,9 @@ bool Bot::IsWeaponBadInDistance (int weaponIndex, float distance)
|
||||||
// this function checks, is it better to use pistol instead of current primary weapon
|
// this function checks, is it better to use pistol instead of current primary weapon
|
||||||
// to attack our enemy, since current weapon is not very good in this situation.
|
// to attack our enemy, since current weapon is not very good in this situation.
|
||||||
|
|
||||||
|
if (m_difficulty < 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
int weaponID = g_weaponSelect[weaponIndex].id;
|
int weaponID = g_weaponSelect[weaponIndex].id;
|
||||||
|
|
||||||
if (weaponID == WEAPON_KNIFE)
|
if (weaponID == WEAPON_KNIFE)
|
||||||
|
|
|
||||||
|
|
@ -1081,6 +1081,7 @@ void Bot::NewRound (void)
|
||||||
|
|
||||||
m_reloadCheckTime = 0.0;
|
m_reloadCheckTime = 0.0;
|
||||||
m_shootTime = GetWorldTime ();
|
m_shootTime = GetWorldTime ();
|
||||||
|
m_playerTargetTime = GetWorldTime ();
|
||||||
m_firePause = 0.0;
|
m_firePause = 0.0;
|
||||||
m_timeLastFired = 0.0;
|
m_timeLastFired = 0.0;
|
||||||
|
|
||||||
|
|
@ -1159,10 +1160,6 @@ void Bot::NewRound (void)
|
||||||
ChatterMessage (Chatter_NewRound);
|
ChatterMessage (Chatter_NewRound);
|
||||||
|
|
||||||
m_thinkInterval = (1.0f / 30.0f) * Random.Float (0.95f, 1.05f);
|
m_thinkInterval = (1.0f / 30.0f) * Random.Float (0.95f, 1.05f);
|
||||||
|
|
||||||
// fixes bot looking at weird positions during buytime with think fps
|
|
||||||
m_aimFlags |= AIM_NAVPOINT;
|
|
||||||
ChooseAimDirection ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::Kill (void)
|
void Bot::Kill (void)
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,8 @@ int Bot::FindGoal (void)
|
||||||
}
|
}
|
||||||
return m_chosenGoalIndex = ChooseBombWaypoint ();
|
return m_chosenGoalIndex = ChooseBombWaypoint ();
|
||||||
}
|
}
|
||||||
defensive += 25.0f;
|
defensive += 25.0f + m_difficulty * 2.0f;
|
||||||
offensive -= 25.0f;
|
offensive -= 25.0f - m_difficulty * 0.5f;
|
||||||
|
|
||||||
if (m_personality != PERSONALITY_RUSHER)
|
if (m_personality != PERSONALITY_RUSHER)
|
||||||
defensive += 10.0f;
|
defensive += 10.0f;
|
||||||
|
|
@ -649,15 +649,6 @@ bool Bot::DoWaypointNav (void)
|
||||||
|
|
||||||
TraceResult tr, tr2;
|
TraceResult tr, tr2;
|
||||||
|
|
||||||
// check if we fallen from something
|
|
||||||
if (IsOnFloor () && m_jumpFinished && m_currentWaypointIndex > 0)
|
|
||||||
{
|
|
||||||
const Vector &wptOrg = m_currentPath->origin;
|
|
||||||
|
|
||||||
if ((pev->origin - wptOrg).GetLength2D () <= 100.0f && (wptOrg.z > pev->origin.z + 20.0f))
|
|
||||||
m_currentWaypointIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if we need to find a waypoint...
|
// check if we need to find a waypoint...
|
||||||
if (m_currentWaypointIndex == -1)
|
if (m_currentWaypointIndex == -1)
|
||||||
{
|
{
|
||||||
|
|
@ -3173,8 +3164,17 @@ void Bot::UpdateLookAngles (void)
|
||||||
|
|
||||||
direction.ClampAngles ();
|
direction.ClampAngles ();
|
||||||
|
|
||||||
|
// lower skilled bot's have lower aiming
|
||||||
|
if (m_difficulty < 3)
|
||||||
|
{
|
||||||
|
UpdateLookAnglesLowSkill (direction, delta);
|
||||||
|
UpdateBodyAngles ();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// this is what makes bot almost godlike (got it from sypb)
|
// this is what makes bot almost godlike (got it from sypb)
|
||||||
if (m_difficulty == 4 && (m_aimFlags & AIM_ENEMY) && (m_wantsToFire || UsesSniper ()) && yb_whose_your_daddy.GetBool ())
|
if (m_difficulty > 3 && (m_aimFlags & AIM_ENEMY) && (m_wantsToFire || UsesSniper ()) && yb_whose_your_daddy.GetBool ())
|
||||||
{
|
{
|
||||||
pev->v_angle = direction;
|
pev->v_angle = direction;
|
||||||
UpdateBodyAngles ();
|
UpdateBodyAngles ();
|
||||||
|
|
@ -3230,6 +3230,94 @@ void Bot::UpdateLookAngles (void)
|
||||||
UpdateBodyAngles ();
|
UpdateBodyAngles ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bot::UpdateLookAnglesLowSkill (const Vector &direction, const float delta)
|
||||||
|
{
|
||||||
|
Vector spring (13.0f, 13.0f, 0.0f);
|
||||||
|
Vector damperCoefficient (0.22f, 0.22f, 0.0f);
|
||||||
|
|
||||||
|
Vector influence = Vector (0.25f, 0.17f, 0.0f) * ((100 - (m_difficulty * 25)) / 100.f);
|
||||||
|
Vector randomization = Vector (2.0f, 0.18f, 0.0f) * ((100 - (m_difficulty * 25)) / 100.f);
|
||||||
|
|
||||||
|
const float noTargetRatio = 0.3f;
|
||||||
|
const float offsetDelay = 1.2f;
|
||||||
|
|
||||||
|
Vector stiffness = nullvec;
|
||||||
|
Vector randomize = nullvec;
|
||||||
|
|
||||||
|
m_idealAngles = direction.Get2D ();
|
||||||
|
m_idealAngles.ClampAngles ();
|
||||||
|
|
||||||
|
if (m_aimFlags & (AIM_ENEMY | AIM_ENTITY | AIM_GRENADE | AIM_LAST_ENEMY) || GetTaskId () == TASK_SHOOTBREAKABLE)
|
||||||
|
{
|
||||||
|
m_playerTargetTime = GetWorldTime ();
|
||||||
|
m_randomizedIdealAngles = m_idealAngles;
|
||||||
|
|
||||||
|
stiffness = spring * (0.2 + (m_difficulty * 25) / 125.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// is it time for bot to randomize the aim direction again (more often where moving) ?
|
||||||
|
if (m_randomizeAnglesTime < GetWorldTime () && ((pev->velocity.GetLength () > 1.0 && m_angularDeviation.GetLength () < 5.0) || m_angularDeviation.GetLength () < 1.0))
|
||||||
|
{
|
||||||
|
// is the bot standing still ?
|
||||||
|
if (pev->velocity.GetLength () < 1.0)
|
||||||
|
randomize = randomization * 0.2; // randomize less
|
||||||
|
else
|
||||||
|
randomize = randomization;
|
||||||
|
|
||||||
|
// randomize targeted location a bit (slightly towards the ground)
|
||||||
|
m_randomizedIdealAngles = m_idealAngles + Vector (Random.Float (-randomize.x * 0.5, randomize.x * 1.5), Random.Float (-randomize.y, randomize.y), 0);
|
||||||
|
|
||||||
|
// set next time to do this
|
||||||
|
m_randomizeAnglesTime = GetWorldTime () + Random.Float (0.4f, offsetDelay);
|
||||||
|
}
|
||||||
|
float stiffnessMultiplier = noTargetRatio;
|
||||||
|
|
||||||
|
// take in account whether the bot was targeting someone in the last N seconds
|
||||||
|
if (GetWorldTime () - (m_playerTargetTime + offsetDelay) < noTargetRatio * 10.0)
|
||||||
|
{
|
||||||
|
stiffnessMultiplier = 1.0 - (GetWorldTime () - m_timeLastFired) * 0.1;
|
||||||
|
|
||||||
|
// don't allow that stiffness multiplier less than zero
|
||||||
|
if (stiffnessMultiplier < 0.0)
|
||||||
|
stiffnessMultiplier = 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// also take in account the remaining deviation (slow down the aiming in the last 10°)
|
||||||
|
if (m_difficulty < 3 && (m_angularDeviation.GetLength () < 10.0))
|
||||||
|
stiffnessMultiplier *= m_angularDeviation.GetLength () * 0.1;
|
||||||
|
|
||||||
|
// slow down even more if we are not moving
|
||||||
|
if (m_difficulty < 3 && pev->velocity.GetLength () < 1.0 && GetTaskId () != TASK_CAMP && GetTaskId () != TASK_ATTACK)
|
||||||
|
stiffnessMultiplier *= 0.5;
|
||||||
|
|
||||||
|
// but don't allow getting below a certain value
|
||||||
|
if (stiffnessMultiplier < 0.35)
|
||||||
|
stiffnessMultiplier = 0.35;
|
||||||
|
|
||||||
|
stiffness = spring * stiffnessMultiplier; // increasingly slow aim
|
||||||
|
}
|
||||||
|
// compute randomized angle deviation this time
|
||||||
|
m_angularDeviation = m_randomizedIdealAngles - pev->v_angle;
|
||||||
|
m_angularDeviation.ClampAngles ();
|
||||||
|
|
||||||
|
// spring/damper model aiming
|
||||||
|
m_aimSpeed.x = (stiffness.x * m_angularDeviation.x) - (damperCoefficient.x * m_aimSpeed.x);
|
||||||
|
m_aimSpeed.y = (stiffness.y * m_angularDeviation.y) - (damperCoefficient.y * m_aimSpeed.y);
|
||||||
|
|
||||||
|
// influence of y movement on x axis and vice versa (less influence than x on y since it's
|
||||||
|
// easier and more natural for the bot to "move its mouse" horizontally than vertically)
|
||||||
|
m_aimSpeed.x += m_aimSpeed.y * influence.y;
|
||||||
|
m_aimSpeed.y += m_aimSpeed.x * influence.x;
|
||||||
|
|
||||||
|
// move the aim cursor
|
||||||
|
if (m_difficulty == 4 && (m_aimFlags & AIM_ENEMY) && (m_wantsToFire || UsesSniper ()))
|
||||||
|
pev->v_angle = direction;
|
||||||
|
else
|
||||||
|
pev->v_angle = pev->v_angle + delta * Vector (m_aimSpeed.x, m_aimSpeed.y, 0.0f);
|
||||||
|
|
||||||
|
pev->v_angle.ClampAngles ();
|
||||||
|
}
|
||||||
|
|
||||||
void Bot::SetStrafeSpeed (const Vector &moveDir, float strafeSpeed)
|
void Bot::SetStrafeSpeed (const Vector &moveDir, float strafeSpeed)
|
||||||
{
|
{
|
||||||
|
|
@ -3290,7 +3378,7 @@ bool Bot::IsPointOccupied (int index)
|
||||||
// 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 (occupyId == index || bot->GetTask ()->data == index || length < GET_SQUARE (75.0f))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue