nav: rusher bots does not care any danger (idea from pbmm) nav: some changes in collision motion

This commit is contained in:
commandcobra7 2024-02-04 15:32:13 +03:00 committed by GitHub
commit eea78ac031
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 113 additions and 205 deletions

View file

@ -320,6 +320,15 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) {
if (goalChoices[0] == kInvalidNodeIndex) {
return m_chosenGoalIndex = graph.random ();
}
// rusher bots does not care any danger (idea from pbmm)
if (m_personality == Personality::Rusher) {
const auto randomGoal = goalChoices[rg.get (0, 3)];
if (graph.exists (randomGoal)) {
return m_chosenGoalIndex = randomGoal;
}
}
bool sorting = false;
do {
@ -344,7 +353,7 @@ void Bot::postprocessGoals (const IntArray &goals, int result[]) {
int recurseCount = 0;
auto isRecentOrHistorical = [&] (int index) -> bool {
auto isRecentOrHistorical = [&] (int index) -> bool {
if (m_prevGoalIndex == index || m_previousNodes[0] == index) {
return true;
}
@ -590,65 +599,26 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
state[i] = 0;
state[i + 1] = 0;
// to start strafing, we have to first figure out if the target is on the left side or right side
Vector right {}, forward {};
m_moveAngles.angleVectors (&forward, &right, nullptr);
const Vector &dirToPoint = (pev->origin - m_destOrigin).normalize2d_apx ();
const Vector &rightSide = right.normalize2d_apx ();
bool dirRight = false;
bool dirLeft = false;
bool blockedLeft = false;
bool blockedRight = false;
if ((dirToPoint | rightSide) > 0.0f) {
dirRight = true;
}
else {
dirLeft = true;
}
const auto &testDir = m_moveSpeed > 0.0f ? forward : -forward;
constexpr float kBlockDistance = 32.0f;
// now check which side is blocked
src = pev->origin + right * kBlockDistance;
dst = src + testDir * kBlockDistance;
game.testHull (src, dst, TraceIgnore::Monsters, head_hull, ent (), &tr);
if (!cr::fequal (tr.flFraction, 1.0f)) {
blockedRight = true;
}
src = pev->origin - right * kBlockDistance;
dst = src + testDir * kBlockDistance;
game.testHull (src, dst, TraceIgnore::Monsters, head_hull, ent (), &tr);
if (!cr::fequal (tr.flFraction, 1.0f)) {
blockedLeft = true;
}
if (dirLeft) {
if (canStrafeLeft (&tr)) {
state[i] += 5;
}
else {
state[i] -= 5;
}
if (blockedLeft) {
if (isBlockedLeft ()) {
state[i] -= 5;
}
++i;
if (dirRight) {
if (canStrafeRight (&tr)) {
state[i] += 5;
}
else {
state[i] -= 5;
}
if (blockedRight) {
if (isBlockedRight ()) {
state[i] -= 5;
}
}
@ -787,44 +757,12 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
void Bot::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_pathFlags & NodeFlag::Crouch) && !(m_pathFlags & (NodeFlag::Camp | NodeFlag::Goal))) {
pev->button |= IN_DUCK;
}
m_lastUsedNodesTime = game.time ();
// press jump button if we need to leave the ladder
if (!(m_pathFlags & 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_pathFlags & NodeFlag::Ladder) {
if (m_pathOrigin.z < pev->origin.z + 16.0f && !isOnLadder () && isOnFloor () && !isDucking ()) {
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;
}
}
}
m_lastUsedNodesTime = game.time ();
// special movement for swimming here
if (isInWater ()) {
// check if we need to go forward or back press the correct buttons
@ -955,7 +893,7 @@ bool Bot::updateNavigation () {
}
}
if ((m_pathFlags & NodeFlag::Ladder) || isOnLadder ()) {
if (m_pathFlags & NodeFlag::Ladder) {
if (m_pathOrigin.z >= (pev->origin.z + 16.0f)) {
constexpr auto kLadderOffset = Vector (0.0f, 0.0f, 16.0f);
m_pathOrigin = m_path->origin + kLadderOffset;
@ -973,7 +911,7 @@ bool Bot::updateNavigation () {
// 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 == ent ()) {
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || (client.ent->v.movetype != MOVETYPE_FLY) || client.team != m_team || client.ent == ent ()) {
continue;
}
TraceResult tr {};
@ -981,61 +919,24 @@ bool Bot::updateNavigation () {
int previousNode = 0;
// more than likely someone is already using our ladder...
if (client.ent->v.origin.distanceSq (m_path->origin) < cr::sqrf (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);
if (client.ent->v.origin.distanceSq (m_path->origin) < cr::sqrf (48.0f)) {
game.testHull (getEyesPos (), m_pathOrigin, TraceIgnore::Monsters, isDucking () ? head_hull : human_hull, 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;
// 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)) {
const auto numPreviousNode = rg.get (0, 2);
m_enemyParts = Visibility::None;
m_enemyParts |= (Visibility::Head | Visibility::Body);
m_states |= Sense::SeeingEnemy;
m_seeEnemyTime = game.time ();
break;
}
}
else {
game.testHull (getEyesPos (), m_pathOrigin, TraceIgnore::Monsters, isDucking () ? 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)) {
changeNodeIndex (m_previousNodes[0]);
startTask (Task::MoveToPosition, TaskPri::PlantBomb, previousNode, 0.0f, true);
}
for (int i = 0; i < numPreviousNode; ++i) {
if (graph.exists (m_previousNodes[i]) && (graph[m_previousNodes[i]].flags & NodeFlag::Ladder)) {
foundGround = true;
previousNode = m_previousNodes[i];
break;
}
}
if (foundGround) {
changeNodeIndex (m_previousNodes[0]);
findPath (m_previousNodes[0], previousNode, m_pathType);
}
}
}
}
@ -2888,66 +2789,6 @@ bool Bot::isDeadlyMove (const Vector &to) {
return false;
}
void Bot::changePitch (float speed) {
// this function turns a bot towards its ideal_pitch
const float idealPitch = cr::wrapAngle (pev->idealpitch);
const float curent = cr::wrapAngle (pev->v_angle.x);
// turn from the current v_angle pitch to the idealpitch by selecting
// the quickest way to turn to face that direction
// find the difference in the curent and ideal angle
float normalizePitch = cr::wrapAngle (idealPitch - curent);
if (normalizePitch > 0.0f) {
if (normalizePitch > speed) {
normalizePitch = speed;
}
}
else {
if (normalizePitch < -speed) {
normalizePitch = -speed;
}
}
pev->v_angle.x = cr::wrapAngle (curent + normalizePitch);
if (pev->v_angle.x > 89.9f) {
pev->v_angle.x = 89.9f;
}
if (pev->v_angle.x < -89.9f) {
pev->v_angle.x = -89.9f;
}
pev->angles.x = -pev->v_angle.x / 3;
}
void Bot::changeYaw (float speed) {
// this function turns a bot towards its ideal_yaw
const float idealPitch = cr::wrapAngle (pev->ideal_yaw);
const float curent = cr::wrapAngle (pev->v_angle.y);
// turn from the current v_angle yaw to the ideal_yaw by selecting
// the quickest way to turn to face that direction
// find the difference in the curent and ideal angle
float normalizePitch = cr::wrapAngle (idealPitch - curent);
if (normalizePitch > 0.0f) {
if (normalizePitch > speed) {
normalizePitch = speed;
}
}
else {
if (normalizePitch < -speed) {
normalizePitch = -speed;
}
}
pev->v_angle.y = cr::wrapAngle (curent + normalizePitch);
pev->angles.y = pev->v_angle.y;
}
int Bot::getRandomCampDir () {
// find a good node to look at when camping