Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
aim.qc File Reference
Include dependency graph for aim.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool bot_aim (entity this,.entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, bool applygravity, bool shot_accurate)
void bot_aim_reset (entity this)
void bot_aimdir (entity this, vector v, float maxfiredeviation)
vector bot_shotlead (vector targorigin, vector targvelocity, float shotspeed, float shotdelay)
bool bot_shouldattack (entity this, entity targ)
float findtrajectorywithleading (vector org, vector m1, vector m2, entity targ, float shotspeed, float shotspeedupward, float maxtime, float shotdelay, entity ignore)

Function Documentation

◆ bot_aim()

bool bot_aim ( entity this,
.entity weaponentity,
float shotspeed,
float shotspeedupward,
float maxshottime,
bool applygravity,
bool shot_accurate )

Definition at line 339 of file aim.qc.

340{
341 float hf, distanceratio;
342 vector v;
343 hf = this.dphitcontentsmask;
345
346 float speed_factor = W_WeaponSpeedFactor(this);
347 shotspeed *= speed_factor;
348 shotspeedupward *= speed_factor;
349 if (!shotspeed)
350 {
351 LOG_TRACE("bot_aim: WARNING: weapon ", this.(weaponentity).m_weapon.m_name, " shotspeed is zero!");
352 shotspeed = 1000000;
353 }
354 if (!maxshottime)
355 {
356 LOG_TRACE("bot_aim: WARNING: weapon ", this.(weaponentity).m_weapon.m_name, " maxshottime is zero!");
357 maxshottime = 1;
358 }
359 makevectors(this.v_angle);
360 shotorg = this.origin + this.view_ofs;
362 vector enemy_org = (this.enemy.absmin + this.enemy.absmax) * 0.5;
363 v = bot_shotlead(enemy_org, this.enemy.velocity, shotspeed, this.bot_aimlatency);
364
365 // this formula was created starting from empiric values of distance and max hit angle
366 // with a player as target (32 qu wide) from the center of it right in front of the bot
367 // distance: 32 50 75 100 150 200 300 400 500
368 // max ang: 44 24 15.1 10.5 6.5 4.9 3.1 2.3 1.8
369 float dist = max(10, vlen(v - shotorg));
370 float maxfiredeviation = 1000 / (dist - 9) - 0.35;
371
372 float f = (shot_accurate) ? 1 : 1.6;
373 f += bound(0, (10 - (skill + this.bot_aimskill)) * 0.3, 3);
374 maxfiredeviation = min(90, maxfiredeviation * f);
375
376 if (applygravity && this.enemy)
377 {
378 if (!findtrajectorywithleading(shotorg, '0 0 0', '0 0 0', this.enemy, shotspeed, shotspeedupward, maxshottime, 0, this))
379 {
380 this.dphitcontentsmask = hf;
381 return false;
382 }
383
384 bot_aimdir(this, findtrajectory_velocity - shotspeedupward * '0 0 1', maxfiredeviation);
385 }
386 else
387 {
388 bot_aimdir(this, v - shotorg, maxfiredeviation);
389 //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");
390 //traceline(shotorg, shotorg + shotdir * 10000, false, this);
391 //if (trace_ent.takedamage)
392 //if (trace_fraction < 1)
393 //if (!bot_shouldattack(this, trace_ent))
394 // return false;
395 traceline(shotorg, enemy_org, false, this);
396 if (trace_fraction < 1)
397 if (trace_ent != this.enemy)
398 if (!bot_shouldattack(this, trace_ent))
399 {
400 this.dphitcontentsmask = hf;
401 return false;
402 }
403 }
404
405 if (time > this.bot_firetimer)
406 {
407 this.dphitcontentsmask = hf;
408 return false;
409 }
410
411 //if (r > maxshottime * shotspeed)
412 // return false;
413 this.dphitcontentsmask = hf;
414 return true;
415}
bool bot_shouldattack(entity this, entity targ)
Definition aim.qc:97
vector bot_shotlead(vector targorigin, vector targvelocity, float shotspeed, float shotdelay)
Definition aim.qc:333
float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, float shotspeed, float shotspeedupward, float maxtime, float shotdelay, entity ignore)
Definition aim.qc:16
void bot_aimdir(entity this, vector v, float maxfiredeviation)
Definition aim.qc:150
vector findtrajectory_velocity
Definition aim.qh:8
vector shotorg
Definition aim.qh:10
float bot_firetimer
Definition aim.qh:17
vector shotdir
Definition aim.qh:11
float skill
Definition api.qh:35
float bot_aimskill
Definition bot.qh:37
vector v_angle
Definition player.qh:237
entity trace_ent
float DPCONTENTS_SOLID
float DPCONTENTS_CORPSE
float DPCONTENTS_BODY
float time
vector v_forward
vector origin
float trace_fraction
float dphitcontentsmask
#define LOG_TRACE(...)
Definition log.qh:76
float bound(float min, float value, float max)
float vlen(vector v)
float min(float f,...)
float max(float f,...)
#define makevectors
Definition post.qh:21
vector view_ofs
Definition progsdefs.qc:151
vector
Definition self.qh:92
entity enemy
Definition sv_ctf.qh:153
float W_WeaponSpeedFactor(entity this)
Weapon m_weapon
Definition wepent.qh:26

References bot_aimdir(), bot_aimskill, bot_firetimer, bot_shotlead(), bot_shouldattack(), bound(), DPCONTENTS_BODY, DPCONTENTS_CORPSE, DPCONTENTS_SOLID, dphitcontentsmask, enemy, entity(), findtrajectory_velocity, findtrajectorywithleading(), LOG_TRACE, m_weapon, makevectors, max(), min(), origin, shotdir, shotorg, skill, time, trace_ent, trace_fraction, v_angle, v_forward, vector, view_ofs, vlen(), and W_WeaponSpeedFactor().

◆ bot_aim_reset()

void bot_aim_reset ( entity this)

Definition at line 134 of file aim.qc.

135{
136 this.bot_mouseaim = this.v_angle;
137 this.bot_olddesiredang = this.v_angle;
138 this.bot_aimdir_executed = true;
139 this.bot_badaimtime = 0;
140 this.bot_aimthinktime = time;
141 this.bot_prevaimtime = time;
142 this.bot_1st_order_aimfilter = '0 0 0';
143 this.bot_2nd_order_aimfilter = '0 0 0';
144 this.bot_3th_order_aimfilter = '0 0 0';
145 this.bot_4th_order_aimfilter = '0 0 0';
146 this.bot_5th_order_aimfilter = '0 0 0';
147 this.bot_firetimer = 0;
148}
vector bot_4th_order_aimfilter
Definition aim.qh:25
vector bot_mouseaim
Definition aim.qh:20
float bot_prevaimtime
Definition aim.qh:16
vector bot_olddesiredang
Definition aim.qh:27
vector bot_3th_order_aimfilter
Definition aim.qh:24
float bot_aimthinktime
Definition aim.qh:15
vector bot_1st_order_aimfilter
Definition aim.qh:22
bool bot_aimdir_executed
Definition aim.qh:13
float bot_badaimtime
Definition aim.qh:14
vector bot_5th_order_aimfilter
Definition aim.qh:26
vector bot_2nd_order_aimfilter
Definition aim.qh:23

References bot_1st_order_aimfilter, bot_2nd_order_aimfilter, bot_3th_order_aimfilter, bot_4th_order_aimfilter, bot_5th_order_aimfilter, bot_aimdir_executed, bot_aimthinktime, bot_badaimtime, bot_firetimer, bot_mouseaim, bot_olddesiredang, bot_prevaimtime, entity(), time, and v_angle.

Referenced by MUTATOR_HOOKFUNCTION(), ons_Teleport(), PutPlayerInServer(), TeleportPlayer(), and WarpZone_TeleportPlayer().

◆ bot_aimdir()

void bot_aimdir ( entity this,
vector v,
float maxfiredeviation )

Definition at line 150 of file aim.qc.

151{
152 float dist, delta_t, blend;
153 vector desiredang, diffang;
154
155 this.bot_aimdir_executed = true;
156
157 //dprint("aim ", this.netname, ": old:", vtos(this.v_angle));
158 // make sure v_angle is sane first
159 this.v_angle_y = this.v_angle.y - floor(this.v_angle.y / 360) * 360;
160 this.v_angle_z = 0;
161
162 // make work bot_aim_reset even if called before this function
163 if (this.bot_prevaimtime == time)
164 return;
165
166 // if skill is high enough bots will not have any aim smoothing or aim errors
167 if (SUPERBOT)
168 {
169 this.v_angle = vectoangles(normalize(v));
170
171 this.v_angle.x *= -1;
172
173 makevectors(this.v_angle);
174 shotorg = this.origin + this.view_ofs;
176
177 // bot will fire on the next tick
178 this.bot_firetimer = time + 0.001;
179 return;
180 }
181
182 // invalid aim dir (can happen when bot overlaps target)
183 if(!v) return;
184
185 float skill_save = skill;
186 // allow turning in a more natural way when bot is walking
187 if (!this.enemy)
188 skill = max(4, skill);
189
190 // get the desired angles to aim at
191 //dprint(" at:", vtos(v));
192 //v = normalize(v);
193 //te_lightning2(NULL, this.origin + this.view_ofs, this.origin + this.view_ofs + v * 200);
194 if (time >= this.bot_badaimtime)
195 {
196 this.bot_badaimtime = max(this.bot_badaimtime + 0.2 + 0.3 * random(), time);
197 int f = bound(0, 1 - 0.1 * (skill + this.bot_offsetskill), 1);
199 this.bot_badaimoffset.x *= 0.7; // smaller vertical offset
200 }
201 float enemy_factor = ((this.enemy) ? 5 : 2);
202 // apply enemy_factor every frame so that the bigger offset is applied instantly when the bot aims to a new target
203 desiredang = vectoangles(v) + this.bot_badaimoffset * enemy_factor;
204 //dprint(" desired:", vtos(desiredang));
205 if (desiredang.x >= 180)
206 desiredang.x = desiredang.x - 360;
207 desiredang.x = bound(-90, 0 - desiredang.x, 90);
208 desiredang.z = this.v_angle.z;
209 //dprint(" / ", vtos(desiredang));
210
212 //if (this.bot_painintensity)
213 //{
214 // // shake from pain
215 // desiredang = desiredang + randomvec() * this.bot_painintensity * 0.2;
216 //}
217
218 // calculate turn angles
219 diffang = (desiredang - this.bot_olddesiredang);
220 // wrap yaw turn
221 diffang.y = diffang.y - floor(diffang.y / 360) * 360;
222 if (diffang.y >= 180)
223 diffang.y = diffang.y - 360;
224 this.bot_olddesiredang = desiredang;
225 //dprint(" diff:", vtos(diffang));
226
227 delta_t = time-this.bot_prevaimtime;
228 this.bot_prevaimtime = time;
229 // Here we will try to anticipate the comming aiming direction
231 + (diffang * (1 / delta_t) - this.bot_1st_order_aimfilter) * bound(0, autocvar_bot_ai_aimskill_order_filter_1st,1);
240
241 //blend = (bound(0,skill,10)*0.1)*((1-bound(0,skill,10)*0.05) ** 2.5)*5.656854249; //Plot formule before changing !
242 blend = bound(0,skill+this.bot_aimskill,10)*0.1;
243 desiredang = desiredang + blend *
244 (
250 );
251 desiredang.x = bound(-90, desiredang.x, 90);
252
253 // calculate turn angles
254 diffang = desiredang - this.bot_mouseaim;
255 // wrap yaw turn
256 diffang.y = diffang.y - floor(diffang.y / 360) * 360;
257 if (diffang.y >= 180)
258 diffang.y = diffang.y - 360;
259 //dprint(" diff:", vtos(diffang));
260
261 if (time >= this.bot_aimthinktime)
262 {
263 this.bot_aimthinktime = max(this.bot_aimthinktime + 0.5 - 0.05*(skill+this.bot_thinkskill), time);
264 this.bot_mouseaim = this.bot_mouseaim + diffang * (1-random()*0.1*bound(1,10-(skill+this.bot_thinkskill),10));
265 }
266
267 //this.v_angle = this.v_angle + diffang * bound(0, r * frametime * (skill * 0.5 + 2), 1);
268
269 diffang = this.bot_mouseaim - desiredang;
270 // wrap yaw turn
271 diffang.y = diffang.y - floor(diffang.y / 360) * 360;
272 if (diffang.y >= 180)
273 diffang.y = diffang.y - 360;
274 desiredang = desiredang + diffang * bound(0,autocvar_bot_ai_aimskill_think,1);
275
276 // calculate turn angles
277 diffang = desiredang - this.v_angle;
278 // wrap yaw turn
279 diffang.y = diffang.y - floor(diffang.y / 360) * 360;
280 if (diffang.y >= 180)
281 diffang.y = diffang.y - 360;
282 //dprint(" diff:", vtos(diffang));
283
284 // jitter tracking
285 dist = vlen(diffang);
286 //diffang = diffang + randomvec() * (dist * 0.05 * (3.5 - bound(0, skill, 3)));
287
288 // turn
289 float r, fixedrate, blendrate;
290 fixedrate = autocvar_bot_ai_aimskill_fixedrate / bound(1,dist,1000);
292 r = max(fixedrate, blendrate);
293 //this.v_angle = this.v_angle + diffang * bound(frametime, r * frametime * (2+skill*skill*0.05-random()*0.05*(10-skill)), 1);
294 r = bound(delta_t, r * delta_t * (2 + ((skill + this.bot_mouseskill) ** 3) * 0.005 - random()), 1);
295 this.v_angle += diffang * (r + (1 - r) * bound(0, 1 - autocvar_bot_ai_aimskill_mouse, 1));
296 this.v_angle_z = 0;
297 this.v_angle_y = this.v_angle.y - floor(this.v_angle.y / 360) * 360;
298 //dprint(" turn:", vtos(this.v_angle));
299
300 skill = skill_save;
301
302 if (maxfiredeviation <= 0)
303 return;
304
306 {
307 this.bot_firetimer = time + 0.2;
308 return;
309 }
310
311 makevectors(this.v_angle);
312 shotorg = this.origin + this.view_ofs;
314
315 // decide whether to fire this time
316 // v is the calculated trajectory, shotdir is bot view direction
317 // NOTE: checking if (v * shotdir > cos(maxfiredeviation * DEG2RAD)) would be cheaper
318 // but it gets evaluated to true even if v and shotdir have nearly opposite direction
319 vector deviation = vectoangles(v) - vectoangles(shotdir);
320 while (deviation.x < -180) deviation.x += 360; while (deviation.x > 180) deviation.x -= 360;
321 while (deviation.y < -180) deviation.y += 360; while (deviation.y > 180) deviation.y -= 360;
322 if (fabs(deviation.x) < maxfiredeviation && fabs(deviation.y) < maxfiredeviation)
323 {
324 traceline(shotorg, shotorg + shotdir * 1000, false, NULL);
325 if (vdist(trace_endpos - shotorg, <, 500 + 500 * bound(0, skill + this.bot_aggresskill, 10))
326 || random() * random() > bound(0, (skill + this.bot_aggresskill) * 0.05, 1))
327 {
328 this.bot_firetimer = time + bound(0.1, 0.5 - (skill + this.bot_aggresskill) * 0.05, 0.5);
329 }
330 }
331}
vector bot_badaimoffset
Definition aim.qh:21
float bot_aggresskill
Definition bot.qh:34
float bot_mouseskill
Definition bot.qh:39
#define SUPERBOT
Definition bot.qh:23
float bot_thinkskill
Definition bot.qh:41
float bot_offsetskill
Definition bot.qh:38
vector trace_endpos
float autocvar_bot_ai_aimskill_order_mix_5th
Definition cvars.qh:17
float autocvar_bot_ai_aimskill_order_mix_1st
Definition cvars.qh:13
int autocvar_bot_ai_aimskill_firetolerance
Definition cvars.qh:4
float autocvar_bot_ai_aimskill_order_filter_5th
Definition cvars.qh:12
float autocvar_bot_ai_aimskill_order_mix_2nd
Definition cvars.qh:14
float autocvar_bot_ai_aimskill_think
Definition cvars.qh:18
float autocvar_bot_ai_aimskill_order_mix_4th
Definition cvars.qh:16
float autocvar_bot_ai_aimskill_order_filter_3th
Definition cvars.qh:10
float autocvar_bot_ai_aimskill_order_filter_4th
Definition cvars.qh:11
float autocvar_bot_ai_aimskill_order_filter_2nd
Definition cvars.qh:9
float autocvar_bot_ai_aimskill_order_filter_1st
Definition cvars.qh:8
float autocvar_bot_ai_aimskill_mouse
Definition cvars.qh:6
float autocvar_bot_ai_aimskill_offset
Definition cvars.qh:7
float autocvar_bot_ai_aimskill_order_mix_3th
Definition cvars.qh:15
float autocvar_bot_ai_aimskill_blendrate
Definition cvars.qh:3
float autocvar_bot_ai_aimskill_fixedrate
Definition cvars.qh:5
float random(void)
vector vectoangles(vector v)
vector randomvec(void)
vector normalize(vector v)
float fabs(float f)
float floor(float f)
#define NULL
Definition post.qh:14
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8

References autocvar_bot_ai_aimskill_blendrate, autocvar_bot_ai_aimskill_firetolerance, autocvar_bot_ai_aimskill_fixedrate, autocvar_bot_ai_aimskill_mouse, autocvar_bot_ai_aimskill_offset, autocvar_bot_ai_aimskill_order_filter_1st, autocvar_bot_ai_aimskill_order_filter_2nd, autocvar_bot_ai_aimskill_order_filter_3th, autocvar_bot_ai_aimskill_order_filter_4th, autocvar_bot_ai_aimskill_order_filter_5th, autocvar_bot_ai_aimskill_order_mix_1st, autocvar_bot_ai_aimskill_order_mix_2nd, autocvar_bot_ai_aimskill_order_mix_3th, autocvar_bot_ai_aimskill_order_mix_4th, autocvar_bot_ai_aimskill_order_mix_5th, autocvar_bot_ai_aimskill_think, bot_1st_order_aimfilter, bot_2nd_order_aimfilter, bot_3th_order_aimfilter, bot_4th_order_aimfilter, bot_5th_order_aimfilter, bot_aggresskill, bot_aimdir_executed, bot_aimskill, bot_aimthinktime, bot_badaimoffset, bot_badaimtime, bot_firetimer, bot_mouseaim, bot_mouseskill, bot_offsetskill, bot_olddesiredang, bot_prevaimtime, bot_thinkskill, bound(), enemy, entity(), fabs(), floor(), makevectors, max(), normalize(), NULL, origin, random(), randomvec(), shotdir, shotorg, skill, SUPERBOT, time, trace_endpos, v_angle, v_forward, vdist, vectoangles(), vector, view_ofs, and vlen().

Referenced by bot_aim(), havocbot_ai(), havocbot_moveto(), and havocbot_movetogoal().

◆ bot_shotlead()

vector bot_shotlead ( vector targorigin,
vector targvelocity,
float shotspeed,
float shotdelay )

Definition at line 333 of file aim.qc.

334{
335 // Try to add code here that predicts gravity effect here, no clue HOW to though ... well not yet atleast...
336 return targorigin + targvelocity * (shotdelay + vlen(targorigin - shotorg) / shotspeed);
337}

References shotorg, vector, and vlen().

Referenced by bot_aim().

◆ bot_shouldattack()

bool bot_shouldattack ( entity this,
entity targ )

Definition at line 97 of file aim.qc.

98{
99 if (targ.team == this.team)
100 {
101 if (targ == this)
102 return false;
103 if (teamplay)
104 if (targ.team != 0)
105 return false;
106 }
107
108 if(teamplay)
109 {
110 if(targ.team==0)
111 return false;
112 }
113 else if (autocvar_bot_ignore_bots && IS_BOT_CLIENT(targ))
114 return false;
115
116 if (!targ.takedamage)
117 return false;
118 if (IS_DEAD(targ))
119 return false;
121 return false;
122 if(targ.flags & FL_NOTARGET)
123 return false;
124 if(targ.alpha <= 0.1 && targ.alpha != 0)
125 return false; // invisible via alpha
126
127 if(MUTATOR_CALLHOOK(BotShouldAttack, this, targ))
128 return false;
129
130 return true;
131}
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
#define IS_DEAD(s)
Definition player.qh:245
#define PHYS_INPUT_BUTTON_CHAT(s)
Definition player.qh:159
const int FL_NOTARGET
Definition constants.qh:76
bool autocvar_bot_typefrag
Definition cvars.qh:58
bool autocvar_bot_ignore_bots
Definition cvars.qh:48
bool teamplay
Definition teams.qh:59
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15

References autocvar_bot_ignore_bots, autocvar_bot_typefrag, entity(), FL_NOTARGET, IS_BOT_CLIENT, IS_DEAD, MUTATOR_CALLHOOK, PHYS_INPUT_BUTTON_CHAT, and teamplay.

Referenced by bot_aim(), havocbot_chooseenemy(), and havocbot_goalrating_enemyplayers().

◆ findtrajectorywithleading()

float findtrajectorywithleading ( vector org,
vector m1,
vector m2,
entity targ,
float shotspeed,
float shotspeedupward,
float maxtime,
float shotdelay,
entity ignore )

Definition at line 16 of file aim.qc.

17{
18 float c, savesolid, shottime;
19 vector dir, end, v, o;
20 if (shotspeed < 1)
21 return false; // could cause division by zero if calculated
22 if (targ.solid < SOLID_BBOX) // SOLID_NOT and SOLID_TRIGGER
23 return false; // could never hit it
24 if (!tracetossent)
26 tracetossent.owner = ignore;
27 setsize(tracetossent, m1, m2);
28 savesolid = targ.solid;
29 targ.solid = SOLID_NOT;
30 o = (targ.absmin + targ.absmax) * 0.5;
31 shottime = ((vlen(o - org) / shotspeed) + shotdelay);
32 v = targ.velocity * shottime + o;
33 tracebox(o, targ.mins, targ.maxs, v, false, targ);
34 v = trace_endpos;
35 end = v + (targ.mins + targ.maxs) * 0.5;
36 float shotdistance = max(0.001, vlen(end - org));
37 if ((shotdistance / shotspeed + 0.2) > maxtime)
38 {
39 // out of range
40 targ.solid = savesolid;
41 return false;
42 }
43
46 tracetossfaketarget.solid = savesolid;
47 set_movetype(tracetossfaketarget, targ.move_movetype);
48 _setmodel(tracetossfaketarget, targ.model); // no low precision
49 tracetossfaketarget.model = targ.model;
50 tracetossfaketarget.modelindex = targ.modelindex;
51 setsize(tracetossfaketarget, targ.mins, targ.maxs);
52 setorigin(tracetossfaketarget, v);
53
54 c = 0;
55 // TODO: Consider changing this back to `/ shotdistance` after https://github.com/graphitemaster/gmqcc/issues/210.
56 dir = (end - org) * (1 / shotdistance); // same as dir = normalize(end - org); but cheaper
57 vector test_dir = dir;
58 vector test_dir_normalized = dir;
59 while (c < 10) // 10 traces
60 {
61 setorigin(tracetossent, org); // reset
62 tracetossent.velocity = findtrajectory_velocity = test_dir_normalized * shotspeed + shotspeedupward * '0 0 1';
63 tracetoss(tracetossent, ignore); // love builtin functions...
64 if (trace_ent == tracetossfaketarget) // done
65 {
66 targ.solid = savesolid;
67
68 // make it disappear
71 tracetossfaketarget.model = "";
72 tracetossfaketarget.modelindex = 0;
73 // relink to remove it from physics considerations
74 setorigin(tracetossfaketarget, v);
75
76 return true;
77 }
78 test_dir.z += 0.1; // aim up a little more
79 test_dir_normalized = normalize(test_dir);
80 c = c + 1;
81 }
82 targ.solid = savesolid;
83
84 // make it disappear
87 tracetossfaketarget.model = "";
88 tracetossfaketarget.modelindex = 0;
89 // relink to remove it from physics considerations
90 setorigin(tracetossfaketarget, v);
91
92 // leave a valid one even if it won't reach
93 findtrajectory_velocity = dir * shotspeed + shotspeedupward * '0 0 1';
94 return false;
95}
entity tracetossent
Definition aim.qh:6
entity tracetossfaketarget
Definition aim.qh:7
const float SOLID_BBOX
const float SOLID_NOT
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_NONE
Definition movetypes.qh:129
vector org
Definition self.qh:92
int dir
Definition impulse.qc:89

References dir, entity(), findtrajectory_velocity, max(), MOVETYPE_NONE, normalize(), org, set_movetype(), SOLID_BBOX, SOLID_NOT, trace_endpos, trace_ent, tracetossent, tracetossfaketarget, vector, and vlen().

Referenced by bot_aim().