// invalid aim dir (can happen when bot overlaps target)
if(!v) return;
+ float skill_save = skill;
+ // allow turning in a more natural way when bot is walking
+ if (!this.bot_aimtarg)
+ skill = max(4, skill);
+
// get the desired angles to aim at
//dprint(" at:", vtos(v));
v = normalize(v);
//if (diffang_y >= 180)
// diffang_y = diffang_y - 360;
+ skill = skill_save;
+
//dprint("e ", vtos(diffang), " < ", ftos(maxfiredeviation), "\n");
+ if (maxfiredeviation <= 0)
+ return;
+
+ if (!autocvar_bot_ai_aimskill_firetolerance)
+ {
+ this.bot_firetimer = time + 0.2;
+ return;
+ }
+
// decide whether to fire this time
- if (maxfiredeviation != 0 && v * shotdir > cos(maxfiredeviation * DEG2RAD))
+ if (v * shotdir > cos(maxfiredeviation * DEG2RAD))
{
traceline(shotorg, shotorg + shotdir * 1000, false, NULL);
if (vdist(trace_endpos - shotorg, <, 500 + 500 * bound(0, skill + this.bot_aggresskill, 10))
}
//dprint(ftos(maxfiredeviation),"\n");
//dprint(" diff:", vtos(diffang), "\n");
-
- //return this.bot_canfire && (time < this.bot_firetimer);
}
vector bot_shotlead(vector targorigin, vector targvelocity, float shotspeed, float shotdelay)
#pragma once
float autocvar_bot_ai_aimskill_blendrate;
+int autocvar_bot_ai_aimskill_firetolerance;
float autocvar_bot_ai_aimskill_firetolerance_distdegrees;
float autocvar_bot_ai_aimskill_firetolerance_maxdegrees;
float autocvar_bot_ai_aimskill_firetolerance_mindegrees;
keyboard = CS(this).movement / autocvar_sv_maxspeed;
float trigger = autocvar_bot_ai_keyboard_threshold;
- float trigger1 = -trigger;
// categorize forward movement
// at skill < 1.5 only forward
if (sk < 2.5)
keyboard.y = 0;
}
- else if (keyboard.x < trigger1 && sk > 1.5)
+ else if (keyboard.x < -trigger && sk > 1.5)
{
keyboard.x = -1;
if (sk < 4.5)
if (keyboard.y > trigger)
keyboard.y = 1;
- else if (keyboard.y < trigger1)
+ else if (keyboard.y < -trigger)
keyboard.y = -1;
else
keyboard.y = 0;
if (keyboard.z > trigger)
keyboard.z = 1;
- else if (keyboard.z < trigger1)
+ else if (keyboard.z < -trigger)
keyboard.z = -1;
else
keyboard.z = 0;
+ // make sure bots don't get stuck if havocbot_keyboardtime is very high
+ if (keyboard == '0 0 0')
+ this.havocbot_keyboardtime = min(this.havocbot_keyboardtime, time + 0.2);
+
this.havocbot_keyboard = keyboard * autocvar_sv_maxspeed;
if (this.havocbot_ducktime > time)
PHYS_INPUT_BUTTON_CROUCH(this) = true;
- }
- keyboard = this.havocbot_keyboard;
- float blend = bound(0, vlen(destorg - this.origin) / autocvar_bot_ai_keyboard_distance, 1); // When getting close move with 360 degree
- //dprint("movement ", vtos(CS(this).movement), " keyboard ", vtos(keyboard), " blend ", ftos(blend), "\n");
- CS(this).movement = CS(this).movement + (keyboard - CS(this).movement) * blend;
+ keyboard = this.havocbot_keyboard;
+ float blend = bound(0, vlen(destorg - this.origin) / autocvar_bot_ai_keyboard_distance, 1); // When getting close move with 360 degree
+ //dprint("movement ", vtos(CS(this).movement), " keyboard ", vtos(keyboard), " blend ", ftos(blend), "\n");
+ CS(this).movement = CS(this).movement + (keyboard - CS(this).movement) * blend;
+ }
}
void havocbot_bunnyhop(entity this, vector dir)
this.bot_stop_moving_timeout = time + 0.4 + random() * 0.2;
}
- offset = (vdist(this.velocity, >, 32) ? this.velocity * 0.2 : v_forward * 32);
+ offset = (vdist(this.velocity, >, 32) ? this.velocity * 0.2 : flatdir * 32);
vector dst_ahead = this.origin + this.view_ofs + offset;
vector dst_down = dst_ahead - '0 0 3000';
traceline(this.origin + this.view_ofs, dst_ahead, true, NULL);
// Look downwards
traceline(dst_ahead , dst_down, true, NULL);
//te_lightning2(NULL, this.origin + this.view_ofs, dst_ahead); // Draw "ahead" look
- //te_lightning2(NULL, dst_ahead, dst_down); // Draw "downwards" look
+ //te_lightning2(NULL, dst_ahead, trace_endpos); // Draw "downwards" look
if(trace_endpos.z < this.origin.z + this.mins.z)
{
s = pointcontents(trace_endpos + '0 0 1');
this.goalstack31 = NULL;
navigation_routetogoal(this, navigation_bestgoal, this.origin);
- LOG_DEBUG("best goal ", this.goalcurrent.classname);
+ LOG_DEBUG("best goal ", navigation_bestgoal.classname);
if (wp && this.goalcurrent == wp)
navigation_poproute(this);
set bot_ai_dangerdetectionupdates 64 "How many waypoints will be considered for danger detection"
set bot_ai_aimskill_blendrate 2 "How much correction will be applied to the aiming angle"
set bot_ai_aimskill_fixedrate 15
+set bot_ai_aimskill_firetolerance 0 "enable fire tolerance"
set bot_ai_aimskill_firetolerance_distdegrees 100
set bot_ai_aimskill_firetolerance_mindegrees 2 "Minimum angle tolerance. Used on large distances"
set bot_ai_aimskill_firetolerance_maxdegrees 60 "Maximum firing angle. Used on close range"
set bot_ai_weapon_combo_threshold 0.4 "Try to make a combo N seconds after the last attack"
set bot_ai_friends_aware_pickup_radius "500" "Bots will not pickup items if a team mate is this distance near the item"
set bot_ai_ignoregoal_timeout 3 "Ignore goals making bots to get stuck in front of a wall for N seconds"
-set bot_ai_bunnyhop_skilloffset 7 "Bots with skill equal or greater than this value will perform the \"bunnyhop\" technique"
+set bot_ai_bunnyhop_skilloffset 7 "Bots with skill equal or greater than this value will perform the \"bunnyhop\" technique"
set bot_ai_bunnyhop_startdistance 200 "Run to goals located further than this distance"
set bot_ai_bunnyhop_stopdistance 300 "Stop jumping after reaching this distance to the goal"
set bot_ai_bunnyhop_firstjumpdelay 0.2 "Start running to the goal only if it was seen for more than N seconds"
set bot_ai_navigation_jetpack_mindistance 3500 "Bots will try fly to objects located farther than this distance"
// Better don't touch these, there are hard to tweak!
set bot_ai_aimskill_order_mix_1st 0.01 "Amount of the 1st filter output to apply to the aiming angle"
-set bot_ai_aimskill_order_mix_2nd 0.1 "Amount of the 2nd filter output to apply to the aiming angle"
+set bot_ai_aimskill_order_mix_2nd 0.075 "Amount of the 2nd filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_3th 0.01 "Amount of the 3th filter output to apply to the aiming angle"
-set bot_ai_aimskill_order_mix_4th 0.05 "Amount of the 4th filter output to apply to the aiming angle"
+set bot_ai_aimskill_order_mix_4th 0.0375 "Amount of the 4th filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_5th 0.01 "Amount of the 5th filter output to apply to the aiming angle"
-set bot_ai_aimskill_order_filter_1st 0.4 "Position filter"
-set bot_ai_aimskill_order_filter_2nd 0.4 "Movement filter"
-set bot_ai_aimskill_order_filter_3th 0.2 "Acceleration filter"
-set bot_ai_aimskill_order_filter_4th 0.4 "Position prediction filter. Used rarely"
-set bot_ai_aimskill_order_filter_5th 0.5 "Movement prediction filter. Used rarely"
+set bot_ai_aimskill_order_filter_1st 0.2 "Position filter"
+set bot_ai_aimskill_order_filter_2nd 0.2 "Movement filter"
+set bot_ai_aimskill_order_filter_3th 0.1 "Acceleration filter"
+set bot_ai_aimskill_order_filter_4th 0.2 "Position prediction filter. Used rarely"
+set bot_ai_aimskill_order_filter_5th 0.25 "Movement prediction filter. Used rarely"
set bot_ai_timeitems 1 "allow skilled bots to run to important items a little time before respawning"
set bot_ai_timeitems_minrespawndelay 25 "bots run to items with this minimum respawn delay before respawning"