]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/vehicles/racer.qc
now with REAL linear falloff (old formula was wrong)
[divverent/nexuiz.git] / data / qcsrc / server / vehicles / racer.qc
1 #define RACER_MIN '-80 -80 -40'
2 #define RACER_MAX '80 80 40'
3
4 void racer_exit(float eject);
5 void racer_enter();
6
7 float racer_power_air;
8 float racer_power_solid;
9 float racer_power_min;
10 float racer_anglestabilizer;
11 float racer_springlength;
12
13 float racer_healthmax;
14 float racer_shieldmax;
15 float racer_energymax;
16
17 float  jetfromtag_power;
18 float  jetfromtag_normpower;
19 vector jetfromtag_origin;
20 float  jetfromtag_groundcontact;
21
22 .entity ccamera;
23
24 void racer_loadsettings()
25 {
26     racer_power_min         = cvar("g_vehicle_racer_power_min");
27     racer_power_air         = cvar("g_vehicle_racer_power_air");
28     racer_power_solid       = cvar("g_vehicle_racer_power_solid");
29     racer_springlength      = cvar("g_vehicle_racer_springlength");
30     racer_anglestabilizer   = cvar("g_vehicle_racer_anglestabilizer");
31
32     racer_healthmax = cvar("g_vehicle_racer_health");
33     racer_shieldmax = cvar("g_vehicle_racer_shield");
34     racer_energymax = cvar("g_vehicle_racer_energy_max");
35
36 }
37
38 vector racer_jetfromtag(string tagname)
39 {
40     vector force_dir;
41     float  air_frac, solid_frac, air_pwr, solid_pwr;
42
43     jetfromtag_origin = gettaginfo(self,gettagindex(self,tagname));
44     v_forward  = normalize(v_forward) * -1;
45
46     force_dir = jetfromtag_origin - (v_forward  * racer_springlength);
47     traceline(jetfromtag_origin, force_dir, MOVE_NORMAL, self);
48     //te_lightning1(world,jetfromtag_origin, force_dir);
49
50     trace_fraction *= trace_fraction;
51
52     solid_frac = 1 - trace_fraction;
53     air_frac = trace_fraction;
54
55     if (trace_fraction != 1.0)
56         jetfromtag_groundcontact = 1;
57
58     solid_pwr = solid_frac * racer_power_solid;
59     air_pwr   = air_frac * racer_power_air;
60
61     jetfromtag_power     = solid_pwr + air_pwr;
62     jetfromtag_normpower = jetfromtag_power / (racer_power_air + racer_power_solid);
63
64     return v_forward  * max(jetfromtag_power, racer_power_min);
65 }
66
67 void racer_align4point()
68 {
69     vector push_vector;
70     float fl_push, fr_push, bl_push, br_push;
71
72     jetfromtag_groundcontact = 0;
73
74     push_vector = racer_jetfromtag("tag_engine_fr");
75     fr_push = jetfromtag_normpower;
76     traceline(jetfromtag_origin, jetfromtag_origin + self.velocity * frametime, MOVE_NORMAL,self);
77     if(trace_fraction != 1)
78         self.velocity += normalize(self.origin - trace_endpos) * (vlen(self.velocity) * 1.25);
79
80     push_vector += racer_jetfromtag("tag_engine_fl");
81     fl_push = jetfromtag_normpower;
82     traceline(jetfromtag_origin, jetfromtag_origin + self.velocity * frametime, MOVE_NORMAL,self);
83     if(trace_fraction != 1)
84         self.velocity += normalize(self.origin - trace_endpos) * (vlen(self.velocity) * 1.25);
85
86     push_vector += racer_jetfromtag("tag_engine_br");
87     br_push = jetfromtag_normpower;
88     traceline(jetfromtag_origin, jetfromtag_origin + self.velocity * frametime, MOVE_NORMAL,self);
89     if(trace_fraction != 1)
90         self.velocity += normalize(self.origin - trace_endpos) * (vlen(self.velocity) * 1.25);
91
92     push_vector += racer_jetfromtag("tag_engine_bl");
93     bl_push = jetfromtag_normpower;
94     traceline(jetfromtag_origin, jetfromtag_origin + self.velocity * frametime, MOVE_NORMAL,self);
95     if(trace_fraction != 1)
96         self.velocity += normalize(self.origin - trace_endpos) * (vlen(self.velocity) * 1.25);
97
98     self.velocity =  self.velocity + (push_vector * frametime);
99     self.velocity_z -= sv_gravity * frametime;
100
101     push_vector_x = (fl_push - bl_push);
102     push_vector_x += (fr_push - br_push);
103     push_vector_x *= 360;
104
105     push_vector_z = (fr_push - fl_push);
106     push_vector_z += (br_push - bl_push);
107     push_vector_z *= 360;
108
109     if(!push_vector_z)
110         if(self.angles_z > 0)
111             self.angles_z = max(0, self.angles_z - (racer_anglestabilizer * frametime));
112         else
113             self.angles_z = min(0, self.angles_z + (racer_anglestabilizer * frametime));
114     else
115         self.angles_z += push_vector_z * frametime;
116
117     if(!push_vector_x)
118         if(self.angles_x > 0)
119             self.angles_x = max(0, self.angles_x - (racer_anglestabilizer * frametime));
120         else
121             self.angles_x = min(0, self.angles_x + (racer_anglestabilizer * frametime));
122     else
123         self.angles_x += push_vector_x * frametime;
124 }
125
126
127 void racer_bolt_explode()
128 {
129     vector org2;
130
131     org2 = findbetterlocation (self.origin, 8);
132     pointparticles(particleeffectnum("laser_impact"), org2, trace_plane_normal * 1000, 1);
133     RadiusDamage (self, self.realowner, cvar("g_vehicle_racer_laser_damage"), 0, cvar("g_vehicle_racer_laser_radius"), world, 150, DEATH_WAKIGUN, world);
134     sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
135
136     remove (self);
137 }
138
139 void racer_rocket_explode()
140 {
141     vector org2;
142
143     //if not(self.owner)
144     //    self.owner = self.realowner;
145
146     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
147     org2 = findbetterlocation (self.origin, 16);
148     pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
149     RadiusDamage (self, self.realowner ,cvar("g_vehicle_racer_rocket_damage"), 0, cvar("g_vehicle_racer_rocket_radius"), world, 150, DEATH_WAKIROCKET, world);
150
151     remove (self);
152 }
153
154 void racer_fire_cannon(string tagname)
155 {
156     entity bolt;
157
158     bolt = spawn();
159     bolt.solid           = SOLID_BBOX;
160     bolt.movetype        = MOVETYPE_FLYMISSILE;
161     bolt.flags           = FL_PROJECTILE | FL_NOTARGET;
162     bolt.owner           = self;
163     bolt.realowner       = self.owner;
164     bolt.touch           = racer_bolt_explode;
165     bolt.think           = racer_bolt_explode;
166     bolt.nextthink       = time + 9;
167     bolt.bot_dodge       = TRUE;
168     bolt.bot_dodgerating = cvar("g_vehicle_racer_laser_damage");
169     setorigin(bolt, gettaginfo(self,gettagindex(self,tagname)));
170     bolt.velocity = v_forward * cvar("g_vehicle_racer_laser_speed");
171
172     CSQCProjectile(bolt, TRUE, PROJECTILE_LASER, TRUE);
173 }
174
175 void racer_rocket_think()
176 {
177     vector newdir,olddir;
178
179     self.nextthink  = time;
180
181     if ((self.owner.deadflag != DEAD_NO) || (self.cnt < time))
182     {
183         racer_rocket_explode();
184         return;
185     }
186
187     if not (self.realowner.vehicle)
188     {
189         UpdateCSQCProjectile(self);
190         return;
191     }
192
193     self.solid      = SOLID_BBOX;
194     self.touch      = racer_rocket_explode;
195
196     olddir = normalize(self.velocity);
197     newdir = normalize((0.5 * (self.enemy.absmin + self.enemy.absmax)) - self.origin);
198
199     self.velocity = normalize(olddir + newdir * cvar("g_vehicle_spiderbot_rocket_turnrate")) * cvar("g_vehicle_racer_rocket_speed");
200
201     UpdateCSQCProjectile(self);
202 }
203
204 void racer_fire_rocket(string tagname)
205 {
206     entity rocket;
207     dprint("self.owner=",self.owner.netname,"\n");
208
209     rocket = spawn();
210     setsize (rocket, '-1 -1 -1', '1 1 1');
211     rocket.solid           = SOLID_BBOX;
212     rocket.movetype        = MOVETYPE_FLYMISSILE;
213     rocket.flags           = FL_PROJECTILE;
214     rocket.owner           = self;
215     rocket.realowner       = self.owner;
216     rocket.touch           = racer_rocket_explode;
217     rocket.bot_dodge       = TRUE;
218     rocket.bot_dodgerating = cvar("g_vehicle_racer_rocket_damage");
219     setorigin(rocket, gettaginfo(self,gettagindex(self,tagname)));
220
221     if( (self.tur_head.gun1) && (self.tur_head.cnt > time))
222         rocket.enemy = self.tur_head.gun1;
223
224     if(rocket.enemy)
225     {
226         rocket.cnt             = time + 9;
227         rocket.velocity = v_forward * cvar("g_vehicle_racer_rocket_speed");
228         rocket.think = racer_rocket_think;
229         rocket.nextthink = time;
230         CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
231         //dprint("Tracking...", rocket.enemy.netname, " (", rocket.enemy.classname, ")\n");
232     }
233     else
234     {
235         rocket.velocity = v_forward * cvar("g_vehicle_racer_rocket_speed");
236         rocket.think = racer_rocket_explode;
237         rocket.nextthink = time + 9;
238         CSQCProjectile(rocket, TRUE, PROJECTILE_ROCKET, TRUE);
239     }
240 }
241
242 float racer_customizeentityforclient()
243 {
244
245     if(self.deadflag == DEAD_DEAD)
246         return FALSE;
247
248     /*
249     if(other == self.owner)
250         self.alpha = -1;
251     else
252         self.alpha = 1;
253     */
254
255     return TRUE;
256 }
257
258 float racer_pplug()
259 {
260     entity player, racer;
261     float ftmp, ftmp2;
262     vector df;
263
264
265     if(cvar("g_vehicle_racer_reload"))
266     {
267         racer_loadsettings();
268         cvar_set("g_vehicle_racer_reload","0");
269     }
270
271     player          = self;
272     racer           = self.vehicle;
273
274     player.BUTTON_ZOOM = 0;
275     player.BUTTON_CROUCH = 0;
276
277     self = racer;
278
279     if(player.BUTTON_USE)
280     {
281         self = racer;
282         racer_exit(0);
283         self = player;
284         return 0;
285     }
286
287     if(racer.deadflag != DEAD_NO)
288     {
289         self = player;
290         player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
291         return 1;
292     }
293
294     racer_align4point();
295
296     racer.angles_x *= -1;
297     makevectors(racer.angles);
298
299     // Rotate Body
300     ftmp = cvar("g_vehicle_racer_turnspeed") * sys_ticrate;
301     ftmp2 = ftmp * -1;
302
303     ftmp = bound(ftmp2,shortangle_f(player.v_angle_y - racer.angles_y,racer.angles_y),ftmp);
304     ftmp2 = safeangle(racer.angles_y + ftmp);
305
306     // Roll
307     ftmp = bound(-90,shortangle_f(player.v_angle_z + ((racer.angles_y - ftmp2) * cvar("g_vehicle_racer_turnroll")), racer.angles_z),90);
308     ftmp = safeangle(racer.angles_z + ftmp);
309     racer.angles_z = ftmp;
310
311     // Turn
312     racer.angles_y = ftmp2;
313
314     // Pitch Body
315     ftmp = cvar("g_vehicle_racer_pitchspeed") * sys_ticrate;
316     ftmp2 = ftmp * -1;
317
318     ftmp = bound(ftmp2,shortangle_f(player.v_angle_x - racer.angles_x,racer.angles_x),ftmp);
319     racer.angles_x = safeangle(racer.angles_x + ftmp);
320     racer.angles_x *= -1;
321
322
323     if(player.movement_x != 0)
324     {
325         if(player.movement_x > 0)
326             df += v_forward  * cvar("g_vehicle_racer_speed_forward");
327         else if(player.movement_x < 0)
328             df -= v_forward  * cvar("g_vehicle_racer_speed_forward");
329     }
330
331     if(player.movement_y != 0)
332     {
333         if(player.movement_y < 0)
334             df -= v_right * cvar("g_vehicle_racer_speed_strafe");
335         else if(player.movement_y > 0)
336             df += v_right * cvar("g_vehicle_racer_speed_strafe");
337     }
338
339     // limit _z to avoid flying on normal thrust
340     if(df_z > 0)
341         df_z = min(df_z,700);
342
343     // Afterburn
344
345     //if (jetfromtag_groundcontact)
346     if (player.BUTTON_JUMP)
347     if(racer.vehicle_energy >= (cvar("g_vehicle_racer_speed_afterburn_cost")* frametime))
348     {
349         racer.wait = time + cvar("g_vehicle_racer_energy_usepause");
350         racer.vehicle_energy -= cvar("g_vehicle_racer_speed_afterburn_cost") * frametime;
351         df += (v_forward * cvar("g_vehicle_racer_speed_afterburn"));
352     }
353
354     racer.velocity  += df * frametime;
355
356     df = (vlen(racer.velocity) * cvar("g_vehicle_racer_downforce") * v_up) * frametime;
357     racer.velocity  = racer.velocity - df;
358     player.movement = racer.velocity;
359
360     if(cvar("g_vehicle_racer_drag"))
361         racer.velocity  = movelib_dragvec(cvar("g_vehicle_racer_drag"), cvar("g_vehicle_racer_dragexp"));
362
363     if(self.owner.cursor_trace_ent)
364     {
365         //dprint("Lock: ", self.owner.cursor_trace_ent.classname, "\n");
366         //if not (self.tur_head.enemy)
367         //    bprint(self.owner,"Locked: ",
368         self.tur_head.gun1 = self.owner.cursor_trace_ent;
369         self.tur_head.cnt = time + 1;
370     }
371
372     if(player.BUTTON_ATCK)
373     if(time > racer.attack_finished_single)
374     if(racer.vehicle_energy >= cvar("g_vehicle_racer_laser_cost"))
375     {
376         racer.vehicle_energy -= cvar("g_vehicle_racer_laser_cost");
377         racer.wait = time + cvar("g_vehicle_racer_energy_usepause");
378
379         if(racer.cnt)
380         {
381             racer_fire_cannon("tag_fire1");
382             racer.cnt = 0;
383         }
384         else
385         {
386             racer_fire_cannon("tag_fire2");
387             racer.cnt = 1;
388         }
389         racer.attack_finished_single = time + cvar("g_vehicle_racer_laser_refire");
390     }
391
392     if(player.BUTTON_ATCK2)
393     if(time > racer.delay)
394     {
395         racer_fire_rocket("tag_rocket_r");
396         racer_fire_rocket("tag_rocket_l");
397         racer.delay = time + cvar("g_vehicle_racer_rocket_refire");
398         racer.lip = time;
399
400     }
401
402     player.vehicle_reload1 = (time - racer.lip) / (racer.delay-racer.lip);
403     //player.vehicle_energy = racer.vehicle_energy;
404
405     vehicle_stdproc_shiledregen(CCVAR("_shield"), frametime);
406     vehicle_stdproc_healthregen(CCVAR("_health"), frametime);
407
408     if (racer.wait < time)
409         vehicle_stdproc_energyregen(CCVAR("_energy"), frametime);
410     else
411         player.vehicle_energy = (racer.vehicle_energy / CCVAR("_energy"));
412
413     self = player;
414
415     player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
416     setorigin(player,racer.origin + '0 0 32');
417     player.velocity = racer.velocity;
418
419     return 1;
420 }
421
422 void racer_think()
423 {
424     movelib_beak_simple(cvar("g_vehicle_racer_speed_stop"));
425
426     self.nextthink = time;
427 }
428
429 void racer_enter()
430 {
431     self.owner = other;
432
433
434     self.nextthink = 0;
435     self.flags               = 0;
436     self.vehicle_hudmodel.viewmodelforclient = self.owner;
437     self.colormap             = self.owner.colormap;
438
439     self.owner.PlayerPhysplug = racer_pplug;
440     self.owner.takedamage     = DAMAGE_NO;
441     self.owner.event_damage   = SUB_Null;
442     self.owner.vehicle        = self;
443     self.owner.angles = self.angles;
444     self.owner.solid          = SOLID_NOT;
445     self.owner.movetype       = MOVETYPE_NOCLIP;
446     self.owner.alpha          = -1;
447     self.owner.hud            = HUD_WAKIZASHI;
448     self.owner.effects        |= EF_NODRAW;
449     self.owner.view_ofs = '0 0 0';
450
451     self.owner.vehicle_health = (self.vehicle_health / cvar("g_vehicle_racer_health"));
452     self.owner.vehicle_shield = (self.vehicle_shield / cvar("g_vehicle_racer_shield"));
453
454     setorigin(other,self.origin + '0 0 32');
455     other.velocity = self.velocity;
456
457     other.flags &~= FL_ONGROUND;
458     msg_entity = other;
459     WriteByte (MSG_ONE, SVC_SETVIEWPORT);
460     WriteEntity( MSG_ONE, self.vehicle_viewport);
461
462     WriteByte (MSG_ONE, SVC_SETVIEWANGLES); // 10 = SVC_SETVIEWANGLES
463     WriteAngle(MSG_ONE,  self.angles_x * -1);    // tilt
464     WriteAngle(MSG_ONE,  self.angles_y);    // yaw
465     WriteAngle(MSG_ONE,  0);                // roll
466 }
467
468 void racer_exit(float eject)
469 {
470         self.colormap   = 1024;
471         self.flags      = FL_NOTARGET;
472     self.velocity = '0 0 0';
473
474     if not (self.owner)
475         return;
476
477     msg_entity = self.owner;
478     WriteByte (MSG_ONE, SVC_SETVIEWPORT);
479     WriteEntity( MSG_ONE, self.owner);
480
481     WriteByte (MSG_ONE, SVC_SETVIEWANGLES);    // 10 = SVC_SETVIEWANGLES
482     WriteAngle(MSG_ONE,  0);                   // tilt
483     WriteAngle(MSG_ONE,  self.angles_y); // yaw
484     WriteAngle(MSG_ONE,  0);                   // roll
485
486     if (self.deadflag == DEAD_NO)
487     {
488         self.think = racer_think;
489         self.nextthink = time;
490     }
491
492     self.owner.takedamage     = DAMAGE_AIM;
493     self.owner.solid          = SOLID_SLIDEBOX;
494     self.owner.movetype       = MOVETYPE_WALK;
495
496     setsize(self.owner,PL_MIN,PL_MAX);
497
498     self.owner.effects        &~= EF_NODRAW;
499     self.owner.alpha          = 1;
500     self.owner.PlayerPhysplug = SUB_Null;
501     self.owner.vehicle        = world;
502         self.owner.view_ofs       = PL_VIEW_OFS;
503         self.owner.event_damage   = PlayerDamage;
504         self.owner.hud            = HUD_NORMAL;
505         //self.owner.exteriormodeltoclient = self;
506
507
508     self.vehicle_hudmodel.viewmodelforclient = self;
509
510         if(eject)
511         {
512             makevectors(self.angles);
513             setorigin(self.owner,self.origin + v_forward * 100);
514             self.owner.velocity = (v_up + v_forward * 0.25) * 750;
515         }
516         else
517         {
518             self.owner.velocity = (v_forward) * -150;
519         setorigin(self.owner,self.origin - v_forward * 128);
520         }
521
522     self.owner = world;
523 }
524
525 void racer_entercap()
526 {
527     entity oldself;
528     entity oldother;
529
530     oldself = self;
531     oldother = other;
532
533     other = self.enemy;
534     self = self.owner;
535
536     racer_enter();
537
538     other = oldother;
539     self = oldself;
540
541     self.think = SUB_Remove;
542     self.nextthink = time;
543 }
544
545 void racer_touch()
546 {
547     if(self.owner)
548     {
549         if(vlen(self.velocity) == 0)
550             return;
551
552         if(other.classname != "player")
553             return;
554
555         vector a;
556         a = normalize(other.origin - self.origin);
557         a = a - normalize(self.velocity);
558
559         return;
560     }
561
562     if(other.classname != "player")
563         return;
564
565     if(other.deadflag != DEAD_NO)
566         return;
567
568     if(other.vehicle != world)
569         return;
570
571     /*
572     entity entercap;
573     entercap = spawn();
574     entercap.enemy = other;
575     entercap.owner = self;
576     entercap.think = racer_entercap;
577     entercap.nextthink = time;
578     */
579
580     racer_enter();
581 }
582
583 /*
584 float racer_customizeentityforclient()
585 {
586     if(self.deadflag == DEAD_DEAD)
587         return FALSE;
588
589     return TRUE;
590 }
591 */
592
593 void racer_spawn()
594 {
595     self.think = racer_think;
596     self.nextthink = time;
597
598     self.flags      = FL_NOTARGET;
599     self.effects   = 0;
600
601     self.vehicle_health = CCVAR("_health");
602     self.vehicle_shield = CCVAR("_shield");
603
604     self.event_damage = vehicle_stdproc_damage;
605     self.touch      = racer_touch;
606
607     self.iscreature = TRUE;
608     self.scale      = 0.5;
609     self.movetype   = MOVETYPE_FLY;
610     self.solid      = SOLID_SLIDEBOX;
611     self.takedamage = DAMAGE_AIM;
612
613     self.alpha = 1;
614         self.colormap = 1024;
615         self.deadflag    = DEAD_NO;
616     self.bot_attack = TRUE;
617
618     self.vehicle_energy = 1;
619     self.vehicle_hudmodel.viewmodelforclient = self;
620
621     setorigin(self, self.pos1);
622     self.angles = self.pos2;
623
624     setsize(self,RACER_MIN * 0.5,RACER_MAX * 0.5);
625     pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
626     self.delay = time;
627 }
628
629
630 void racer_blowup()
631 {
632
633     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
634     pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
635
636     self.deadflag    = DEAD_DEAD;
637     self.vehicle_exit(VHEF_NORMAL);
638     RadiusDamage (self, self, 250, 15, 250, world, 250, DEATH_WAKIBLOWUP, world);
639
640     self.alpha = -1;
641     self.nextthink  = time + 10;
642     self.think      = racer_spawn;
643     self.movetype   = MOVETYPE_NONE;
644     self.effects    = EF_NODRAW;
645
646     self.avelocity_z  = 0;
647     self.colormod = '0 0 0';
648
649     setorigin(self,self.pos1);
650 }
651
652 void racer_dietouch()
653 {
654     if(self.wait > time)
655         return;
656
657     self.wait = time + 0.75;
658
659     pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
660 }
661
662 void racer_die()
663 {
664     self.health       = 0;
665     self.event_damage = SUB_Null;
666     self.iscreature   = FALSE;
667     self.solid        = SOLID_NOT;
668     self.takedamage   = DAMAGE_NO;
669     self.touch        = racer_dietouch;
670     self.deadflag     = DEAD_DYING;
671     self.movetype     = MOVETYPE_BOUNCE;
672     self.wait = time;
673
674     pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
675
676     self.velocity     += '0 0 128';
677
678     if(random() < 0.5)
679         self.avelocity_z  = 16;
680     else
681         self.avelocity_z  = -16;
682
683     self.colormod = '-0.5 -0.5 -0.5';
684
685         self.think     = racer_blowup;
686         self.nextthink = time + 3;
687 }
688
689 void racer_dinit()
690 {
691
692     if (self.netname == "")
693         self.netname     = "Race PoD";
694
695     self.cvar_basename      = "g_vehicle_racer";
696
697     self.vehicle_viewport   = spawn();
698     self.vehicle_hudmodel   = spawn();
699     //self.ccamera            = spawn();
700
701     setorigin(self, self.origin);
702
703     setmodel(self,"models/vehicles/wakizashi.dpm");
704     setmodel(self.vehicle_hudmodel, "models/vehicles/wakizashi_cockpit.dpm");
705     setmodel (self.vehicle_viewport, "null");
706
707     setattachment(self.vehicle_hudmodel, self, "");
708     setattachment(self.vehicle_viewport, self, "tag_viewport");
709
710     self.vehicle_hudmodel.viewmodelforclient = self;
711     self.customizeentityforclient            = racer_customizeentityforclient;
712
713     self.tur_head     = spawn();
714
715     self.pos1         = self.origin;
716     self.pos2         = self.angles;
717     self.angles       = '0 0 0';
718     self.angles       = self.pos1;
719
720     self.vehicle_die  = racer_die;
721     self.vehicle_exit = racer_exit;
722
723     addstat(STAT_HUD, AS_INT,  hud);
724         addstat(STAT_VEHICLESTAT_HEALTH,  AS_FLOAT, vehicle_health);
725         addstat(STAT_VEHICLESTAT_SHIELD,  AS_FLOAT, vehicle_shield);
726         addstat(STAT_VEHICLESTAT_ENERGY,  AS_FLOAT, vehicle_energy);
727
728         addstat(STAT_VEHICLESTAT_AMMO1,   AS_INT,   vehicle_ammo1);
729         addstat(STAT_VEHICLESTAT_RELOAD1, AS_FLOAT, vehicle_reload1);
730
731         addstat(STAT_VEHICLESTAT_AMMO2,   AS_INT,   vehicle_ammo2);
732         addstat(STAT_VEHICLESTAT_RELOAD2, AS_FLOAT, vehicle_reload2);
733
734     racer_spawn();
735 }
736
737 void spawnfunc_vehicle_racer()
738 {
739     g_turrets_common_precash();
740     racer_loadsettings();
741
742     self.vehicle_flags      = VHF_HASSHIELD | VHF_SHIELDREGEN;
743     precache_model ("models/vehicles/wakizashi.dpm");
744     precache_model ("models/vehicles/wakizashi_cockpit.dpm");
745     precache_model ("models/rocket.md3");
746
747     self.think = racer_dinit;
748     self.nextthink = time + 1;
749 }