more optimizations

removed ancient firedelays
maybe some more...
This commit is contained in:
jeefo 2015-07-12 17:18:20 +03:00
commit c445d07c2b
13 changed files with 383 additions and 472 deletions

View file

@ -685,20 +685,6 @@ struct WeaponSelect
bool primaryFireHold; // hold down primary fire button to use?
};
// fire delay definiton
struct FireDelay
{
int weaponIndex;
int maxFireBullets;
float minBurstPauseFactor;
float primaryBaseDelay;
float primaryMinDelay[6];
float primaryMaxDelay[6];
float secondaryBaseDelay;
float secondaryMinDelay[5];
float secondaryMaxDelay[5];
};
// struct for menus
struct MenuText
{
@ -1069,7 +1055,6 @@ private:
Vector CheckBombAudible (void);
const Vector &GetAimPosition (void);
float GetZOffset (float distance);
int CheckGrenades (void);
@ -1077,7 +1062,7 @@ private:
void AttachToUser (void);
void CombatFight (void);
bool IsWeaponBadInDistance (int weaponIndex, float distance);
bool DoFirePause (float distance, FireDelay *fireDelay);
bool DoFirePause (float distance);
bool LookupEnemy (void);
bool IsEnemyHiddenByRendering (edict_t *enemy);
void FireWeapon (void);
@ -1091,8 +1076,8 @@ private:
bool IsShootableThruObstacle (const Vector &dest);
bool IsShootableThruObstacleEx (const Vector &dest);
int GetNearbyEnemiesNearPosition (const Vector &origin, int radius);
int GetNearbyFriendsNearPosition (const Vector &origin, int radius);
int GetNearbyEnemiesNearPosition (const Vector &origin, float radius);
int GetNearbyFriendsNearPosition (const Vector &origin, float radius);
void SelectWeaponByName (const char *name);
void SelectWeaponbyNumber (int num);
@ -1110,7 +1095,7 @@ private:
void FindShortestPath (int srcIndex, int destIndex);
void FindPath (int srcIndex, int destIndex, unsigned char pathType = 0);
void DebugMsg (const char *format, ...);
void SecondThink (void);
void PeriodicThink (void);
public:
entvars_t *pev;
@ -1127,7 +1112,9 @@ public:
float m_timePeriodicUpdate; // time to per-second think
bool m_isVIP; // bot is vip?
bool m_bIsDefendingTeam; // bot in defending team on this map
int m_numEnemiesLeft; // number of enemies alive left on map
int m_numFriendsLeft; // number of friend alive left on map
int m_startAction; // team/class selection state
bool m_notKilled; // has the player been killed or has he just respawned
@ -1137,8 +1124,7 @@ public:
int m_lastVoteKick; // last index
int m_voteMap; // number of map to vote for
int m_logotypeIndex; // index for logotype
int m_burstShotsFired; // number of bullets fired
bool m_inBombZone; // bot in the bomb zone or not
int m_buyState; // current Count in Buying
float m_nextBuyTime; // next buy time
@ -1245,7 +1231,7 @@ public:
void VerifyBreakable (edict_t *touch);
void RemoveCertainTask (TaskID id);
void StartTask (TaskID id, float desire, int data, float time, bool canContinue);
void PushTask (TaskID id, float desire, int data, float time, bool canContinue);
void ResetTasks (void);
TaskItem *GetTask (void);
@ -1328,6 +1314,8 @@ public:
int GetBotsNum (void);
void Think (void);
void PeriodicThink (void);
void Free (void);
void Free (int index);
void CheckAutoVacate (void);

View file

@ -4068,3 +4068,8 @@ public:
// Sizeof bounds
//
#define SIZEOF_CHAR(in) sizeof (in) - 1
//
// Squared Length
//
#define GET_SQUARE(in) (in * in)

View file

@ -65,7 +65,6 @@ extern Array <BotName> g_botNames;
extern Array <KeywordFactory> g_replyFactory;
extern RandomSequenceOfUnique Random;
extern FireDelay g_fireDelay[NUM_WEAPONS + 1];
extern WeaponSelect g_weaponSelect[NUM_WEAPONS + 1];
extern WeaponProperty g_weaponDefs[MAX_WEAPONS + 1];

View file

@ -20,7 +20,7 @@
#define PRODUCT_COPYRIGHT "Copyright © 2003-2015, by " PRODUCT_AUTHOR
#define PRODUCT_LEGAL "Half-Life, Counter-Strike, Counter-Strike: Condition Zero, Steam, Valve is a trademark of Valve Corporation"
#define PRODUCT_ORIGINAL_NAME "yapb.dll"
#define PRODUCT_INTERNAL_NAME "podbot"
#define PRODUCT_INTERNAL_NAME "skybot"
#define PRODUCT_VERSION_DWORD 2,7,0,0
#define PRODUCT_SUPPORT_VERSION "1.0 - CZ"
#define PRODUCT_COMMENTS "http://github.com/jeefo/yapb/"

View file

@ -96,133 +96,6 @@ bool Bot::IsInViewCone (const Vector &origin)
return ::IsInViewCone (origin, GetEntity ());
}
bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart)
{
// this function checks visibility of a bot target.
if (IsEnemyHiddenByRendering (target))
{
*bodyPart = 0;
*origin = nullvec;
return false;
}
const Vector &botHead = EyePosition ();
TraceResult tr;
*bodyPart = 0;
// check for the body
TraceLine (botHead, target->v.origin, true, true, GetEntity (), &tr);
if (tr.flFraction >= 1.0f)
{
*bodyPart |= VISIBLE_BODY;
*origin = target->v.origin;
if (m_difficulty == 4)
origin->z += 3.0f;
}
// check for the head
TraceLine (botHead, target->v.origin + target->v.view_ofs, true, true, GetEntity (), &tr);
if (tr.flFraction >= 1.0f)
{
*bodyPart |= VISIBLE_HEAD;
*origin = target->v.origin + target->v.view_ofs;
if (m_difficulty == 4)
origin->z += 1.0f;
}
if (*bodyPart != 0)
return true;
// thanks for this code goes to kwo
MakeVectors (target->v.angles);
// worst case, choose random position in enemy body
for (int i = 0; i < 6; i++)
{
Vector pos = target->v.origin;
switch (i)
{
case 0: // left arm
pos.x -= 10.0f * g_pGlobals->v_right.x;
pos.y -= 10.0f * g_pGlobals->v_right.y;
pos.z += 8.0f;
break;
case 1: // right arm
pos.x += 10.0f * g_pGlobals->v_right.x;
pos.y += 10.0f * g_pGlobals->v_right.y;
pos.z += 8.0f;
break;
case 2: // left leg
pos.x -= 10.0f * g_pGlobals->v_right.x;
pos.y -= 10.0f * g_pGlobals->v_right.y;
pos.z -= 12.0f;
break;
case 3: // right leg
pos.x += 10.0f * g_pGlobals->v_right.x;
pos.y += 10.0f * g_pGlobals->v_right.y;
pos.z -= 12.0f;
break;
case 4: // left foot
pos.x -= 10.0f * g_pGlobals->v_right.x;
pos.y -= 10.0f * g_pGlobals->v_right.y;
pos.z -= 24.0f;
break;
case 5: // right foot
pos.x += 10.0f * g_pGlobals->v_right.x;
pos.y += 10.0f * g_pGlobals->v_right.y;
pos.z -= 24.0f;
break;
}
// check direct line to random part of the player body
TraceLine (botHead, pos, true, true, GetEntity (), &tr);
// check if we hit something
if (tr.flFraction >= 1.0f)
{
*origin = tr.vecEndPos;
*bodyPart |= VISIBLE_OTHER;
return true;
}
}
return false;
}
bool Bot::IsEnemyViewable (edict_t *player)
{
if (IsEntityNull (player))
return false;
bool forceTrueIfVisible = false;
if (IsValidPlayer (pev->dmg_inflictor) && GetTeam (pev->dmg_inflictor) != m_team)
forceTrueIfVisible = true;
if (CheckVisibility (player, &m_enemyOrigin, &m_visibility) && (IsInViewCone (player->v.origin + pev->view_ofs) || forceTrueIfVisible))
{
m_seeEnemyTime = GetWorldTime ();
m_lastEnemy = player;
m_lastEnemyOrigin = player->v.origin;
return true;
}
return false;
}
bool Bot::ItemIsVisible (const Vector &destination, char *itemName)
{
TraceResult tr;
@ -286,7 +159,7 @@ void Bot::CheckGrenadeThrow (void)
// is enemy to high to throw
if ((m_lastEnemy->v.origin.z > (pev->origin.z + 650.0)) || !(m_lastEnemy->v.flags & (FL_ONGROUND | FL_DUCKING)))
distance = FLT_MAX; // just some crazy value
distance = 99999.0f; // just some crazy value
// enemy is within a good throwing distance ?
if (distance > (grenadeToThrow == WEAPON_SMOKE ? 400 : 600) && distance <= 1000)
@ -297,7 +170,7 @@ void Bot::CheckGrenadeThrow (void)
bool allowThrowing = true;
// check for teammates
if (GetNearbyFriendsNearPosition (m_lastEnemy->v.origin, 256) > 0)
if (GetNearbyFriendsNearPosition (m_lastEnemy->v.origin, 256.0f) > 0)
allowThrowing = false;
if (allowThrowing && m_seeEnemyTime + 2.0 < GetWorldTime ())
@ -359,7 +232,9 @@ void Bot::CheckGrenadeThrow (void)
{
Path *path = g_waypoint->GetPath (i);
if (GetNearbyFriendsNearPosition (path->origin, 256) != 0 || !(m_difficulty == 4 && GetNearbyFriendsNearPosition (path->origin, 256) != 0))
int friendCount = GetNearbyFriendsNearPosition (path->origin, 256.0f);
if (friendCount != 0 || !(m_difficulty == 4 && friendCount != 0))
continue;
m_throw = path->origin;
@ -383,11 +258,11 @@ void Bot::CheckGrenadeThrow (void)
}
if (m_states & STATE_THROW_HE)
StartTask (TASK_THROWHEGRENADE, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0, false);
PushTask (TASK_THROWHEGRENADE, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0, false);
else if (m_states & STATE_THROW_FB)
StartTask (TASK_THROWFLASHBANG, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0, false);
PushTask (TASK_THROWFLASHBANG, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0, false);
else if (m_states & STATE_THROW_SG)
StartTask (TASK_THROWSMOKE, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0, false);
PushTask (TASK_THROWSMOKE, TASKPRI_THROWGRENADE, -1, GetWorldTime () + 3.0, false);
// delay next grenade throw
if (m_states & (STATE_THROW_HE | STATE_THROW_FB | STATE_THROW_SG))
@ -585,7 +460,7 @@ bool Bot::RateGroundWeapon (edict_t *ent)
void Bot::VerifyBreakable (edict_t *touch)
{
if (m_breakableCheckTime >= GetWorldTime () || !IsShootableBreakable (touch))
if (m_breakableCheckTime < GetWorldTime () || !IsShootableBreakable (touch))
return;
m_breakableEntity = FindBreakable ();
@ -595,8 +470,8 @@ void Bot::VerifyBreakable (edict_t *touch)
m_campButtons = pev->button & IN_DUCK;
StartTask (TASK_SHOOTBREAKABLE, TASKPRI_SHOOTBREAKABLE, -1, 0.0, false);
m_breakableCheckTime = GetWorldTime () + 1.0f;
PushTask (TASK_SHOOTBREAKABLE, TASKPRI_SHOOTBREAKABLE, -1, 0.0, false);
m_breakableCheckTime = GetWorldTime () + 0.5f;
}
edict_t *Bot::FindBreakable (void)
@ -841,8 +716,8 @@ void Bot::FindItem (void)
{
int index = FindDefendWaypoint (entityOrigin);
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0, 60.0), true); // push camp task on to stack
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (3.0, 6.0), true); // push move command
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0, 60.0), true); // push camp task on to stack
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (3.0, 6.0), true); // push move command
if (g_waypoint->GetPath (index)->vis.crouch <= g_waypoint->GetPath (index)->vis.stand)
m_campButtons |= IN_DUCK;
@ -873,8 +748,8 @@ void Bot::FindItem (void)
{
RemoveCertainTask (TASK_MOVETOPOSITION); // remove any move tasks
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, timeMidBlowup, true); // push camp task on to stack
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, timeMidBlowup, true); // push move command
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, timeMidBlowup, true); // push camp task on to stack
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, timeMidBlowup, true); // push move command
if (path->vis.crouch <= path->vis.stand)
m_campButtons |= IN_DUCK;
@ -935,8 +810,8 @@ void Bot::FindItem (void)
RemoveCertainTask (TASK_MOVETOPOSITION); // remove any move tasks
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, timeToExplode, true); // push camp task on to stack
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, timeToExplode, true); // push move command
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, timeToExplode, true); // push camp task on to stack
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, timeToExplode, true); // push move command
if (path->vis.crouch <= path->vis.stand)
m_campButtons |= IN_DUCK;
@ -956,8 +831,8 @@ void Bot::FindItem (void)
{
int index = FindDefendWaypoint (entityOrigin);
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0, 70.0), true); // push camp task on to stack
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (10.0, 30.0), true); // push move command
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0, 70.0), true); // push camp task on to stack
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (10.0, 30.0), true); // push move command
if (g_waypoint->GetPath (index)->vis.crouch <= g_waypoint->GetPath (index)->vis.stand)
m_campButtons |= IN_DUCK;
@ -1030,8 +905,8 @@ void Bot::GetCampDirection (Vector *dest)
if (length > 10000)
return;
float minDistance = FLT_MAX;
float maxDistance = FLT_MAX;
float minDistance = 99999.0f;
float maxDistance = 99999.0f;
int enemyIndex = -1, tempIndex = -1;
@ -1057,7 +932,7 @@ void Bot::GetCampDirection (Vector *dest)
if (tempIndex == -1 || enemyIndex == -1)
return;
minDistance = FLT_MAX;
minDistance = 99999.0f;
int lookAtWaypoint = -1;
Path *path = g_waypoint->GetPath (tempIndex);
@ -1087,7 +962,6 @@ void Bot::SwitchChatterIcon (bool show)
if (g_gameVersion == CSV_OLD || yb_communication_type.GetInt () != 2)
return;
for (int i = 0; i < GetMaxClients (); i++)
{
if (!(g_clients[i].flags & CF_USED) || (g_clients[i].ent->v.flags & FL_FAKECLIENT) || g_clients[i].team != m_team)
@ -1152,7 +1026,7 @@ void Bot::RadioMessage (int message)
{
// this function inserts the radio message into the message queue
if (yb_communication_type.GetInt () == 0 || GetNearbyFriendsNearPosition (pev->origin, 9999) == 0)
if (yb_communication_type.GetInt () == 0 || m_numFriendsLeft == 0)
return;
if (g_chatterFactory[message].IsEmpty () || g_gameVersion == CSV_OLD || yb_communication_type.GetInt () != 2)
@ -1166,14 +1040,14 @@ void Bot::ChatterMessage (int message)
{
// this function inserts the voice message into the message queue (mostly same as above)
if (g_gameVersion == CSV_OLD || yb_communication_type.GetInt () != 2 || g_chatterFactory[message].IsEmpty () || GetNearbyFriendsNearPosition (pev->origin, 9999) == 0)
if (g_gameVersion == CSV_OLD || yb_communication_type.GetInt () != 2 || g_chatterFactory[message].IsEmpty () || m_numFriendsLeft == 0)
return;
bool shouldExecute = false;
if (m_voiceTimers[message] < GetWorldTime () || m_voiceTimers[message] == FLT_MAX)
if (m_voiceTimers[message] < GetWorldTime () || m_voiceTimers[message] == 99999.0f)
{
if (m_voiceTimers[message] != FLT_MAX)
if (m_voiceTimers[message] != 99999.0f)
m_voiceTimers[message] = GetWorldTime () + g_chatterFactory[message][0].repeatTime;
shouldExecute = true;
@ -1946,7 +1820,7 @@ void Bot::SetConditions (void)
ChatterMessage (Chatter_SniperKilled);
else
{
switch (GetNearbyEnemiesNearPosition (pev->origin, 9999))
switch (m_numEnemiesLeft)
{
case 0:
if (Random.Long (0, 100) < 50)
@ -1974,7 +1848,7 @@ void Bot::SetConditions (void)
}
// if no more enemies found AND bomb planted, switch to knife to get to bombplace faster
if (m_team == TEAM_CF && m_currentWeapon != WEAPON_KNIFE && GetNearbyEnemiesNearPosition (pev->origin, 9999) == 0 && g_bombPlanted)
if (m_team == TEAM_CF && m_currentWeapon != WEAPON_KNIFE && m_numEnemiesLeft == 0 && g_bombPlanted)
{
SelectWeaponByName ("weapon_knife");
m_plantedBombWptIndex = FindPlantedBomb ();
@ -2173,7 +2047,7 @@ void Bot::SetConditions (void)
if (!m_tasks.IsEmpty ())
{
final = MaxDesire (final, GetTask ());
StartTask (final->id, final->desire, final->data, final->time, final->resume); // push the final behavior in our task stack to carry out
PushTask (final->id, final->desire, final->data, final->time, final->resume); // push the final behavior in our task stack to carry out
}
}
@ -2184,7 +2058,7 @@ void Bot::ResetTasks (void)
m_tasks.RemoveAll ();
}
void Bot::StartTask (TaskID id, float desire, int data, float time, bool resume)
void Bot::PushTask (TaskID id, float desire, int data, float time, bool resume)
{
if (!m_tasks.IsEmpty ())
{
@ -2422,7 +2296,7 @@ void Bot::CheckRadioCommands (void)
if (taskID == TASK_PAUSE || taskID == TASK_CAMP)
GetTask ()->time = GetWorldTime ();
StartTask (TASK_FOLLOWUSER, TASKPRI_FOLLOWUSER, -1, 0.0, true);
PushTask (TASK_FOLLOWUSER, TASKPRI_FOLLOWUSER, -1, 0.0, true);
}
else if (numFollowers > allowedFollowers)
{
@ -2461,7 +2335,7 @@ void Bot::CheckRadioCommands (void)
m_campButtons = 0;
StartTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + Random.Float (30.0, 60.0), false);
PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + Random.Float (30.0, 60.0), false);
}
}
break;
@ -2555,7 +2429,7 @@ void Bot::CheckRadioCommands (void)
m_position = m_radioEntity->v.origin + g_pGlobals->v_forward * Random.Long (1024, 2048);
DeleteSearchNodes ();
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0, true);
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0, true);
}
}
else if (!IsEntityNull (m_doubleJumpEntity))
@ -2576,7 +2450,7 @@ void Bot::CheckRadioCommands (void)
RemoveCertainTask (TASK_CAMP);
m_targetEntity = NULL;
StartTask (TASK_ESCAPEFROMBOMB, TASKPRI_ESCAPEFROMBOMB, -1, 0.0, true);
PushTask (TASK_ESCAPEFROMBOMB, TASKPRI_ESCAPEFROMBOMB, -1, 0.0, true);
}
else
RadioMessage (Radio_Negative);
@ -2585,7 +2459,7 @@ void Bot::CheckRadioCommands (void)
case Radio_RegroupTeam:
// if no more enemies found AND bomb planted, switch to knife to get to bombplace faster
if ((m_team == TEAM_CF) && m_currentWeapon != WEAPON_KNIFE && GetNearbyEnemiesNearPosition (pev->origin, 9999) == 0 && g_bombPlanted && GetTaskId () != TASK_DEFUSEBOMB)
if ((m_team == TEAM_CF) && m_currentWeapon != WEAPON_KNIFE && m_numEnemiesLeft == 0 && g_bombPlanted && GetTaskId () != TASK_DEFUSEBOMB)
{
SelectWeaponByName ("weapon_knife");
@ -2613,7 +2487,7 @@ void Bot::CheckRadioCommands (void)
m_position = m_radioEntity->v.origin + g_pGlobals->v_forward * Random.Long (1024, 2048);
DeleteSearchNodes ();
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0, true);
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0, true);
m_fearLevel -= 0.3;
@ -2656,7 +2530,7 @@ void Bot::CheckRadioCommands (void)
// if bot has no enemy
if (m_lastEnemyOrigin == nullvec)
{
float nearestDistance = FLT_MAX;
float nearestDistance = 99999.0f;
// take nearest enemy to ordering player
for (int i = 0; i < GetMaxClients (); i++)
@ -2696,7 +2570,7 @@ void Bot::CheckRadioCommands (void)
{
if (g_timeNextBombUpdate < GetWorldTime ())
{
float minDistance = FLT_MAX;
float minDistance = 99999.0f;
// find nearest bomb waypoint to player
FOR_EACH_AE (g_waypoint->m_goalPoints, i)
@ -2753,7 +2627,7 @@ void Bot::CheckRadioCommands (void)
// if bot has no enemy
if (m_lastEnemyOrigin == nullvec)
{
float nearestDistance = FLT_MAX;
float nearestDistance = 99999.0f;
// take nearest enemy to ordering player
for (int i = 0; i < GetMaxClients (); i++)
@ -2777,9 +2651,9 @@ void Bot::CheckRadioCommands (void)
int index = FindDefendWaypoint (m_radioEntity->v.origin);
// push camp task on to stack
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0, 60.0), true);
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (30.0, 60.0), true);
// push move command
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (30.0, 60.0), true);
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (30.0, 60.0), true);
if (g_waypoint->GetPath (index)->vis.crouch <= g_waypoint->GetPath (index)->vis.stand)
m_campButtons |= IN_DUCK;
@ -2808,7 +2682,7 @@ void Bot::TryHeadTowardRadioEntity (void)
m_position = m_radioEntity->v.origin;
DeleteSearchNodes ();
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0, true);
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, -1, 0.0, true);
}
}
@ -2992,7 +2866,7 @@ void Bot::ChooseAimDirection (void)
m_lookAt = g_waypoint->GetPath (GetAimingWaypoint (m_lastEnemyOrigin))->origin;
m_camp = m_lookAt;
m_timeNextTracking = GetWorldTime () + 0.5;
m_timeNextTracking = GetWorldTime () + 0.5f;
m_trackingEdict = m_lastEnemy;
// feel free to fire if shoot able
@ -3150,14 +3024,6 @@ void Bot::Think (void)
if (g_lastRadioTime[team] + Random.Float (0.8, 2.1) < GetWorldTime ())
SwitchChatterIcon (false); // hide icon
// check is it time to execute think (called once per second (not frame))
if (m_timePeriodicUpdate < GetWorldTime ())
{
SecondThink ();
// update timer to one second
m_timePeriodicUpdate = GetWorldTime () + 0.99f;
}
CheckMessageQueue (); // check for pending messages
if (pev->maxspeed < 10 && GetTaskId () != TASK_PLANTBOMB && GetTaskId () != TASK_DEFUSEBOMB)
@ -3171,12 +3037,20 @@ void Bot::Think (void)
RunPlayerMovement (); // run the player movement
}
void Bot::SecondThink (void)
void Bot::PeriodicThink (void)
{
if (m_timePeriodicUpdate > GetWorldTime ())
return;
// this function is called from main think function every second (second not frame).
m_numFriendsLeft = GetNearbyFriendsNearPosition (pev->origin, 99999.0f);
m_numEnemiesLeft = GetNearbyEnemiesNearPosition (pev->origin, 99999.0f);
if (g_bombPlanted && m_team == TEAM_CF && (pev->origin - g_waypoint->GetBombPosition ()).GetLength () < 700 && !IsBombDefusing (g_waypoint->GetBombPosition ()) && !m_hasProgressBar && GetTaskId () != TASK_ESCAPEFROMBOMB)
ResetTasks ();
m_timePeriodicUpdate = GetWorldTime () + 0.65f;
}
void Bot::RunTask (void)
@ -3211,7 +3085,7 @@ void Bot::RunTask (void)
else
pev->button |= IN_ATTACK2;
m_knifeAttackTime = GetWorldTime () + Random.Float (2.5, 6.0);
m_knifeAttackTime = GetWorldTime () + Random.Float (2.5f, 6.0f);
}
if (m_reloadState == RELOAD_NONE && GetAmmo () != 0 && GetAmmoInClip () < 5 && g_weaponDefs[m_currentWeapon].ammo1 != -1)
@ -3235,7 +3109,7 @@ void Bot::RunTask (void)
// spray logo sometimes if allowed to do so
if (m_timeLogoSpray < GetWorldTime () && yb_spraypaints.GetBool () && Random.Long (1, 100) < 80 && m_moveSpeed > GetWalkSpeed ())
StartTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, GetWorldTime () + 1.0, false);
PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, GetWorldTime () + 1.0, false);
// reached waypoint is a camp waypoint
if ((m_currentPath->flags & FLAG_CAMP) && !yb_csdm_mode.GetBool ())
@ -3280,7 +3154,7 @@ void Bot::RunTask (void)
MakeVectors (pev->v_angle);
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (20.0f, 40.0f), true);
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (20.0f, 40.0f), true);
m_camp = Vector (m_currentPath->campStartX, m_currentPath->campStartY, 0.0f);
m_aimFlags |= AIM_CAMP;
@ -3317,8 +3191,8 @@ void Bot::RunTask (void)
{
int index = FindDefendWaypoint (m_currentPath->origin);
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (60.0, 120.0), true); // push camp task on to stack
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (5.0, 10.0), true); // push move command
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (60.0, 120.0), true); // push camp task on to stack
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (5.0, 10.0), true); // push move command
if (g_waypoint->GetPath (index)->vis.crouch <= g_waypoint->GetPath (index)->vis.stand)
m_campButtons |= IN_DUCK;
@ -3339,10 +3213,10 @@ void Bot::RunTask (void)
RadioMessage (Radio_NeedBackup);
InstantChatterMessage (Chatter_ScaredEmotion);
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (4.0, 8.0), true);
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (4.0, 8.0), true);
}
else
StartTask (TASK_PLANTBOMB, TASKPRI_PLANTBOMB, -1, 0.0, false);
PushTask (TASK_PLANTBOMB, TASKPRI_PLANTBOMB, -1, 0.0, false);
}
else if (m_team == TEAM_CF)
{
@ -3350,8 +3224,8 @@ void Bot::RunTask (void)
{
int index = FindDefendWaypoint (m_currentPath->origin);
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (25.0, 40.0), true); // push camp task on to stack
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (5.0f, 11.0f), true); // push move command
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (25.0, 40.0), true); // push camp task on to stack
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (5.0f, 11.0f), true); // push move command
if (g_waypoint->GetPath (index)->vis.crouch <= g_waypoint->GetPath (index)->vis.stand)
m_campButtons |= IN_DUCK;
@ -3532,7 +3406,7 @@ void Bot::RunTask (void)
m_pathType = 0;
// start hide task
StartTask (TASK_HIDE, TASKPRI_HIDE, -1, GetWorldTime () + Random.Float (5.0, 15.0), false);
PushTask (TASK_HIDE, TASKPRI_HIDE, -1, GetWorldTime () + Random.Float (5.0, 15.0), false);
destination = m_lastEnemyOrigin;
// get a valid look direction
@ -3694,7 +3568,7 @@ void Bot::RunTask (void)
// half the reaction time if camping because you're more aware of enemies if camping
SetIdealReactionTimes ();
m_idealReactionTime /= 2;
m_idealReactionTime *= 0.5f;
m_navTimeset = GetWorldTime ();
m_timeCamping = GetWorldTime();
@ -3793,7 +3667,7 @@ void Bot::RunTask (void)
// half the reaction time if camping
SetIdealReactionTimes ();
m_idealReactionTime /= 2;
m_idealReactionTime *= 0.5f;
m_navTimeset = GetWorldTime ();
m_moveSpeed = 0;
@ -3924,9 +3798,9 @@ void Bot::RunTask (void)
float bombTimer = mp_c4timer.GetFloat ();
// push camp task on to stack
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + (bombTimer * 0.5 + bombTimer * 0.25), true);
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + (bombTimer * 0.5 + bombTimer * 0.25), true);
// push move command
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + (bombTimer * 0.5 + bombTimer * 0.25), true);
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + (bombTimer * 0.5 + bombTimer * 0.25), true);
if (g_waypoint->GetPath (index)->vis.crouch <= g_waypoint->GetPath (index)->vis.stand)
m_campButtons |= IN_DUCK;
@ -3950,7 +3824,7 @@ void Bot::RunTask (void)
exceptionCaught = true;
g_bombPlanted = false;
if (GetNearbyFriendsNearPosition (pev->origin, 9999) != 0 && Random.Long (0, 100) < 50)
if (Random.Long (0, 100) < 50 && m_numFriendsLeft != 0)
{
if (timeToBlowUp <= 3.0)
{
@ -3969,9 +3843,9 @@ void Bot::RunTask (void)
{
if (GetNearbyFriendsNearPosition (pev->origin, 128) == 0)
{
if (defuseRemainingTime > 0.75)
if (defuseRemainingTime > 0.75f)
{
if (GetNearbyFriendsNearPosition (pev->origin, 128) > 0)
if (GetNearbyFriendsNearPosition (pev->origin, 512.0f) > 0)
RadioMessage (Radio_NeedBackup);
exceptionCaught = true;
@ -3986,7 +3860,7 @@ void Bot::RunTask (void)
{
if (timeToBlowUp > fullDefuseTime + 10.0)
{
if (GetNearbyFriendsNearPosition (pev->origin, 128) > 0)
if (GetNearbyFriendsNearPosition (pev->origin, 512.0f) > 0)
RadioMessage (Radio_NeedBackup);
exceptionCaught = true;
@ -3994,7 +3868,6 @@ void Bot::RunTask (void)
}
}
// one of exceptions is thrown. finish task.
if (exceptionCaught)
{
@ -4021,7 +3894,7 @@ void Bot::RunTask (void)
// bot is reloading and we close enough to start defusing
if (m_isReloading && (g_waypoint->GetBombPosition () - pev->origin).GetLength2D () < 80.0)
{
if (GetNearbyEnemiesNearPosition (pev->origin, 9999) == 0 || GetNearbyFriendsNearPosition (pev->origin, 768) > 2 || timeToBlowUp < fullDefuseTime + 7.0 || ((GetAmmoInClip () > 8 && m_reloadState == RELOAD_PRIMARY) || (GetAmmoInClip () > 5 && m_reloadState == RELOAD_SECONDARY)))
if (m_numEnemiesLeft == 0 || timeToBlowUp < fullDefuseTime + 7.0 || ((GetAmmoInClip () > 8 && m_reloadState == RELOAD_PRIMARY) || (GetAmmoInClip () > 5 && m_reloadState == RELOAD_SECONDARY)))
{
int weaponIndex = GetHighestWeapon ();
@ -4054,7 +3927,7 @@ void Bot::RunTask (void)
// if defusing is not already started, maybe crouch before
if (!m_hasProgressBar && m_duckDefuseCheckTime < GetWorldTime ())
{
if (m_difficulty >= 2 && GetNearbyEnemiesNearPosition (pev->origin, 9999.0) != 0)
if (m_difficulty >= 2 && m_numEnemiesLeft != 0)
m_duckDefuse = true;
Vector botDuckOrigin, botStandOrigin;
@ -4105,11 +3978,11 @@ void Bot::RunTask (void)
m_strafeSpeed = 0.0;
// notify team
if (GetNearbyFriendsNearPosition (pev->origin, 9999) != 0)
if (m_numFriendsLeft != 0)
{
ChatterMessage (Chatter_DefusingC4);
if (GetNearbyFriendsNearPosition (pev->origin, 256) < 2)
if (GetNearbyFriendsNearPosition (pev->origin, 512.0f) < 2)
RadioMessage (Radio_NeedBackup);
}
}
@ -4477,7 +4350,7 @@ void Bot::RunTask (void)
if (IsShieldDrawn ())
pev->button |= IN_ATTACK2;
if (m_currentWeapon != WEAPON_KNIFE && GetNearbyEnemiesNearPosition (pev->origin, 9999) == 0)
if (m_currentWeapon != WEAPON_KNIFE && m_numEnemiesLeft == 0)
SelectWeaponByName ("weapon_knife");
if (DoWaypointNav ()) // reached destination?
@ -4489,7 +4362,7 @@ void Bot::RunTask (void)
m_campButtons = IN_DUCK;
// we're reached destination point so just sit down and camp
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + 10.0, true);
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + 10.0, true);
}
else if (!GoalIsValid ()) // didn't choose goal waypoint yet?
{
@ -4660,7 +4533,7 @@ void Bot::RunTask (void)
ChatterMessage (Chatter_DefusingC4);
// notify team of defusing
if (GetNearbyFriendsNearPosition (pev->origin, 9999) < 2)
if (m_numFriendsLeft < 3)
RadioMessage (Radio_NeedBackup);
m_moveToGoal = false;
@ -4669,7 +4542,7 @@ void Bot::RunTask (void)
m_moveSpeed = 0;
m_strafeSpeed = 0;
StartTask (TASK_DEFUSEBOMB, TASKPRI_DEFUSEBOMB, -1, 0.0, false);
PushTask (TASK_DEFUSEBOMB, TASKPRI_DEFUSEBOMB, -1, 0.0, false);
}
break;
@ -4770,7 +4643,7 @@ void Bot::CheckSpawnTimeConditions (void)
if (m_checkKnifeSwitch && !m_checkWeaponSwitch && m_buyingFinished && m_spawnTime + Random.Float (4.0, 6.5) < GetWorldTime ())
{
if (Random.Long (1, 100) < 2 && yb_spraypaints.GetBool ())
StartTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, GetWorldTime () + 1.0, false);
PushTask (TASK_SPRAY, TASKPRI_SPRAYLOGO, -1, GetWorldTime () + 1.0, false);
if (m_difficulty >= 2 && Random.Long (0, 100) < (m_personality == PERSONALITY_RUSHER ? 99 : 50) && !m_isReloading && (g_mapType & (MAP_CS | MAP_DE | MAP_ES | MAP_AS)))
{
@ -4864,22 +4737,24 @@ void Bot::BotAI (void)
{
if ((m_states & STATE_SEEING_ENEMY) && !IsEntityNull (m_enemy))
{
if (Random.Long (0, 100) < 45 && GetNearbyFriendsNearPosition (pev->origin, 512) == 0 && (m_enemy->v.weapons & (1 << WEAPON_C4)))
int hasFriendNearby = GetNearbyFriendsNearPosition (pev->origin, 512.0f);
if (!hasFriendNearby && Random.Long (0, 100) < 45 && (m_enemy->v.weapons & (1 << WEAPON_C4)))
ChatterMessage (Chatter_SpotTheBomber);
if (Random.Long (0, 100) < 45 && m_team == TEAM_TF && GetNearbyFriendsNearPosition (pev->origin, 512) == 0 && IsPlayerVIP (m_enemy))
else if (!hasFriendNearby && Random.Long (0, 100) < 45 && m_team == TEAM_TF && IsPlayerVIP (m_enemy))
ChatterMessage (Chatter_VIPSpotted);
if (Random.Long (0, 100) < 50 && GetNearbyFriendsNearPosition (pev->origin, 450) == 0 && GetTeam (m_enemy) != m_team && IsGroupOfEnemies (m_enemy->v.origin, 2, 384))
else if (!hasFriendNearby && Random.Long (0, 100) < 50 && GetTeam (m_enemy) != m_team && IsGroupOfEnemies (m_enemy->v.origin, 2, 384))
ChatterMessage (Chatter_ScaredEmotion);
if (Random.Long (0, 100) < 40 && GetNearbyFriendsNearPosition (pev->origin, 1024) == 0 && ((m_enemy->v.weapons & (1 << WEAPON_AWP)) || (m_enemy->v.weapons & (1 << WEAPON_SCOUT)) || (m_enemy->v.weapons & (1 << WEAPON_G3SG1)) || (m_enemy->v.weapons & (1 << WEAPON_SG550))))
else if (!hasFriendNearby && Random.Long (0, 100) < 40 && ((m_enemy->v.weapons & (1 << WEAPON_AWP)) || (m_enemy->v.weapons & (1 << WEAPON_SCOUT)) || (m_enemy->v.weapons & (1 << WEAPON_G3SG1)) || (m_enemy->v.weapons & (1 << WEAPON_SG550))))
ChatterMessage (Chatter_SniperWarning);
}
// if bot is trapped under shield yell for help !
if (GetTaskId () == TASK_CAMP && HasShield () && IsShieldDrawn () && GetNearbyEnemiesNearPosition (pev->origin, 650) >= 2 && IsEnemyViewable (m_enemy))
InstantChatterMessage (Chatter_Pinned_Down);
// if bot is trapped under shield yell for help !
if (GetTaskId () == TASK_CAMP && HasShield () && IsShieldDrawn () && hasFriendNearby >= 2 && IsEnemyViewable (m_enemy))
InstantChatterMessage (Chatter_Pinned_Down);
}
// if bomb planted warn teammates !
if (g_canSayBombPlanted && g_bombPlanted && GetTeam (GetEntity ()) == TEAM_CF)
@ -4936,7 +4811,7 @@ void Bot::BotAI (void)
TaskComplete (); // complete current task
// then start escape from bomb immidiate
StartTask (TASK_ESCAPEFROMBOMB, TASKPRI_ESCAPEFROMBOMB, -1, 0.0, true);
PushTask (TASK_ESCAPEFROMBOMB, TASKPRI_ESCAPEFROMBOMB, -1, 0.0, true);
}
// allowed to move to a destination position?
@ -6139,7 +6014,7 @@ bool Bot::IsBombDefusing (const Vector &bombOrigin)
float Bot::GetWalkSpeed (void)
{
if ((pev->flags & FL_DUCKING) || (pev->button & IN_DUCK) || (pev->oldbuttons & IN_DUCK) || (m_currentTravelFlags & PATHFLAG_JUMP) || (m_currentPath != NULL && m_currentPath->flags & FLAG_LADDER) || IsOnLadder () || IsInWater ())
if ((GetTaskId () == TASK_SEEKCOVER) || (pev->flags & FL_DUCKING) || (pev->button & IN_DUCK) || (pev->oldbuttons & IN_DUCK) || (m_currentTravelFlags & PATHFLAG_JUMP) || (m_currentPath != NULL && m_currentPath->flags & FLAG_LADDER) || IsOnLadder () || IsInWater ())
return pev->maxspeed;
return static_cast <float> ((static_cast <int> (pev->maxspeed) * 0.5f) + (static_cast <int> (pev->maxspeed) / 50.0f)) - 18.0f;

View file

@ -16,7 +16,7 @@ ConVar yb_check_enemy_rendering ("yb_check_enemy_rendering", "0", VT_NOSERVER);
ConVar mp_friendlyfire ("mp_friendlyfire", NULL, VT_NOREGISTER);
int Bot::GetNearbyFriendsNearPosition (const Vector &origin, int radius)
int Bot::GetNearbyFriendsNearPosition(const Vector &origin, float radius)
{
int count = 0;
@ -25,13 +25,13 @@ int Bot::GetNearbyFriendsNearPosition (const Vector &origin, int radius)
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team != m_team || g_clients[i].ent == GetEntity ())
continue;
if ((g_clients[i].origin - origin).GetLengthSquared () < static_cast <float> (radius * radius))
if ((g_clients[i].origin - origin).GetLengthSquared () < GET_SQUARE (radius))
count++;
}
return count;
}
int Bot::GetNearbyEnemiesNearPosition (const Vector &origin, int radius)
int Bot::GetNearbyEnemiesNearPosition(const Vector &origin, float radius)
{
int count = 0;
@ -40,7 +40,7 @@ int Bot::GetNearbyEnemiesNearPosition (const Vector &origin, int radius)
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].team == m_team)
continue;
if ((g_clients[i].origin - origin).GetLengthSquared () < static_cast <float> (radius * radius))
if ((g_clients[i].origin - origin).GetLengthSquared () < GET_SQUARE (radius))
count++;
}
return count;
@ -89,6 +89,133 @@ bool Bot::IsEnemyHiddenByRendering (edict_t *enemy)
return false;
}
bool Bot::CheckVisibility (edict_t *target, Vector *origin, byte *bodyPart)
{
// this function checks visibility of a bot target.
if (IsEnemyHiddenByRendering (target))
{
*bodyPart = 0;
*origin = nullvec;
return false;
}
const Vector &botHead = EyePosition ();
TraceResult tr;
*bodyPart = 0;
// check for the body
TraceLine (botHead, target->v.origin, true, true, GetEntity (), &tr);
if (tr.flFraction >= 1.0f)
{
*bodyPart |= VISIBLE_BODY;
*origin = target->v.origin;
if (m_difficulty == 4)
origin->z += 3.0f;
}
// check for the head
TraceLine (botHead, target->v.origin + target->v.view_ofs, true, true, GetEntity (), &tr);
if (tr.flFraction >= 1.0f)
{
*bodyPart |= VISIBLE_HEAD;
*origin = target->v.origin + target->v.view_ofs;
if (m_difficulty == 4)
origin->z += 1.0f;
}
if (*bodyPart != 0)
return true;
// thanks for this code goes to kwo
MakeVectors (target->v.angles);
// worst case, choose random position in enemy body
for (int i = 0; i < 6; i++)
{
Vector pos = target->v.origin;
switch (i)
{
case 0: // left arm
pos.x -= 10.0f * g_pGlobals->v_right.x;
pos.y -= 10.0f * g_pGlobals->v_right.y;
pos.z += 8.0f;
break;
case 1: // right arm
pos.x += 10.0f * g_pGlobals->v_right.x;
pos.y += 10.0f * g_pGlobals->v_right.y;
pos.z += 8.0f;
break;
case 2: // left leg
pos.x -= 10.0f * g_pGlobals->v_right.x;
pos.y -= 10.0f * g_pGlobals->v_right.y;
pos.z -= 12.0f;
break;
case 3: // right leg
pos.x += 10.0f * g_pGlobals->v_right.x;
pos.y += 10.0f * g_pGlobals->v_right.y;
pos.z -= 12.0f;
break;
case 4: // left foot
pos.x -= 10.0f * g_pGlobals->v_right.x;
pos.y -= 10.0f * g_pGlobals->v_right.y;
pos.z -= 24.0f;
break;
case 5: // right foot
pos.x += 10.0f * g_pGlobals->v_right.x;
pos.y += 10.0f * g_pGlobals->v_right.y;
pos.z -= 24.0f;
break;
}
// check direct line to random part of the player body
TraceLine (botHead, pos, true, true, GetEntity (), &tr);
// check if we hit something
if (tr.flFraction >= 1.0f)
{
*origin = tr.vecEndPos;
*bodyPart |= VISIBLE_OTHER;
return true;
}
}
return false;
}
bool Bot::IsEnemyViewable (edict_t *player)
{
if (IsEntityNull (player))
return false;
bool forceTrueIfVisible = false;
if (IsValidPlayer (pev->dmg_inflictor) && GetTeam (pev->dmg_inflictor) != m_team)
forceTrueIfVisible = true;
if ((IsInViewCone (player->v.origin + pev->view_ofs) || forceTrueIfVisible) && CheckVisibility (player, &m_enemyOrigin, &m_visibility))
{
m_seeEnemyTime = GetWorldTime ();
m_lastEnemy = player;
m_lastEnemyOrigin = player->v.origin;
return true;
}
return false;
}
bool Bot::LookupEnemy (void)
{
// this function tries to find the best suitable enemy for the bot
@ -97,16 +224,6 @@ bool Bot::LookupEnemy (void)
if (m_blindTime > GetWorldTime () || yb_ignore_enemies.GetBool ())
return false;
// do not check for new enemy too fast
#if 0
if (!IsEntityNull (m_enemy) && m_enemyUpdateTime + 2.5f > GetWorldTime () && !(m_states & STATE_SUSPECT_ENEMY))
{
m_aimFlags |= AIM_ENEMY;
m_states |= STATE_SUSPECT_ENEMY;
return true;
}
#endif
edict_t *player, *newEnemy = NULL;
float nearestDistance = m_viewDistance;
@ -500,38 +617,42 @@ bool Bot::IsShootableThruObstacle (const Vector &dest)
if (penetratePower == 0)
return false;
// set conditions....
Vector source = EyePosition ();
const Vector &direction = (dest - source).Normalize () * 8.0f; // 8 units long
TraceResult tr;
do
{
// trace from the bot's eyes to destination...
TraceLine (source, dest, true, GetEntity (), &tr);
float obstacleDistance = 0.0f;
TraceLine (EyePosition (), dest, true, GetEntity (), &tr);
if (tr.fStartSolid)
if (tr.fStartSolid)
{
const Vector &source = tr.vecEndPos;
TraceLine (dest, source, true, GetEntity (), &tr);
if (tr.flFraction != 1.0f)
{
if (tr.fAllSolid)
if ((tr.vecEndPos - dest).GetLengthSquared () > GET_SQUARE (800.0f))
return false;
// move 8 units closer to the destination....
source += direction;
if (tr.vecEndPos.z >= dest.z + 200.0f)
return false;
obstacleDistance = (tr.vecEndPos - source).GetLength ();
}
else
}
if (obstacleDistance > 0.0f)
{
while (penetratePower > 0)
{
// check if line hit anything
if (tr.flFraction == 1.0f)
return true;
if (obstacleDistance > 75.0f)
{
obstacleDistance -= 75.0f;
penetratePower--;
--penetratePower;
// move 8 units closer to the destination....
source = tr.vecEndPos + direction;
continue;
}
return true;
}
} while (penetratePower > 0);
}
return false;
}
@ -575,7 +696,7 @@ bool Bot::IsShootableThruObstacleEx (const Vector &dest)
return false;
}
bool Bot::DoFirePause (float distance, FireDelay *fireDelay)
bool Bot::DoFirePause (float distance)
{
// returns true if bot needs to pause between firing to compensate for punchangle & weapon spread
@ -585,12 +706,6 @@ bool Bot::DoFirePause (float distance, FireDelay *fireDelay)
return false;
}
if (UsesPistol () && distance > 450.0f)
{
m_shootTime = GetWorldTime () + Random.Float (0.15f, 0.4f);
return false;
}
if (m_firePause > GetWorldTime ())
return true;
@ -619,21 +734,6 @@ bool Bot::DoFirePause (float distance, FireDelay *fireDelay)
if (m_firePause < GetWorldTime () - 0.4f)
m_firePause = GetWorldTime () + Random.Float (0.4f, 0.4f + 0.3f * ((100 - (m_difficulty * 25)) / 100.f));
m_burstShotsFired = 0;
return true;
}
if (m_difficulty < 3 && fireDelay->maxFireBullets + Random.Long (0, 1) <= m_burstShotsFired)
{
float delayTime = 0.1 * distance / fireDelay->minBurstPauseFactor;
if (delayTime > (125.0 / (m_difficulty * 25 + 1)))
delayTime = 125.0 / (m_difficulty * 25 + 1);
m_firePause = GetWorldTime () + delayTime;
m_burstShotsFired = 0;
return true;
}
return false;
@ -662,8 +762,6 @@ void Bot::FireWeapon (void)
return;
}
}
FireDelay *delay = &g_fireDelay[0];
WeaponSelect *selectTab = &g_weaponSelect[0];
edict_t *enemy = m_enemy;
@ -742,14 +840,10 @@ WeaponSelectEnd:
// reset burst fire variables
m_firePause = 0.0;
m_timeLastFired = 0.0;
m_burstShotsFired = 0;
return;
}
if (delay[chosenWeaponIndex].weaponIndex != selectId)
return;
if (selectTab[chosenWeaponIndex].id != selectId)
{
chosenWeaponIndex = 0;
@ -818,10 +912,6 @@ WeaponSelectEnd:
return;
}
const float baseDelay = delay[chosenWeaponIndex].primaryBaseDelay;
const float minDelay = delay[chosenWeaponIndex].primaryMinDelay[abs (m_difficulty - 4)];
const float maxDelay = delay[chosenWeaponIndex].primaryMaxDelay[abs (m_difficulty - 4)];
// need to care for burst fire?
if (distance < 256.0 || m_blindTime > GetWorldTime ())
@ -852,7 +942,7 @@ WeaponSelectEnd:
}
else
{
if (DoFirePause (distance, &delay[chosenWeaponIndex]))
if (DoFirePause (distance))
return;
// don't attack with knife over long distance
@ -873,7 +963,8 @@ WeaponSelectEnd:
{
pev->button |= IN_ATTACK;
m_shootTime = GetWorldTime () + baseDelay + Random.Float (minDelay, maxDelay);
// m_shootTime = GetWorldTime () + baseDelay + Random.Float (minDelay, maxDelay);
m_shootTime = GetWorldTime () + Random.Float (0.15f, 0.35f);
m_zoomCheckTime = GetWorldTime () - 0.09f;
}
}
@ -993,7 +1084,7 @@ void Bot::CombatFight (void)
CheckThrow (EyePosition(), m_throw);
if ((m_states & STATE_SEEING_ENEMY) && !m_hasC4)
StartTask (TASK_SEEKCOVER, TASKPRI_SEEKCOVER, -1, Random.Long (10, 20), true);
PushTask (TASK_SEEKCOVER, TASKPRI_SEEKCOVER, -1, Random.Long (10, 20), true);
}
// only take cover when bomb is not planted and enemy can see the bot or the bot is VIP
@ -1392,7 +1483,7 @@ void Bot::SelectWeaponbyNumber (int num)
void Bot::AttachToUser (void)
{
// this function forces bot to join to user
// this function forces bot to follow user
Array <edict_t *> foundUsers;
// search friends near us
@ -1411,7 +1502,7 @@ void Bot::AttachToUser (void)
m_targetEntity = foundUsers.GetRandomElement ();
ChatterMessage (Chatter_LeadOnSir);
StartTask (TASK_FOLLOWUSER, TASKPRI_FOLLOWUSER, -1, 0.0, true);
PushTask (TASK_FOLLOWUSER, TASKPRI_FOLLOWUSER, -1, 0.0, true);
}
void Bot::CommandTeam (void)
@ -1463,7 +1554,7 @@ bool Bot::IsGroupOfEnemies (const Vector &location, int numEnemies, int radius)
if (!(g_clients[i].flags & CF_USED) || !(g_clients[i].flags & CF_ALIVE) || g_clients[i].ent == GetEntity ())
continue;
if ((g_clients[i].ent->v.origin - location).GetLength () < radius)
if ((g_clients[i].ent->v.origin - location).GetLengthSquared () < GET_SQUARE (radius))
{
// don't target our teammates...
if (g_clients[i].team == m_team)

View file

@ -186,39 +186,6 @@ WeaponSelect g_weaponSelect[NUM_WEAPONS + 1] =
{0, "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, false}
};
// weapon firing delay based on skill (min and max delay for each weapon)
FireDelay g_fireDelay[NUM_WEAPONS + 1] =
{
{ WEAPON_KNIFE, 255, 256, 0.10f,{ 0.0f, 0.2f, 0.3f, 0.4f, 0.6f, 0.8f },{ 0.1f, 0.3f, 0.5f, 0.7f, 1.0f, 1.2f }, 0.0f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
{ WEAPON_USP, 3, 853, 0.15f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_GLOCK, 5, 853, 0.15f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_DEAGLE, 2, 640, 0.20f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_P228, 4, 853, 0.14f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_ELITE, 3, 640, 0.20f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_FIVESEVEN, 4, 731, 0.14f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_M3, 8, 365, 0.86f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_XM1014, 7, 512, 0.15f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_MP5, 4, 731, 0.10f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_TMP, 3, 731, 0.05f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_P90, 4, 731, 0.10f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_MAC10, 3, 731, 0.06f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_UMP45, 4, 731, 0.15f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_AK47, 2, 512, 0.09f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_SG552, 3, 512, 0.11f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_M4A1, 3, 512, 0.08f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_GALIL, 4, 512, 0.09f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_FAMAS, 4, 512, 0.10f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_AUG, 3, 512, 0.11f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_SCOUT, 10, 256, 0.18f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_AWP, 10, 170, 0.22f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_G3SG1, 4, 256, 0.25f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_SG550, 4, 256, 0.25f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_M249, 3, 640, 0.10f,{ 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.6f },{ 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.7f }, 0.2f,{ 0.0f, 0.0f, 0.1f, 0.1f, 0.2f },{ 0.1f, 0.1f, 0.2f, 0.2f, 0.4f } },
{ WEAPON_SHIELD, 0, 256, 0.00f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, 0.0f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } },
{ 0, 0, 256, 0.00f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, 0.0f,{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }
};
// bot menus
MenuText g_menus[21] =
{

View file

@ -11,7 +11,7 @@
// console vars
ConVar yb_password ("yb_password", "", VT_PASSWORD);
ConVar yb_password_key ("yb_password_key", "_ybwp", VT_NOSERVER);
ConVar yb_password_key ("yb_password_key", "_ybpw", VT_NOSERVER);
ConVar yb_language ("yb_language", "en");
ConVar yb_version ("yb_version", PRODUCT_VERSION, VT_READONLY);
@ -728,82 +728,83 @@ void InitConfig (void)
array[1].TrimRight (';');
array[1].TrimRight (')');
#define PARSE_VOICE_EVENT(type, timeToRepeatAgain) { if (strcmp (array[0], #type) == 0) ParseVoiceEvent (array[1], type, timeToRepeatAgain); }
#define PARSE_CHATTER_ITEM(type, timeToRepeatAgain) { if (strcmp (array[0], #type) == 0) ParseVoiceEvent (array[1], type, timeToRepeatAgain); }
#define PARSE_CHATTER_ITEM_NR(type) PARSE_CHATTER_ITEM(type, 99999.0f)
// radio system
PARSE_VOICE_EVENT (Radio_CoverMe, FLT_MAX);
PARSE_VOICE_EVENT (Radio_YouTakePoint, FLT_MAX);
PARSE_VOICE_EVENT (Radio_HoldPosition, FLT_MAX);
PARSE_VOICE_EVENT (Radio_RegroupTeam, FLT_MAX);
PARSE_VOICE_EVENT (Radio_FollowMe, FLT_MAX);
PARSE_VOICE_EVENT (Radio_TakingFire, FLT_MAX);
PARSE_VOICE_EVENT (Radio_GoGoGo, FLT_MAX);
PARSE_VOICE_EVENT (Radio_Fallback, FLT_MAX);
PARSE_VOICE_EVENT (Radio_StickTogether, FLT_MAX);
PARSE_VOICE_EVENT (Radio_GetInPosition, FLT_MAX);
PARSE_VOICE_EVENT (Radio_StormTheFront, FLT_MAX);
PARSE_VOICE_EVENT (Radio_ReportTeam, FLT_MAX);
PARSE_VOICE_EVENT (Radio_Affirmative, FLT_MAX);
PARSE_VOICE_EVENT (Radio_EnemySpotted, FLT_MAX);
PARSE_VOICE_EVENT (Radio_NeedBackup, FLT_MAX);
PARSE_VOICE_EVENT (Radio_SectorClear, FLT_MAX);
PARSE_VOICE_EVENT (Radio_InPosition, FLT_MAX);
PARSE_VOICE_EVENT (Radio_ReportingIn, FLT_MAX);
PARSE_VOICE_EVENT (Radio_ShesGonnaBlow, FLT_MAX);
PARSE_VOICE_EVENT (Radio_Negative, FLT_MAX);
PARSE_VOICE_EVENT (Radio_EnemyDown, FLT_MAX);
PARSE_CHATTER_ITEM_NR (Radio_CoverMe);
PARSE_CHATTER_ITEM_NR (Radio_YouTakePoint);
PARSE_CHATTER_ITEM_NR (Radio_HoldPosition);
PARSE_CHATTER_ITEM_NR (Radio_RegroupTeam);
PARSE_CHATTER_ITEM_NR (Radio_FollowMe);
PARSE_CHATTER_ITEM_NR (Radio_TakingFire);
PARSE_CHATTER_ITEM_NR (Radio_GoGoGo);
PARSE_CHATTER_ITEM_NR (Radio_Fallback);
PARSE_CHATTER_ITEM_NR (Radio_StickTogether);
PARSE_CHATTER_ITEM_NR (Radio_GetInPosition);
PARSE_CHATTER_ITEM_NR (Radio_StormTheFront);
PARSE_CHATTER_ITEM_NR (Radio_ReportTeam);
PARSE_CHATTER_ITEM_NR (Radio_Affirmative);
PARSE_CHATTER_ITEM_NR (Radio_EnemySpotted);
PARSE_CHATTER_ITEM_NR (Radio_NeedBackup);
PARSE_CHATTER_ITEM_NR (Radio_SectorClear);
PARSE_CHATTER_ITEM_NR (Radio_InPosition);
PARSE_CHATTER_ITEM_NR (Radio_ReportingIn);
PARSE_CHATTER_ITEM_NR (Radio_ShesGonnaBlow);
PARSE_CHATTER_ITEM_NR (Radio_Negative);
PARSE_CHATTER_ITEM_NR (Radio_EnemyDown);
// voice system
PARSE_VOICE_EVENT (Chatter_SpotTheBomber, 4.3f);
PARSE_VOICE_EVENT (Chatter_VIPSpotted, 5.3f);
PARSE_VOICE_EVENT (Chatter_FriendlyFire, 2.1f);
PARSE_VOICE_EVENT (Chatter_DiePain, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_GotBlinded, 5.0f);
PARSE_VOICE_EVENT (Chatter_GoingToPlantBomb, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_GoingToGuardVIPSafety, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_RescuingHostages, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_GoingToCamp, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_TeamKill, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_ReportingIn, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_GuardDroppedC4, 3.0f);
PARSE_VOICE_EVENT (Chatter_Camp, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_GuardingVipSafety, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_PlantingC4, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_DefusingC4, 3.0f);
PARSE_VOICE_EVENT (Chatter_InCombat, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_SeeksEnemy, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_Nothing, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_EnemyDown, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_UseHostage, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_FoundC4, 5.5f);
PARSE_VOICE_EVENT (Chatter_WonTheRound, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_ScaredEmotion, 6.1f);
PARSE_VOICE_EVENT (Chatter_HeardEnemy, 12.2f);
PARSE_VOICE_EVENT (Chatter_SniperWarning, 4.3f);
PARSE_VOICE_EVENT (Chatter_SniperKilled, 2.1f);
PARSE_VOICE_EVENT (Chatter_QuicklyWonTheRound, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_OneEnemyLeft, 2.5f);
PARSE_VOICE_EVENT (Chatter_TwoEnemiesLeft, 2.5f);
PARSE_VOICE_EVENT (Chatter_ThreeEnemiesLeft, 2.5f);
PARSE_VOICE_EVENT (Chatter_NoEnemiesLeft, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_FoundBombPlace, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_WhereIsTheBomb, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_DefendingBombSite, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_BarelyDefused, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_NiceshotCommander, FLT_MAX);
PARSE_VOICE_EVENT (Chatter_NiceshotPall, 2.0);
PARSE_VOICE_EVENT (Chatter_GoingToGuardHostages, 3.0f);
PARSE_VOICE_EVENT (Chatter_GoingToGuardDoppedBomb, 3.0f);
PARSE_VOICE_EVENT (Chatter_OnMyWay, 1.5f);
PARSE_VOICE_EVENT (Chatter_LeadOnSir, 5.0f);
PARSE_VOICE_EVENT (Chatter_Pinned_Down, 5.0f);
PARSE_VOICE_EVENT (Chatter_GottaFindTheBomb, 3.0f);
PARSE_VOICE_EVENT (Chatter_You_Heard_The_Man, 3.0f);
PARSE_VOICE_EVENT (Chatter_Lost_The_Commander, 4.5f);
PARSE_VOICE_EVENT (Chatter_NewRound, 3.5f);
PARSE_VOICE_EVENT (Chatter_CoverMe, 3.5f);
PARSE_VOICE_EVENT (Chatter_BehindSmoke, 3.5f);
PARSE_VOICE_EVENT (Chatter_BombSiteSecured, 3.5f);
PARSE_CHATTER_ITEM (Chatter_SpotTheBomber, 4.3f);
PARSE_CHATTER_ITEM (Chatter_VIPSpotted, 5.3f);
PARSE_CHATTER_ITEM (Chatter_FriendlyFire, 2.1f);
PARSE_CHATTER_ITEM_NR (Chatter_DiePain);
PARSE_CHATTER_ITEM (Chatter_GotBlinded, 5.0f);
PARSE_CHATTER_ITEM_NR (Chatter_GoingToPlantBomb);
PARSE_CHATTER_ITEM_NR (Chatter_GoingToGuardVIPSafety);
PARSE_CHATTER_ITEM_NR (Chatter_RescuingHostages);
PARSE_CHATTER_ITEM_NR (Chatter_GoingToCamp);
PARSE_CHATTER_ITEM_NR (Chatter_TeamKill);
PARSE_CHATTER_ITEM_NR (Chatter_ReportingIn);
PARSE_CHATTER_ITEM (Chatter_GuardDroppedC4, 3.0f);
PARSE_CHATTER_ITEM_NR (Chatter_Camp);
PARSE_CHATTER_ITEM_NR (Chatter_GuardingVipSafety);
PARSE_CHATTER_ITEM_NR (Chatter_PlantingC4);
PARSE_CHATTER_ITEM (Chatter_DefusingC4, 3.0f);
PARSE_CHATTER_ITEM_NR (Chatter_InCombat);
PARSE_CHATTER_ITEM_NR (Chatter_SeeksEnemy);
PARSE_CHATTER_ITEM_NR (Chatter_Nothing);
PARSE_CHATTER_ITEM_NR (Chatter_EnemyDown);
PARSE_CHATTER_ITEM_NR (Chatter_UseHostage);
PARSE_CHATTER_ITEM (Chatter_FoundC4, 5.5f);
PARSE_CHATTER_ITEM_NR (Chatter_WonTheRound);
PARSE_CHATTER_ITEM (Chatter_ScaredEmotion, 6.1f);
PARSE_CHATTER_ITEM (Chatter_HeardEnemy, 12.2f);
PARSE_CHATTER_ITEM (Chatter_SniperWarning, 4.3f);
PARSE_CHATTER_ITEM (Chatter_SniperKilled, 2.1f);
PARSE_CHATTER_ITEM_NR (Chatter_QuicklyWonTheRound);
PARSE_CHATTER_ITEM (Chatter_OneEnemyLeft, 2.5f);
PARSE_CHATTER_ITEM (Chatter_TwoEnemiesLeft, 2.5f);
PARSE_CHATTER_ITEM (Chatter_ThreeEnemiesLeft, 2.5f);
PARSE_CHATTER_ITEM_NR (Chatter_NoEnemiesLeft);
PARSE_CHATTER_ITEM_NR (Chatter_FoundBombPlace);
PARSE_CHATTER_ITEM_NR (Chatter_WhereIsTheBomb);
PARSE_CHATTER_ITEM_NR (Chatter_DefendingBombSite);
PARSE_CHATTER_ITEM_NR (Chatter_BarelyDefused);
PARSE_CHATTER_ITEM_NR (Chatter_NiceshotCommander);
PARSE_CHATTER_ITEM (Chatter_NiceshotPall, 2.0);
PARSE_CHATTER_ITEM (Chatter_GoingToGuardHostages, 3.0f);
PARSE_CHATTER_ITEM (Chatter_GoingToGuardDoppedBomb, 3.0f);
PARSE_CHATTER_ITEM (Chatter_OnMyWay, 1.5f);
PARSE_CHATTER_ITEM (Chatter_LeadOnSir, 5.0f);
PARSE_CHATTER_ITEM (Chatter_Pinned_Down, 5.0f);
PARSE_CHATTER_ITEM (Chatter_GottaFindTheBomb, 3.0f);
PARSE_CHATTER_ITEM (Chatter_You_Heard_The_Man, 3.0f);
PARSE_CHATTER_ITEM (Chatter_Lost_The_Commander, 4.5f);
PARSE_CHATTER_ITEM (Chatter_NewRound, 3.5f);
PARSE_CHATTER_ITEM (Chatter_CoverMe, 3.5f);
PARSE_CHATTER_ITEM (Chatter_BehindSmoke, 3.5f);
PARSE_CHATTER_ITEM (Chatter_BombSiteSecured, 3.5f);
}
}
fp.Close ();
@ -1575,7 +1576,7 @@ void ClientCommand (edict_t *ent)
bot->m_doubleJumpOrigin = client->ent->v.origin;
bot->m_doubleJumpEntity = client->ent;
bot->StartTask (TASK_DOUBLEJUMP, TASKPRI_DOUBLEJUMP, -1, GetWorldTime (), true);
bot->PushTask (TASK_DOUBLEJUMP, TASKPRI_DOUBLEJUMP, -1, GetWorldTime (), true);
bot->TeamSayText (FormatBuffer ("Ok %s, i will help you!", STRING (ent->v.netname)));
}
else if (selection == 2)
@ -2103,6 +2104,9 @@ void StartFrame (void)
// for example if a new player joins the server, we should disconnect a bot, and if the
// player population decreases, we should fill the server with other bots.
// run periodic update of bot states
g_botManager->PeriodicThink ();
// record some stats of all players on the server
for (int i = 0; i < GetMaxClients (); i++)
{

View file

@ -241,6 +241,17 @@ void BotManager::Think (void)
}
}
void BotManager::PeriodicThink (void)
{
// this function calls periodic SecondThink () function for all available at call moment bots
for (int i = 0; i < GetMaxClients (); i++)
{
if (m_bots[i] != NULL)
m_bots[i]->PeriodicThink ();
}
}
void BotManager::AddBot (const String &name, int difficulty, int personality, int team, int member)
{
// this function putting bot creation process to queue to prevent engine crashes
@ -931,6 +942,9 @@ void Bot::NewRound (void)
m_duckDefuse = false;
m_duckDefuseCheckTime = 0.0;
m_numFriendsLeft = 0;
m_numEnemiesLeft = 0;
for (i = 0; i < 5; i++)
m_prevWptIndex[i] = -1;
@ -1009,7 +1023,6 @@ void Bot::NewRound (void)
m_doorOpenAttempt = 0;
m_aimFlags = 0;
m_liftState = 0;
m_burstShotsFired = 0;
m_position = nullvec;
m_liftTravelPos = nullvec;
@ -1106,7 +1119,7 @@ void Bot::NewRound (void)
// and put buying into its message queue
PushMessageQueue (GSM_BUY_STUFF);
StartTask (TASK_NORMAL, TASKPRI_NORMAL, -1, 0.0, true);
PushTask (TASK_NORMAL, TASKPRI_NORMAL, -1, 0.0, true);
if (Random.Long (0, 100) < 50)
ChatterMessage (Chatter_NewRound);

View file

@ -442,7 +442,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal)
else if (IsInWater ())
bits |= (PROBE_JUMP | PROBE_STRAFE);
else
bits |= ((Random.Long (0, 20) > (cantMoveForward ? 15 : 10) ? PROBE_JUMP : 0) | PROBE_STRAFE | PROBE_DUCK);
bits |= ((Random.Long (0, 20) > (cantMoveForward ? 10 : 7) ? PROBE_JUMP : 0) | PROBE_STRAFE | PROBE_DUCK);
// collision check allowed if not flying through the air
if (IsOnFloor () || IsOnLadder () || IsInWater ())
@ -1138,7 +1138,7 @@ bool Bot::DoWaypointNav (void)
// if bot hits the door, then it opens, so wait a bit to let it open safely
if (pev->velocity.GetLength2D () < 2 && m_timeDoorOpen < GetWorldTime ())
{
StartTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + 1, false);
PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + 1, false);
m_doorOpenAttempt++;
m_timeDoorOpen = GetWorldTime () + 1.0; // retry in 1 sec until door is open
@ -1816,7 +1816,7 @@ void Bot::DeleteSearchNodes (void)
int Bot::GetAimingWaypoint (const Vector &to)
{
// return the most distant waypoint which is seen from the Bot to the Target and is within count
// return the most distant waypoint which is seen from the bot to the target and is within count
if (m_currentWaypointIndex == -1)
m_currentWaypointIndex = ChangeWptIndex (g_waypoint->FindNearest (pev->origin));
@ -1825,13 +1825,6 @@ int Bot::GetAimingWaypoint (const Vector &to)
int destIndex = g_waypoint->FindNearest (to);
int bestIndex = srcIndex;
PathNode *node = new PathNode;
node->index = destIndex;
node->next = NULL;
PathNode *startNode = node;
while (destIndex != srcIndex)
{
destIndex = *(g_waypoint->m_pathMatrix + (destIndex * g_numWaypoints) + srcIndex);
@ -1839,29 +1832,12 @@ int Bot::GetAimingWaypoint (const Vector &to)
if (destIndex < 0)
break;
node->next = new PathNode;
node = node->next;
if (node == NULL)
TerminateOnMalloc ();
node->index = destIndex;
node->next = NULL;
if (g_waypoint->IsVisible (m_currentWaypointIndex, destIndex))
{
bestIndex = destIndex;
break;
}
}
while (startNode != NULL)
{
node = startNode->next;
delete startNode;
startNode = node;
}
return bestIndex;
}
@ -1887,7 +1863,7 @@ bool Bot::FindWaypoint (void)
#if 0
if (i == m_currentWaypointIndex || i == m_prevWptIndex[0] || i == m_prevWptIndex[1] || i == m_prevWptIndex[2] || i == m_prevWptIndex[3] || i == m_prevWptIndex[4])
#else
if (i == m_currentWaypointIndex)
if (i == m_currentWaypointIndex || i == m_prevWptIndex[0])
#endif
continue;
@ -2101,7 +2077,7 @@ int Bot::ChooseBombWaypoint (void)
bombOrigin = pev->origin;
int goal = 0, count = 0;
float lastDistance = FLT_MAX;
float lastDistance = 99999.0f;
// find nearest goal waypoint either to bomb (if "heard" or player)
FOR_EACH_AE (goals, i)
@ -2471,8 +2447,8 @@ bool Bot::HeadTowardWaypoint (void)
if (m_baseAgressionLevel < kills && HasPrimaryWeapon ())
{
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (m_difficulty * 0.5, m_difficulty) * 5, true);
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, FindDefendWaypoint (g_waypoint->GetPath (waypoint)->origin), GetWorldTime () + Random.Float (3.0f, 10.0f), true);
PushTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (m_difficulty * 0.5, m_difficulty) * 5, true);
PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, FindDefendWaypoint (g_waypoint->GetPath (waypoint)->origin), GetWorldTime () + Random.Float (3.0f, 10.0f), true);
}
}
else if (g_botsCanPause && !IsOnLadder () && !IsInWater () && !m_currentTravelFlags && IsOnFloor ())
@ -2547,7 +2523,7 @@ bool Bot::HeadTowardWaypoint (void)
// if another bot uses this ladder, wait 3 secs
if (otherBot != NULL && otherBot != this && IsAlive (otherBot->GetEntity ()) && otherBot->m_currentWaypointIndex == m_navNode->index)
{
StartTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + 3.0, false);
PushTask (TASK_PAUSE, TASKPRI_PAUSE, -1, GetWorldTime () + 3.0, false);
return true;
}
}
@ -3136,13 +3112,13 @@ void Bot::ChangeYaw (float speed)
int Bot::GetAimingWaypoint (void)
{
// Find a good WP to look at when camping
// find a good waypoint to look at when camping
int count = 0, indeces[3];
float distTab[3];
uint16 visibility[3];
int currentWaypoint = g_waypoint->FindNearest (pev->origin);
int currentWaypoint = m_currentWaypointIndex;
if (currentWaypoint == -1)
return Random.Long (0, g_numWaypoints - 1);
@ -3443,7 +3419,7 @@ edict_t *Bot::FindNearestButton (const char *targetName)
if (IsNullString (targetName))
return NULL;
float nearestDistance = FLT_MAX;
float nearestDistance = 99999.0f;
edict_t *searchEntity = NULL, *foundEntity = NULL;
// find the nearest button which can open our target

View file

@ -148,13 +148,8 @@ void NetworkMsg::Execute (void *p)
// ammo amount decreased ? must have fired a bullet...
if (id == m_bot->m_currentWeapon && m_bot->m_ammoInClip[id] > clip)
{
// time fired with in burst firing time ?
if (m_bot->m_timeLastFired + 1.0 > GetWorldTime ())
m_bot->m_burstShotsFired++;
m_bot->m_timeLastFired = GetWorldTime (); // remember the last bullet time
}
m_bot->m_ammoInClip[id] = clip;
}
break;

View file

@ -1272,7 +1272,7 @@ void SoundAttachToThreat (edict_t *ent, const char *sample, float volume)
if (index < 0 || index >= GetMaxClients ())
{
float nearestDistance = FLT_MAX;
float nearestDistance = 99999.0f;
// loop through all players
for (int i = 0; i < GetMaxClients (); i++)
@ -1372,7 +1372,6 @@ void SoundSimulateUpdate (int playerIndex)
edict_t *player = g_clients[playerIndex].ent;
float velocity = player->v.velocity.GetLength2D ();
float hearDistance = 0.0;
float timeSound = 0.0;
float timeMaxSound = 0.5;
@ -1411,7 +1410,7 @@ void SoundSimulateUpdate (int playerIndex)
if (mp_footsteps.GetBool ())
{
// moves fast enough?
hearDistance = 1280.0 * (velocity / 240);
hearDistance = 1280.0 * (player->v.velocity.GetLength2D () / 240);
timeSound = GetWorldTime () + 0.3;
timeMaxSound = 0.3;
}

View file

@ -153,11 +153,10 @@ void Waypoint::FindInRadius (Array <int> &radiusHolder, float radius, const Vect
{
for (int i = 0; i < g_numWaypoints; i++)
{
if ((m_paths[i]->origin - origin).GetLength () <= radius)
if ((m_paths[i]->origin - origin).GetLength () < radius)
radiusHolder.Push (i);
}
}
void Waypoint::Add (int flags, const Vector &waypointOrigin)
{
if (IsEntityNull (g_hostEntity))
@ -1515,7 +1514,7 @@ void Waypoint::Think (void)
if (IsEntityNull (g_hostEntity))
return; // this function is only valid on listenserver, and in waypoint enabled mode.
float nearestDistance = FLT_MAX;
float nearestDistance = 99999.0f;
int nearestIndex = -1;
// check if it's time to add jump waypoint
@ -1573,7 +1572,7 @@ void Waypoint::Think (void)
m_facingAtIndex = GetFacingIndex ();
// reset the minimal distance changed before
nearestDistance = FLT_MAX;
nearestDistance = 99999.0f;
// now iterate through all waypoints in a map, and draw required ones
for (int i = 0; i < g_numWaypoints; i++)