]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/vehicles/raptor.qc
Better defaults, fix aux xhair, add aux xhair to raptor.
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / vehicles / raptor.qc
1 #define RAPTOR_MIN '-80 -80 0'
2 #define RAPTOR_MAX '80 80 70'
3
4 float autocvar_g_vehicle_raptor_respawntime;
5
6 float autocvar_g_vehicle_raptor_movestyle;
7 float autocvar_g_vehicle_raptor_turnspeed;
8 float autocvar_g_vehicle_raptor_pitchspeed;
9 float autocvar_g_vehicle_raptor_pitchlimit;
10
11 float autocvar_g_vehicle_raptor_speed_forward;
12 float autocvar_g_vehicle_raptor_speed_strafe;
13 float autocvar_g_vehicle_raptor_speed_up;
14 float autocvar_g_vehicle_raptor_speed_down;
15
16 float autocvar_g_vehicle_raptor_bomblets;
17 float autocvar_g_vehicle_raptor_bomblet_alt;
18 float autocvar_g_vehicle_raptor_bomblet_time;
19 float autocvar_g_vehicle_raptor_bomblet_damage;
20 float autocvar_g_vehicle_raptor_bomblet_spread;
21 float autocvar_g_vehicle_raptor_bomblet_edgedamage;
22 float autocvar_g_vehicle_raptor_bomblet_radius;
23 float autocvar_g_vehicle_raptor_bomblet_force;
24 float autocvar_g_vehicle_raptor_bombs_refire;
25
26 float autocvar_g_vehicle_raptor_guns_turnspeed;
27 float autocvar_g_vehicle_raptor_guns_turnlimit;
28 float autocvar_g_vehicle_raptor_guns_pitchlimit_up;
29 float autocvar_g_vehicle_raptor_guns_pitchlimit_down;
30
31 float autocvar_g_vehicle_raptor_cannon_cost;
32 float autocvar_g_vehicle_raptor_cannon_damage;
33 float autocvar_g_vehicle_raptor_cannon_radius;
34 float autocvar_g_vehicle_raptor_cannon_refire;
35 float autocvar_g_vehicle_raptor_cannon_speed;
36 float autocvar_g_vehicle_raptor_cannon_spread;
37
38
39 float autocvar_g_vehicle_raptor_energy;
40 float autocvar_g_vehicle_raptor_energy_regen;
41 float autocvar_g_vehicle_raptor_energy_regen_pause;
42
43 float autocvar_g_vehicle_raptor_health;
44 float autocvar_g_vehicle_raptor_health_regen;
45 float autocvar_g_vehicle_raptor_health_regen_pause;
46
47 float autocvar_g_vehicle_raptor_shield;
48 float autocvar_g_vehicle_raptor_shield_regen;
49 float autocvar_g_vehicle_raptor_shield_regen_pause;
50
51 void raptor_spawn();
52 //void raptor_return();
53 float raptor_frame();
54 //float raptor_takeoff();
55
56 .entity bomb1;
57 .entity bomb2;
58
59 float raptor_altitude(float amax)
60 {
61         tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * amax), TRUE, self);
62     return vlen(self.origin - trace_endpos);
63 }
64
65 void raptor_bombs_return()
66 {
67     self.owner.bomb1.alpha = 1;
68     self.owner.bomb2.alpha = 1;
69     remove(self);
70 }
71
72 void raptor_bomblet_boom()
73 {
74     if(other == self.owner || other.owner == self.owner)
75         return;
76
77     pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
78     RadiusDamage (self, self.enemy, autocvar_g_vehicle_raptor_bomblet_damage,
79                                     autocvar_g_vehicle_raptor_bomblet_edgedamage,
80                                     autocvar_g_vehicle_raptor_bomblet_radius, world,
81                                     autocvar_g_vehicle_raptor_bomblet_force, DEATH_SBROCKET, world);
82     remove(self);
83 }
84
85 void raptor_bomb_burst()
86 {
87     self.angles = vectoangles(self.velocity);
88
89
90     if(autocvar_g_vehicle_raptor_bomblet_alt)
91     {
92         self.nextthink = time;
93         // FIXME: this can make bombs stic forever if fierd at low altitude and land close to vehicle.
94         traceline(self.origin, self.origin + (normalize(self.velocity) * autocvar_g_vehicle_raptor_bomblet_alt), MOVE_NORMAL, self);
95         if(trace_fraction == 1.0)
96             return;
97
98         if(vlen(self.origin - self.owner.origin) < autocvar_g_vehicle_raptor_bomblet_radius)
99             return;
100     }
101
102     entity bomblet;
103     float i,v;
104     vector d;
105
106     v = vlen(self.velocity);
107     d = normalize(self.velocity);
108     pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
109
110     for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i)
111     {
112
113         bomblet = spawn();
114         setorigin(bomblet,self.origin);
115
116         setmodel(bomblet,"models/vehicles/raptor_bomb.dpm");
117         bomblet.scale = 0.5;
118
119         bomblet.solid       = SOLID_TRIGGER;
120         bomblet.movetype    = MOVETYPE_BOUNCE;
121         bomblet.touch       = raptor_bomblet_boom;
122         bomblet.think       = raptor_bomblet_boom;
123         bomblet.nextthink   = time + 5;
124         bomblet.owner       = self.owner;
125
126         bomblet.modelflags = MF_GRENADE;
127
128         bomblet.velocity = normalize(d + (randomvec() * autocvar_g_vehicle_raptor_bomblet_spread)) * v;
129
130         bomblet.angles = vectoangles(bomblet.velocity);
131     }
132
133     remove(self);
134 }
135
136 void raptor_bomb_touch()
137 {
138     raptor_bomb_burst();
139 }
140
141 void raptor_bombdrop()
142 {
143     entity bomb_1, bomb_2;
144
145     self.bomb1.alpha = 0.25;
146     self.bomb2.alpha = 0.25;
147
148     bomb_1 = spawn();
149     bomb_2 = spawn();
150
151     setmodel(bomb_1,"models/vehicles/raptor_bomb.dpm");
152     setmodel(bomb_2,"models/vehicles/raptor_bomb.dpm");
153
154     setorigin(bomb_1, gettaginfo(self, gettagindex(self, "bombmount_left")));
155     setorigin(bomb_2, gettaginfo(self, gettagindex(self, "bombmount_right")));
156
157     bomb_1.movetype  = bomb_2.movetype   = MOVETYPE_TOSS;
158     bomb_1.velocity  = bomb_2.velocity   = self.velocity;
159     bomb_1.touch     = bomb_2.touch      = raptor_bomb_touch;
160     bomb_1.think     = bomb_2.think      = raptor_bomb_burst;
161
162     if(autocvar_g_vehicle_raptor_bomblet_alt)
163         bomb_1.nextthink = bomb_2.nextthink  = time;
164     else
165         bomb_1.nextthink = bomb_2.nextthink  = time + autocvar_g_vehicle_raptor_bomblet_time;
166
167     bomb_1.avelocity = bomb_2.avelocity  = '0 0 180';
168     bomb_1.owner     = bomb_2.owner      = self;
169     bomb_1.enemy     = bomb_2.enemy      = self.owner;
170     bomb_1.angles    = bomb_2.angles     = self.angles;
171     bomb_1.solid     = bomb_2.solid      = SOLID_BBOX;
172
173     bomb_1 = spawn();
174     bomb_1.owner = self;
175     bomb_1.think = raptor_bombs_return;
176     bomb_1.nextthink = time + autocvar_g_vehicle_raptor_bombs_refire;
177 }
178
179 void raptor_bolt_explode()
180 {
181         PROJECTILE_TOUCH;
182     pointparticles(particleeffectnum("raptor_cannon_impact"), findbetterlocation (self.origin, 8), trace_plane_normal * 1000, 1);
183     RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_cannon_damage, 0, autocvar_g_vehicle_raptor_cannon_radius, world, 150, DEATH_WAKIGUN, world);
184     sound (self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
185     remove (self);
186 }
187
188 void raptor_fire_cannon(entity gun, string tagname)
189 {
190     entity bolt;
191
192     bolt = spawn();
193
194     PROJECTILE_MAKETRIGGER(bolt);
195     sound (gun, CHAN_WEAPON, "weapons/lasergun_fire.wav", VOL_BASE, ATTN_NORM);
196     setorigin(bolt, gettaginfo(gun, gettagindex(gun, tagname)));
197
198     bolt.movetype        = MOVETYPE_FLYMISSILE;
199     bolt.flags           = FL_PROJECTILE | FL_NOTARGET;
200     bolt.owner           = self;
201     bolt.realowner       = self.owner;
202     bolt.touch           = raptor_bolt_explode;
203     bolt.think           = raptor_bolt_explode;
204     bolt.nextthink       = time + 9;
205     bolt.bot_dodge       = TRUE;
206     bolt.bot_dodgerating = autocvar_g_vehicle_raptor_cannon_damage;
207     bolt.velocity        = normalize(v_forward + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed;
208
209     pointparticles(particleeffectnum("raptor_cannon_muzzleflash"), bolt.origin, bolt.velocity, 1);
210
211     CSQCProjectile(bolt, TRUE, PROJECTILE_CRYLINK   , TRUE);
212 }
213
214 void raptor_think()
215 {
216 }
217
218 void raptor_enter()
219 {
220     self.movetype   = MOVETYPE_BOUNCEMISSILE;
221     self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_raptor_health);
222     self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_raptor_shield);
223     self.velocity_z = 1;
224 }
225
226 void raptor_land()
227 {
228     float hgt;
229
230     hgt = raptor_altitude(512);
231     self.velocity = (self.velocity * 0.9) + ('0 0 -1800' * (hgt / 256) * sys_frametime);
232     self.angles_x *= 0.95;
233     self.angles_z *= 0.95;
234
235     if(hgt < 128)
236         if(self.frame != 0)
237             self.frame = max(self.frame - 0.25, 0);
238
239     self.bomb1.gun1.avelocity_y = 90 + ((self.frame / 25) * 2000);
240     self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y;
241
242     if(hgt < 16)
243     {
244         self.movetype   = MOVETYPE_BOUNCE;
245         self.think      = raptor_think;
246     }
247
248     self.nextthink  = time;
249 }
250
251 void raptor_exit(float eject)
252 {
253
254     if(self.deadflag == DEAD_NO)
255     {
256         vehicles_setreturn(autocvar_g_vehicle_raptor_respawntime, raptor_spawn);
257         self.think      = raptor_land;
258         self.nextthink  = time;
259     }
260
261     if not (self.owner)
262         return;
263
264     Release_AuxiliaryXhair(self.owner);
265         makevectors(self.angles);
266         if(eject)
267         {
268             setorigin(self.owner,self.origin + v_forward * 100 + '0 0 64');
269             self.owner.velocity = (v_up + v_forward * 0.25) * 750;
270         }
271         else
272         setorigin(self.owner,self.origin - v_forward * 200 + '0 0 64');
273
274     self.owner = world;
275 }
276
277 float raptor_frame()
278 {
279     entity player, raptor;
280     float ftmp, ftmp2;
281     vector df;
282
283     player = self;
284     raptor   = self.vehicle;
285     self    = raptor;
286
287     if(player.BUTTON_USE)
288     {
289         self = raptor;
290         vehicles_exit(VHEF_NORMAL);
291         self = player;
292         return 0;
293     }
294
295     if(raptor.deadflag != DEAD_NO)
296     {
297         self = player;
298         player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
299         return 1;
300     }
301
302     // Takeoff sequense
303     if(raptor.frame < 25)
304     {
305         raptor.frame += 0.25;
306         raptor.velocity_z = min(raptor.velocity_z * 1.5, 256);
307         self.bomb1.gun1.avelocity_y = 90 + ((raptor.frame / 25) * 2000);
308         self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y;
309         return 1;
310     }
311
312     raptor.angles_x *= -1;
313     // Rotate Body
314     ftmp = autocvar_g_vehicle_raptor_turnspeed * sys_frametime;
315     ftmp = bound(-ftmp, shortangle_f(player.v_angle_y - raptor.angles_y, raptor.angles_y), ftmp);
316
317     // Turn
318     raptor.angles_y = anglemods(raptor.angles_y + ftmp);
319
320     // Pitch Body
321     ftmp = autocvar_g_vehicle_raptor_pitchspeed  * sys_frametime;
322     ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - raptor.angles_x, raptor.angles_x), ftmp);
323
324     raptor.angles_x = bound(-autocvar_g_vehicle_raptor_pitchlimit, anglemods(raptor.angles_x + ftmp), autocvar_g_vehicle_raptor_pitchlimit);
325     raptor.angles_x *= -1;
326
327     if(autocvar_g_vehicle_raptor_movestyle == 1)
328     {
329         ftmp = raptor.angles_z;
330         raptor.angles_z = 0;
331         ftmp2 = raptor.angles_x;
332         raptor.angles_x = 0;
333         fixedmakevectors(raptor.angles);
334         raptor.angles_z = ftmp;
335         raptor.angles_x = ftmp2;
336     }
337     else
338         makevectors(player.v_angle);
339
340     df = raptor.velocity * -1;
341
342     if(player.movement_x != 0)
343     {
344         if(player.movement_x > 0)
345             df += v_forward  * autocvar_g_vehicle_raptor_speed_forward;
346         else if(player.movement_x < 0)
347             df -= v_forward  * autocvar_g_vehicle_raptor_speed_forward;
348     }
349
350     if(player.movement_y != 0)
351     {
352         if(player.movement_y < 0)
353             df -= v_right * autocvar_g_vehicle_raptor_speed_strafe;
354         else if(player.movement_y > 0)
355             df += v_right * autocvar_g_vehicle_raptor_speed_strafe;
356
357         raptor.angles_z = bound(-30,raptor.angles_z + (player.movement_y / autocvar_g_vehicle_raptor_speed_strafe),30);
358     }
359     else
360     {
361         raptor.angles_z *= 0.95;
362         if(raptor.angles_z >= -1 && raptor.angles_z <= -1)
363             raptor.angles_z = 0;
364     }
365
366     if(player.BUTTON_CROUCH)
367         df -=   v_up * autocvar_g_vehicle_raptor_speed_down;
368     else if (player.BUTTON_JUMP)
369         df +=  v_up * autocvar_g_vehicle_raptor_speed_up;
370
371     raptor.velocity  += df * frametime;
372     player.velocity = player.movement  = raptor.velocity;
373     setorigin(player,raptor.origin + '0 0 32');
374
375     // Aim the gunz
376     crosshair_trace(player);
377     ftmp2 = autocvar_g_vehicle_raptor_guns_turnspeed * frametime;
378     ftmp = -ftmp2;
379
380     vector vf, ad;
381     // Gun1
382     df = gettaginfo(raptor.gun1, gettagindex(raptor.gun1, "fire1"));
383     ad += df;
384     vf += v_forward;
385     df = vectoangles(normalize(trace_endpos - df)); // Find the direction & angle
386     df = shortangle_vxy(df - (raptor.angles + raptor.gun1.angles), raptor.angles + raptor.gun1.angles);     // Find aim offset
387     // Bind to aimspeed
388     df_x = bound(ftmp, df_x, ftmp2);
389     df_y = bound(ftmp, df_y, ftmp2);
390     // Bind to limts
391     raptor.gun1.angles_x = bound(-autocvar_g_vehicle_raptor_guns_pitchlimit_down, df_x + raptor.gun1.angles_x, autocvar_g_vehicle_raptor_guns_pitchlimit_up);
392     raptor.gun1.angles_y = bound(-autocvar_g_vehicle_raptor_guns_turnlimit,  df_y + raptor.gun1.angles_y, autocvar_g_vehicle_raptor_guns_turnlimit);
393
394     //Gun 2
395     df = gettaginfo(raptor.gun2, gettagindex(raptor.gun2, "fire1"));
396     ad += df;
397     vf += v_forward;
398     df = vectoangles(normalize(trace_endpos - df)); // Find the direction & angle
399     df = shortangle_vxy(df - (raptor.angles + raptor.gun2.angles), raptor.angles + raptor.gun2.angles);     // Find aim offset
400     // Bind to aimspeed
401     df_x = bound(ftmp, df_x, ftmp2);
402     df_y = bound(ftmp, df_y, ftmp2);
403     // Bind to limts
404     raptor.gun2.angles_x = bound(-autocvar_g_vehicle_raptor_guns_pitchlimit_down, df_x + raptor.gun2.angles_x, autocvar_g_vehicle_raptor_guns_pitchlimit_up);
405     raptor.gun2.angles_y = bound(-autocvar_g_vehicle_raptor_guns_turnlimit,  df_y + raptor.gun2.angles_y, autocvar_g_vehicle_raptor_guns_turnlimit);
406
407
408     ad = ad * 0.5;
409     v_forward = vf * 0.5;
410     traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, raptor);
411     SpawnOrUpdateAuxiliaryXhair(player, trace_endpos);
412
413
414     if(player.BUTTON_ATCK)
415     if(raptor.attack_finished_single <= time)
416     if(raptor.vehicle_energy > autocvar_g_vehicle_raptor_cannon_cost)
417     {
418         raptor_fire_cannon(self.gun1, "fire1");
419         raptor_fire_cannon(self.gun2, "fire1");
420
421         raptor.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost;
422         raptor.attack_finished_single = time + autocvar_g_vehicle_raptor_cannon_refire;
423         self.cnt = time;
424     }
425
426     if(self.vehicle_flags  & VHF_SHIELDREGEN)
427         vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime);
428
429     if(self.vehicle_flags  & VHF_HEALTHREGEN)
430         vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime);
431
432     if(self.vehicle_flags  & VHF_ENERGYREGEN)
433         vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime);
434
435     player.vehicle_energy = raptor.vehicle_energy / autocvar_g_vehicle_raptor_energy;
436
437     if(time > raptor.delay)
438     if(player.BUTTON_ATCK2)
439     {
440         raptor_bombdrop();
441         raptor.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
442         raptor.lip = time;
443     }
444
445     player.vehicle_reload1 = (time - raptor.lip) / (raptor.delay - raptor.lip);
446     VEHICLE_UPDATE_PLAYER(health, raptor);
447
448     if(self.vehicle_flags & VHF_HASSHIELD)
449         VEHICLE_UPDATE_PLAYER(shield, raptor);
450
451     player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
452
453     self = player;
454     return 1;
455 }
456
457 void raptor_touch()
458 {
459     if(self.owner)
460     {
461         if(vlen(self.velocity) == 0)
462             return;
463
464         if(other.classname != "player")
465             return;
466
467         return;
468     }
469
470     if(other.classname != "player")
471         return;
472
473     if(other.deadflag != DEAD_NO)
474         return;
475
476     if(other.vehicle != world)
477         return;
478
479     vehicles_enter();
480 }
481
482 void raptor_blowup()
483 {
484     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
485     pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
486
487     self.deadflag    = DEAD_DEAD;
488     self.vehicle_exit(VHEF_NORMAL);
489     RadiusDamage (self, self, 250, 15, 250, world, 250, DEATH_WAKIBLOWUP, world);
490
491     self.alpha          = -1;
492     self.movetype       = MOVETYPE_NONE;
493     self.effects        = EF_NODRAW;
494     self.colormod       = '0 0 0';
495     self.avelocity      = '0 0 0';
496     self.velocity       = '0 0 0';
497
498     setorigin(self, self.pos1);
499     self.touch = SUB_Null;
500 }
501
502 void raptor_die()
503 {
504     self.health       = 0;
505     self.event_damage = SUB_Null;
506     self.iscreature   = FALSE;
507     self.solid        = SOLID_CORPSE;
508     self.takedamage   = DAMAGE_NO;
509     self.deadflag     = DEAD_DYING;
510     self.movetype     = MOVETYPE_BOUNCE;
511     //self.wait         = time;
512
513     pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
514
515     self.velocity_z += 128;
516
517     if(random() < 0.5)
518         self.avelocity_z  = 45 + random() * 270;
519     else
520         self.avelocity_z  = -45 + random() * -270;
521
522     self.colormod = '-0.5 -0.5 -0.5';
523
524         self.touch     = raptor_blowup;
525         self.think     = raptor_spawn;
526         self.nextthink = time + autocvar_g_vehicle_raptor_respawntime;
527 }
528
529 void raptor_spawn()
530 {
531     self.flags     = FL_NOTARGET;
532     self.effects   = 0;
533
534     self.vehicle_health = autocvar_g_vehicle_raptor_health;
535     self.vehicle_shield = autocvar_g_vehicle_raptor_shield;
536     self.event_damage   = vehicles_damage;
537     self.touch          = raptor_touch;
538     self.iscreature     = TRUE;
539     self.movetype       = MOVETYPE_FLY;
540     self.solid          = SOLID_SLIDEBOX;
541     self.takedamage     = DAMAGE_AIM;
542     self.alpha          = 1;
543         self.colormap       = 1024;
544         self.deadflag       = DEAD_NO;
545     self.bot_attack     = TRUE;
546     self.colormod       = '1 1 1';
547     self.avelocity      = '0 0 0';
548     self.velocity       = '0 0 0';
549     self.vehicle_energy = 1;
550     self.vehicle_hudmodel.viewmodelforclient = self;
551
552     self.bomb1.gun1.avelocity_y = 90;
553     self.bomb1.gun2.avelocity_y = -90;
554     self.frame = 0;
555
556     setorigin(self, self.pos1);
557     self.angles = self.pos2;
558
559     setsize(self, RAPTOR_MIN, RAPTOR_MAX );
560     pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
561     self.delay = time;
562 }
563
564 void raptor_dinit()
565 {
566     entity spinner;
567     vector ofs;
568
569     if not (vehicle_initialize(
570              "Raptor",
571              "models/vehicles/raptor.dpm",
572              "",
573              "models/vehicles/raptor_cockpit.dpm",
574              "", "tag_hud", "tag_camera",
575              HUD_RAPTOR,
576              RAPTOR_MIN, RAPTOR_MAX,
577              FALSE,
578              raptor_spawn, raptor_frame,
579              raptor_enter, raptor_exit,
580              raptor_die,   raptor_think))
581     {
582         remove(self);
583         return;
584     }
585
586     //FIXME: Camera is in a bad place in HUD model.
587     setorigin(self.vehicle_viewport, '10 0 3');
588
589     self.frame = 0;
590
591     self.bomb1 = spawn();
592     self.bomb2 = spawn();
593     self.gun1  = spawn();
594     self.gun2  = spawn();
595
596     setmodel(self.bomb1,"models/vehicles/raptor_bomb.dpm");
597     setmodel(self.bomb2,"models/vehicles/raptor_bomb.dpm");
598     setmodel(self.gun1, "models/vehicles/raptor_gun.dpm");
599     setmodel(self.gun2, "models/vehicles/raptor_gun.dpm");
600
601     setattachment(self.bomb1, self,"bombmount_left");
602     setattachment(self.bomb2, self,"bombmount_right");
603
604     // FIXME Guns mounts to angled bones
605     // This messes up gun-aim, so work arround it.
606     //setattachment(self.gun1, self, "gunmount_left");
607     ofs = gettaginfo(self, gettagindex(self, "gunmount_left"));
608     ofs -= self.origin;
609     setattachment(self.gun1, self, "");
610     setorigin(self.gun1, ofs);
611
612     //setattachment(self.gun2, self, "gunmount_right");
613     ofs = gettaginfo(self, gettagindex(self, "gunmount_right"));
614     ofs -= self.origin;
615     setattachment(self.gun2, self, "");
616     setorigin(self.gun2, ofs);
617
618     spinner = spawn();
619     spinner.owner = self;
620     setmodel(spinner,"models/vehicles/spinner.dpm");
621     setattachment(spinner, self, "engine_left");
622     spinner.movetype = MOVETYPE_NOCLIP;
623     spinner.avelocity = '0 90 0';
624     self.bomb1.gun1 = spinner;
625
626     spinner = spawn();
627     spinner.owner = self;
628     setmodel(spinner,"models/vehicles/spinner.dpm");
629     setattachment(spinner, self, "engine_right");
630     spinner.movetype = MOVETYPE_NOCLIP;
631     spinner.avelocity = '0 -90 0';
632     self.bomb1.gun2 = spinner;
633 }
634
635 void spawnfunc_vehicle_raptor()
636 {
637     vehicles_configcheck("vehicle_raptor.cfg", autocvar_g_vehicle_raptor_health);
638
639     if(autocvar_g_vehicle_raptor_shield)
640         self.vehicle_flags |= VHF_HASSHIELD;
641
642     if(autocvar_g_vehicle_raptor_shield_regen)
643         self.vehicle_flags |= VHF_SHIELDREGEN;
644
645     if(autocvar_g_vehicle_raptor_health_regen)
646         self.vehicle_flags |= VHF_HEALTHREGEN;
647
648     if(autocvar_g_vehicle_raptor_energy_regen)
649         self.vehicle_flags |= VHF_ENERGYREGEN;
650
651     precache_model ("models/vehicles/raptor.dpm");
652     precache_model ("models/vehicles/raptor_gun.dpm");
653     precache_model ("models/vehicles/spinner.dpm");
654     precache_model ("models/vehicles/raptor_cockpit.dpm");
655     precache_model ("models/vehicles/raptor_bomb.dpm");
656
657
658     self.think = raptor_dinit;
659     self.nextthink = time + 1;
660 }