simplified a bit hearing and aim dir choosing
bots thnik function not run every frame, should save some fps
This commit is contained in:
parent
abab282bbd
commit
55e4cf4bd9
7 changed files with 151 additions and 247 deletions
|
|
@ -706,7 +706,6 @@ struct Client
|
|||
|
||||
float hearingDistance; // distance this sound is heared
|
||||
float timeSoundLasting; // time sound is played/heared
|
||||
float maxTimeSoundLasting; // max time sound is played/heared (to divide the difference between that above one and the current one)
|
||||
};
|
||||
|
||||
// experience data hold in memory while playing
|
||||
|
|
@ -1010,7 +1009,7 @@ private:
|
|||
|
||||
bool DoWaypointNav (void);
|
||||
bool EnemyIsThreat (void);
|
||||
void FacePosition (void);
|
||||
void UpdateLookAngles (void);
|
||||
void SetIdealReactionTimes (bool actual = false);
|
||||
bool IsRestricted (int weaponIndex);
|
||||
bool IsRestrictedAMX (int weaponIndex);
|
||||
|
|
@ -1178,6 +1177,7 @@ public:
|
|||
float m_agressionLevel; // dynamic aggression level (in game)
|
||||
float m_fearLevel; // dynamic fear level (in game)
|
||||
float m_nextEmotionUpdate; // next time to sanitize emotions
|
||||
float m_thinkFps; // skip some frames in bot thinking
|
||||
|
||||
int m_actMessageIndex; // current processed message
|
||||
int m_pushMessageIndex; // offset for next pushed message
|
||||
|
|
@ -1240,6 +1240,7 @@ public:
|
|||
inline Vector Center (void) { return (pev->absmax + pev->absmin) * 0.5; };
|
||||
inline Vector EyePosition (void) { return pev->origin + pev->view_ofs; };
|
||||
|
||||
void ThinkMain (void);
|
||||
void Think (void);
|
||||
void NewRound (void);
|
||||
void EquipInBuyzone (int buyCount);
|
||||
|
|
@ -1704,7 +1705,7 @@ extern void DrawLine (edict_t *ent, const Vector &start, const Vector &end, int
|
|||
extern void DrawArrow (edict_t *ent, const Vector &start, const Vector &end, int width, int noise, int red, int green, int blue, int brightness, int speed, int life);
|
||||
extern void DisplayMenuToClient (edict_t *ent, MenuText *menu);
|
||||
extern void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex);
|
||||
extern void SoundAttachToThreat (edict_t *ent, const char *sample, float volume);
|
||||
extern void SoundAttachToClients (edict_t *ent, const char *sample, float volume);
|
||||
extern void SoundSimulateUpdate (int playerIndex);
|
||||
|
||||
// very global convars
|
||||
|
|
|
|||
|
|
@ -733,7 +733,7 @@ void Bot::FindItem (void)
|
|||
{
|
||||
allowPickup = false;
|
||||
|
||||
if (!m_defendedBomb)
|
||||
if (!m_defendedBomb && m_personality != PERSONALITY_RUSHER && Random.Long (0, 100) < 80)
|
||||
{
|
||||
m_defendedBomb = true;
|
||||
|
||||
|
|
@ -1503,7 +1503,7 @@ void Bot::PurchaseWeapons (void)
|
|||
{
|
||||
case WEAPON_SG550:
|
||||
case WEAPON_G3SG1:
|
||||
case WEAPON_AWP:
|
||||
case WEAPON_AWP:
|
||||
case WEAPON_M249:
|
||||
if (m_moneyAmount < g_botBuyEconomyTable[5] || m_moneyAmount > g_botBuyEconomyTable[6])
|
||||
ignoreWeapon = true;
|
||||
|
|
@ -2788,38 +2788,6 @@ void Bot::SelectLeaderEachTeam (int team)
|
|||
|
||||
void Bot::ChooseAimDirection (void)
|
||||
{
|
||||
TraceResult tr;
|
||||
memset (&tr, 0, sizeof (TraceResult));
|
||||
|
||||
if (!(m_currentWaypointIndex >= 0 && m_currentWaypointIndex < g_numWaypoints))
|
||||
GetValidWaypoint ();
|
||||
|
||||
bool tracelineIssued = false;
|
||||
|
||||
// check if last enemy vector valid
|
||||
if (m_seeEnemyTime + 7.0 < GetWorldTime () && m_lastEnemyOrigin != nullvec && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0f && IsEntityNull (m_enemy) && !UsesSniper ())
|
||||
{
|
||||
TraceLine (EyePosition (), m_lastEnemyOrigin, false, true, GetEntity (), &tr);
|
||||
|
||||
if (tr.flFraction <= 0.2)
|
||||
{
|
||||
if ((m_aimFlags & (AIM_LAST_ENEMY | AIM_PREDICT_PATH)) && m_wantsToFire)
|
||||
m_wantsToFire = false;
|
||||
|
||||
m_lastEnemyOrigin = nullvec;
|
||||
m_aimFlags &= ~(AIM_LAST_ENEMY | AIM_PREDICT_PATH);
|
||||
}
|
||||
tracelineIssued = true;
|
||||
}
|
||||
else if (m_lastEnemyOrigin == nullvec)
|
||||
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 (m_difficulty < 4 && m_seeEnemyTime + 2.0f < GetWorldTime () && !(m_aimFlags & AIM_ENEMY) && m_lastEnemyOrigin != nullvec && IsAlive (m_lastEnemy))
|
||||
{
|
||||
m_aimFlags |= AIM_LAST_ENEMY;
|
||||
m_canChooseAimDirection = false;
|
||||
}
|
||||
|
||||
unsigned int flags = m_aimFlags;
|
||||
|
||||
|
|
@ -2846,51 +2814,33 @@ void Bot::ChooseAimDirection (void)
|
|||
m_lookAt = m_lastEnemyOrigin;
|
||||
|
||||
// did bot just see enemy and is quite aggressive?
|
||||
if (m_seeEnemyTime + 3.0 - m_actualReactionTime + m_baseAgressionLevel > GetWorldTime ())
|
||||
if (m_seeEnemyTime + 2.0f - m_actualReactionTime + m_baseAgressionLevel > GetWorldTime ())
|
||||
{
|
||||
// feel free to fire if shootable
|
||||
if (!UsesSniper () && LastEnemyShootable ())
|
||||
m_wantsToFire = true;
|
||||
}
|
||||
else // forget an enemy far away
|
||||
{
|
||||
m_aimFlags &= ~AIM_LAST_ENEMY;
|
||||
|
||||
if ((pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0)
|
||||
m_lastEnemyOrigin = nullvec;
|
||||
}
|
||||
}
|
||||
else if (flags & AIM_PREDICT_PATH)
|
||||
{
|
||||
if (((pev->origin - m_lastEnemyOrigin).GetLength () < 1600 || UsesSniper ()) && (((tr.flFraction >= 0.2 || tr.pHit != g_worldEntity) && tracelineIssued) || !tracelineIssued))
|
||||
bool changePredictedEnemy = true;
|
||||
|
||||
if (m_trackingEdict == m_lastEnemy)
|
||||
{
|
||||
bool recalcPath = true;
|
||||
|
||||
if (!IsEntityNull (m_lastEnemy) && m_trackingEdict == m_lastEnemy && m_timeNextTracking < GetWorldTime ())
|
||||
recalcPath = false;
|
||||
|
||||
if (recalcPath)
|
||||
{
|
||||
m_lookAt = waypoint->GetPath (GetAimingWaypoint (m_lastEnemyOrigin))->origin;
|
||||
m_camp = m_lookAt;
|
||||
|
||||
m_timeNextTracking = GetWorldTime () + 0.5f;
|
||||
m_trackingEdict = m_lastEnemy;
|
||||
|
||||
// feel free to fire if shoot able
|
||||
if (LastEnemyShootable ())
|
||||
m_wantsToFire = true;
|
||||
}
|
||||
else
|
||||
m_lookAt = m_camp;
|
||||
if (m_timeNextTracking < GetWorldTime ())
|
||||
changePredictedEnemy = IsAlive (m_lastEnemy);
|
||||
}
|
||||
else // forget an enemy far away
|
||||
|
||||
if (changePredictedEnemy)
|
||||
{
|
||||
m_aimFlags &= ~AIM_PREDICT_PATH;
|
||||
m_lookAt = waypoint->GetPath (GetAimingWaypoint (m_lastEnemyOrigin))->origin + pev->view_ofs;
|
||||
m_camp = m_lookAt;
|
||||
|
||||
if ((pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0)
|
||||
m_lastEnemyOrigin = nullvec;
|
||||
m_timeNextTracking = GetWorldTime () + 2.0f;
|
||||
m_trackingEdict = m_lastEnemy;
|
||||
}
|
||||
else
|
||||
m_lookAt = m_camp;
|
||||
}
|
||||
else if (flags & AIM_CAMP)
|
||||
m_lookAt = m_camp;
|
||||
|
|
@ -2905,38 +2855,12 @@ void Bot::ChooseAimDirection (void)
|
|||
if (m_team == TEAM_TF)
|
||||
{
|
||||
if ((g_experienceData + (index * g_numWaypoints) + index)->team0DangerIndex != -1)
|
||||
{
|
||||
const Vector &dest = waypoint->GetPath ((g_experienceData + (index * g_numWaypoints) + index)->team0DangerIndex)->origin;
|
||||
TraceLine (pev->origin, dest, true, GetEntity (), &tr);
|
||||
|
||||
if (tr.flFraction > 0.8 || tr.pHit != g_worldEntity)
|
||||
m_lookAt = dest + pev->view_ofs;
|
||||
}
|
||||
m_lookAt = waypoint->GetPath ((g_experienceData + (index * g_numWaypoints) + index)->team0DangerIndex)->origin + pev->view_ofs;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((g_experienceData + (index * g_numWaypoints) + index)->team1DangerIndex != -1)
|
||||
{
|
||||
const Vector &dest = waypoint->GetPath ((g_experienceData + (index * g_numWaypoints) + index)->team1DangerIndex)->origin;
|
||||
TraceLine (pev->origin, dest, true, GetEntity (), &tr);
|
||||
|
||||
if (tr.flFraction > 0.8 || tr.pHit != g_worldEntity)
|
||||
m_lookAt = dest + pev->view_ofs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_canChooseAimDirection && m_prevWptIndex[0] >= 0 && m_prevWptIndex[0] < g_numWaypoints)
|
||||
{
|
||||
Path *path = waypoint->GetPath (m_prevWptIndex[0]);
|
||||
|
||||
if (!(path->flags & FLAG_LADDER) && (fabsf (path->origin.z - m_destOrigin.z) < 30.0 || (m_waypointFlags & FLAG_CAMP)))
|
||||
{
|
||||
// trace forward
|
||||
TraceLine (m_destOrigin, m_destOrigin + ((m_destOrigin - path->origin).Normalize () * 96), true, GetEntity (), &tr);
|
||||
|
||||
if (tr.flFraction < 1.0 && tr.pHit == g_worldEntity)
|
||||
m_lookAt = path->origin + pev->view_ofs;
|
||||
m_lookAt = waypoint->GetPath ((g_experienceData + (index * g_numWaypoints) + index)->team1DangerIndex)->origin + pev->view_ofs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2945,6 +2869,21 @@ void Bot::ChooseAimDirection (void)
|
|||
m_lookAt = m_destOrigin;
|
||||
}
|
||||
|
||||
static float ThinkFps = 1.0f / 30.0f;
|
||||
|
||||
void Bot::ThinkMain (void)
|
||||
{
|
||||
if (m_thinkFps < GetWorldTime ())
|
||||
{
|
||||
Think ();
|
||||
|
||||
// skip some frames
|
||||
m_thinkFps = GetWorldTime () + ThinkFps * Random.Float (0.95f, 1.05f);
|
||||
}
|
||||
else
|
||||
UpdateLookAngles ();
|
||||
}
|
||||
|
||||
void Bot::Think (void)
|
||||
{
|
||||
pev->button = 0;
|
||||
|
|
@ -2958,7 +2897,7 @@ void Bot::Think (void)
|
|||
m_notKilled = IsAlive (GetEntity ());
|
||||
m_team = GetTeam (GetEntity ());
|
||||
|
||||
if (m_team == TEAM_TF)
|
||||
if (m_team == TEAM_TF && (g_mapType & MAP_DE))
|
||||
m_hasC4 = !!(pev->weapons & (1 << WEAPON_C4));
|
||||
|
||||
// is bot movement enabled
|
||||
|
|
@ -3028,13 +2967,17 @@ void Bot::Think (void)
|
|||
|
||||
CheckMessageQueue (); // check for pending messages
|
||||
|
||||
// remove voice icon
|
||||
if (g_lastRadioTime[g_clients[IndexOfEntity (GetEntity ()) - 1].realTeam] + Random.Float (0.8f, 2.1f) < GetWorldTime ())
|
||||
SwitchChatterIcon (false); // hide icon
|
||||
|
||||
if (pev->maxspeed < 10 && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB)
|
||||
botMovement = false;
|
||||
|
||||
if (m_notKilled && botMovement && !yb_freeze_bots.GetBool ())
|
||||
BotAI (); // execute main code
|
||||
|
||||
RunPlayerMovement (); // run the player movement
|
||||
RunPlayerMovement (); // run the player movement
|
||||
}
|
||||
|
||||
void Bot::PeriodicThink (void)
|
||||
|
|
@ -3052,10 +2995,12 @@ void Bot::PeriodicThink (void)
|
|||
|
||||
CheckSpawnTimeConditions ();
|
||||
|
||||
// remove voice icon
|
||||
if (g_lastRadioTime[g_clients[IndexOfEntity (GetEntity ()) - 1].realTeam] + Random.Float (0.8f, 2.1f) < GetWorldTime ())
|
||||
SwitchChatterIcon (false); // hide icon
|
||||
|
||||
// clear enemy far away
|
||||
if (m_lastEnemyOrigin != nullvec && !IsEntityNull (m_lastEnemy) && (pev->origin - m_lastEnemyOrigin).GetLength () >= 1600.0)
|
||||
{
|
||||
m_lastEnemy = nullptr;
|
||||
m_lastEnemyOrigin = nullvec;
|
||||
}
|
||||
m_timePeriodicUpdate = GetWorldTime () + 0.25f;
|
||||
}
|
||||
|
||||
|
|
@ -3101,7 +3046,7 @@ void Bot::RunTask_Normal (void)
|
|||
m_prevGoalIndex = -1;
|
||||
|
||||
// spray logo sometimes if allowed to do so
|
||||
if (m_timeLogoSpray < GetWorldTime () && yb_spraypaints.GetBool () && Random.Long (1, 100) < 80 && m_moveSpeed > GetWalkSpeed ())
|
||||
if (m_timeLogoSpray < GetWorldTime () && yb_spraypaints.GetBool () && Random.Long (1, 100) < 60 && m_moveSpeed > GetWalkSpeed () && IsEntityNull (m_pickupItem))
|
||||
PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, GetWorldTime () + 1.0, false);
|
||||
|
||||
// reached waypoint is a camp waypoint
|
||||
|
|
@ -4879,7 +4824,7 @@ void Bot::BotAI (void)
|
|||
|
||||
RunTask (); // execute current task
|
||||
ChooseAimDirection (); // choose aim direction
|
||||
FacePosition (); // and turn to chosen aim direction
|
||||
UpdateLookAngles (); // and turn to chosen aim direction
|
||||
|
||||
// the bots wants to fire at something?
|
||||
if (m_wantsToFire && !m_isUsingGrenade && m_shootTime <= GetWorldTime ())
|
||||
|
|
@ -5795,7 +5740,7 @@ void Bot::RunPlayerMovement (void)
|
|||
byte msecVal = ThrottledMsec ();
|
||||
m_lastCommandTime = GetWorldTime ();
|
||||
|
||||
(*g_engfuncs.pfnRunPlayerMove) (pev->pContainingEntity, m_moveAngles, m_moveSpeed, m_strafeSpeed, 0.0, pev->button, pev->impulse, msecVal);
|
||||
(*g_engfuncs.pfnRunPlayerMove) (pev->pContainingEntity, m_moveAngles, m_moveSpeed, m_strafeSpeed, 0.0f, pev->button, pev->impulse, msecVal);
|
||||
}
|
||||
|
||||
void Bot::CheckBurstMode (float distance)
|
||||
|
|
@ -5822,10 +5767,10 @@ void Bot::CheckSilencer (void)
|
|||
{
|
||||
if (((m_currentWeapon == WEAPON_USP && m_difficulty < 2) || m_currentWeapon == WEAPON_M4A1) && !HasShield())
|
||||
{
|
||||
int iRandomNum = (m_personality == PERSONALITY_RUSHER ? 35 : 65);
|
||||
int random = (m_personality == PERSONALITY_RUSHER ? 35 : 65);
|
||||
|
||||
// aggressive bots don't like the silencer
|
||||
if (Random.Long (1, 100) <= (m_currentWeapon == WEAPON_USP ? iRandomNum / 3 : iRandomNum))
|
||||
if (Random.Long (1, 100) <= (m_currentWeapon == WEAPON_USP ? random / 3 : random))
|
||||
{
|
||||
if (pev->weaponanim > 6) // is the silencer not attached...
|
||||
pev->button |= IN_ATTACK2; // attach the silencer
|
||||
|
|
@ -5929,22 +5874,17 @@ bool Bot::OutOfBombTimer (void)
|
|||
|
||||
void Bot::ReactOnSound (void)
|
||||
{
|
||||
int ownIndex = GetIndex ();
|
||||
float ownSoundLast = 0.0;
|
||||
|
||||
if (g_clients[ownIndex].timeSoundLasting > GetWorldTime ())
|
||||
{
|
||||
if (g_clients[ownIndex].maxTimeSoundLasting <= 0.0)
|
||||
g_clients[ownIndex].maxTimeSoundLasting = 0.5;
|
||||
|
||||
ownSoundLast = (g_clients[ownIndex].hearingDistance * 0.2) * (g_clients[ownIndex].timeSoundLasting - GetWorldTime ()) / g_clients[ownIndex].maxTimeSoundLasting;
|
||||
}
|
||||
|
||||
edict_t *player = NULL;
|
||||
|
||||
float maxVolume = 0.0f, volume = 0.0f;
|
||||
int hearEnemyIndex = -1;
|
||||
|
||||
Vector pasOrg = EyePosition ();
|
||||
|
||||
if (pev->flags & FL_DUCKING)
|
||||
pasOrg = pasOrg + (VEC_HULL_MIN - VEC_DUCK_HULL_MIN);
|
||||
|
||||
byte *pas = ENGINE_SET_PVS (reinterpret_cast <float *> (&pasOrg));
|
||||
|
||||
float minDistance = 99999.0f;
|
||||
|
||||
// loop through all enemy clients to check for hearable stuff
|
||||
for (int i = 0; i < GetMaxClients (); i++)
|
||||
{
|
||||
|
|
@ -5952,30 +5892,20 @@ void Bot::ReactOnSound (void)
|
|||
continue;
|
||||
|
||||
float distance = (g_clients[i].soundPosition - pev->origin).GetLength ();
|
||||
float hearingDistance = g_clients[i].hearingDistance;
|
||||
|
||||
if (distance > hearingDistance)
|
||||
|
||||
if (distance > g_clients[i].hearingDistance)
|
||||
continue;
|
||||
|
||||
if (g_clients[i].maxTimeSoundLasting <= 0.0)
|
||||
g_clients[i].maxTimeSoundLasting = 0.5;
|
||||
|
||||
if (distance <= 0.5 * hearingDistance)
|
||||
volume = hearingDistance * (g_clients[i].timeSoundLasting - GetWorldTime ()) / g_clients[i].maxTimeSoundLasting;
|
||||
else
|
||||
volume = 2.0 * hearingDistance * (1.0 - distance / hearingDistance) * (g_clients[i].timeSoundLasting - GetWorldTime ()) / g_clients[i].maxTimeSoundLasting;
|
||||
|
||||
// we will care about the most hearable sound instead of the closest one - KWo
|
||||
if (volume < maxVolume)
|
||||
if (!ENGINE_CHECK_VISIBILITY (g_clients[i].ent, pas))
|
||||
continue;
|
||||
|
||||
maxVolume = volume;
|
||||
|
||||
if (volume < ownSoundLast)
|
||||
continue;
|
||||
|
||||
hearEnemyIndex = i;
|
||||
if (distance < minDistance)
|
||||
{
|
||||
hearEnemyIndex = i;
|
||||
minDistance = distance;
|
||||
}
|
||||
}
|
||||
edict_t *player = NULL;
|
||||
|
||||
if (hearEnemyIndex >= 0)
|
||||
{
|
||||
|
|
@ -5987,17 +5917,15 @@ void Bot::ReactOnSound (void)
|
|||
if (IsValidPlayer (player))
|
||||
{
|
||||
// change to best weapon if heard something
|
||||
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 ())
|
||||
if (m_shootTime < GetWorldTime () - 5.0f && IsOnFloor () && m_currentWeapon != WEAPON_C4 && m_currentWeapon != WEAPON_EXPLOSIVE && m_currentWeapon != WEAPON_SMOKE && m_currentWeapon != WEAPON_FLASHBANG && !yb_jasonmode.GetBool ())
|
||||
SelectBestWeapon ();
|
||||
|
||||
m_heardSoundTime = GetWorldTime () + 5.0;
|
||||
m_states |= STATE_HEARING_ENEMY;
|
||||
|
||||
if ((Random.Long (0, 100) < 25) && IsEntityNull (m_enemy) && IsEntityNull (m_lastEnemy) && m_seeEnemyTime + 7.0 < GetWorldTime ())
|
||||
if ((Random.Long (0, 100) < 15) && IsEntityNull (m_enemy) && IsEntityNull (m_lastEnemy) && m_seeEnemyTime + 7.0 < GetWorldTime ())
|
||||
ChatterMessage (Chatter_HeardEnemy);
|
||||
|
||||
m_aimFlags |= AIM_LAST_ENEMY;
|
||||
|
||||
// didn't bot already have an enemy ? take this one...
|
||||
if (m_lastEnemyOrigin == nullvec || m_lastEnemy == NULL)
|
||||
{
|
||||
|
|
@ -6040,7 +5968,7 @@ void Bot::ReactOnSound (void)
|
|||
m_states |= STATE_SEEING_ENEMY;
|
||||
m_seeEnemyTime = GetWorldTime ();
|
||||
}
|
||||
else if (m_lastEnemyOrigin != nullvec && m_lastEnemy == player && m_seeEnemyTime + 1.0 > GetWorldTime () && yb_shoots_thru_walls.GetBool () && IsShootableThruObstacle (m_lastEnemyOrigin))
|
||||
else if (m_lastEnemyOrigin != nullvec && m_lastEnemy == player && m_seeEnemyTime + 3.0f > GetWorldTime () && yb_shoots_thru_walls.GetBool () && IsShootableThruObstacle (m_lastEnemyOrigin))
|
||||
{
|
||||
m_states |= STATE_SEEING_ENEMY;
|
||||
m_seeEnemyTime = GetWorldTime ();
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ const Vector &Bot::GetAimPosition (void)
|
|||
}
|
||||
m_lastEnemyOrigin = targetOrigin;
|
||||
}
|
||||
const Vector &velocity = UsesSniper () ? nullvec : ((1.0f * m_frameInterval * m_enemy->v.velocity - 1.0 * m_frameInterval * pev->velocity) * m_frameInterval).Get2D ();
|
||||
const Vector &velocity = UsesSniper () ? nullvec : 1.0f * m_frameInterval * (m_enemy->v.velocity - pev->velocity);
|
||||
|
||||
if (m_difficulty < 3 && randomize != nullvec)
|
||||
{
|
||||
|
|
@ -504,10 +504,13 @@ const Vector &Bot::GetAimPosition (void)
|
|||
divOffs = divOffs / 500;
|
||||
|
||||
// randomize the target position
|
||||
m_enemyOrigin = divOffs * randomize + velocity;
|
||||
m_enemyOrigin = divOffs * randomize;
|
||||
}
|
||||
else
|
||||
m_enemyOrigin = targetOrigin + velocity;
|
||||
m_enemyOrigin = targetOrigin;
|
||||
|
||||
if (distance >= 256.0f)
|
||||
m_enemyOrigin += velocity;
|
||||
|
||||
return m_enemyOrigin;
|
||||
}
|
||||
|
|
@ -891,7 +894,7 @@ WeaponSelectEnd:
|
|||
m_navTimeset = GetWorldTime ();
|
||||
}
|
||||
}
|
||||
else if (m_difficulty <= 3 && UsesZoomableRifle () && m_zoomCheckTime < GetWorldTime ()) // else is the bot holding a zoomable rifle?
|
||||
else if (m_difficulty < 4 && 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?
|
||||
pev->button |= IN_ATTACK2;
|
||||
|
|
@ -963,7 +966,6 @@ WeaponSelectEnd:
|
|||
{
|
||||
pev->button |= IN_ATTACK;
|
||||
|
||||
// m_shootTime = GetWorldTime () + baseDelay + Random.Float (minDelay, maxDelay);
|
||||
m_shootTime = GetWorldTime () + Random.Float (0.15f, 0.35f);
|
||||
m_zoomCheckTime = GetWorldTime () - 0.09f;
|
||||
}
|
||||
|
|
@ -1149,7 +1151,7 @@ void Bot::CombatFight (void)
|
|||
}
|
||||
}
|
||||
|
||||
if ((m_difficulty >= 1 && m_fightStyle == 0) || ((pev->button & IN_RELOAD) || m_isReloading) || (UsesPistol () && distance < 400.0f))
|
||||
if (m_fightStyle == 0 || ((pev->button & IN_RELOAD) || m_isReloading) || (UsesPistol () && distance < 400.0f))
|
||||
{
|
||||
if (m_strafeSetTime < GetWorldTime ())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2304,7 +2304,7 @@ void pfnEmitSound (edict_t *entity, int channel, const char *sample, float volum
|
|||
// SoundAttachToThreat() to bring the sound to the ears of the bots. Since bots have no client DLL
|
||||
// to handle this for them, such a job has to be done manually.
|
||||
|
||||
SoundAttachToThreat (entity, sample, volume);
|
||||
SoundAttachToClients (entity, sample, volume);
|
||||
|
||||
if (g_isMetamod)
|
||||
RETURN_META (MRES_IGNORED);
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ int BotManager::CreateBot (const String &name, int difficulty, int personality,
|
|||
personality = PERSONALITY_NORMAL;
|
||||
else
|
||||
{
|
||||
if (Random.Long (0, 100) > 50)
|
||||
if (Random.Long (0, 100) < 65)
|
||||
personality = PERSONALITY_RUSHER;
|
||||
else
|
||||
personality = PERSONALITY_CAREFUL;
|
||||
|
|
@ -237,7 +237,7 @@ void BotManager::Think (void)
|
|||
for (int i = 0; i < GetMaxClients (); i++)
|
||||
{
|
||||
if (m_bots[i] != NULL)
|
||||
m_bots[i]->Think ();
|
||||
m_bots[i]->ThinkMain ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1504,7 +1504,7 @@ float gfunctionKillsT (int currentIndex, int)
|
|||
}
|
||||
|
||||
if (current->flags & FLAG_CROUCH)
|
||||
cost *= 1.5;
|
||||
cost *= 1.5f;
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
|
@ -1647,7 +1647,6 @@ void Bot::FindPath (int srcIndex, int destIndex, unsigned char pathType)
|
|||
AddLogEntry (true, LL_ERROR, "Pathfinder destination path index not valid (%d)", destIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteSearchNodes ();
|
||||
|
||||
m_chosenGoalIndex = srcIndex;
|
||||
|
|
@ -3117,7 +3116,7 @@ int Bot::GetAimingWaypoint (void)
|
|||
{
|
||||
// find a good waypoint to look at when camping
|
||||
|
||||
int count = 0, indeces[3];
|
||||
int count = 0, indices[3];
|
||||
float distTab[3];
|
||||
uint16 visibility[3];
|
||||
|
||||
|
|
@ -3135,7 +3134,7 @@ int Bot::GetAimingWaypoint (void)
|
|||
|
||||
if (count < 3)
|
||||
{
|
||||
indeces[count] = i;
|
||||
indices[count] = i;
|
||||
|
||||
distTab[count] = (pev->origin - path->origin).GetLengthSquared ();
|
||||
visibility[count] = path->vis.crouch + path->vis.stand;
|
||||
|
|
@ -3151,7 +3150,7 @@ int Bot::GetAimingWaypoint (void)
|
|||
{
|
||||
if (visBits >= visibility[j] && distance > distTab[j])
|
||||
{
|
||||
indeces[j] = i;
|
||||
indices[j] = i;
|
||||
|
||||
distTab[j] = distance;
|
||||
visibility[j] = visBits;
|
||||
|
|
@ -3164,17 +3163,17 @@ int Bot::GetAimingWaypoint (void)
|
|||
count--;
|
||||
|
||||
if (count >= 0)
|
||||
return indeces[Random.Long (0, count)];
|
||||
return indices[Random.Long (0, count)];
|
||||
|
||||
return Random.Long (0, g_numWaypoints - 1);
|
||||
}
|
||||
|
||||
void Bot::FacePosition (void)
|
||||
void Bot::UpdateLookAngles (void)
|
||||
{
|
||||
// adjust all body and view angles to face an absolute vector
|
||||
Vector direction = (m_lookAt - EyePosition ()).ToAngles ();
|
||||
direction = direction + pev->punchangle * (m_difficulty * 25) / 100.0;
|
||||
direction.x *= -1.0; // invert for engine
|
||||
direction.x *= -1.0f; // invert for engine
|
||||
|
||||
Vector deviation = (direction - pev->v_angle);
|
||||
|
||||
|
|
@ -3216,15 +3215,15 @@ void Bot::FacePosition (void)
|
|||
else if (aimMethod == 3)
|
||||
{
|
||||
#if defined (NDEBUG)
|
||||
Vector springStiffness (15.0f, 15.0f, 0.0f);
|
||||
Vector springStiffness (13.0f, 13.0f, 0.0f);
|
||||
Vector damperCoefficient (0.22f, 0.22f, 0.0f);
|
||||
|
||||
Vector influence (0.26f, 0.18f, 0.0f);
|
||||
Vector influence (0.25f, 0.17f, 0.0f);
|
||||
Vector randomization (2.0f, 0.18f, 0.0f);
|
||||
|
||||
const float noTargetRatio = 0.6f;
|
||||
const float offsetDelay = 0.5f;
|
||||
const float targetRatio = 5.0f;
|
||||
const float noTargetRatio = 0.3f;
|
||||
const float offsetDelay = 1.2f;
|
||||
const float targetRatio = 0.8f;
|
||||
#else
|
||||
Vector springStiffness (yb_aim_spring_stiffness_x.GetFloat (), yb_aim_spring_stiffness_y.GetFloat (), 0);
|
||||
Vector damperCoefficient (yb_aim_damper_coefficient_x.GetFloat (), yb_aim_damper_coefficient_y.GetFloat (), 0);
|
||||
|
|
@ -3337,7 +3336,11 @@ void Bot::FacePosition (void)
|
|||
m_aimSpeed.y += m_aimSpeed.x * influence.x;
|
||||
|
||||
// move the aim cursor
|
||||
pev->v_angle = pev->v_angle + m_frameInterval * Vector (m_aimSpeed.x, m_aimSpeed.y, 0);
|
||||
if (m_difficulty == 4 && (m_aimFlags & AIM_ENEMY) && (m_wantsToFire || UsesSniper ()))
|
||||
pev->v_angle = direction;
|
||||
else
|
||||
pev->v_angle = pev->v_angle + m_frameInterval * Vector (m_aimSpeed.x, m_aimSpeed.y, 0.0f);
|
||||
|
||||
pev->v_angle.ClampAngles ();
|
||||
}
|
||||
|
||||
|
|
@ -3368,7 +3371,7 @@ int Bot::FindPlantedBomb (void)
|
|||
{
|
||||
// this function tries to find planted c4 on the defuse scenario map and returns nearest to it waypoint
|
||||
|
||||
if ((m_team != TEAM_TF) || !(g_mapType & MAP_DE))
|
||||
if (m_team != TEAM_TF || !(g_mapType & MAP_DE))
|
||||
return -1; // don't search for bomb if the player is CT, or it's not defusing bomb
|
||||
|
||||
edict_t *bombEntity = NULL; // temporaly pointer to bomb
|
||||
|
|
@ -3380,7 +3383,7 @@ int Bot::FindPlantedBomb (void)
|
|||
{
|
||||
int nearestIndex = waypoint->FindNearest (GetEntityOrigin (bombEntity));
|
||||
|
||||
if ((nearestIndex >= 0) && (nearestIndex < g_numWaypoints))
|
||||
if (nearestIndex >= 0 && nearestIndex < g_numWaypoints)
|
||||
return nearestIndex;
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1259,7 +1259,7 @@ bool FindNearestPlayer (void **pvHolder, edict_t *to, float searchDistance, bool
|
|||
return true;
|
||||
}
|
||||
|
||||
void SoundAttachToThreat (edict_t *ent, const char *sample, float volume)
|
||||
void SoundAttachToClients (edict_t *ent, const char *sample, float volume)
|
||||
{
|
||||
// this function called by the sound hooking code (in emit_sound) enters the played sound into
|
||||
// the array associated with the entity
|
||||
|
|
@ -1290,73 +1290,57 @@ void SoundAttachToThreat (edict_t *ent, const char *sample, float volume)
|
|||
}
|
||||
}
|
||||
}
|
||||
Client *client = &g_clients[index];
|
||||
|
||||
if (strncmp ("player/bhit_flesh", sample, 17) == 0 || strncmp ("player/headshot", sample, 15) == 0)
|
||||
{
|
||||
// hit/fall sound?
|
||||
g_clients[index].hearingDistance = 768.0 * volume;
|
||||
g_clients[index].timeSoundLasting = GetWorldTime () + 0.5;
|
||||
g_clients[index].maxTimeSoundLasting = 0.5;
|
||||
g_clients[index].soundPosition = origin;
|
||||
client->hearingDistance = 768.0 * volume;
|
||||
client->timeSoundLasting = GetWorldTime () + 0.5;
|
||||
client->soundPosition = origin;
|
||||
}
|
||||
else if (strncmp ("items/gunpickup", sample, 15) == 0)
|
||||
{
|
||||
// weapon pickup?
|
||||
g_clients[index].hearingDistance = 768.0 * volume;
|
||||
g_clients[index].timeSoundLasting = GetWorldTime () + 0.5;
|
||||
g_clients[index].maxTimeSoundLasting = 0.5;
|
||||
g_clients[index].soundPosition = origin;
|
||||
client->hearingDistance = 768.0 * volume;
|
||||
client->timeSoundLasting = GetWorldTime () + 0.5;
|
||||
client->soundPosition = origin;
|
||||
}
|
||||
else if (strncmp ("weapons/zoom", sample, 12) == 0)
|
||||
{
|
||||
// sniper zooming?
|
||||
g_clients[index].hearingDistance = 512.0 * volume;
|
||||
g_clients[index].timeSoundLasting = GetWorldTime () + 0.1;
|
||||
g_clients[index].maxTimeSoundLasting = 0.1;
|
||||
g_clients[index].soundPosition = origin;
|
||||
client->hearingDistance = 512.0 * volume;
|
||||
client->timeSoundLasting = GetWorldTime () + 0.1;
|
||||
client->soundPosition = origin;
|
||||
}
|
||||
else if (strncmp ("items/9mmclip", sample, 13) == 0)
|
||||
{
|
||||
// ammo pickup?
|
||||
g_clients[index].hearingDistance = 512.0 * volume;
|
||||
g_clients[index].timeSoundLasting = GetWorldTime () + 0.1;
|
||||
g_clients[index].maxTimeSoundLasting = 0.1;
|
||||
g_clients[index].soundPosition = origin;
|
||||
client->hearingDistance = 512.0 * volume;
|
||||
client->timeSoundLasting = GetWorldTime () + 0.1;
|
||||
client->soundPosition = origin;
|
||||
}
|
||||
else if (strncmp ("hostage/hos", sample, 11) == 0)
|
||||
{
|
||||
// CT used hostage?
|
||||
g_clients[index].hearingDistance = 1024.0 * volume;
|
||||
g_clients[index].timeSoundLasting = GetWorldTime () + 5.0;
|
||||
g_clients[index].maxTimeSoundLasting = 0.5;
|
||||
g_clients[index].soundPosition = origin;
|
||||
client->hearingDistance = 1024.0 * volume;
|
||||
client->timeSoundLasting = GetWorldTime () + 5.0;
|
||||
client->soundPosition = origin;
|
||||
}
|
||||
else if (strncmp ("debris/bustmetal", sample, 16) == 0 || strncmp ("debris/bustglass", sample, 16) == 0)
|
||||
{
|
||||
// broke something?
|
||||
g_clients[index].hearingDistance = 1024.0 * volume;
|
||||
g_clients[index].timeSoundLasting = GetWorldTime () + 2.0;
|
||||
g_clients[index].maxTimeSoundLasting = 2.0;
|
||||
g_clients[index].soundPosition = origin;
|
||||
client->hearingDistance = 1024.0 * volume;
|
||||
client->timeSoundLasting = GetWorldTime () + 2.0;
|
||||
client->soundPosition = origin;
|
||||
}
|
||||
else if (strncmp ("doors/doormove", sample, 14) == 0)
|
||||
{
|
||||
// someone opened a door
|
||||
g_clients[index].hearingDistance = 1024.0 * volume;
|
||||
g_clients[index].timeSoundLasting = GetWorldTime () + 3.0;
|
||||
g_clients[index].maxTimeSoundLasting = 3.0;
|
||||
g_clients[index].soundPosition = origin;
|
||||
client->hearingDistance = 1024.0 * volume;
|
||||
client->timeSoundLasting = GetWorldTime () + 3.0;
|
||||
client->soundPosition = origin;
|
||||
}
|
||||
#if 0
|
||||
else if (strncmp ("weapons/reload", sample, 14) == 0)
|
||||
{
|
||||
// reloading ?
|
||||
g_clients[index].hearingDistance = 512.0 * volume;
|
||||
g_clients[index].timeSoundLasting = GetWorldTime () + 0.5;
|
||||
g_clients[index].maxTimeSoundLasting = 0.5;
|
||||
g_clients[index].soundPosition = origin;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SoundSimulateUpdate (int playerIndex)
|
||||
|
|
@ -1364,43 +1348,36 @@ void SoundSimulateUpdate (int playerIndex)
|
|||
// this function tries to simulate playing of sounds to let the bots hear sounds which aren't
|
||||
// captured through server sound hooking
|
||||
|
||||
InternalAssert (playerIndex >= 0);
|
||||
InternalAssert (playerIndex < GetMaxClients ());
|
||||
|
||||
if (playerIndex < 0 || playerIndex >= GetMaxClients ())
|
||||
return; // reliability check
|
||||
|
||||
edict_t *player = g_clients[playerIndex].ent;
|
||||
Client *client = &g_clients[playerIndex];
|
||||
|
||||
float hearDistance = 0.0;
|
||||
float timeSound = 0.0;
|
||||
float timeMaxSound = 0.5;
|
||||
float hearDistance = 0.0f;
|
||||
float timeSound = 0.0f;
|
||||
|
||||
if (player->v.oldbuttons & IN_ATTACK) // pressed attack button?
|
||||
if (client->ent->v.oldbuttons & IN_ATTACK) // pressed attack button?
|
||||
{
|
||||
hearDistance = 3072.0;
|
||||
timeSound = GetWorldTime () + 0.3;
|
||||
timeMaxSound = 0.3;
|
||||
timeSound = GetWorldTime () + 0.3f;
|
||||
}
|
||||
else if (player->v.oldbuttons & IN_USE) // pressed used button?
|
||||
else if (client->ent->v.oldbuttons & IN_USE) // pressed used button?
|
||||
{
|
||||
hearDistance = 512.0;
|
||||
timeSound = GetWorldTime () + 0.5;
|
||||
timeMaxSound = 0.5;
|
||||
timeSound = GetWorldTime () + 0.5f;
|
||||
}
|
||||
else if (player->v.oldbuttons & IN_RELOAD) // pressed reload button?
|
||||
else if (client->ent->v.oldbuttons & IN_RELOAD) // pressed reload button?
|
||||
{
|
||||
hearDistance = 512.0;
|
||||
timeSound = GetWorldTime () + 0.5;
|
||||
timeMaxSound = 0.5;
|
||||
timeSound = GetWorldTime () + 0.5f;
|
||||
}
|
||||
else if (player->v.movetype == MOVETYPE_FLY) // uses ladder?
|
||||
else if (client->ent->v.movetype == MOVETYPE_FLY) // uses ladder?
|
||||
{
|
||||
if (fabs (player->v.velocity.z) > 50.0)
|
||||
if (fabsf (client->ent->v.velocity.z) > 50.0f)
|
||||
{
|
||||
hearDistance = 1024.0;
|
||||
timeSound = GetWorldTime () + 0.3;
|
||||
timeMaxSound = 0.3;
|
||||
hearDistance = 1024.0f;
|
||||
timeSound = GetWorldTime () + 0.3f;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1410,9 +1387,8 @@ void SoundSimulateUpdate (int playerIndex)
|
|||
if (mp_footsteps.GetBool ())
|
||||
{
|
||||
// moves fast enough?
|
||||
hearDistance = 1280.0 * (player->v.velocity.GetLength2D () / 240);
|
||||
timeSound = GetWorldTime () + 0.3;
|
||||
timeMaxSound = 0.3;
|
||||
hearDistance = 1280.0f * (client->ent->v.velocity.GetLength2D () / 260.0f);
|
||||
timeSound = GetWorldTime () + 0.3f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1420,28 +1396,22 @@ void SoundSimulateUpdate (int playerIndex)
|
|||
return; // didn't issue sound?
|
||||
|
||||
// some sound already associated
|
||||
if (g_clients[playerIndex].timeSoundLasting > GetWorldTime ())
|
||||
if (client->timeSoundLasting > GetWorldTime ())
|
||||
{
|
||||
// new sound louder (bigger range) than old one ?
|
||||
if (g_clients[playerIndex].maxTimeSoundLasting <= 0.0)
|
||||
g_clients[playerIndex].maxTimeSoundLasting = 0.5;
|
||||
|
||||
if (g_clients[playerIndex].hearingDistance * (g_clients[playerIndex].timeSoundLasting - GetWorldTime ()) / g_clients[playerIndex].maxTimeSoundLasting <= hearDistance)
|
||||
if (client->hearingDistance <= hearDistance)
|
||||
{
|
||||
// override it with new
|
||||
g_clients[playerIndex].hearingDistance = hearDistance;
|
||||
g_clients[playerIndex].timeSoundLasting = timeSound;
|
||||
g_clients[playerIndex].maxTimeSoundLasting = timeMaxSound;
|
||||
g_clients[playerIndex].soundPosition = player->v.origin;
|
||||
client->hearingDistance = hearDistance;
|
||||
client->timeSoundLasting = timeSound;
|
||||
client->soundPosition = client->ent->v.origin;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// just remember it
|
||||
g_clients[playerIndex].hearingDistance = hearDistance;
|
||||
g_clients[playerIndex].timeSoundLasting = timeSound;
|
||||
g_clients[playerIndex].maxTimeSoundLasting = timeMaxSound;
|
||||
g_clients[playerIndex].soundPosition = player->v.origin;
|
||||
client->hearingDistance = hearDistance;
|
||||
client->timeSoundLasting = timeSound;
|
||||
client->soundPosition = client->ent->v.origin;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue