- rename sys_ticrate global to sys_frametime, and premultiply it with slowmo (fixes...
[divverent/nexuiz.git] / data / qcsrc / server / tturrets / system / system_aimprocs.qc
1 /*
2 * Generic aim
3
4 supports:
5 TFL_AIM_NO
6 TFL_AIM_GROUND
7 TFL_AIM_LEAD
8 TFL_AIM_SHOTTIMECOMPENSATE
9 TFL_AIM_INFRONT
10 TFL_AIM_BEHIND
11 TFL_AIM_ZEASE
12
13 not supported:
14 TFL_AIM_BALISTIC
15 */
16 vector turret_stdproc_aim_generic()
17 {
18
19     vector pre_pos,prep;
20     float distance,impact_time,i,mintime;
21
22     turret_tag_fire_update();
23
24     if(self.aim_flags & TFL_AIM_SIMPLE)
25         return real_origin(self.enemy);
26
27     // Keep track of when we can shoot the next time and
28     // try to predict where the target will be then, so we can put our aimpoint there.
29     // + sys_frametime, becouse spawned REMOVE THIS IF sv_gameplayfix_delayprojectiles are 0!
30     // projectiles dont move during the first tic of their life.
31     //if (self.turrcaps_flags & TFL_TURRCAPS_HITSCAN)
32     //    mintime = max(self.attack_finished_single - time,0) + sys_frametime;
33     //else
34
35     mintime = max(self.attack_finished_single - time,0) + sys_frametime;
36
37     // Baseline
38     pre_pos = real_origin(self.enemy);
39
40     if (self.aim_flags & TFL_AIM_INFRONT)   // Aim a bit in front of the target
41         pre_pos = pre_pos + (normalize(self.enemy.velocity) * 64);
42
43     if (self.aim_flags & TFL_AIM_BEHIND)    // Aim a bit behind the target
44         pre_pos = pre_pos - (normalize(self.enemy.velocity) * 32);
45
46     // Lead?
47     if (self.aim_flags & TFL_AIM_LEAD)
48     if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE)       // Need to conpensate for shot traveltime
49     {
50         // FIXME: this cant be the best way to do this..
51         prep = pre_pos;
52         for(i = 0; i < 4; ++i)
53         {
54             distance = vlen(prep - self.tur_shotorg);
55             impact_time = distance / self.shot_speed;
56             prep = pre_pos + self.enemy.velocity * impact_time;
57         }
58
59
60         // tnx to Rudolf "div0" Polzer for this solution.
61         // hmm tobad it dont work.
62         /*
63         vector q;
64         q = solve_quadratic(self.enemy.velocity*self.enemy.velocity - self.shot_speed*self.shot_speed, 2*(pre_pos*self.enemy.velocity), pre_pos * pre_pos);
65         if(q_x > 0)
66             impact_time = q_x;
67         else
68             impact_time = q_y;
69         */
70
71         prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
72
73         if(self.aim_flags & TFL_AIM_ZPREDICT)
74         if not(self.enemy.flags & FL_ONGROUND)
75         if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
76         {
77             float vz;
78             prep_z = pre_pos_z;
79             vz = self.enemy.velocity_z;
80             for(i = 0; i < impact_time; i += sys_frametime)
81             {
82                 vz = vz - (sv_gravity * sys_frametime);
83                 prep_z = prep_z + vz * sys_frametime;
84             }
85         }
86         pre_pos = prep;
87     }
88     else
89         pre_pos = pre_pos + self.enemy.velocity * mintime;
90
91     // Smooth out predict-Z?
92     /*
93     if (self.aim_flags & TFL_AIM_ZEASE)
94     if (self.enemy.flags & FL_CLIENT)
95     {
96         vector v;
97         v = real_origin(self.enemy);
98         pre_pos_z = (pre_pos_z + v_z) * 0.5;
99     }
100     */
101
102     if(self.aim_flags & TFL_AIM_GROUND2)
103     {
104         //tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
105         traceline(pre_pos + '0 0 32',pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
106         if(trace_fraction != 1.0)
107             pre_pos = trace_endpos;
108     }
109
110     /*
111     // This turret should hit the ground neer a target rather the do a direct hit
112     if (self.aim_flags & TFL_AIM_GROUND)
113     {
114         traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',MOVE_WORLDONLY,self.enemy);
115         pre_pos = trace_endpos;
116     }
117     */
118
119     return pre_pos;
120 }