Vehicles: extract raptor weapons
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / vehicles / vehicle / raptor.qc
1 #ifndef VEHICLE_RAPTOR
2 #define VEHICLE_RAPTOR
3 #include "raptor.qh"
4
5 CLASS(Raptor, Vehicle)
6 /* spawnflags */ ATTRIB(Raptor, spawnflags, int, VHF_DMGSHAKE | VHF_DMGROLL);
7 /* mins       */ ATTRIB(Raptor, mins, vector, '-80 -80 0');
8 /* maxs       */ ATTRIB(Raptor, maxs, vector, '80 80 70');
9 /* model          */ ATTRIB(Raptor, mdl, string, "models/vehicles/raptor.dpm");
10 /* model          */ ATTRIB(Raptor, model, string, "models/vehicles/raptor.dpm");
11 /* head_model */ ATTRIB(Raptor, head_model, string, "");
12 /* hud_model  */ ATTRIB(Raptor, hud_model, string, "models/vehicles/raptor_cockpit.dpm");
13 /* tags       */ ATTRIB(Raptor, tag_head, string, "");
14 /* tags       */ ATTRIB(Raptor, tag_hud, string, "tag_hud");
15 /* tags       */ ATTRIB(Raptor, tag_hview, string, "tag_camera");
16 /* netname    */ ATTRIB(Raptor, netname, string, "raptor");
17 /* fullname   */ ATTRIB(Raptor, vehicle_name, string, _("Raptor"));
18 /* icon       */ ATTRIB(Raptor, m_icon, string, "vehicle_raptor");
19 ENDCLASS(Raptor)
20
21 REGISTER_VEHICLE(RAPTOR, NEW(Raptor));
22
23 #include "../../weapons/all.qh"
24
25 CLASS(RaptorCannon, PortoLaunch)
26 /* flags     */ ATTRIB(RaptorCannon, spawnflags, int, WEP_TYPE_OTHER);
27 /* impulse   */ ATTRIB(RaptorCannon, impulse, int, 3);
28 /* refname   */ ATTRIB(RaptorCannon, netname, string, "raptorcannon");
29 /* wepname   */ ATTRIB(RaptorCannon, message, string, _("Raptor cannon"));
30 ENDCLASS(RaptorCannon)
31 REGISTER_WEAPON(RAPTOR, NEW(RaptorCannon));
32
33 CLASS(RaptorBomb, PortoLaunch)
34 /* flags     */ ATTRIB(RaptorBomb, spawnflags, int, WEP_TYPE_OTHER);
35 /* impulse   */ ATTRIB(RaptorBomb, impulse, int, 3);
36 /* refname   */ ATTRIB(RaptorBomb, netname, string, "raptorbomb");
37 /* wepname   */ ATTRIB(RaptorBomb, message, string, _("Raptor bomb"));
38 ENDCLASS(RaptorBomb)
39 REGISTER_WEAPON(RAPTOR_BOMB, NEW(RaptorBomb));
40
41 CLASS(RaptorFlare, PortoLaunch)
42 /* flags     */ ATTRIB(RaptorFlare, spawnflags, int, WEP_TYPE_OTHER);
43 /* impulse   */ ATTRIB(RaptorFlare, impulse, int, 3);
44 /* refname   */ ATTRIB(RaptorFlare, netname, string, "raptorflare");
45 /* wepname   */ ATTRIB(RaptorFlare, message, string, _("Raptor flare"));
46 ENDCLASS(RaptorFlare)
47 REGISTER_WEAPON(RAPTOR_FLARE, NEW(RaptorFlare));
48
49 #endif
50
51 #ifdef IMPLEMENTATION
52
53 #ifdef SVQC
54 float autocvar_g_vehicle_raptor_cannon_cost;
55 float autocvar_g_vehicle_raptor_cannon_damage;
56 float autocvar_g_vehicle_raptor_cannon_radius;
57 float autocvar_g_vehicle_raptor_cannon_refire;
58 float autocvar_g_vehicle_raptor_cannon_speed;
59 float autocvar_g_vehicle_raptor_cannon_spread;
60 float autocvar_g_vehicle_raptor_cannon_force;
61
62 METHOD(RaptorCannon, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
63         SELFPARAM();
64         bool isPlayer = IS_PLAYER(self);
65         entity player = isPlayer ? self : self.owner;
66         entity veh = player.vehicle;
67         setself(player);
68         // 1 [wait] 1 [wait] 2 [wait] 2 [wait] [wait]
69         float t = autocvar_g_vehicle_raptor_cannon_refire * (1 + veh.misc_bulletcounter == 4);
70         if (fire1)
71         if (weapon_prepareattack(false, t)) {
72                 if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0);
73                 vector org = w_shotorg;
74                 vector dir = w_shotdir;
75                 if (veh) {
76                         veh.misc_bulletcounter += 1;
77                         org = (veh.misc_bulletcounter <= 2) ? gettaginfo(veh.gun1, gettagindex(veh.gun1, "fire1"))
78                           : (((veh.misc_bulletcounter == 4) ? veh.misc_bulletcounter = 0 : 0), gettaginfo(veh.gun2, gettagindex(veh.gun2, "fire1")));
79                         dir = v_forward;
80                         veh.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost;
81                         self.cnt = time;
82                 }
83                 vehicles_projectile(EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
84                                                            org, normalize(dir + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed,
85                                                            autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force,  0,
86                                                            DEATH_VH_RAPT_CANNON, PROJECTILE_RAPTORCANNON, 0, true, true, player);
87                 weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
88         }
89         setself(this);
90         return true;
91 }
92 METHOD(RaptorCannon, wr_checkammo1, bool(RacerAttack thiswep)) {
93         SELFPARAM();
94         bool isPlayer = IS_PLAYER(self);
95         entity player = isPlayer ? self : self.owner;
96         entity veh = player.vehicle;
97         return isPlayer || veh.vehicle_energy >= autocvar_g_vehicle_raptor_cannon_cost;
98 }
99
100 float autocvar_g_vehicle_raptor_bombs_refire;
101
102 void raptor_bombdrop();
103 METHOD(RaptorBomb, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
104         SELFPARAM();
105         bool isPlayer = IS_PLAYER(self);
106         entity player = isPlayer ? self : self.owner;
107         setself(player);
108         if (fire2)
109         if (weapon_prepareattack(false, autocvar_g_vehicle_raptor_bombs_refire)) {
110                 raptor_bombdrop();
111                 weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
112         }
113         setself(this);
114         return true;
115 }
116
117 float autocvar_g_vehicle_raptor_flare_refire;
118 float autocvar_g_vehicle_raptor_flare_lifetime;
119 float autocvar_g_vehicle_raptor_flare_chase;
120 float autocvar_g_vehicle_raptor_flare_range;
121
122 void raptor_flare_think();
123 void raptor_flare_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
124 void raptor_flare_touch();
125
126 METHOD(RaptorFlare, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
127         SELFPARAM();
128         bool isPlayer = IS_PLAYER(self);
129         entity player = isPlayer ? self : self.owner;
130         setself(player);
131         if (fire2)
132         if (weapon_prepareattack(true, autocvar_g_vehicle_raptor_flare_refire)) {
133                 for(int i = 0; i < 3; ++i) {
134                         entity _flare = spawn();
135                         setmodel(_flare, MDL_VEH_RAPTOR_FLARE);
136                         _flare.effects = EF_LOWPRECISION | EF_FLAME;
137                         _flare.scale = 0.5;
138                         setorigin(_flare, self.origin - '0 0 16');
139                         _flare.movetype = MOVETYPE_TOSS;
140                         _flare.gravity = 0.15;
141                         _flare.velocity = 0.25 * self.velocity + (v_forward + randomvec() * 0.25)* -500;
142                         _flare.think = raptor_flare_think;
143                         _flare.nextthink = time;
144                         _flare.owner = self;
145                         _flare.solid = SOLID_CORPSE;
146                         _flare.takedamage = DAMAGE_YES;
147                         _flare.event_damage = raptor_flare_damage;
148                         _flare.health = 20;
149                         _flare.tur_impacttime = time + autocvar_g_vehicle_raptor_flare_lifetime;
150                         _flare.touch = raptor_flare_touch;
151                 }
152                 weapon_thinkf(WFRAME_FIRE2, 0, w_ready);
153         }
154         setself(this);
155         return true;
156 }
157
158 bool autocvar_g_vehicle_raptor;
159
160 float autocvar_g_vehicle_raptor_respawntime;
161 float autocvar_g_vehicle_raptor_takeofftime;
162
163 float autocvar_g_vehicle_raptor_movestyle;
164 float autocvar_g_vehicle_raptor_turnspeed;
165 float autocvar_g_vehicle_raptor_pitchspeed;
166 float autocvar_g_vehicle_raptor_pitchlimit;
167
168 float autocvar_g_vehicle_raptor_speed_forward;
169 float autocvar_g_vehicle_raptor_speed_strafe;
170 float autocvar_g_vehicle_raptor_speed_up;
171 float autocvar_g_vehicle_raptor_speed_down;
172 float autocvar_g_vehicle_raptor_friction;
173
174 float autocvar_g_vehicle_raptor_bomblets;
175 float autocvar_g_vehicle_raptor_bomblet_alt;
176 float autocvar_g_vehicle_raptor_bomblet_time;
177 float autocvar_g_vehicle_raptor_bomblet_damage;
178 float autocvar_g_vehicle_raptor_bomblet_spread;
179 float autocvar_g_vehicle_raptor_bomblet_edgedamage;
180 float autocvar_g_vehicle_raptor_bomblet_radius;
181 float autocvar_g_vehicle_raptor_bomblet_force;
182 float autocvar_g_vehicle_raptor_bomblet_explode_delay;
183
184 float autocvar_g_vehicle_raptor_cannon_turnspeed;
185 float autocvar_g_vehicle_raptor_cannon_turnlimit;
186 float autocvar_g_vehicle_raptor_cannon_pitchlimit_up;
187 float autocvar_g_vehicle_raptor_cannon_pitchlimit_down;
188
189 float autocvar_g_vehicle_raptor_cannon_locktarget;
190 float autocvar_g_vehicle_raptor_cannon_locking_time;
191 float autocvar_g_vehicle_raptor_cannon_locking_releasetime;
192 float autocvar_g_vehicle_raptor_cannon_locked_time;
193 float autocvar_g_vehicle_raptor_cannon_predicttarget;
194
195 float autocvar_g_vehicle_raptor_energy;
196 float autocvar_g_vehicle_raptor_energy_regen;
197 float autocvar_g_vehicle_raptor_energy_regen_pause;
198
199 float autocvar_g_vehicle_raptor_health;
200 float autocvar_g_vehicle_raptor_health_regen;
201 float autocvar_g_vehicle_raptor_health_regen_pause;
202
203 float autocvar_g_vehicle_raptor_shield;
204 float autocvar_g_vehicle_raptor_shield_regen;
205 float autocvar_g_vehicle_raptor_shield_regen_pause;
206
207 float autocvar_g_vehicle_raptor_bouncefactor;
208 float autocvar_g_vehicle_raptor_bouncestop;
209 vector autocvar_g_vehicle_raptor_bouncepain;
210
211 .entity bomb1;
212 .entity bomb2;
213
214 float raptor_altitude(float amax)
215 {SELFPARAM();
216         tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * amax), MOVE_WORLDONLY, self);
217         return vlen(self.origin - trace_endpos);
218 }
219
220 void raptor_bomblet_boom()
221 {SELFPARAM();
222         RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage,
223                                                                         autocvar_g_vehicle_raptor_bomblet_edgedamage,
224                                                                         autocvar_g_vehicle_raptor_bomblet_radius, world, world,
225                                                                         autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB, world);
226         remove(self);
227 }
228
229 void raptor_bomblet_touch()
230 {SELFPARAM();
231         if(other == self.owner)
232                 return;
233
234         PROJECTILE_TOUCH;
235         self.think = raptor_bomblet_boom;
236         self.nextthink = time + random() * autocvar_g_vehicle_raptor_bomblet_explode_delay;
237 }
238
239 void raptor_bomb_burst()
240 {SELFPARAM();
241         if(self.cnt > time)
242         if(autocvar_g_vehicle_raptor_bomblet_alt)
243         {
244                 self.nextthink = time;
245                 traceline(self.origin, self.origin + (normalize(self.velocity) * autocvar_g_vehicle_raptor_bomblet_alt), MOVE_NORMAL, self);
246                 if((trace_fraction == 1.0) || (vlen(self.origin - self.owner.origin) < autocvar_g_vehicle_raptor_bomblet_radius))
247                 {
248                         UpdateCSQCProjectile(self);
249                         return;
250                 }
251         }
252
253         entity bomblet;
254         float i;
255
256         Damage_DamageInfo(self.origin, 0, 0, 0, '0 0 0', DEATH_VH_RAPT_FRAGMENT, 0, self);
257
258         for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i)
259         {
260                 bomblet = spawn();
261                 setorigin(bomblet, self.origin);
262
263                 bomblet.movetype        = MOVETYPE_TOSS;
264                 bomblet.touch      = raptor_bomblet_touch;
265                 bomblet.think      = raptor_bomblet_boom;
266                 bomblet.nextthink   = time + 5;
267                 bomblet.owner      = self.owner;
268                 bomblet.realowner   = self.realowner;
269                 bomblet.velocity        = normalize(normalize(self.velocity) + (randomvec() * autocvar_g_vehicle_raptor_bomblet_spread)) * vlen(self.velocity);
270
271                 PROJECTILE_MAKETRIGGER(bomblet);
272                 CSQCProjectile(bomblet, true, PROJECTILE_RAPTORBOMBLET, true);
273         }
274
275         remove(self);
276 }
277
278 void raptor_bombdrop()
279 {SELFPARAM();
280         entity bomb_1, bomb_2;
281
282         bomb_1 = spawn();
283         bomb_2 = spawn();
284
285         setorigin(bomb_1, gettaginfo(self, gettagindex(self, "bombmount_left")));
286         setorigin(bomb_2, gettaginfo(self, gettagindex(self, "bombmount_right")));
287
288         bomb_1.movetype  = bomb_2.movetype   = MOVETYPE_BOUNCE;
289         bomb_1.velocity  = bomb_2.velocity   = self.velocity;
290         bomb_1.touch            = bomb_2.touch    = raptor_bomb_burst;
291         bomb_1.think            = bomb_2.think    = raptor_bomb_burst;
292         bomb_1.cnt                = bomb_2.cnt          = time + 10;
293
294         if(autocvar_g_vehicle_raptor_bomblet_alt)
295                 bomb_1.nextthink = bomb_2.nextthink  = time;
296         else
297                 bomb_1.nextthink = bomb_2.nextthink  = time + autocvar_g_vehicle_raptor_bomblet_time;
298
299         bomb_1.owner     = bomb_2.owner   = self;
300         bomb_1.realowner = bomb_2.realowner  = self.owner;
301         bomb_1.solid     = bomb_2.solid   = SOLID_BBOX;
302         bomb_1.gravity   = bomb_2.gravity       = 1;
303
304         PROJECTILE_MAKETRIGGER(bomb_1);
305         PROJECTILE_MAKETRIGGER(bomb_2);
306
307         CSQCProjectile(bomb_1, true, PROJECTILE_RAPTORBOMB, true);
308         CSQCProjectile(bomb_2, true, PROJECTILE_RAPTORBOMB, true);
309 }
310
311
312 void raptor_land()
313 {SELFPARAM();
314         float hgt;
315
316         hgt = raptor_altitude(512);
317         self.velocity = (self.velocity * 0.9) + ('0 0 -1800' * (hgt / 256) * sys_frametime);
318         self.angles_x *= 0.95;
319         self.angles_z *= 0.95;
320
321         if(hgt < 128)
322         if(hgt > 0)
323                 self.frame = (hgt / 128) * 25;
324
325         self.bomb1.gun1.avelocity_y = 90 + ((self.frame / 25) * 2000);
326         self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y;
327
328         if(hgt < 16)
329         {
330                 self.movetype = MOVETYPE_TOSS;
331                 self.think      = vehicles_think;
332                 self.frame      = 0;
333         }
334
335         self.nextthink  = time;
336
337         CSQCMODEL_AUTOUPDATE(self);
338 }
339
340 void raptor_exit(float eject)
341 {SELFPARAM();
342         vector spot;
343         self.tur_head.exteriormodeltoclient = world;
344
345         if(self.deadflag == DEAD_NO)
346         {
347                 self.think        = raptor_land;
348                 self.nextthink  = time;
349         }
350
351         if(!self.owner)
352                 return;
353
354         makevectors(self.angles);
355         if(eject)
356         {
357                 spot = self.origin + v_forward * 100 + '0 0 64';
358                 spot = vehicles_findgoodexit(spot);
359                 setorigin(self.owner , spot);
360                 self.owner.velocity = (v_up + v_forward * 0.25) * 750;
361                 self.owner.oldvelocity = self.owner.velocity;
362         }
363         else
364         {
365                 if(vlen(self.velocity) > 2 * autocvar_sv_maxairspeed)
366                 {
367                         self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed * 2;
368                         self.owner.velocity_z += 200;
369                         spot = self.origin + v_forward * 32 + '0 0 64';
370                         spot = vehicles_findgoodexit(spot);
371                 }
372                 else
373                 {
374                         self.owner.velocity = self.velocity * 0.5;
375                         self.owner.velocity_z += 10;
376                         spot = self.origin - v_forward * 200 + '0 0 64';
377                         spot = vehicles_findgoodexit(spot);
378                 }
379                 self.owner.oldvelocity = self.owner.velocity;
380                 setorigin(self.owner , spot);
381         }
382
383         antilag_clear(self.owner);
384         self.owner = world;
385 }
386
387 void raptor_flare_touch()
388 {SELFPARAM();
389         remove(self);
390 }
391
392 void raptor_flare_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
393 {SELFPARAM();
394         self.health -= damage;
395         if(self.health <= 0)
396                 remove(self);
397 }
398
399 void raptor_flare_think()
400 {SELFPARAM();
401         self.nextthink = time + 0.1;
402         entity _missile = findchainentity(enemy, self.owner);
403         while(_missile)
404         {
405                 if(_missile.flags & FL_PROJECTILE)
406                 if(vlen(self.origin - _missile.origin) < autocvar_g_vehicle_raptor_flare_range)
407                 if(random() > autocvar_g_vehicle_raptor_flare_chase)
408                         _missile.enemy = self;
409                 _missile = _missile.chain;
410         }
411
412         if(self.tur_impacttime < time)
413                 remove(self);
414 }
415
416 float raptor_frame()
417 {SELFPARAM();
418         entity player, raptor;
419         float ftmp = 0;
420         vector df;
421
422         if(intermission_running)
423         {
424                 self.vehicle.velocity = '0 0 0';
425                 self.vehicle.avelocity = '0 0 0';
426                 return 1;
427         }
428
429         player = self;
430         raptor = self.vehicle;
431         setself(raptor);
432
433         vehicles_painframe();
434         /*
435         ftmp = vlen(self.velocity);
436         if(ftmp > autocvar_g_vehicle_raptor_speed_forward)
437                 ftmp = 1;
438         else
439                 ftmp = ftmp / autocvar_g_vehicle_raptor_speed_forward;
440         */
441
442         if(self.sound_nexttime < time)
443         {
444                 self.sound_nexttime = time + 7.955812;
445                 //sound (self.tur_head, CH_TRIGGER_SINGLE, SND_VEH_RAPTOR_FLY, 1 - ftmp,   ATTEN_NORM );
446                 sound (self, CH_TRIGGER_SINGLE, SND_VEH_RAPTOR_SPEED, 1, ATTEN_NORM);
447                 self.wait = ftmp;
448         }
449         /*
450         else if(fabs(ftmp - self.wait) > 0.2)
451         {
452                 sound (self.tur_head, CH_TRIGGER_SINGLE, SND_Null, 1 - ftmp,   ATTEN_NORM );
453                 sound (self, CH_TRIGGER_SINGLE, SND_Null, ftmp, ATTEN_NORM);
454                 self.wait = ftmp;
455         }
456         */
457
458         if(raptor.deadflag != DEAD_NO)
459         {
460                 setself(player);
461                 player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
462                 return 1;
463         }
464         crosshair_trace(player);
465
466         //if(time - self.lastteleporttime < 1)
467         //{
468                 if(raptor.angles_z > 50 || raptor.angles_z < -50)
469                 {
470                         if(player.BUTTON_JUMP)
471                         {
472                                 player.BUTTON_CROUCH = true;
473                                 player.BUTTON_JUMP = false;
474                         }
475                 }
476         //}
477
478         vector vang;
479         vang = raptor.angles;
480         df = vectoangles(normalize(trace_endpos - self.origin + '0 0 32'));
481         vang_x *= -1;
482         df_x *= -1;
483         if(df_x > 180)  df_x -= 360;
484         if(df_x < -180) df_x += 360;
485         if(df_y > 180)  df_y -= 360;
486         if(df_y < -180) df_y += 360;
487
488         ftmp = shortangle_f(player.v_angle_y - vang_y, vang_y);
489         if(ftmp > 180)  ftmp -= 360; if(ftmp < -180) ftmp += 360;
490         raptor.avelocity_y = bound(-autocvar_g_vehicle_raptor_turnspeed, ftmp + raptor.avelocity_y * 0.9, autocvar_g_vehicle_raptor_turnspeed);
491
492         // Pitch
493         ftmp = 0;
494         if(player.movement_x > 0 && vang_x < autocvar_g_vehicle_raptor_pitchlimit) ftmp = 5;
495         else if(player.movement_x < 0 && vang_x > -autocvar_g_vehicle_raptor_pitchlimit) ftmp = -20;
496
497         df_x = bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x , autocvar_g_vehicle_raptor_pitchlimit);
498         ftmp = vang_x - bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x + ftmp, autocvar_g_vehicle_raptor_pitchlimit);
499         raptor.avelocity_x = bound(-autocvar_g_vehicle_raptor_pitchspeed, ftmp + raptor.avelocity_x * 0.9, autocvar_g_vehicle_raptor_pitchspeed);
500
501         raptor.angles_x = anglemods(raptor.angles_x);
502         raptor.angles_y = anglemods(raptor.angles_y);
503         raptor.angles_z = anglemods(raptor.angles_z);
504
505         if(autocvar_g_vehicle_raptor_movestyle == 1)
506                 makevectors('0 1 0' * raptor.angles_y);
507         else
508                 makevectors(player.v_angle);
509
510         df = raptor.velocity * -autocvar_g_vehicle_raptor_friction;
511
512         if(player.movement_x != 0)
513         {
514                 if(player.movement_x > 0)
515                         df += v_forward  * autocvar_g_vehicle_raptor_speed_forward;
516                 else if(player.movement_x < 0)
517                         df -= v_forward  * autocvar_g_vehicle_raptor_speed_forward;
518         }
519
520         if(player.movement_y != 0)
521         {
522                 if(player.movement_y < 0)
523                         df -= v_right * autocvar_g_vehicle_raptor_speed_strafe;
524                 else if(player.movement_y > 0)
525                         df += v_right * autocvar_g_vehicle_raptor_speed_strafe;
526
527                 raptor.angles_z = bound(-30,raptor.angles_z + (player.movement_y / autocvar_g_vehicle_raptor_speed_strafe),30);
528         }
529         else
530         {
531                 raptor.angles_z *= 0.95;
532                 if(raptor.angles_z >= -1 && raptor.angles_z <= -1)
533                         raptor.angles_z = 0;
534         }
535
536         if(player.BUTTON_CROUCH)
537                 df -=   v_up * autocvar_g_vehicle_raptor_speed_down;
538         else if (player.BUTTON_JUMP)
539                 df +=  v_up * autocvar_g_vehicle_raptor_speed_up;
540
541         raptor.velocity  += df * frametime;
542         player.velocity = player.movement  = raptor.velocity;
543         setorigin(player, raptor.origin + '0 0 32');
544
545         player.vehicle_weapon2mode = raptor.vehicle_weapon2mode;
546
547         vector vf, ad;
548         // Target lock & predict
549         if(autocvar_g_vehicle_raptor_cannon_locktarget == 2)
550         {
551                 if(raptor.gun1.lock_time < time || raptor.gun1.enemy.deadflag)
552                         raptor.gun1.enemy = world;
553
554                 if(trace_ent)
555                 if(trace_ent.movetype)
556                 if(trace_ent.takedamage)
557                 if(!trace_ent.deadflag)
558                 {
559                         if(teamplay)
560                         {
561                                 if(trace_ent.team != player.team)
562                                 {
563                                         raptor.gun1.enemy = trace_ent;
564                                         raptor.gun1.lock_time = time + 5;
565                                 }
566                         }
567                         else
568                         {
569                                 raptor.gun1.enemy = trace_ent;
570                                 raptor.gun1.lock_time = time + 0.5;
571                         }
572                 }
573
574                 if(raptor.gun1.enemy)
575                 {
576                         float distance, impact_time;
577
578                         vf = real_origin(raptor.gun1.enemy);
579                         UpdateAuxiliaryXhair(player, vf, '1 0 0', 1);
580                         vector _vel = raptor.gun1.enemy.velocity;
581                         if(raptor.gun1.enemy.movetype == MOVETYPE_WALK)
582                                 _vel_z *= 0.1;
583
584                         if(autocvar_g_vehicle_raptor_cannon_predicttarget)
585                         {
586                                 ad = vf;
587                                 distance = vlen(ad - player.origin);
588                                 impact_time = distance / autocvar_g_vehicle_raptor_cannon_speed;
589                                 ad = vf + _vel * impact_time;
590                                 trace_endpos = ad;
591                         }
592                         else
593                                 trace_endpos = vf;
594                 }
595         }
596         else if(autocvar_g_vehicle_raptor_cannon_locktarget == 1)
597         {
598
599                 vehicles_locktarget((1 / autocvar_g_vehicle_raptor_cannon_locking_time) * frametime,
600                                                          (1 / autocvar_g_vehicle_raptor_cannon_locking_releasetime) * frametime,
601                                                          autocvar_g_vehicle_raptor_cannon_locked_time);
602
603                 if(self.lock_target != world)
604                 if(autocvar_g_vehicle_raptor_cannon_predicttarget)
605                 if(self.lock_strength == 1)
606                 {
607                         float i, distance, impact_time;
608
609                         vf = real_origin(raptor.lock_target);
610                         ad = vf;
611                         for(i = 0; i < 4; ++i)
612                         {
613                                 distance = vlen(ad - raptor.origin);
614                                 impact_time = distance / autocvar_g_vehicle_raptor_cannon_speed;
615                                 ad = vf + raptor.lock_target.velocity * impact_time;
616                         }
617                         trace_endpos = ad;
618                 }
619
620                 if(self.lock_target)
621                 {
622                         if(raptor.lock_strength == 1)
623                                 UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '1 0 0', 1);
624                         else if(self.lock_strength > 0.5)
625                                 UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '0 1 0', 1);
626                         else if(self.lock_strength < 0.5)
627                                 UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '0 0 1', 1);
628                 }
629         }
630
631
632         vehicle_aimturret(raptor, trace_endpos, raptor.gun1, "fire1",
633                                                   autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1,  autocvar_g_vehicle_raptor_cannon_pitchlimit_up,
634                                                   autocvar_g_vehicle_raptor_cannon_turnlimit * -1,  autocvar_g_vehicle_raptor_cannon_turnlimit,  autocvar_g_vehicle_raptor_cannon_turnspeed);
635
636         vehicle_aimturret(raptor, trace_endpos, raptor.gun2, "fire1",
637                                                   autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1,  autocvar_g_vehicle_raptor_cannon_pitchlimit_up,
638                                                   autocvar_g_vehicle_raptor_cannon_turnlimit * -1,  autocvar_g_vehicle_raptor_cannon_turnlimit,  autocvar_g_vehicle_raptor_cannon_turnspeed);
639
640         /*
641         ad = ad * 0.5;
642         v_forward = vf * 0.5;
643         traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, raptor);
644         UpdateAuxiliaryXhair(player, trace_endpos, '0 1 0', 0);
645         */
646
647         Weapon wep1 = WEP_RAPTOR;
648         if(!forbidWeaponUse(player))
649         if(player.BUTTON_ATCK)
650         if (wep1.wr_checkammo1(wep1))
651         {
652                 wep1.wr_think(wep1, true, false);
653         }
654
655         if(self.vehicle_flags  & VHF_SHIELDREGEN)
656                 vehicles_regen(raptor.dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime, true);
657
658         if(self.vehicle_flags  & VHF_HEALTHREGEN)
659                 vehicles_regen(raptor.dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime, false);
660
661         if(self.vehicle_flags  & VHF_ENERGYREGEN)
662                 vehicles_regen(raptor.cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime, false);
663
664         Weapon wep2a = WEP_RAPTOR_BOMB;
665         if(!forbidWeaponUse(player))
666         if(raptor.vehicle_weapon2mode == RSM_BOMB)
667         {
668                 if(time > raptor.lip + autocvar_g_vehicle_raptor_bombs_refire)
669                 if(player.BUTTON_ATCK2)
670                 {
671                         wep2a.wr_think(wep2a, false, true);
672                         raptor.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
673                         raptor.lip   = time;
674                 }
675         }
676         else
677         {
678                 Weapon wep2b = WEP_RAPTOR_FLARE;
679                 if(time > raptor.lip + autocvar_g_vehicle_raptor_flare_refire)
680                 if(player.BUTTON_ATCK2)
681                 {
682                         wep2b.wr_think(wep2b, false, true);
683                         raptor.delay = time + autocvar_g_vehicle_raptor_flare_refire;
684                         raptor.lip   = time;
685                 }
686         }
687
688         raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip);
689         player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100);
690         player.vehicle_ammo2 = (player.vehicle_reload2 == 100) ? 100 : 0;
691
692         if(self.bomb1.cnt < time)
693         {
694                 entity _missile = findchainentity(enemy, raptor);
695                 float _incomming = 0;
696                 while(_missile)
697                 {
698                         if(_missile.flags & FL_PROJECTILE)
699                         if(MISSILE_IS_TRACKING(_missile))
700                         if(vlen(self.origin - _missile.origin) < 2 * autocvar_g_vehicle_raptor_flare_range)
701                                 ++_incomming;
702
703                         _missile = _missile.chain;
704                 }
705
706                 if(_incomming)
707                         sound(self, CH_PAIN_SINGLE, SND_VEH_MISSILE_ALARM, VOL_BASE, ATTEN_NONE);
708
709                 self.bomb1.cnt = time + 1;
710         }
711
712
713         VEHICLE_UPDATE_PLAYER(player, health, raptor);
714         VEHICLE_UPDATE_PLAYER(player, energy, raptor);
715         if(self.vehicle_flags & VHF_HASSHIELD)
716                 VEHICLE_UPDATE_PLAYER(player, shield, raptor);
717
718         player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
719
720         setself(player);
721         return 1;
722 }
723
724 float raptor_takeoff()
725 {SELFPARAM();
726         entity player, raptor;
727
728         player = self;
729         raptor = self.vehicle;
730         setself(raptor);
731
732         self.nextthink = time;
733         CSQCMODEL_AUTOUPDATE(self);
734         self.nextthink = 0; // will this work?
735
736         if(self.sound_nexttime < time)
737         {
738                 self.sound_nexttime = time + 7.955812; //soundlength("vehicles/raptor_fly.wav");
739                 sound (self, CH_TRIGGER_SINGLE, SND_VEH_RAPTOR_SPEED, VOL_VEHICLEENGINE, ATTEN_NORM);
740         }
741
742         // Takeoff sequense
743         if(raptor.frame < 25)
744         {
745                 raptor.frame += 25 / (autocvar_g_vehicle_raptor_takeofftime / sys_frametime);
746                 raptor.velocity_z = min(raptor.velocity_z * 1.5, 256);
747                 self.bomb1.gun1.avelocity_y = 90 + ((raptor.frame / 25) * 25000);
748                 self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y;
749                 player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
750
751                 setorigin(player, raptor.origin + '0 0 32');
752         }
753         else
754                 player.PlayerPhysplug = raptor_frame;
755
756         if(self.vehicle_flags  & VHF_SHIELDREGEN)
757                 vehicles_regen(raptor.dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime, true);
758
759         if(self.vehicle_flags  & VHF_HEALTHREGEN)
760                 vehicles_regen(raptor.dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime, false);
761
762         if(self.vehicle_flags  & VHF_ENERGYREGEN)
763                 vehicles_regen(raptor.cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime, false);
764
765
766         raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip);
767         player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100);
768         player.vehicle_ammo2 = (player.vehicle_reload2 == 100) ? 100 : 0;
769
770         VEHICLE_UPDATE_PLAYER(player, health, raptor);
771         VEHICLE_UPDATE_PLAYER(player, energy, raptor);
772         if(self.vehicle_flags & VHF_HASSHIELD)
773                 VEHICLE_UPDATE_PLAYER(player, shield, raptor);
774
775         player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
776         setself(player);
777         return 1;
778 }
779
780 void raptor_blowup()
781 {SELFPARAM();
782         self.deadflag   = DEAD_DEAD;
783         self.vehicle_exit(VHEF_NORMAL);
784         RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_VH_RAPT_DEATH, world);
785
786         self.alpha                = -1;
787         self.movetype      = MOVETYPE_NONE;
788         self.effects            = EF_NODRAW;
789         self.colormod      = '0 0 0';
790         self.avelocity    = '0 0 0';
791         self.velocity      = '0 0 0';
792
793         setorigin(self, self.pos1);
794         self.touch = func_null;
795         self.nextthink = 0;
796 }
797
798 void raptor_diethink()
799 {SELFPARAM();
800         if(time >= self.wait)
801                 self.think = raptor_blowup;
802
803         if(random() < 0.05)
804         {
805                 sound (self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
806                 Send_Effect(EFFECT_EXPLOSION_SMALL, randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
807         }
808         self.nextthink = time;
809
810         CSQCMODEL_AUTOUPDATE(self);
811 }
812
813 // If we dont do this ever now and then, the raptors rotors
814 // stop working, presumably due to angle overflow. cute.
815 void raptor_rotor_anglefix()
816 {SELFPARAM();
817         self.gun1.angles_y = anglemods(self.gun1.angles_y);
818         self.gun2.angles_y = anglemods(self.gun2.angles_y);
819         self.nextthink = time + 15;
820 }
821
822 float raptor_impulse(float _imp)
823 {SELFPARAM();
824         switch(_imp)
825         {
826                 case 1:
827                 case 230:
828                         self.vehicle.vehicle_weapon2mode = RSM_BOMB;
829                         CSQCVehicleSetup(self, 0);
830                         return true;
831                 case 2:
832                 case 231:
833                         self.vehicle.vehicle_weapon2mode = RSM_FLARE;
834                         CSQCVehicleSetup(self, 0);
835                         return true;
836
837                 case 10:
838                 case 15:
839                 case 18:
840                         self.vehicle.vehicle_weapon2mode += 1;
841                         if(self.vehicle.vehicle_weapon2mode > RSM_LAST)
842                                 self.vehicle.vehicle_weapon2mode = RSM_FIRST;
843
844                         CSQCVehicleSetup(self, 0);
845                         return true;
846                 case 11:
847                 case 12:
848                 case 16:
849                 case 19:
850                         self.vehicle.vehicle_weapon2mode -= 1;
851                         if(self.vehicle.vehicle_weapon2mode < RSM_FIRST)
852                                 self.vehicle.vehicle_weapon2mode = RSM_LAST;
853
854                         CSQCVehicleSetup(self, 0);
855                         return true;
856
857                 /*
858                 case 17: // toss gun, could be used to exit?
859                         break;
860                 case 20: // Manual minigun reload?
861                         break;
862                 */
863         }
864         return false;
865 }
866
867 void spawnfunc_vehicle_raptor()
868 {SELFPARAM();
869         if(!autocvar_g_vehicle_raptor) { remove(self); return; }
870         if(!vehicle_initialize(VEH_RAPTOR, false)) { remove(self); return; }
871 }
872
873                 METHOD(Raptor, vr_impact, bool(Raptor thisveh))
874                 {
875                         if(autocvar_g_vehicle_raptor_bouncepain)
876                                 vehicles_impact(autocvar_g_vehicle_raptor_bouncepain_x, autocvar_g_vehicle_raptor_bouncepain_y, autocvar_g_vehicle_raptor_bouncepain_z);
877
878                         return true;
879                 }
880                 METHOD(Raptor, vr_enter, bool(Raptor thisveh))
881                 {
882                         self.vehicle_weapon2mode = RSM_BOMB;
883                         self.owner.PlayerPhysplug = raptor_takeoff;
884                         self.movetype      = MOVETYPE_BOUNCEMISSILE;
885                         self.solid                = SOLID_SLIDEBOX;
886                         self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_raptor_health) * 100;
887                         self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_raptor_shield) * 100;
888                         self.velocity_z = 1; // Nudge upwards to takeoff sequense can work.
889                         self.tur_head.exteriormodeltoclient = self.owner;
890
891                         self.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
892                         self.lip   = time;
893
894                         if(self.owner.flagcarried)
895                            setorigin(self.owner.flagcarried, '-20 0 96');
896
897                         CSQCVehicleSetup(self.owner, 0);
898                         return true;
899                 }
900                 METHOD(Raptor, vr_think, bool(Raptor thisveh))
901                 {
902                         return true;
903                 }
904                 METHOD(Raptor, vr_death, bool(Raptor thisveh))
905                 {
906                         self.health                             = 0;
907                         self.event_damage               = func_null;
908                         self.solid                              = SOLID_CORPSE;
909                         self.takedamage                 = DAMAGE_NO;
910                         self.deadflag                   = DEAD_DYING;
911                         self.movetype                   = MOVETYPE_BOUNCE;
912                         self.think                              = raptor_diethink;
913                         self.nextthink                  = time;
914                         self.wait                               = time + 5 + (random() * 5);
915
916                         Send_Effect(EFFECT_EXPLOSION_MEDIUM, findbetterlocation (self.origin, 16), '0 0 0', 1);
917
918                         self.velocity_z += 600;
919
920                         self.avelocity = '0 0.5 1' * (random() * 400);
921                         self.avelocity -= '0 0.5 1' * (random() * 400);
922
923                         self.colormod = '-0.5 -0.5 -0.5';
924                         self.touch = raptor_blowup;
925                         return true;
926                 }
927                 METHOD(Raptor, vr_spawn, bool(Raptor thisveh))
928                 {
929                         if(!self.gun1)
930                         {
931                                 entity spinner;
932                                 vector ofs;
933
934                                 //FIXME: Camera is in a bad place in HUD model.
935                                 //setorigin(self.vehicle_viewport, '25 0 5');
936
937                                 self.vehicles_impulse   = raptor_impulse;
938
939                                 self.frame = 0;
940
941                                 self.bomb1 = spawn();
942                                 self.bomb2 = spawn();
943                                 self.gun1  = spawn();
944                                 self.gun2  = spawn();
945
946                                 setmodel(self.bomb1, MDL_VEH_RAPTOR_CB_FOLDED);
947                                 setmodel(self.bomb2, MDL_VEH_RAPTOR_CB_FOLDED);
948                                 setmodel(self.gun1, MDL_VEH_RAPTOR_GUN);
949                                 setmodel(self.gun2, MDL_VEH_RAPTOR_GUN);
950                                 setmodel(self.tur_head, MDL_VEH_RAPTOR_TAIL);
951
952                                 setattachment(self.bomb1, self, "bombmount_left");
953                                 setattachment(self.bomb2, self, "bombmount_right");
954                                 setattachment(self.tur_head, self,"root");
955
956                                 // FIXMODEL Guns mounts to angled bones
957                                 self.bomb1.angles = self.angles;
958                                 self.angles = '0 0 0';
959                                 // This messes up gun-aim, so work arround it.
960                                 //setattachment(self.gun1, self, "gunmount_left");
961                                 ofs = gettaginfo(self, gettagindex(self, "gunmount_left"));
962                                 ofs -= self.origin;
963                                 setattachment(self.gun1, self, "");
964                                 setorigin(self.gun1, ofs);
965
966                                 //setattachment(self.gun2, self, "gunmount_right");
967                                 ofs = gettaginfo(self, gettagindex(self, "gunmount_right"));
968                                 ofs -= self.origin;
969                                 setattachment(self.gun2, self, "");
970                                 setorigin(self.gun2, ofs);
971
972                                 self.angles = self.bomb1.angles;
973                                 self.bomb1.angles = '0 0 0';
974
975                                 spinner = spawn();
976                                 spinner.owner = self;
977                                 setmodel(spinner, MDL_VEH_RAPTOR_PROP);
978                                 setattachment(spinner, self, "engine_left");
979                                 spinner.movetype = MOVETYPE_NOCLIP;
980                                 spinner.avelocity = '0 90 0';
981                                 self.bomb1.gun1 = spinner;
982
983                                 spinner = spawn();
984                                 spinner.owner = self;
985                                 setmodel(spinner, MDL_VEH_RAPTOR_PROP);
986                                 setattachment(spinner, self, "engine_right");
987                                 spinner.movetype = MOVETYPE_NOCLIP;
988                                 spinner.avelocity = '0 -90 0';
989                                 self.bomb1.gun2 = spinner;
990
991                                 // Sigh.
992                                 self.bomb1.think = raptor_rotor_anglefix;
993                                 self.bomb1.nextthink = time;
994
995                                 self.mass                          = 1 ;
996                         }
997
998                         self.frame                = 0;
999                         self.vehicle_health = autocvar_g_vehicle_raptor_health;
1000                         self.vehicle_shield = autocvar_g_vehicle_raptor_shield;
1001                         self.movetype      = MOVETYPE_TOSS;
1002                         self.solid                = SOLID_SLIDEBOX;
1003                         self.vehicle_energy = 1;
1004
1005                         self.PlayerPhysplug = raptor_frame;
1006
1007                         self.bomb1.gun1.avelocity_y = 90;
1008                         self.bomb1.gun2.avelocity_y = -90;
1009
1010                         self.delay = time;
1011
1012                         self.bouncefactor = autocvar_g_vehicle_raptor_bouncefactor;
1013                         self.bouncestop = autocvar_g_vehicle_raptor_bouncestop;
1014                         self.damageforcescale = 0.25;
1015                         self.vehicle_health = autocvar_g_vehicle_raptor_health;
1016                         self.vehicle_shield = autocvar_g_vehicle_raptor_shield;
1017                         return true;
1018                 }
1019                 METHOD(Raptor, vr_setup, bool(Raptor thisveh))
1020                 {
1021                         if(autocvar_g_vehicle_raptor_shield)
1022                                 self.vehicle_flags |= VHF_HASSHIELD;
1023
1024                         if(autocvar_g_vehicle_raptor_shield_regen)
1025                                 self.vehicle_flags |= VHF_SHIELDREGEN;
1026
1027                         if(autocvar_g_vehicle_raptor_health_regen)
1028                                 self.vehicle_flags |= VHF_HEALTHREGEN;
1029
1030                         if(autocvar_g_vehicle_raptor_energy_regen)
1031                                 self.vehicle_flags |= VHF_ENERGYREGEN;
1032
1033                         self.vehicle_exit = raptor_exit;
1034                         self.respawntime = autocvar_g_vehicle_raptor_respawntime;
1035                         self.vehicle_health = autocvar_g_vehicle_raptor_health;
1036                         self.vehicle_shield = autocvar_g_vehicle_raptor_shield;
1037                         self.max_health = self.vehicle_health;
1038
1039                         return true;
1040                 }
1041                 METHOD(Raptor, vr_precache, bool(Raptor thisveh))
1042                 {
1043                         return true;
1044                 }
1045
1046 #endif // SVQC
1047 #ifdef CSQC
1048
1049 void RaptorCBShellfragDraw()
1050 {SELFPARAM();
1051         if(wasfreed(self))
1052                 return;
1053
1054         Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
1055         self.move_avelocity += randomvec() * 15;
1056         self.renderflags = 0;
1057
1058         if(self.cnt < time)
1059                 self.alpha = bound(0, self.nextthink - time, 1);
1060
1061         if(self.alpha < ALPHA_MIN_VISIBLE)
1062                 remove(self);
1063 }
1064
1065 void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
1066 {SELFPARAM();
1067         entity sfrag;
1068
1069         sfrag = spawn();
1070         setmodel(sfrag, MDL_VEH_RAPTOR_CB_FRAGMENT);
1071         setorigin(sfrag, _org);
1072
1073         sfrag.move_movetype = MOVETYPE_BOUNCE;
1074         sfrag.gravity = 0.15;
1075         sfrag.solid = SOLID_CORPSE;
1076
1077         sfrag.draw = RaptorCBShellfragDraw;
1078
1079         sfrag.move_origin = sfrag.origin = _org;
1080         sfrag.move_velocity = _vel;
1081         sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity);
1082         sfrag.angles = self.move_angles = _ang;
1083
1084         sfrag.move_time = time;
1085         sfrag.damageforcescale = 4;
1086
1087         sfrag.nextthink = time + 3;
1088         sfrag.cnt = time + 2;
1089         sfrag.alpha = 1;
1090         sfrag.drawmask = MASK_NORMAL;
1091 }
1092
1093                 METHOD(Raptor, vr_hud, bool(Raptor thisveh))
1094                 {
1095                         string crosshair;
1096
1097                         switch(weapon2mode)
1098                         {
1099                                 case RSM_FLARE: crosshair = vCROSS_RAIN;  break;
1100                                 case RSM_BOMB:  crosshair = vCROSS_BURST; break;
1101                                 default:        crosshair = vCROSS_BURST;
1102                         }
1103
1104                         Vehicles_drawHUD(VEH_RAPTOR.m_icon, "vehicle_raptor_weapon1", "vehicle_raptor_weapon2",
1105                                                          "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color,
1106                                                          "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color,
1107                                                          crosshair);
1108                         return true;
1109                 }
1110                 METHOD(Raptor, vr_setup, bool(Raptor thisveh))
1111                 {
1112                         AuxiliaryXhair[1].axh_image = vCROSS_LOCK;
1113                         return true;
1114                 }
1115                 METHOD(Raptor, vr_precache, bool(Raptor thisveh))
1116                 {
1117                         return true;
1118                 }
1119
1120 #endif // CSQC
1121 #endif // REGISTER_VEHICLE