1 #define RACER_MIN '-80 -80 -40'
2 #define RACER_MAX '80 80 40'
4 void racer_exit(float eject);
8 float racer_power_solid;
10 float racer_anglestabilizer;
11 float racer_springlength;
13 float racer_healthmax;
14 float racer_shieldmax;
15 float racer_energymax;
17 float jetfromtag_power;
18 float jetfromtag_normpower;
19 vector jetfromtag_origin;
20 float jetfromtag_groundcontact;
24 void racer_loadsettings()
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");
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");
38 vector racer_jetfromtag(string tagname)
41 float air_frac, solid_frac, air_pwr, solid_pwr;
43 jetfromtag_origin = gettaginfo(self,gettagindex(self,tagname));
44 v_forward = normalize(v_forward) * -1;
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);
50 trace_fraction *= trace_fraction;
52 solid_frac = 1 - trace_fraction;
53 air_frac = trace_fraction;
55 if (trace_fraction != 1.0)
56 jetfromtag_groundcontact = 1;
58 solid_pwr = solid_frac * racer_power_solid;
59 air_pwr = air_frac * racer_power_air;
61 jetfromtag_power = solid_pwr + air_pwr;
62 jetfromtag_normpower = jetfromtag_power / (racer_power_air + racer_power_solid);
64 return v_forward * max(jetfromtag_power, racer_power_min);
67 void racer_align4point()
70 float fl_push, fr_push, bl_push, br_push;
72 jetfromtag_groundcontact = 0;
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);
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);
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);
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);
98 self.velocity = self.velocity + (push_vector * frametime);
99 self.velocity_z -= sv_gravity * frametime;
101 push_vector_x = (fl_push - bl_push);
102 push_vector_x += (fr_push - br_push);
103 push_vector_x *= 360;
105 push_vector_z = (fr_push - fl_push);
106 push_vector_z += (br_push - bl_push);
107 push_vector_z *= 360;
110 if(self.angles_z > 0)
111 self.angles_z = max(0, self.angles_z - (racer_anglestabilizer * frametime));
113 self.angles_z = min(0, self.angles_z + (racer_anglestabilizer * frametime));
115 self.angles_z += push_vector_z * frametime;
118 if(self.angles_x > 0)
119 self.angles_x = max(0, self.angles_x - (racer_anglestabilizer * frametime));
121 self.angles_x = min(0, self.angles_x + (racer_anglestabilizer * frametime));
123 self.angles_x += push_vector_x * frametime;
127 void racer_bolt_explode()
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);
139 void racer_rocket_explode()
144 // self.owner = self.realowner;
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);
154 void racer_fire_cannon(string tagname)
159 bolt.solid = SOLID_BBOX;
160 bolt.movetype = MOVETYPE_FLYMISSILE;
161 bolt.flags = FL_PROJECTILE | FL_NOTARGET;
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");
172 CSQCProjectile(bolt, TRUE, PROJECTILE_LASER, TRUE);
175 void racer_rocket_think()
177 vector newdir,olddir;
179 self.nextthink = time;
181 if ((self.owner.deadflag != DEAD_NO) || (self.cnt < time))
183 racer_rocket_explode();
187 if not (self.realowner.vehicle)
189 UpdateCSQCProjectile(self);
193 self.solid = SOLID_BBOX;
194 self.touch = racer_rocket_explode;
196 olddir = normalize(self.velocity);
197 newdir = normalize((0.5 * (self.enemy.absmin + self.enemy.absmax)) - self.origin);
199 self.velocity = normalize(olddir + newdir * cvar("g_vehicle_spiderbot_rocket_turnrate")) * cvar("g_vehicle_racer_rocket_speed");
201 UpdateCSQCProjectile(self);
204 void racer_fire_rocket(string tagname)
207 dprint("self.owner=",self.owner.netname,"\n");
210 setsize (rocket, '-1 -1 -1', '1 1 1');
211 rocket.solid = SOLID_BBOX;
212 rocket.movetype = MOVETYPE_FLYMISSILE;
213 rocket.flags = FL_PROJECTILE;
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)));
221 if( (self.tur_head.gun1) && (self.tur_head.cnt > time))
222 rocket.enemy = self.tur_head.gun1;
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");
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);
242 float racer_customizeentityforclient()
245 if(self.deadflag == DEAD_DEAD)
249 if(other == self.owner)
260 entity player, racer;
265 if(cvar("g_vehicle_racer_reload"))
267 racer_loadsettings();
268 cvar_set("g_vehicle_racer_reload","0");
272 racer = self.vehicle;
274 player.BUTTON_ZOOM = 0;
275 player.BUTTON_CROUCH = 0;
279 if(player.BUTTON_USE)
287 if(racer.deadflag != DEAD_NO)
290 player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
296 racer.angles_x *= -1;
297 makevectors(racer.angles);
300 ftmp = cvar("g_vehicle_racer_turnspeed") * sys_ticrate;
303 ftmp = bound(ftmp2,shortangle_f(player.v_angle_y - racer.angles_y,racer.angles_y),ftmp);
304 ftmp2 = safeangle(racer.angles_y + ftmp);
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;
312 racer.angles_y = ftmp2;
315 ftmp = cvar("g_vehicle_racer_pitchspeed") * sys_ticrate;
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;
323 if(player.movement_x != 0)
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");
331 if(player.movement_y != 0)
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");
339 // limit _z to avoid flying on normal thrust
341 df_z = min(df_z,700);
345 //if (jetfromtag_groundcontact)
346 if (player.BUTTON_JUMP)
347 if(racer.vehicle_energy >= (cvar("g_vehicle_racer_speed_afterburn_cost")* frametime))
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"));
354 racer.velocity += df * frametime;
356 df = (vlen(racer.velocity) * cvar("g_vehicle_racer_downforce") * v_up) * frametime;
357 racer.velocity = racer.velocity - df;
358 player.movement = racer.velocity;
360 if(cvar("g_vehicle_racer_drag"))
361 racer.velocity = movelib_dragvec(cvar("g_vehicle_racer_drag"), cvar("g_vehicle_racer_dragexp"));
363 if(self.owner.cursor_trace_ent)
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;
372 if(player.BUTTON_ATCK)
373 if(time > racer.attack_finished_single)
374 if(racer.vehicle_energy >= cvar("g_vehicle_racer_laser_cost"))
376 racer.vehicle_energy -= cvar("g_vehicle_racer_laser_cost");
377 racer.wait = time + cvar("g_vehicle_racer_energy_usepause");
381 racer_fire_cannon("tag_fire1");
386 racer_fire_cannon("tag_fire2");
389 racer.attack_finished_single = time + cvar("g_vehicle_racer_laser_refire");
392 if(player.BUTTON_ATCK2)
393 if(time > racer.delay)
395 racer_fire_rocket("tag_rocket_r");
396 racer_fire_rocket("tag_rocket_l");
397 racer.delay = time + cvar("g_vehicle_racer_rocket_refire");
402 player.vehicle_reload1 = (time - racer.lip) / (racer.delay-racer.lip);
403 //player.vehicle_energy = racer.vehicle_energy;
405 vehicle_stdproc_shiledregen(CCVAR("_shield"), frametime);
406 vehicle_stdproc_healthregen(CCVAR("_health"), frametime);
408 if (racer.wait < time)
409 vehicle_stdproc_energyregen(CCVAR("_energy"), frametime);
411 player.vehicle_energy = (racer.vehicle_energy / CCVAR("_energy"));
415 player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
416 setorigin(player,racer.origin + '0 0 32');
417 player.velocity = racer.velocity;
424 movelib_beak_simple(cvar("g_vehicle_racer_speed_stop"));
426 self.nextthink = time;
436 self.vehicle_hudmodel.viewmodelforclient = self.owner;
437 self.colormap = self.owner.colormap;
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';
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"));
454 setorigin(other,self.origin + '0 0 32');
455 other.velocity = self.velocity;
457 other.flags &~= FL_ONGROUND;
459 WriteByte (MSG_ONE, SVC_SETVIEWPORT);
460 WriteEntity( MSG_ONE, self.vehicle_viewport);
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
468 void racer_exit(float eject)
470 self.colormap = 1024;
471 self.flags = FL_NOTARGET;
472 self.velocity = '0 0 0';
477 msg_entity = self.owner;
478 WriteByte (MSG_ONE, SVC_SETVIEWPORT);
479 WriteEntity( MSG_ONE, self.owner);
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
486 if (self.deadflag == DEAD_NO)
488 self.think = racer_think;
489 self.nextthink = time;
492 self.owner.takedamage = DAMAGE_AIM;
493 self.owner.solid = SOLID_SLIDEBOX;
494 self.owner.movetype = MOVETYPE_WALK;
496 setsize(self.owner,PL_MIN,PL_MAX);
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;
508 self.vehicle_hudmodel.viewmodelforclient = self;
512 makevectors(self.angles);
513 setorigin(self.owner,self.origin + v_forward * 100);
514 self.owner.velocity = (v_up + v_forward * 0.25) * 750;
518 self.owner.velocity = (v_forward) * -150;
519 setorigin(self.owner,self.origin - v_forward * 128);
525 void racer_entercap()
541 self.think = SUB_Remove;
542 self.nextthink = time;
549 if(vlen(self.velocity) == 0)
552 if(other.classname != "player")
556 a = normalize(other.origin - self.origin);
557 a = a - normalize(self.velocity);
562 if(other.classname != "player")
565 if(other.deadflag != DEAD_NO)
568 if(other.vehicle != world)
574 entercap.enemy = other;
575 entercap.owner = self;
576 entercap.think = racer_entercap;
577 entercap.nextthink = time;
584 float racer_customizeentityforclient()
586 if(self.deadflag == DEAD_DEAD)
595 self.think = racer_think;
596 self.nextthink = time;
598 self.flags = FL_NOTARGET;
601 self.vehicle_health = CCVAR("_health");
602 self.vehicle_shield = CCVAR("_shield");
604 self.event_damage = vehicle_stdproc_damage;
605 self.touch = racer_touch;
607 self.iscreature = TRUE;
609 self.movetype = MOVETYPE_FLY;
610 self.solid = SOLID_SLIDEBOX;
611 self.takedamage = DAMAGE_AIM;
614 self.colormap = 1024;
615 self.deadflag = DEAD_NO;
616 self.bot_attack = TRUE;
618 self.vehicle_energy = 1;
619 self.vehicle_hudmodel.viewmodelforclient = self;
621 setorigin(self, self.pos1);
622 self.angles = self.pos2;
624 setsize(self,RACER_MIN * 0.5,RACER_MAX * 0.5);
625 pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
633 sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
634 pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
636 self.deadflag = DEAD_DEAD;
637 self.vehicle_exit(VHEF_NORMAL);
638 RadiusDamage (self, self, 250, 15, 250, world, 250, DEATH_WAKIBLOWUP, world);
641 self.nextthink = time + 10;
642 self.think = racer_spawn;
643 self.movetype = MOVETYPE_NONE;
644 self.effects = EF_NODRAW;
646 self.avelocity_z = 0;
647 self.colormod = '0 0 0';
649 setorigin(self,self.pos1);
652 void racer_dietouch()
657 self.wait = time + 0.75;
659 pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
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;
674 pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
676 self.velocity += '0 0 128';
679 self.avelocity_z = 16;
681 self.avelocity_z = -16;
683 self.colormod = '-0.5 -0.5 -0.5';
685 self.think = racer_blowup;
686 self.nextthink = time + 3;
692 if (self.netname == "")
693 self.netname = "Race PoD";
695 self.cvar_basename = "g_vehicle_racer";
697 self.vehicle_viewport = spawn();
698 self.vehicle_hudmodel = spawn();
699 //self.ccamera = spawn();
701 setorigin(self, self.origin);
703 setmodel(self,"models/vehicles/wakizashi.dpm");
704 setmodel(self.vehicle_hudmodel, "models/vehicles/wakizashi_cockpit.dpm");
705 setmodel (self.vehicle_viewport, "null");
707 setattachment(self.vehicle_hudmodel, self, "");
708 setattachment(self.vehicle_viewport, self, "tag_viewport");
710 self.vehicle_hudmodel.viewmodelforclient = self;
711 self.customizeentityforclient = racer_customizeentityforclient;
713 self.tur_head = spawn();
715 self.pos1 = self.origin;
716 self.pos2 = self.angles;
717 self.angles = '0 0 0';
718 self.angles = self.pos1;
720 self.vehicle_die = racer_die;
721 self.vehicle_exit = racer_exit;
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);
728 addstat(STAT_VEHICLESTAT_AMMO1, AS_INT, vehicle_ammo1);
729 addstat(STAT_VEHICLESTAT_RELOAD1, AS_FLOAT, vehicle_reload1);
731 addstat(STAT_VEHICLESTAT_AMMO2, AS_INT, vehicle_ammo2);
732 addstat(STAT_VEHICLESTAT_RELOAD2, AS_FLOAT, vehicle_reload2);
737 void spawnfunc_vehicle_racer()
739 g_turrets_common_precash();
740 racer_loadsettings();
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");
747 self.think = racer_dinit;
748 self.nextthink = time + 1;