diff --git a/source/basecode.cpp b/source/basecode.cpp index dc12997..2e0d1f1 100644 --- a/source/basecode.cpp +++ b/source/basecode.cpp @@ -3025,7 +3025,7 @@ void Bot::RunTask_Normal (void) } // bots rushing with knife, when have no enemy (thanks for idea to nicebot project) - if (m_currentWeapon == WEAPON_KNIFE && (engine.IsNullEntity (m_lastEnemy) || !IsAlive (m_lastEnemy)) && engine.IsNullEntity (m_enemy) && m_knifeAttackTime < engine.Time () && !HasShield () && GetNearbyFriendsNearPosition (pev->origin, 96) == 0) + if (m_currentWeapon == WEAPON_KNIFE && (engine.IsNullEntity (m_lastEnemy) || !IsAlive (m_lastEnemy)) && engine.IsNullEntity (m_enemy) && m_knifeAttackTime < engine.Time () && !HasShield () && GetNearbyFriendsNearPosition (pev->origin, 96.0f) == 0) { if (Random.Int (0, 100) < 40) pev->button |= IN_ATTACK; @@ -3137,14 +3137,17 @@ void Bot::RunTask_Normal (void) m_hostages[i] = nullptr; // clear array of hostage pointers } } - else if (m_team == TERRORIST && Random.Int (0, 100) < 80) + else if (m_team == TERRORIST && Random.Int (0, 100) < 75) { int index = FindDefendWaypoint (m_currentPath->origin); PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + Random.Float (60.0f, 120.0f), true); // push camp task on to stack PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (5.0f, 10.0f), true); // push move command - if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand) + auto path = waypoints.GetPath (index); + + // decide to duck or not to duck + if (path->vis.crouch <= path->vis.stand) m_campButtons |= IN_DUCK; else m_campButtons &= ~IN_DUCK; @@ -3183,10 +3186,13 @@ void Bot::RunTask_Normal (void) PushTask (TASK_CAMP, TASKPRI_CAMP, -1, engine.Time () + campTime, true); // push camp task on to stack PushTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, engine.Time () + Random.Float (5.0f, 11.0f), true); // push move command - if (waypoints.GetPath (index)->vis.crouch <= waypoints.GetPath (index)->vis.stand) - m_campButtons |= IN_DUCK; - else - m_campButtons &= ~IN_DUCK; + auto path = waypoints.GetPath (index); + + // decide to duck or not to duck + if (path->vis.crouch <= path->vis.stand) + m_campButtons |= IN_DUCK; + else + m_campButtons &= ~IN_DUCK; ChatterMessage (Chatter_DefendingBombSite); // play info about that } @@ -3211,7 +3217,7 @@ void Bot::RunTask_Normal (void) // do pathfinding if it's not the current waypoint if (destIndex != m_currentWaypointIndex) - FindPath (m_currentWaypointIndex, destIndex, ((g_bombPlanted && m_team == CT) || yb_debug_goal.GetInt () != -1) ? SEARCH_PATH_FASTEST : m_pathType); + FindPath (m_currentWaypointIndex, destIndex, m_pathType); } else { diff --git a/source/interface.cpp b/source/interface.cpp index 01d6ef5..ae5786e 100644 --- a/source/interface.cpp +++ b/source/interface.cpp @@ -1119,20 +1119,17 @@ void ClientDisconnect (edict_t *ent) // to reset his entity pointer for safety. There are still a few server frames to go once a // listen server client disconnects, and we don't want to send him any sort of message then. - bots.AdjustQuota (false, ent); + int index = engine.IndexOfEntity (ent) - 1; - int i = engine.IndexOfEntity (ent) - 1; + InternalAssert (index >= 0 && index < MAX_ENGINE_PLAYERS); - InternalAssert (i >= 0 && i < MAX_ENGINE_PLAYERS); - - Bot *bot = bots.GetBot (i); + Bot *bot = bots.GetBot (index); // check if its a bot - if (bot != nullptr) - { - if (bot->pev == &ent->v) - bots.Free (i); - } + if (bot != nullptr && bot->pev == &ent->v) + bots.Free (index); + + bots.AdjustQuota (false, ent); if (g_gameFlags & GAME_METAMOD) RETURN_META (MRES_IGNORED); diff --git a/source/manager.cpp b/source/manager.cpp index a8decbe..3d5a867 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -1297,7 +1297,7 @@ void Bot::NewRound (void) m_defendHostage = false; m_headedTime = 0.0f; - m_timeLogoSpray = engine.Time () + Random.Float (0.5f, 2.0f); + m_timeLogoSpray = engine.Time () + Random.Float (5.0f, 30.0f); m_spawnTime = engine.Time (); m_lastChatTime = engine.Time (); diff --git a/source/navigate.cpp b/source/navigate.cpp index 64688da..d701081 100644 --- a/source/navigate.cpp +++ b/source/navigate.cpp @@ -626,7 +626,7 @@ void Bot::CheckTerrain (float movedDistance, const Vector &dirNormal) if (IsOnFloor () || IsInWater ()) { pev->button |= IN_JUMP; - m_jumpStateTimer = Random.Float (1.0f, 2.0f); + m_jumpStateTimer = Random.Float (2.0f, 3.0f); } break; @@ -1150,7 +1150,6 @@ bool Bot::DoWaypointNav (void) m_lastEnemy = ent; m_enemy = ent; m_lastEnemyOrigin = ent->v.origin; - } else if (IsValidPlayer (ent) && IsAlive (ent) && m_team == engine.GetTeam (ent)) { @@ -1193,7 +1192,7 @@ bool Bot::DoWaypointNav (void) if (waypointDistance < desiredDistance) { - // Did we reach a destination Waypoint? + // did we reach a destination waypoint? if (GetTask ()->data == m_currentWaypointIndex) { // add goal values @@ -1247,7 +1246,7 @@ bool Bot::DoWaypointNav (void) { float distance = (bombOrigin - waypoints.GetPath (taskTarget)->origin).GetLength (); - if (distance > 512.0) + if (distance > 512.0f) { if (Random.Int (0, 100) < 50 && !waypoints.IsGoalVisited (taskTarget)) RadioMessage (Radio_SectorClear); @@ -2427,8 +2426,10 @@ bool Bot::HeadTowardWaypoint (void) GetBestNextWaypoint (); m_minSpeed = pev->maxspeed; + TaskID taskID = GetTaskId (); + // only if we in normal task and bomb is not planted - if (GetTaskId () == TASK_NORMAL && g_timeRoundMid + 5.0f < engine.Time () && m_timeCamping + 5.0f < engine.Time () && !g_bombPlanted && m_personality != PERSONALITY_RUSHER && !m_hasC4 && !m_isVIP && m_loosedBombWptIndex == -1 && !HasHostage ()) + if (taskID == TASK_NORMAL && g_timeRoundMid + 5.0f < engine.Time () && m_timeCamping + 5.0f < engine.Time () && !g_bombPlanted && m_personality != PERSONALITY_RUSHER && !m_hasC4 && !m_isVIP && m_loosedBombWptIndex == -1 && !HasHostage ()) { m_campButtons = 0; @@ -2467,6 +2468,24 @@ bool Bot::HeadTowardWaypoint (void) else if (Random.Int (1, 100) > m_difficulty * 25) m_minSpeed = GetWalkSpeed (); } + + // force terrorist bot to plant bomb + if (taskID == TASK_NORMAL && m_inBombZone && !m_hasProgressBar && m_hasC4) + { + int newGoal = FindGoal (); + + m_prevGoalIndex = newGoal; + m_chosenGoalIndex = newGoal; + + // remember index + GetTask ()->data = newGoal; + + // do path finding if it's not the current waypoint + if (newGoal != m_currentWaypointIndex) + FindPath (m_currentWaypointIndex, newGoal, m_pathType); + + return false; + } } } @@ -3373,12 +3392,21 @@ bool Bot::IsPointOccupied (int index) if (bot->m_notKilled && m_currentWaypointIndex != -1 && bot->m_prevWptIndex[0] != -1) { + int targetId = bot->GetTask ()->data; + + if (index == targetId) + return true; + + // check bot's current waypoint int occupyId = GetShootingConeDeviation (bot->GetEntity (), &pev->origin) >= 0.7f ? bot->m_prevWptIndex[0] : m_currentWaypointIndex; + if (index == occupyId) + return true; + // length check float length = (waypoints.GetPath (occupyId)->origin - waypoints.GetPath (index)->origin).GetLengthSquared (); - if (occupyId == index || bot->GetTask ()->data == index || length < GET_SQUARE (64.0f)) + if (length < GET_SQUARE (128.0f)) return true; } }