some optimizations in changes in player avoidance code

This commit is contained in:
jeefo 2015-07-01 00:47:39 +03:00
commit dbd22ec99e
3 changed files with 79 additions and 54 deletions

View file

@ -1020,7 +1020,8 @@ private:
int FindGoal (void); int FindGoal (void);
void FilterGoals (const Array <int> &goals, int *result); void FilterGoals (const Array <int> &goals, int *result);
void FindItem (void); void FindItem (void);
void CheckTerrain (float movedDistance, const Vector &dir, const Vector &dirNormal); void CheckTerrain (float movedDistance, const Vector &dirNormal);
void CheckCloseAvoidance (const Vector &dirNormal);
void GetCampDirection (Vector *dest); void GetCampDirection (Vector *dest);
void CollectGoalExperience (int damage, int team); void CollectGoalExperience (int damage, int team);

View file

@ -2009,7 +2009,7 @@ void Bot::SetConditions (void)
} }
// don't listen if seeing enemy, just checked for sounds or being blinded (because its inhuman) // don't listen if seeing enemy, just checked for sounds or being blinded (because its inhuman)
if (!yb_ignore_enemies.GetBool () && m_soundUpdateTime <= GetWorldTime () && m_blindTime < GetWorldTime ()) if (!yb_ignore_enemies.GetBool () && m_soundUpdateTime < GetWorldTime () && m_blindTime < GetWorldTime () && m_seeEnemyTime + 1.0f < GetWorldTime ())
{ {
ReactOnSound (); ReactOnSound ();
m_soundUpdateTime = GetWorldTime () + 0.25f; m_soundUpdateTime = GetWorldTime () + 0.25f;
@ -2019,10 +2019,7 @@ void Bot::SetConditions (void)
if (IsEntityNull (m_enemy) && !IsEntityNull (m_lastEnemy) && m_lastEnemyOrigin != nullvec) if (IsEntityNull (m_enemy) && !IsEntityNull (m_lastEnemy) && m_lastEnemyOrigin != nullvec)
{ {
TraceResult tr; if ((pev->origin - m_lastEnemyOrigin).GetLength () < 1600.0f)
TraceLine (EyePosition (), m_lastEnemyOrigin, true, GetEntity (), &tr);
if ((pev->origin - m_lastEnemyOrigin).GetLength () < 1600.0 && (tr.flFraction >= 0.2 || tr.pHit != g_worldEntity))
{ {
m_aimFlags |= AIM_PREDICT_PATH; m_aimFlags |= AIM_PREDICT_PATH;
@ -2926,7 +2923,7 @@ void Bot::ChooseAimDirection (void)
{ {
TraceLine (EyePosition (), m_lastEnemyOrigin, false, true, GetEntity (), &tr); TraceLine (EyePosition (), m_lastEnemyOrigin, false, true, GetEntity (), &tr);
if (tr.flFraction <= 0.2 && tr.pHit == g_worldEntity) if (tr.flFraction <= 0.2)
{ {
if ((m_aimFlags & (AIM_LAST_ENEMY | AIM_PREDICT_PATH)) && m_wantsToFire) if ((m_aimFlags & (AIM_LAST_ENEMY | AIM_PREDICT_PATH)) && m_wantsToFire)
m_wantsToFire = false; m_wantsToFire = false;
@ -2940,7 +2937,7 @@ void Bot::ChooseAimDirection (void)
m_aimFlags &= ~(AIM_LAST_ENEMY | AIM_PREDICT_PATH); m_aimFlags &= ~(AIM_LAST_ENEMY | AIM_PREDICT_PATH);
// if in battle, and enemy is behind something for short period of time, look at that origin! // if in battle, and enemy is behind something for short period of time, look at that origin!
if (m_seeEnemyTime + 2.0f < GetWorldTime () && !(m_aimFlags & AIM_ENEMY) && m_lastEnemyOrigin != nullvec && IsAlive (m_lastEnemy)) if (m_difficulty < 4 && m_seeEnemyTime + 2.0f < GetWorldTime () && !(m_aimFlags & AIM_ENEMY) && m_lastEnemyOrigin != nullvec && IsAlive (m_lastEnemy))
{ {
m_aimFlags |= AIM_LAST_ENEMY; m_aimFlags |= AIM_LAST_ENEMY;
m_canChooseAimDirection = false; m_canChooseAimDirection = false;
@ -3447,8 +3444,11 @@ void Bot::RunTask (void)
m_checkTerrain = false; m_checkTerrain = false;
m_navTimeset = GetWorldTime (); m_navTimeset = GetWorldTime ();
m_moveSpeed = 0; m_moveSpeed = 0.0f;
m_strafeSpeed = 0.0; m_strafeSpeed = 0.0f;
m_isStuck = false;
m_lastCollTime = GetWorldTime () + 0.5f;
break; break;
@ -4917,13 +4917,10 @@ void Bot::BotAI (void)
SetIdealReactionTimes (); SetIdealReactionTimes ();
// calculate 2 direction vectors, 1 without the up/down component // calculate 2 direction vectors, 1 without the up/down component
const Vector &directionOld = m_destOrigin - (pev->origin + pev->velocity * m_frameInterval); const Vector &dirOld = m_destOrigin - (pev->origin + pev->velocity * m_frameInterval);
Vector directionNormal = directionOld.Normalize (); const Vector &dirNormal = dirOld.Normalize2D ();
const Vector &direction = directionNormal; m_moveAngles = dirOld.ToAngles ();
directionNormal.z = 0.0;
m_moveAngles = directionOld.ToAngles ();
m_moveAngles.ClampAngles (); m_moveAngles.ClampAngles ();
m_moveAngles.x *= -1.0; // invert for engine m_moveAngles.x *= -1.0; // invert for engine
@ -4973,7 +4970,7 @@ void Bot::BotAI (void)
} }
if (m_checkTerrain) // are we allowed to check blocking terrain (and react to it)? if (m_checkTerrain) // are we allowed to check blocking terrain (and react to it)?
CheckTerrain (movedDistance, direction, directionNormal); CheckTerrain (movedDistance, dirNormal);
// must avoid a grenade? // must avoid a grenade?
if (m_needAvoidGrenade != 0) if (m_needAvoidGrenade != 0)
@ -5975,7 +5972,7 @@ void Bot::ReactOnSound (void)
// loop through all enemy clients to check for hearable stuff // loop through all enemy clients to check for hearable stuff
for (int i = 0; i < GetMaxClients (); i++) for (int i = 0; i < GetMaxClients (); i++)
{ {
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].ent == GetEntity () || g_clients[i].timeSoundLasting < GetWorldTime ()) if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].ent == GetEntity () || g_clients[i].team == m_team || g_clients[i].timeSoundLasting < GetWorldTime ())
continue; continue;
float distance = (g_clients[i].soundPosition - pev->origin).GetLength (); float distance = (g_clients[i].soundPosition - pev->origin).GetLength ();
@ -5992,9 +5989,6 @@ void Bot::ReactOnSound (void)
else else
volume = 2.0 * hearingDistance * (1.0 - distance / hearingDistance) * (g_clients[i].timeSoundLasting - GetWorldTime ()) / g_clients[i].maxTimeSoundLasting; volume = 2.0 * hearingDistance * (1.0 - distance / hearingDistance) * (g_clients[i].timeSoundLasting - GetWorldTime ()) / g_clients[i].maxTimeSoundLasting;
if (g_clients[i].team == m_team && yb_csdm_mode.GetInt () != 2)
volume = 0.3 * volume;
// we will care about the most hearable sound instead of the closest one - KWo // we will care about the most hearable sound instead of the closest one - KWo
if (volume < maxVolume) if (volume < maxVolume)
continue; continue;
@ -6017,7 +6011,7 @@ void Bot::ReactOnSound (void)
if (IsValidPlayer (player)) if (IsValidPlayer (player))
{ {
// change to best weapon if heard something // change to best weapon if heard something
if (!(m_states & STATE_SEEING_ENEMY) && m_seeEnemyTime + 2.5 < GetWorldTime () && IsOnFloor () && m_currentWeapon != WEAPON_C4 && m_currentWeapon != WEAPON_EXPLOSIVE && m_currentWeapon != WEAPON_SMOKE && m_currentWeapon != WEAPON_FLASHBANG && !yb_jasonmode.GetBool ()) if (m_shootTime + 2.5 < GetWorldTime () && IsOnFloor () && m_currentWeapon != WEAPON_C4 && m_currentWeapon != WEAPON_EXPLOSIVE && m_currentWeapon != WEAPON_SMOKE && m_currentWeapon != WEAPON_FLASHBANG && !yb_jasonmode.GetBool ())
SelectBestWeapon (); SelectBestWeapon ();
m_heardSoundTime = GetWorldTime () + 5.0; m_heardSoundTime = GetWorldTime () + 5.0;

View file

@ -317,27 +317,41 @@ void Bot::ResetCollideState (void)
m_collideMoves[i] = 0; m_collideMoves[i] = 0;
} }
void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &dirNormal) void Bot::CheckCloseAvoidance (const Vector &dirNormal)
{ {
m_isStuck = false; if (m_seeEnemyTime + 1.0f > GetWorldTime ())
return;
Vector src = nullvec;
Vector dst = nullvec;
Vector direction = dir;
Vector directionNormal = dirNormal;
TraceResult tr;
edict_t *nearest = NULL; edict_t *nearest = NULL;
float nearestDist = 99999.0f;
int playerCount = 0;
if (g_timeRoundStart + 10.0f < GetWorldTime () && FindNearestPlayer (reinterpret_cast <void **> (&nearest), GetEntity (), pev->maxspeed, true, false, true, true)) // found somebody? for (int i = 0; i < GetMaxClients (); i++)
{
Client *cl = &g_clients[i];
if (!(cl->flags & (CF_USED | CF_USED)) || cl->ent == GetEntity () || cl->team != m_team)
continue;
float distance = (cl->ent->v.origin - pev->origin).GetLength ();
if (distance < nearestDist && distance < pev->maxspeed)
{
nearestDist = distance;
nearest = cl->ent;
playerCount++;
}
}
if (playerCount < 3 && IsValidPlayer (nearest))
{ {
MakeVectors (m_moveAngles); // use our movement angles MakeVectors (m_moveAngles); // use our movement angles
// try to predict where we should be next frame // try to predict where we should be next frame
Vector moved = pev->origin + g_pGlobals->v_forward * m_moveSpeed * m_frameInterval; Vector moved = pev->origin + g_pGlobals->v_forward * m_moveSpeed * m_frameInterval;
moved = moved + g_pGlobals->v_right * m_strafeSpeed * m_frameInterval; moved += g_pGlobals->v_right * m_strafeSpeed * m_frameInterval;
moved = moved + pev->velocity * m_frameInterval; moved += pev->velocity * m_frameInterval;
float nearestDistance = (nearest->v.origin - pev->origin).GetLength2D (); float nearestDistance = (nearest->v.origin - pev->origin).GetLength2D ();
float nextFrameDistance = ((nearest->v.origin + nearest->v.velocity * m_frameInterval) - pev->origin).GetLength2D (); float nextFrameDistance = ((nearest->v.origin + nearest->v.velocity * m_frameInterval) - pev->origin).GetLength2D ();
@ -349,9 +363,9 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
Vector dirToPoint = (pev->origin - nearest->v.origin).Get2D (); Vector dirToPoint = (pev->origin - nearest->v.origin).Get2D ();
if ((dirToPoint | g_pGlobals->v_right.Get2D ()) > 0.0) if ((dirToPoint | g_pGlobals->v_right.Get2D ()) > 0.0)
SetStrafeSpeed (directionNormal, pev->maxspeed); SetStrafeSpeed (dirNormal, pev->maxspeed);
else else
SetStrafeSpeed (directionNormal, -pev->maxspeed); SetStrafeSpeed (dirNormal, -pev->maxspeed);
ResetCollideState (); ResetCollideState ();
@ -359,6 +373,18 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
m_moveSpeed = -pev->maxspeed; m_moveSpeed = -pev->maxspeed;
} }
} }
}
void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal)
{
m_isStuck = false;
Vector src = nullvec;
Vector dst = nullvec;
TraceResult tr;
CheckCloseAvoidance (dirNormal);
// Standing still, no need to check? // Standing still, no need to check?
// FIXME: doesn't care for ladder movement (handled separately) should be included in some way // FIXME: doesn't care for ladder movement (handled separately) should be included in some way
@ -378,7 +404,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
else // not stuck yet else // not stuck yet
{ {
// test if there's something ahead blocking the way // test if there's something ahead blocking the way
if ((cantMoveForward = CantMoveForward (directionNormal, &tr)) && !IsOnLadder ()) if ((cantMoveForward = CantMoveForward (dirNormal, &tr)) && !IsOnLadder ())
{ {
if (m_firstCollideTime == 0.0) if (m_firstCollideTime == 0.0)
m_firstCollideTime = GetWorldTime () + 0.2; m_firstCollideTime = GetWorldTime () + 0.2;
@ -392,7 +418,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
if (!m_isStuck) // not stuck? if (!m_isStuck) // not stuck?
{ {
if (m_probeTime + 0.5 < GetWorldTime ()) if (m_probeTime + 0.5f < GetWorldTime ())
ResetCollideState (); // reset collision memory if not being stuck for 0.5 secs ResetCollideState (); // reset collision memory if not being stuck for 0.5 secs
else else
{ {
@ -414,7 +440,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
else if (IsInWater ()) else if (IsInWater ())
bits |= (PROBE_JUMP | PROBE_STRAFE); bits |= (PROBE_JUMP | PROBE_STRAFE);
else else
bits |= ((Random.Long (0, 10) > (cantMoveForward ? 7 : 5) ? PROBE_JUMP : 0) | PROBE_STRAFE | PROBE_DUCK); bits |= ((Random.Long (0, 20) > (cantMoveForward ? 15 : 10) ? PROBE_JUMP : 0) | PROBE_STRAFE | PROBE_DUCK);
// collision check allowed if not flying through the air // collision check allowed if not flying through the air
if (IsOnFloor () || IsOnLadder () || IsInWater ()) if (IsOnFloor () || IsOnLadder () || IsInWater ())
@ -433,7 +459,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
{ {
state[i] = 0; state[i] = 0;
if (CanJumpUp (directionNormal)) if (CanJumpUp (dirNormal))
state[i] += 10; state[i] += 10;
if (m_destOrigin.z >= pev->origin.z + 18.0) if (m_destOrigin.z >= pev->origin.z + 18.0)
@ -444,14 +470,14 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
MakeVectors (m_moveAngles); MakeVectors (m_moveAngles);
src = EyePosition (); src = EyePosition ();
src = src + (g_pGlobals->v_right * 15); src = src + g_pGlobals->v_right * 15;
TraceLine (src, m_destOrigin, true, true, GetEntity (), &tr); TraceLine (src, m_destOrigin, true, true, GetEntity (), &tr);
if (tr.flFraction >= 1.0) if (tr.flFraction >= 1.0)
{ {
src = EyePosition (); src = EyePosition ();
src = src - (g_pGlobals->v_right * 15); src = src - g_pGlobals->v_right * 15;
TraceLine (src, m_destOrigin, true, true, GetEntity (), &tr); TraceLine (src, m_destOrigin, true, true, GetEntity (), &tr);
@ -464,7 +490,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
else else
src = pev->origin + Vector (0, 0, -17); src = pev->origin + Vector (0, 0, -17);
dst = src + directionNormal * 30; dst = src + dirNormal * 30;
TraceLine (src, dst, true, true, GetEntity (), &tr); TraceLine (src, dst, true, true, GetEntity (), &tr);
if (tr.flFraction != 1.0) if (tr.flFraction != 1.0)
@ -478,7 +504,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
{ {
state[i] = 0; state[i] = 0;
if (CanDuckUnder (directionNormal)) if (CanDuckUnder (dirNormal))
state[i] += 10; state[i] += 10;
if ((m_destOrigin.z + 36.0 <= pev->origin.z) && EntityIsVisible (m_destOrigin)) if ((m_destOrigin.z + 36.0 <= pev->origin.z) && EntityIsVisible (m_destOrigin))
@ -509,14 +535,11 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
else else
dirLeft = true; dirLeft = true;
if (m_moveSpeed > 0) const Vector &testDir = m_moveSpeed > 0.0f ? g_pGlobals->v_forward : -g_pGlobals->v_forward;
direction = g_pGlobals->v_forward;
else
direction = -g_pGlobals->v_forward;
// now check which side is blocked // now check which side is blocked
src = pev->origin + (g_pGlobals->v_right * 32); src = pev->origin + (g_pGlobals->v_right * 32);
dst = src + (direction * 32); dst = src + testDir * 32;
TraceHull (src, dst, true, head_hull, GetEntity (), &tr); TraceHull (src, dst, true, head_hull, GetEntity (), &tr);
@ -524,7 +547,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
blockedRight = true; blockedRight = true;
src = pev->origin - (g_pGlobals->v_right * 32); src = pev->origin - (g_pGlobals->v_right * 32);
dst = src + (direction * 32); dst = src + testDir * 32;
TraceHull (src, dst, true, head_hull, GetEntity (), &tr); TraceHull (src, dst, true, head_hull, GetEntity (), &tr);
@ -549,6 +572,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
if (blockedRight) if (blockedRight)
state[i] -= 5; state[i] -= 5;
} }
// weighted all possible moves, now sort them to start with most probable // weighted all possible moves, now sort them to start with most probable
bool isSorting = false; bool isSorting = false;
@ -616,12 +640,12 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dir, const Vector &di
case COLLISION_STRAFELEFT: case COLLISION_STRAFELEFT:
pev->button |= IN_MOVELEFT; pev->button |= IN_MOVELEFT;
SetStrafeSpeed (directionNormal, -pev->maxspeed); SetStrafeSpeed (dirNormal, -pev->maxspeed);
break; break;
case COLLISION_STRAFERIGHT: case COLLISION_STRAFERIGHT:
pev->button |= IN_MOVERIGHT; pev->button |= IN_MOVERIGHT;
SetStrafeSpeed (directionNormal, pev->maxspeed); SetStrafeSpeed (dirNormal, pev->maxspeed);
break; break;
} }
} }
@ -2156,7 +2180,12 @@ int Bot::FindDefendWaypoint (const Vector &origin)
if (waypointIndex[0] == -1) if (waypointIndex[0] == -1)
{ {
Array <int> found; Array <int> found;
g_waypoint->FindInRadius (found, 1024.0f, origin);
for (int i = 0; i < g_numWaypoints; i++)
{
if ((g_waypoint->GetPath (i)->origin - origin).GetLength () <= 1024.0f && !IsPointOccupied (i))
found.Push (i);
}
if (found.IsEmpty ()) if (found.IsEmpty ())
return Random.Long (0, g_numWaypoints - 1); // most worst case, since there a evil error in waypoints return Random.Long (0, g_numWaypoints - 1); // most worst case, since there a evil error in waypoints
@ -2512,6 +2541,8 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr)
Vector src = EyePosition (); Vector src = EyePosition ();
Vector forward = src + normal * 24; Vector forward = src + normal * 24;
MakeVectors (Vector (0, pev->angles.y, 0));
// trace from the bot's eyes straight forward... // trace from the bot's eyes straight forward...
TraceLine (src, forward, true, GetEntity (), tr); TraceLine (src, forward, true, GetEntity (), tr);
@ -2523,7 +2554,6 @@ bool Bot::CantMoveForward (const Vector &normal, TraceResult *tr)
return true; // bot's head will hit something return true; // bot's head will hit something
} }
MakeVectors (Vector (0, pev->angles.y, 0));
// bot's head is clear, check at shoulder level... // bot's head is clear, check at shoulder level...
// trace from the bot's shoulder left diagonal forward to the right shoulder... // trace from the bot's shoulder left diagonal forward to the right shoulder...