diff --git a/include/core.h b/include/core.h index b9f33f7..f5f0367 100644 --- a/include/core.h +++ b/include/core.h @@ -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); diff --git a/include/corelib.h b/include/corelib.h index 487c4fe..9a7eee3 100644 --- a/include/corelib.h +++ b/include/corelib.h @@ -4068,3 +4068,8 @@ public: // Sizeof bounds // #define SIZEOF_CHAR(in) sizeof (in) - 1 + +// +// Squared Length +// +#define GET_SQUARE(in) (in * in) \ No newline at end of file diff --git a/include/globals.h b/include/globals.h index 2803a25..6e7ce41 100644 --- a/include/globals.h +++ b/include/globals.h @@ -65,7 +65,6 @@ extern Array g_botNames; extern Array 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]; diff --git a/include/resource.h b/include/resource.h index c3b7da7..aade3d9 100644 --- a/include/resource.h +++ b/include/resource.h @@ -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/" diff --git a/source/basecode.cpp b/source/basecode.cpp index f40e8a0..580916e 100644 --- a/source/basecode.cpp +++ b/source/basecode.cpp @@ -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 ((static_cast (pev->maxspeed) * 0.5f) + (static_cast (pev->maxspeed) / 50.0f)) - 18.0f; diff --git a/source/combat.cpp b/source/combat.cpp index 5ea900e..94fd904 100644 --- a/source/combat.cpp +++ b/source/combat.cpp @@ -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 (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 (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 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) diff --git a/source/globals.cpp b/source/globals.cpp index e18801d..ab134ce 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -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] = { diff --git a/source/interface.cpp b/source/interface.cpp index 17d6e67..5a08898 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -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++) { diff --git a/source/manager.cpp b/source/manager.cpp index 560b17f..910f06a 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -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); diff --git a/source/navigate.cpp b/source/navigate.cpp index 08082e6..46fe996 100644 --- a/source/navigate.cpp +++ b/source/navigate.cpp @@ -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 diff --git a/source/netmsg.cpp b/source/netmsg.cpp index 869d82c..aec3782 100644 --- a/source/netmsg.cpp +++ b/source/netmsg.cpp @@ -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; diff --git a/source/support.cpp b/source/support.cpp index 55c29bf..9596230 100644 --- a/source/support.cpp +++ b/source/support.cpp @@ -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; } diff --git a/source/waypoint.cpp b/source/waypoint.cpp index 7b9b7f9..2df769c 100644 --- a/source/waypoint.cpp +++ b/source/waypoint.cpp @@ -153,11 +153,10 @@ void Waypoint::FindInRadius (Array &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++)