From 58a8604ca6e28ad6cc6ad14ca2039e18f2ce2927 Mon Sep 17 00:00:00 2001 From: terencehill Date: Wed, 7 Sep 2022 01:25:17 +0200 Subject: [PATCH] Bot AI: further improve aim of skilled bots by removing simulated aim lag: it's kind of redundant (aim is already lagged in another way) and wastes a lot of fields --- qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc | 2 +- qcsrc/server/bot/default/aim.qc | 45 +++----------- qcsrc/server/bot/default/aim.qh | 61 ------------------- qcsrc/server/bot/default/bot.qc | 1 - qcsrc/server/bot/default/havocbot/havocbot.qc | 11 +--- 5 files changed, 12 insertions(+), 108 deletions(-) diff --git a/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc b/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc index 5fbb2b2a6..83cf455c3 100644 --- a/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc +++ b/qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc @@ -1758,7 +1758,7 @@ void havocbot_role_ctf_carrier(entity this) entity goal = this.goalentity; if (havocbot_ctf_is_basewaypoint(goal) && vdist(goal.origin - this.origin, <, 100)) - this.goalentity_lock_timeout = time + ((this.bot_aimtarg) ? 2 : 3); + this.goalentity_lock_timeout = time + ((this.enemy) ? 2 : 3); if (goal) this.havocbot_cantfindflag = time + 10; diff --git a/qcsrc/server/bot/default/aim.qc b/qcsrc/server/bot/default/aim.qc index f05097fd4..1d0f78b74 100644 --- a/qcsrc/server/bot/default/aim.qc +++ b/qcsrc/server/bot/default/aim.qc @@ -89,26 +89,6 @@ float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, f return false; } -void lag_update(entity this) -{ - if (this.lag1_time && time > this.lag1_time) { this.lag_func(this, this.lag1_time, this.lag1_float1, this.lag1_float2, this.lag1_entity1, this.lag1_vec1, this.lag1_vec2, this.lag1_vec3, this.lag1_vec4); this.lag1_time = 0; } - if (this.lag2_time && time > this.lag2_time) { this.lag_func(this, this.lag2_time, this.lag2_float1, this.lag2_float2, this.lag2_entity1, this.lag2_vec1, this.lag2_vec2, this.lag2_vec3, this.lag2_vec4); this.lag2_time = 0; } - if (this.lag3_time && time > this.lag3_time) { this.lag_func(this, this.lag3_time, this.lag3_float1, this.lag3_float2, this.lag3_entity1, this.lag3_vec1, this.lag3_vec2, this.lag3_vec3, this.lag3_vec4); this.lag3_time = 0; } - if (this.lag4_time && time > this.lag4_time) { this.lag_func(this, this.lag4_time, this.lag4_float1, this.lag4_float2, this.lag4_entity1, this.lag4_vec1, this.lag4_vec2, this.lag4_vec3, this.lag4_vec4); this.lag4_time = 0; } - if (this.lag5_time && time > this.lag5_time) { this.lag_func(this, this.lag5_time, this.lag5_float1, this.lag5_float2, this.lag5_entity1, this.lag5_vec1, this.lag5_vec2, this.lag5_vec3, this.lag5_vec4); this.lag5_time = 0; } -} - -float lag_additem(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4) -{ - if (this.lag1_time == 0) {this.lag1_time = t;this.lag1_float1 = f1;this.lag1_float2 = f2;this.lag1_entity1 = e1;this.lag1_vec1 = v1;this.lag1_vec2 = v2;this.lag1_vec3 = v3;this.lag1_vec4 = v4;return true;} - if (this.lag2_time == 0) {this.lag2_time = t;this.lag2_float1 = f1;this.lag2_float2 = f2;this.lag2_entity1 = e1;this.lag2_vec1 = v1;this.lag2_vec2 = v2;this.lag2_vec3 = v3;this.lag2_vec4 = v4;return true;} - if (this.lag3_time == 0) {this.lag3_time = t;this.lag3_float1 = f1;this.lag3_float2 = f2;this.lag3_entity1 = e1;this.lag3_vec1 = v1;this.lag3_vec2 = v2;this.lag3_vec3 = v3;this.lag3_vec4 = v4;return true;} - if (this.lag4_time == 0) {this.lag4_time = t;this.lag4_float1 = f1;this.lag4_float2 = f2;this.lag4_entity1 = e1;this.lag4_vec1 = v1;this.lag4_vec2 = v2;this.lag4_vec3 = v3;this.lag4_vec4 = v4;return true;} - if (this.lag5_time == 0) {this.lag5_time = t;this.lag5_float1 = f1;this.lag5_float2 = f2;this.lag5_entity1 = e1;this.lag5_vec1 = v1;this.lag5_vec2 = v2;this.lag5_vec3 = v3;this.lag5_vec4 = v4;return true;} - // no room for it (what is the best thing to do here??) - return false; -} - bool bot_shouldattack(entity this, entity targ) { if (targ.team == this.team) @@ -148,16 +128,6 @@ bool bot_shouldattack(entity this, entity targ) return true; } -void bot_lagfunc(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4) -{ - this.bot_aimtarg = e1; - this.bot_aimlatency = CS(this).ping; // FIXME? Shouldn't this be in the lag item? - //this.bot_aimorigin = v1; - //this.bot_aimvelocity = v2; - this.bot_aimtargorigin = v3; - this.bot_aimtargvelocity = v4; -} - // this function should be called after bot_aim so the aim is reset the next frame void bot_aim_reset(entity this) { @@ -196,7 +166,7 @@ void bot_aimdir(entity this, vector v, float maxfiredeviation) float skill_save = skill; // allow turning in a more natural way when bot is walking - if (!this.bot_aimtarg) + if (!this.enemy) skill = max(4, skill); // get the desired angles to aim at @@ -210,7 +180,7 @@ void bot_aimdir(entity this, vector v, float maxfiredeviation) this.bot_badaimoffset = randomvec() * f * autocvar_bot_ai_aimskill_offset; this.bot_badaimoffset.x *= 0.7; // smaller vertical offset } - float enemy_factor = ((this.bot_aimtarg) ? 5 : 2); + float enemy_factor = ((this.enemy) ? 5 : 2); // apply enemy_factor every frame so that the bigger offset is applied instantly when the bot aims to a new target desiredang = vectoangles(v) + this.bot_badaimoffset * enemy_factor; //dprint(" desired:", vtos(desiredang)); @@ -371,7 +341,8 @@ bool bot_aim(entity this, .entity weaponentity, float shotspeed, float shotspeed makevectors(this.v_angle); shotorg = this.origin + this.view_ofs; shotdir = v_forward; - v = bot_shotlead(this.bot_aimtargorigin, this.bot_aimtargvelocity, shotspeed, this.bot_aimlatency); + vector enemy_org = (this.enemy.absmin + this.enemy.absmax) * 0.5; + v = bot_shotlead(enemy_org, this.enemy.velocity, shotspeed, this.bot_aimlatency); // this formula was created starting from empiric values of distance and max hit angle // with a player as target (32 qu wide) from the center of it right in front of the bot @@ -384,9 +355,9 @@ bool bot_aim(entity this, .entity weaponentity, float shotspeed, float shotspeed f += bound(0, (10 - (skill + this.bot_aimskill)) * 0.3, 3); maxfiredeviation = min(90, maxfiredeviation * f); - if (applygravity && this.bot_aimtarg) + if (applygravity && this.enemy) { - if (!findtrajectorywithleading(shotorg, '0 0 0', '0 0 0', this.bot_aimtarg, shotspeed, shotspeedupward, maxshottime, 0, this)) + if (!findtrajectorywithleading(shotorg, '0 0 0', '0 0 0', this.enemy, shotspeed, shotspeedupward, maxshottime, 0, this)) { this.dphitcontentsmask = hf; return false; @@ -397,13 +368,13 @@ bool bot_aim(entity this, .entity weaponentity, float shotspeed, float shotspeed else { bot_aimdir(this, v - shotorg, maxfiredeviation); - //dprint("AIM: ");dprint(vtos(this.bot_aimtargorigin));dprint(" + ");dprint(vtos(this.bot_aimtargvelocity));dprint(" * ");dprint(ftos(this.bot_aimlatency + vlen(this.bot_aimtargorigin - shotorg) / shotspeed));dprint(" = ");dprint(vtos(v));dprint(" : aimdir = ");dprint(vtos(normalize(v - shotorg)));dprint(" : ");dprint(vtos(shotdir));dprint("\n"); + //dprint("AIM: ");dprint(vtos(enemy_org));dprint(" + ");dprint(vtos(this.enemy.velocity));dprint(" * ");dprint(ftos(this.bot_aimlatency + vlen(this.enemy.origin - shotorg) / shotspeed));dprint(" = ");dprint(vtos(v));dprint(" : aimdir = ");dprint(vtos(normalize(v - shotorg)));dprint(" : ");dprint(vtos(shotdir));dprint("\n"); //traceline(shotorg, shotorg + shotdir * 10000, false, this); //if (trace_ent.takedamage) //if (trace_fraction < 1) //if (!bot_shouldattack(this, trace_ent)) // return false; - traceline(shotorg, this.bot_aimtargorigin, false, this); + traceline(shotorg, enemy_org, false, this); if (trace_fraction < 1) if (trace_ent != this.enemy) if (!bot_shouldattack(this, trace_ent)) diff --git a/qcsrc/server/bot/default/aim.qh b/qcsrc/server/bot/default/aim.qh index b03e77a9b..3d1e8894a 100644 --- a/qcsrc/server/bot/default/aim.qh +++ b/qcsrc/server/bot/default/aim.qh @@ -7,58 +7,9 @@ entity tracetossent; entity tracetossfaketarget; vector findtrajectory_velocity; - - vector shotorg; vector shotdir; -// lag simulation -// upto 5 queued messages -.float lag1_time; -.float lag1_float1; -.float lag1_float2; -.entity lag1_entity1; -.vector lag1_vec1; -.vector lag1_vec2; -.vector lag1_vec3; -.vector lag1_vec4; - -.float lag2_time; -.float lag2_float1; -.float lag2_float2; -.entity lag2_entity1; -.vector lag2_vec1; -.vector lag2_vec2; -.vector lag2_vec3; -.vector lag2_vec4; - -.float lag3_time; -.float lag3_float1; -.float lag3_float2; -.entity lag3_entity1; -.vector lag3_vec1; -.vector lag3_vec2; -.vector lag3_vec3; -.vector lag3_vec4; - -.float lag4_time; -.float lag4_float1; -.float lag4_float2; -.entity lag4_entity1; -.vector lag4_vec1; -.vector lag4_vec2; -.vector lag4_vec3; -.vector lag4_vec4; - -.float lag5_time; -.float lag5_float1; -.float lag5_float2; -.entity lag5_entity1; -.vector lag5_vec1; -.vector lag5_vec2; -.vector lag5_vec3; -.vector lag5_vec4; - .bool bot_aimdir_executed; .float bot_badaimtime; .float bot_aimthinktime; @@ -75,21 +26,11 @@ vector shotdir; .vector bot_5th_order_aimfilter; .vector bot_olddesiredang; -//.vector bot_aimorigin; -//.vector bot_aimvelocity; -.vector bot_aimtargorigin; -.vector bot_aimtargvelocity; - -.entity bot_aimtarg; /* * Functions */ -float lag_additem(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4); -void lag_update(entity this); -void bot_lagfunc(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4); - float bot_shouldattack(entity this, entity targ); void bot_aimdir(entity this, vector v, float maxfiredeviation); bool bot_aim(entity this, .entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, bool applygravity, bool shot_accurate); @@ -97,5 +38,3 @@ void bot_aim_reset(entity this); float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, float shotspeed, float shotspeedupward, float maxtime, float shotdelay, entity ignore); vector bot_shotlead(vector targorigin, vector targvelocity, float shotspeed, float shotdelay); - -.void(entity this, float t, float f1, float f2, entity e1, vector v1, vector v2, vector v3, vector v4) lag_func; diff --git a/qcsrc/server/bot/default/bot.qc b/qcsrc/server/bot/default/bot.qc index 2497ecaa0..1e7098925 100644 --- a/qcsrc/server/bot/default/bot.qc +++ b/qcsrc/server/bot/default/bot.qc @@ -442,7 +442,6 @@ void bot_clientconnect(entity this) if (!IS_BOT_CLIENT(this)) return; this.bot_preferredcolors = this.clientcolors; this.bot_nextthink = time - random(); - this.lag_func = bot_lagfunc; this.isbot = true; this.createdtime = this.bot_nextthink; diff --git a/qcsrc/server/bot/default/havocbot/havocbot.qc b/qcsrc/server/bot/default/havocbot/havocbot.qc index 1ec1fde57..f9a56195b 100644 --- a/qcsrc/server/bot/default/havocbot/havocbot.qc +++ b/qcsrc/server/bot/default/havocbot/havocbot.qc @@ -115,7 +115,6 @@ void havocbot_ai(entity this) if (this.goalcurrent) navigation_clearroute(this); this.enemy = NULL; - this.bot_aimtarg = NULL; return; } @@ -132,9 +131,8 @@ void havocbot_ai(entity this) } } havocbot_aim(this); - lag_update(this); - if (this.bot_aimtarg) + if (this.enemy) { this.aistatus |= AI_STATUS_ATTACKING; this.aistatus &= ~AI_STATUS_ROAMING; @@ -162,8 +160,8 @@ void havocbot_ai(entity this) } else { - if(IS_PLAYER(this.bot_aimtarg)) - bot_aimdir(this, this.bot_aimtarg.origin + this.bot_aimtarg.view_ofs - this.origin - this.view_ofs, 0); + if(IS_PLAYER(this.enemy)) + bot_aimdir(this, this.enemy.origin + this.enemy.view_ofs - this.origin - this.view_ofs, 0); } } else if (this.goalcurrent) @@ -1524,10 +1522,7 @@ void havocbot_aim(entity this) vector enemyvel = this.enemy.velocity; if (!this.enemy.waterlevel) enemyvel.z = 0; - lag_additem(this, time + CS(this).ping, 0, 0, this.enemy, this.origin, myvel, (this.enemy.absmin + this.enemy.absmax) * 0.5, enemyvel); } - else - lag_additem(this, time + CS(this).ping, 0, 0, NULL, this.origin, myvel, ( this.goalcurrent.absmin + this.goalcurrent.absmax ) * 0.5, '0 0 0'); } bool havocbot_moveto_refresh_route(entity this) -- 2.39.2