From 50aecc13321a6e67147ed8c5e0c13f84d5af255a Mon Sep 17 00:00:00 2001 From: commandcobra7 <91374215+commandcobra7@users.noreply.github.com> Date: Wed, 18 Jan 2023 22:32:38 +0300 Subject: [PATCH] fix: don't allow to install a silencer if we have a visible enemy aim: fixed the distortion of angles while camping add: special ladder handling (code merged from podbotmm) graph: reworked some node coloring and link color --- src/botlib.cpp | 41 ++++++++++++++++--- src/graph.cpp | 33 ++++++++++------ src/navigate.cpp | 101 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 149 insertions(+), 26 deletions(-) diff --git a/src/botlib.cpp b/src/botlib.cpp index 09466e0..dc14f97 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -2831,9 +2831,9 @@ void Bot::updateAimDir () { else { m_aimFlags &= ~AimFlags::PredictPath; - m_lookAt = m_destOrigin; - m_timeNextTracking = game.time () + 1.5f; - m_trackingEdict = nullptr; + if (!m_camp.empty ()) { + m_lookAt = m_camp; + } } } else { @@ -4929,12 +4929,43 @@ void Bot::logic () { if (m_moveToGoal) { findValidNode (); + bool prevLadder = false; + + if (graph.exists (m_previousNodes[0])) { + if (graph[m_previousNodes[0]].flags & NodeFlag::Ladder) { + prevLadder = true; + } + } + // press duck button if we need to if ((m_path->flags & NodeFlag::Crouch) && !(m_path->flags & (NodeFlag::Camp | NodeFlag::Goal))) { pev->button |= IN_DUCK; } m_lastUsedNodesTime = game.time (); + // press jump button if we need to leave the ladder + if (!(m_path->flags & NodeFlag::Ladder) && prevLadder && isOnFloor () && isOnLadder () && m_moveSpeed > 50.0f && pev->velocity.length () < 50.0f) { + pev->button |= IN_JUMP; + m_jumpTime = game.time () + 1.0f; + } + + if (m_path->flags & NodeFlag::Ladder) { + if (m_pathOrigin.z < pev->origin.z + 16.0f && !isOnLadder () && isOnFloor () && !(pev->flags & FL_DUCKING)) { + if (!prevLadder) { + m_moveSpeed = pev->origin.distance (m_pathOrigin); + } + else { + m_moveSpeed = 150.0f; + } + if (m_moveSpeed < 150.0f) { + m_moveSpeed = 150.0f; + } + else if (m_moveSpeed > pev->maxspeed) { + m_moveSpeed = pev->maxspeed; + } + } + } + // special movement for swimming here if (isInWater ()) { // check if we need to go forward or back press the correct buttons @@ -4998,7 +5029,7 @@ void Bot::logic () { } if (m_jumpTime + 0.85f > game.time ()) { - if (!isOnFloor () && !isInWater ()) { + if (!isOnFloor () && !isInWater () && !isOnLadder ()) { pev->button |= IN_DUCK; } } @@ -5702,7 +5733,7 @@ void Bot::checkBurstMode (float distance) { } void Bot::checkSilencer () { - if ((m_currentWeapon == Weapon::USP || m_currentWeapon == Weapon::M4A1) && !hasShield ()) { + if ((m_currentWeapon == Weapon::USP || m_currentWeapon == Weapon::M4A1) && !hasShield () && game.isNullEntity (m_enemy)) { int prob = (m_personality == Personality::Rusher ? 35 : 65); // aggressive bots don't like the silencer diff --git a/src/graph.cpp b/src/graph.cpp index 71c2495..9cede41 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -2264,10 +2264,7 @@ void BotGraph::frame () { Color nodeColor { -1, -1, -1 }; // colorize all other nodes - if (path.flags & NodeFlag::Camp) { - nodeColor = { 0, 255, 255 }; - } - else if (path.flags & NodeFlag::Goal) { + if (path.flags & NodeFlag::Goal) { nodeColor = { 128, 0, 255 }; } else if (path.flags & NodeFlag::Ladder) { @@ -2276,6 +2273,23 @@ void BotGraph::frame () { else if (path.flags & NodeFlag::Rescue) { nodeColor = { 255, 255, 255 }; } + else if (path.flags & NodeFlag::Camp) { + if (path.flags & NodeFlag::TerroristOnly) { + nodeColor = { 255, 160, 160 }; + } + else if (path.flags & NodeFlag::CTOnly) { + nodeColor = { 255, 160, 255 }; + } + else { + nodeColor = { 0, 255, 255 }; + } + } + else if (path.flags & NodeFlag::TerroristOnly) { + nodeColor = { 255, 0, 0 }; + } + else if (path.flags & NodeFlag::CTOnly) { + nodeColor = { 0, 0, 255 }; + } else { nodeColor = { 0, 255, 0 }; } @@ -2290,11 +2304,8 @@ void BotGraph::frame () { else if (path.flags & NodeFlag::NoHostage) { nodeFlagColor = { 255, 255, 255 }; } - else if (path.flags & NodeFlag::TerroristOnly) { - nodeFlagColor = { 255, 0, 0 }; - } - else if (path.flags & NodeFlag::CTOnly) { - nodeFlagColor = { 0, 0, 255 }; + else if (path.flags & NodeFlag::Lift) { + nodeFlagColor = { 255, 0, 255 }; } int nodeWidth = 14; @@ -2381,14 +2392,14 @@ void BotGraph::frame () { game.drawLine (m_editor, path.origin, m_paths[link.index].origin, 5, 0, { 255, 255, 0 }, 200, 0, 10); } else { // oneway connection - game.drawLine (m_editor, path.origin, m_paths[link.index].origin, 5, 0, { 50, 250, 25 }, 200, 0, 10); + game.drawLine (m_editor, path.origin, m_paths[link.index].origin, 5, 0, { 255, 255, 255 }, 200, 0, 10); } } // now look for oneway incoming connections for (const auto &connected : m_paths) { if (isConnected (connected.number, path.number) && !isConnected (path.number, connected.number)) { - game.drawLine (m_editor, path.origin, connected.origin, 5, 0, { 255, 255, 255 }, 200, 0, 10); + game.drawLine (m_editor, path.origin, connected.origin, 5, 0, { 0, 192, 96 }, 200, 0, 10); } } diff --git a/src/navigate.cpp b/src/navigate.cpp index 690fdee..d340d19 100644 --- a/src/navigate.cpp +++ b/src/navigate.cpp @@ -721,17 +721,98 @@ bool Bot::updateNavigation () { } if (m_path->flags & NodeFlag::Ladder) { - if (m_pathOrigin.z >= (pev->origin.z + 16.0f)) { - m_pathOrigin = m_path->origin + Vector (0.0f, 0.0f, 16.0f); - } - else if (m_pathOrigin.z < pev->origin.z + 16.0f && !isOnLadder () && isOnFloor () && !(pev->flags & FL_DUCKING)) { - m_moveSpeed = nodeDistance; - - if (m_moveSpeed < 150.0f) { - m_moveSpeed = 150.0f; + if (!m_pathWalk.empty ()) { + if (m_pathWalk.hasNext ()) { + if (graph[m_pathWalk.next ()].flags & NodeFlag::Ladder || isOnLadder ()) { + m_path->radius = 17.0f; + } } - else if (m_moveSpeed > pev->maxspeed) { - m_moveSpeed = pev->maxspeed; + } + + if (!(graph[m_previousNodes[0]].flags & NodeFlag::Ladder)) { + if (cr::abs (m_pathOrigin.z - pev->origin.z) > 5.0f) { + m_pathOrigin.z += pev->origin.z - m_pathOrigin.z; + } + if (m_pathOrigin.z > (pev->origin.z + 16.0f)) { + m_pathOrigin = m_path->origin - Vector (0.0f, 0.0f, 16.0f); + } + if (m_pathOrigin.z < (pev->origin.z - 16.0f)) { + m_pathOrigin = m_path->origin + Vector (0.0f, 0.0f, 16.0f); + } + } + m_destOrigin = m_pathOrigin; + + // special detection if someone is using the ladder (to prevent to have bots-towers on ladders) + for (const auto &client : util.getClients ()) { + if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || (client.ent->v.movetype != MOVETYPE_FLY) || client.ent == nullptr || client.ent == ent ()) { + continue; + } + TraceResult tr {}; + bool foundGround = false; + int previousNode = 0; + + // more than likely someone is already using our ladder... + if (client.ent->v.origin.distance (m_path->origin) < 40.0f) { + if ((client.team != m_team || game.is (GameFlags::FreeForAll)) && !cv_ignore_enemies.bool_ ()) { + game.testLine (getEyesPos (), client.ent->v.origin, TraceIgnore::Monsters, ent (), &tr); + + // bot found an enemy on his ladder - he should see him... + if (tr.pHit == client.ent) { + m_enemy = client.ent; + m_lastEnemy = client.ent; + m_lastEnemyOrigin = client.ent->v.origin; + m_enemyParts = Visibility::None; + m_enemyParts = Visibility::Head; + m_enemyParts = Visibility::Body; + m_states |= Sense::SeeingEnemy; + m_seeEnemyTime = game.time (); + break; + } + } + else { + if (graph.exists (m_previousNodes[0])) { + getEyesPos () = graph[m_previousNodes[0]].origin; + } + else { + game.testHull (getEyesPos (), m_path->origin, TraceIgnore::Monsters, pev->flags & FL_DUCKING ? head_hull : human_hull, ent (), &tr); + + // someone is above or below us + // and is using the ladder already + if (tr.pHit == client.ent && cr::abs (pev->origin.z - client.ent->v.origin.z) > 15.0f && (client.ent->v.movetype == MOVETYPE_FLY)) { + if (graph.exists (m_previousNodes[0])) { + if (!(graph[m_previousNodes[0]].flags & NodeFlag::Ladder)) { + foundGround = true; + previousNode = m_previousNodes[0]; + } + else if (graph.exists (m_previousNodes[1])) { + if (!(graph[m_previousNodes[1]].flags & NodeFlag::Ladder)) { + foundGround = true; + previousNode = m_previousNodes[1]; + } + else if (graph.exists (m_previousNodes[2])) { + if (!(graph[m_previousNodes[2]].flags & NodeFlag::Ladder)) { + foundGround = true; + previousNode = m_previousNodes[2]; + } + else if (graph.exists (m_previousNodes[3])) { + if (!(graph[m_previousNodes[3]].flags & NodeFlag::Ladder)) { + foundGround = true; + previousNode = m_previousNodes[3]; + } + } + } + } + } + if (foundGround) { + if (getCurrentTaskId () != Task::MoveToPosition || !cr::fequal (getTask ()->desire, TaskPri::PlantBomb)) { + m_currentNodeIndex = m_previousNodes[0]; + startTask (Task::MoveToPosition, TaskPri::PlantBomb, previousNode, 0.0f, true); + } + break; + } + } + } + } } } }