1 #ifdef REGISTER_VEHICLE
4 /* function */ v_racer,
5 /* spawnflags */ VHF_DMGSHAKE | VHF_DMGROLL,
6 /* mins,maxs */ '-120 -120 -40' * 0.5, '120 120 40' * 0.5,
7 /* model */ "models/vehicles/wakizashi.dpm",
8 /* head_model */ "null",
9 /* hud_model */ "models/vehicles/wakizashi_cockpit.dpm",
10 /* tags */ "", "", "tag_viewport",
11 /* netname */ "racer",
12 /* fullname */ _("Racer")
16 bool autocvar_g_vehicle_racer;
18 float autocvar_g_vehicle_racer_speed_afterburn;
19 float autocvar_g_vehicle_racer_afterburn_cost;
21 float autocvar_g_vehicle_racer_waterburn_cost;
22 float autocvar_g_vehicle_racer_waterburn_speed;
24 float autocvar_g_vehicle_racer_water_speed_forward;
25 float autocvar_g_vehicle_racer_water_speed_strafe;
27 float autocvar_g_vehicle_racer_pitchlimit = 30;
29 float autocvar_g_vehicle_racer_water_downforce = 0.03;
30 float autocvar_g_vehicle_racer_water_upforcedamper = 15;
32 float autocvar_g_vehicle_racer_anglestabilizer;
33 float autocvar_g_vehicle_racer_downforce;
35 float autocvar_g_vehicle_racer_speed_forward;
36 float autocvar_g_vehicle_racer_speed_strafe;
37 float autocvar_g_vehicle_racer_springlength;
38 float autocvar_g_vehicle_racer_upforcedamper;
39 float autocvar_g_vehicle_racer_friction;
41 float autocvar_g_vehicle_racer_water_time = 5;
43 float autocvar_g_vehicle_racer_hovertype;
44 float autocvar_g_vehicle_racer_hoverpower;
46 float autocvar_g_vehicle_racer_turnroll;
47 float autocvar_g_vehicle_racer_turnspeed;
48 float autocvar_g_vehicle_racer_pitchspeed;
50 float autocvar_g_vehicle_racer_energy;
51 float autocvar_g_vehicle_racer_energy_regen;
52 float autocvar_g_vehicle_racer_energy_regen_pause;
54 float autocvar_g_vehicle_racer_health;
55 float autocvar_g_vehicle_racer_health_regen;
56 float autocvar_g_vehicle_racer_health_regen_pause;
58 float autocvar_g_vehicle_racer_shield;
59 float autocvar_g_vehicle_racer_shield_regen;
60 float autocvar_g_vehicle_racer_shield_regen_pause;
62 float autocvar_g_vehicle_racer_cannon_cost;
63 float autocvar_g_vehicle_racer_cannon_damage;
64 float autocvar_g_vehicle_racer_cannon_radius;
65 float autocvar_g_vehicle_racer_cannon_refire;
66 float autocvar_g_vehicle_racer_cannon_speed;
67 float autocvar_g_vehicle_racer_cannon_spread;
68 float autocvar_g_vehicle_racer_cannon_force;
70 float autocvar_g_vehicle_racer_rocket_accel;
71 float autocvar_g_vehicle_racer_rocket_damage;
72 float autocvar_g_vehicle_racer_rocket_radius;
73 float autocvar_g_vehicle_racer_rocket_force;
74 float autocvar_g_vehicle_racer_rocket_refire;
75 float autocvar_g_vehicle_racer_rocket_speed;
76 float autocvar_g_vehicle_racer_rocket_turnrate;
78 float autocvar_g_vehicle_racer_rocket_locktarget;
79 float autocvar_g_vehicle_racer_rocket_locking_time;
80 float autocvar_g_vehicle_racer_rocket_locking_releasetime;
81 float autocvar_g_vehicle_racer_rocket_locked_time;
82 float autocvar_g_vehicle_racer_rocket_locked_maxangle;
83 float autocvar_g_vehicle_racer_rocket_climbspeed;
85 float autocvar_g_vehicle_racer_respawntime;
87 float autocvar_g_vehicle_racer_blowup_radius;
88 float autocvar_g_vehicle_racer_blowup_coredamage;
89 float autocvar_g_vehicle_racer_blowup_edgedamage;
90 float autocvar_g_vehicle_racer_blowup_forceintensity;
92 float autocvar_g_vehicle_racer_bouncefactor;
93 float autocvar_g_vehicle_racer_bouncestop;
94 vector autocvar_g_vehicle_racer_bouncepain;
96 .float racer_watertime;
98 var vector racer_force_from_tag(string tag_name, float spring_length, float max_power);
100 void racer_align4point(float _delta)
103 float fl_push, fr_push, bl_push, br_push;
105 push_vector = racer_force_from_tag("tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
106 fr_push = force_fromtag_normpower;
107 //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
109 push_vector += racer_force_from_tag("tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
110 fl_push = force_fromtag_normpower;
111 //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
113 push_vector += racer_force_from_tag("tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
114 br_push = force_fromtag_normpower;
115 //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
117 push_vector += racer_force_from_tag("tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
118 bl_push = force_fromtag_normpower;
119 //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
121 self.velocity += push_vector * _delta;
123 float uforce = autocvar_g_vehicle_racer_upforcedamper;
125 int cont = pointcontents(self.origin - '0 0 64');
126 if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
128 uforce = autocvar_g_vehicle_racer_water_upforcedamper;
130 if(self.owner.BUTTON_CROUCH && time < self.air_finished)
131 self.velocity_z += 30;
133 self.velocity_z += 200;
138 if(self.velocity_z > 0)
139 self.velocity_z *= 1 - uforce * _delta;
141 push_vector_x = (fl_push - bl_push);
142 push_vector_x += (fr_push - br_push);
143 push_vector_x *= 360;
145 push_vector_z = (fr_push - fl_push);
146 push_vector_z += (br_push - bl_push);
147 push_vector_z *= 360;
149 // Apply angle diffrance
150 self.angles_z += push_vector_z * _delta;
151 self.angles_x += push_vector_x * _delta;
154 self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
155 self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
158 void racer_fire_cannon(string tagname)
163 v = gettaginfo(self, gettagindex(self, tagname));
164 bolt = vehicles_projectile("wakizashi_gun_muzzleflash", "weapons/lasergun_fire.wav",
165 v, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed,
166 autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force, 0,
167 DEATH_VH_WAKI_GUN, PROJECTILE_WAKICANNON, 0, true, true, self.owner);
169 // Fix z-aim (for chase mode)
170 v = normalize(trace_endpos - bolt.origin);
171 v_forward_z = v_z * 0.5;
172 bolt.velocity = v_forward * autocvar_g_vehicle_racer_cannon_speed;
175 void racer_rocket_groundhugger()
177 vector olddir, newdir;
178 float oldvel, newvel;
180 self.nextthink = time;
182 if(self.owner.deadflag != DEAD_NO || self.cnt < time)
188 if(!self.realowner.vehicle)
190 UpdateCSQCProjectile(self);
194 olddir = normalize(self.velocity);
195 oldvel = vlen(self.velocity);
196 newvel = oldvel + self.lip;
198 tracebox(self.origin, self.mins, self.maxs, self.origin + olddir * 64, MOVE_WORLDONLY,self);
199 if(trace_fraction <= 0.5)
201 // Hitting somethign soon, just speed ahead
202 self.velocity = olddir * newvel;
203 UpdateCSQCProjectile(self);
207 traceline(trace_endpos, trace_endpos - '0 0 64', MOVE_NORMAL, self);
208 if(trace_fraction != 1.0)
210 newdir = normalize(trace_endpos + '0 0 64' - self.origin) * autocvar_g_vehicle_racer_rocket_turnrate;
211 self.velocity = normalize(olddir + newdir) * newvel;
215 self.velocity = olddir * newvel;
216 self.velocity_z -= 1600 * sys_frametime; // 2x grav looks better for this one
219 int cont = pointcontents(self.origin - '0 0 32');
220 if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
221 self.velocity_z += 200;
223 UpdateCSQCProjectile(self);
227 void racer_rocket_tracker()
229 vector olddir, newdir;
230 float oldvel, newvel;
232 self.nextthink = time;
234 if (self.owner.deadflag != DEAD_NO || self.cnt < time)
240 if(!self.realowner.vehicle)
242 UpdateCSQCProjectile(self);
246 olddir = normalize(self.velocity);
247 oldvel = vlen(self.velocity);
248 newvel = oldvel + self.lip;
249 makevectors(vectoangles(olddir));
251 float time_to_impact = min(vlen(self.enemy.origin - self.origin) / vlen(self.velocity), 1);
252 vector predicted_origin = self.enemy.origin + self.enemy.velocity * time_to_impact;
254 traceline(self.origin, self.origin + v_forward * 64 - '0 0 32', MOVE_NORMAL, self);
255 newdir = normalize(predicted_origin - self.origin);
258 float height_diff = predicted_origin_z - self.origin_z;
260 if(vlen(newdir - v_forward) > autocvar_g_vehicle_racer_rocket_locked_maxangle)
262 //bprint("Target lost!\n");
263 //dprint("OF:", ftos(vlen(newdir - v_forward)), "\n");
264 self.think = racer_rocket_groundhugger;
268 if(trace_fraction != 1.0 && trace_ent != self.enemy)
269 newdir_z += 16 * sys_frametime;
271 self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_racer_rocket_turnrate) * newvel;
272 self.velocity_z -= 800 * sys_frametime;
273 self.velocity_z += max(height_diff, autocvar_g_vehicle_racer_rocket_climbspeed) * sys_frametime ;
275 UpdateCSQCProjectile(self);
279 void racer_fire_rocket(string tagname, entity trg)
281 vector v = gettaginfo(self, gettagindex(self, tagname));
282 entity rocket = rocket = vehicles_projectile("wakizashi_rocket_launch", "weapons/rocket_fire.wav",
283 v, v_forward * autocvar_g_vehicle_racer_rocket_speed,
284 autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3,
285 DEATH_VH_WAKI_ROCKET, PROJECTILE_WAKIROCKET, 20, false, false, self.owner);
287 rocket.lip = autocvar_g_vehicle_racer_rocket_accel * sys_frametime;
288 rocket.wait = autocvar_g_vehicle_racer_rocket_turnrate;
289 rocket.nextthink = time;
291 rocket.cnt = time + 15;
294 rocket.think = racer_rocket_tracker;
296 rocket.think = racer_rocket_groundhugger;
301 entity player, racer;
305 if(intermission_running)
307 self.vehicle.velocity = '0 0 0';
308 self.vehicle.avelocity = '0 0 0';
313 racer = self.vehicle;
316 vehicles_painframe();
318 if(pointcontents(racer.origin) != CONTENT_WATER)
319 racer.air_finished = time + autocvar_g_vehicle_racer_water_time;
321 if(racer.deadflag != DEAD_NO)
324 player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
328 racer_align4point(frametime);
330 player.BUTTON_ZOOM = player.BUTTON_CROUCH = 0;
332 crosshair_trace(player);
334 racer.angles_x *= -1;
337 ftmp = autocvar_g_vehicle_racer_turnspeed * frametime;
338 ftmp = bound(-ftmp, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp);
339 racer.angles_y = anglemods(racer.angles_y + ftmp);
342 racer.angles_z += -ftmp * autocvar_g_vehicle_racer_turnroll * frametime;
345 ftmp = autocvar_g_vehicle_racer_pitchspeed * frametime;
346 ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - racer.angles_x, racer.angles_x), ftmp);
347 racer.angles_x = bound(-autocvar_g_vehicle_racer_pitchlimit, anglemods(racer.angles_x + ftmp), autocvar_g_vehicle_racer_pitchlimit);
349 makevectors(racer.angles);
350 racer.angles_x *= -1;
352 //ftmp = racer.velocity_z;
353 df = racer.velocity * -autocvar_g_vehicle_racer_friction;
354 //racer.velocity_z = ftmp;
356 int cont = pointcontents(racer.origin);
357 if(vlen(player.movement) != 0)
359 if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
361 if(player.movement_x) { df += v_forward * ((player.movement_x > 0) ? autocvar_g_vehicle_racer_water_speed_forward : -autocvar_g_vehicle_racer_water_speed_forward); }
362 if(player.movement_y) { df += v_right * ((player.movement_y > 0) ? autocvar_g_vehicle_racer_water_speed_strafe : -autocvar_g_vehicle_racer_water_speed_strafe); }
366 if(player.movement_x) { df += v_forward * ((player.movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward); }
367 if(player.movement_y) { df += v_right * ((player.movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe); }
370 if(self.sound_nexttime < time || self.sounds != 1)
373 self.sound_nexttime = time + 10.922667; //soundlength("vehicles/racer_move.wav");
374 sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_move.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
379 if(self.sound_nexttime < time || self.sounds != 0)
382 self.sound_nexttime = time + 11.888604; //soundlength("vehicles/racer_idle.wav");
383 sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
388 if (player.BUTTON_JUMP && racer.vehicle_energy >= (autocvar_g_vehicle_racer_afterburn_cost * frametime))
390 if(time - racer.wait > 0.2)
391 pointparticles(particleeffectnum("wakizashi_booster_smoke"), self.origin - v_forward * 32, v_forward * vlen(self.velocity), 1);
395 if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
397 racer.vehicle_energy -= autocvar_g_vehicle_racer_waterburn_cost * frametime;
398 df += (v_forward * autocvar_g_vehicle_racer_waterburn_speed);
402 racer.vehicle_energy -= autocvar_g_vehicle_racer_afterburn_cost * frametime;
403 df += (v_forward * autocvar_g_vehicle_racer_speed_afterburn);
406 if(racer.invincible_finished < time)
408 traceline(racer.origin, racer.origin - '0 0 256', MOVE_NORMAL, self);
409 if(trace_fraction != 1.0)
410 pointparticles(particleeffectnum("smoke_small"), trace_endpos, '0 0 0', 1);
412 racer.invincible_finished = time + 0.1 + (random() * 0.1);
415 if(racer.strength_finished < time)
417 racer.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav");
418 sound (racer.tur_head, CH_TRIGGER_SINGLE, "vehicles/racer_boost.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
423 racer.strength_finished = 0;
424 sound (racer.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
427 if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
428 racer.racer_watertime = time;
430 float dforce = autocvar_g_vehicle_racer_downforce;
431 if(time - racer.racer_watertime <= 3)
432 dforce = autocvar_g_vehicle_racer_water_downforce;
434 df -= v_up * (vlen(racer.velocity) * dforce);
435 player.movement = racer.velocity += df * frametime;
437 if(!forbidWeaponUse(player))
438 if(player.BUTTON_ATCK)
439 if(time > racer.attack_finished_single)
440 if(racer.vehicle_energy >= autocvar_g_vehicle_racer_cannon_cost)
442 racer.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost;
445 crosshair_trace(player);
448 racer_fire_cannon("tag_fire1");
453 racer_fire_cannon("tag_fire2");
456 racer.attack_finished_single = time + autocvar_g_vehicle_racer_cannon_refire;
459 if(autocvar_g_vehicle_racer_rocket_locktarget)
461 vehicles_locktarget((1 / autocvar_g_vehicle_racer_rocket_locking_time) * frametime,
462 (1 / autocvar_g_vehicle_racer_rocket_locking_releasetime) * frametime,
463 autocvar_g_vehicle_racer_rocket_locked_time);
467 if(racer.lock_strength == 1)
468 UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '1 0 0', 0);
469 else if(self.lock_strength > 0.5)
470 UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 1 0', 0);
471 else if(self.lock_strength < 0.5)
472 UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 0 1', 0);
476 if(!forbidWeaponUse(player))
477 if(time > racer.delay)
478 if(player.BUTTON_ATCK2)
480 racer.misc_bulletcounter += 1;
481 racer.delay = time + 0.3;
483 if(racer.misc_bulletcounter == 1)
484 racer_fire_rocket("tag_rocket_r", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
485 else if(racer.misc_bulletcounter == 2)
487 racer_fire_rocket("tag_rocket_l", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
488 racer.lock_strength = 0;
489 racer.lock_target = world;
490 racer.misc_bulletcounter = 0;
492 racer.delay = time + autocvar_g_vehicle_racer_rocket_refire;
496 player.vehicle_reload1 = bound(0, 100 * ((time - racer.lip) / (racer.delay - racer.lip)), 100);
498 if(racer.vehicle_flags & VHF_SHIELDREGEN)
499 vehicles_regen(racer.dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime, true);
501 if(racer.vehicle_flags & VHF_HEALTHREGEN)
502 vehicles_regen(racer.dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime, false);
504 if(racer.vehicle_flags & VHF_ENERGYREGEN)
505 vehicles_regen(racer.wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime, false);
508 VEHICLE_UPDATE_PLAYER(player, health, racer);
509 VEHICLE_UPDATE_PLAYER(player, energy, racer);
511 if(racer.vehicle_flags & VHF_HASSHIELD)
512 VEHICLE_UPDATE_PLAYER(player, shield, racer);
514 player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
515 setorigin(player,racer.origin + '0 0 32');
516 player.velocity = racer.velocity;
524 self.nextthink = time;
526 float pushdeltatime = time - self.lastpushtime;
527 if (pushdeltatime > 0.15) pushdeltatime = 0;
528 self.lastpushtime = time;
529 if(!pushdeltatime) return;
531 tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * autocvar_g_vehicle_racer_springlength), MOVE_NOMONSTERS, self);
533 vector df = self.velocity * -autocvar_g_vehicle_racer_friction;
534 df_z += (1 - trace_fraction) * autocvar_g_vehicle_racer_hoverpower + sin(time * 2) * (autocvar_g_vehicle_racer_springlength * 2);
536 float forced = autocvar_g_vehicle_racer_upforcedamper;
538 int cont = pointcontents(self.origin - '0 0 64');
539 if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
541 forced = autocvar_g_vehicle_racer_water_upforcedamper;
542 self.velocity_z += 200;
545 self.velocity += df * pushdeltatime;
546 if(self.velocity_z > 0)
547 self.velocity_z *= 1 - forced * pushdeltatime;
549 self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime);
550 self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime);
552 CSQCMODEL_AUTOUPDATE();
555 void racer_exit(float eject)
559 self.think = racer_think;
560 self.nextthink = time;
561 self.movetype = MOVETYPE_BOUNCE;
562 sound (self.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
567 makevectors(self.angles);
570 spot = self.origin + v_forward * 100 + '0 0 64';
571 spot = vehicles_findgoodexit(spot);
572 setorigin(self.owner , spot);
573 self.owner.velocity = (v_up + v_forward * 0.25) * 750;
574 self.owner.oldvelocity = self.owner.velocity;
578 if(vlen(self.velocity) > 2 * autocvar_sv_maxairspeed)
580 self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed * 2;
581 self.owner.velocity_z += 200;
582 spot = self.origin + v_forward * 32 + '0 0 32';
583 spot = vehicles_findgoodexit(spot);
587 self.owner.velocity = self.velocity * 0.5;
588 self.owner.velocity_z += 10;
589 spot = self.origin - v_forward * 200 + '0 0 32';
590 spot = vehicles_findgoodexit(spot);
592 self.owner.oldvelocity = self.owner.velocity;
593 setorigin(self.owner , spot);
595 antilag_clear(self.owner);
601 self.deadflag = DEAD_DEAD;
602 self.vehicle_exit(VHEF_NORMAL);
604 RadiusDamage (self, self.enemy, autocvar_g_vehicle_racer_blowup_coredamage,
605 autocvar_g_vehicle_racer_blowup_edgedamage,
606 autocvar_g_vehicle_racer_blowup_radius, world, world,
607 autocvar_g_vehicle_racer_blowup_forceintensity,
608 DEATH_VH_WAKI_DEATH, world);
610 self.nextthink = time + autocvar_g_vehicle_racer_respawntime;
611 self.think = vehicles_spawn;
612 self.movetype = MOVETYPE_NONE;
613 self.effects = EF_NODRAW;
615 self.colormod = '0 0 0';
616 self.avelocity = '0 0 0';
617 self.velocity = '0 0 0';
619 setorigin(self, self.pos1);
622 void racer_blowup_think()
624 self.nextthink = time;
626 if(time >= self.delay)
629 CSQCMODEL_AUTOUPDATE();
632 void racer_deadtouch()
634 self.avelocity_x *= 0.7;
640 void spawnfunc_vehicle_racer()
642 if(!autocvar_g_vehicle_racer) { remove(self); return; }
643 if(!vehicle_initialize(VEH_RACER, false)) { remove(self); return; }
646 float v_racer(float req)
652 if(autocvar_g_vehicle_racer_bouncepain)
653 vehicles_impact(autocvar_g_vehicle_racer_bouncepain_x, autocvar_g_vehicle_racer_bouncepain_y, autocvar_g_vehicle_racer_bouncepain_z);
658 self.movetype = MOVETYPE_BOUNCE;
659 self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health) * 100;
660 self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield) * 100;
662 if(self.owner.flagcarried)
663 setorigin(self.owner.flagcarried, '-190 0 96');
674 self.event_damage = func_null;
675 self.solid = SOLID_CORPSE;
676 self.takedamage = DAMAGE_NO;
677 self.deadflag = DEAD_DYING;
678 self.movetype = MOVETYPE_BOUNCE;
680 self.delay = 2 + time + random() * 3;
681 self.cnt = 1 + random() * 2;
682 self.touch = racer_deadtouch;
684 pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
687 self.avelocity_z = 32;
689 self.avelocity_z = -32;
691 self.avelocity_x = -vlen(self.velocity) * 0.2;
692 self.velocity += '0 0 700';
693 self.colormod = '-0.5 -0.5 -0.5';
695 self.think = racer_blowup_think;
696 self.nextthink = time;
702 if(self.scale != 0.5)
704 if(autocvar_g_vehicle_racer_hovertype != 0)
705 racer_force_from_tag = vehicles_force_fromtag_maglev;
707 racer_force_from_tag = vehicles_force_fromtag_hover;
709 // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel).
711 setattachment(self.vehicle_hudmodel, self, "");
712 setattachment(self.vehicle_viewport, self, "tag_viewport");
717 self.think = racer_think;
718 self.nextthink = time;
719 self.vehicle_health = autocvar_g_vehicle_racer_health;
720 self.vehicle_shield = autocvar_g_vehicle_racer_shield;
722 self.movetype = MOVETYPE_TOSS;
723 self.solid = SOLID_SLIDEBOX;
727 self.PlayerPhysplug = racer_frame;
729 self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor;
730 self.bouncestop = autocvar_g_vehicle_racer_bouncestop;
731 self.damageforcescale = 0.5;
732 self.vehicle_health = autocvar_g_vehicle_racer_health;
733 self.vehicle_shield = autocvar_g_vehicle_racer_shield;
739 if(autocvar_g_vehicle_racer_energy)
740 if(autocvar_g_vehicle_racer_energy_regen)
741 self.vehicle_flags |= VHF_ENERGYREGEN;
743 if(autocvar_g_vehicle_racer_shield)
744 self.vehicle_flags |= VHF_HASSHIELD;
746 if(autocvar_g_vehicle_racer_shield_regen)
747 self.vehicle_flags |= VHF_SHIELDREGEN;
749 if(autocvar_g_vehicle_racer_health_regen)
750 self.vehicle_flags |= VHF_HEALTHREGEN;
752 self.vehicle_exit = racer_exit;
753 self.respawntime = autocvar_g_vehicle_racer_respawntime;
754 self.vehicle_health = autocvar_g_vehicle_racer_health;
755 self.vehicle_shield = autocvar_g_vehicle_racer_shield;
756 self.max_health = self.vehicle_health;
762 precache_sound ("weapons/lasergun_fire.wav");
763 precache_sound ("weapons/rocket_fire.wav");
765 precache_sound ("vehicles/racer_idle.wav");
766 precache_sound ("vehicles/racer_move.wav");
767 precache_sound ("vehicles/racer_boost.wav");
769 precache_model ("models/vhshield.md3");
770 precache_model ("models/vehicles/wakizashi.dpm");
771 precache_model ("models/vehicles/wakizashi_cockpit.dpm");
782 #define waki_ico "gfx/vehicles/waki.tga"
783 #define waki_eng "gfx/vehicles/waki_e.tga"
784 #define waki_gun "gfx/vehicles/waki_guns.tga"
785 #define waki_rkt "gfx/vehicles/waki_rockets.tga"
786 #define waki_xhair "gfx/vehicles/axh-special1.tga"
788 float v_racer(float req)
794 if(autocvar_r_letterbox)
797 vector picsize, hudloc = '0 0 0', pic2size, picloc;
799 // Fetch health & ammo stats
802 picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
803 hudloc_y = vid_conheight - picsize_y;
804 hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5;
806 drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
813 pic2size = draw_getimagesize(waki_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
814 picloc = picsize * 0.5 - pic2size * 0.5;
816 drawpic(hudloc + picloc, waki_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
818 drawpic(hudloc + picloc, waki_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL);
819 drawpic(hudloc + picloc, waki_eng, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL);
820 drawpic(hudloc + picloc, waki_gun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL);
821 drawpic(hudloc + picloc, waki_rkt, pic2size, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
822 drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL);
825 picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
826 picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
827 drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
828 drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
831 picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
832 picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
835 if(alarm1time < time)
837 alarm1time = time + 2;
838 vehicle_alarm(self, CH_PAIN_SINGLE, "vehicles/alarm.wav");
841 drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
845 drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
848 vehicle_alarm(self, CH_PAIN_SINGLE, "misc/null.wav");
855 picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
856 picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
857 drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight);
858 drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
861 picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
862 picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
865 if(alarm2time < time)
867 alarm2time = time + 1;
868 vehicle_alarm(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav");
870 drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
874 drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
877 vehicle_alarm(self, CH_TRIGGER_SINGLE, "misc/null.wav");
883 picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
884 picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
885 drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight);
886 drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
889 picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
890 picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
892 drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
894 drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
897 picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
898 picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
899 drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload1, vid_conheight);
900 drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
903 pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
904 picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
906 drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
908 drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
910 if (scoreboard_showscores)
911 HUD_DrawScoreboard();
914 picsize = draw_getimagesize(waki_xhair);
919 drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
925 AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-bracket.tga";
926 AuxiliaryXhair[0].axh_scale = 0.25;
939 #endif // REGISTER_VEHICLE