]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/vehicles/vehicle/racer.qc
Put pure entities in the very center of the map (corner has issues on some of the...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / vehicles / vehicle / racer.qc
index c797e75389266f757da994256110fdf23e6c4e5c..ded599b7d2a77cc5b481f65a36dd8ef858f646f3 100644 (file)
 #ifndef VEHICLE_RACER
 #define VEHICLE_RACER
 
+#include "racer_weapon.qh"
+
 CLASS(Racer, Vehicle)
 /* spawnflags */ ATTRIB(Racer, spawnflags, int, VHF_DMGSHAKE | VHF_DMGROLL);
 /* mins       */ ATTRIB(Racer, mins, vector, '-120 -120 -40' * 0.5);
 /* maxs       */ ATTRIB(Racer, maxs, vector, '120 120 40' * 0.5);
+/* view offset*/ ATTRIB(Racer, view_ofs, vector, '0 0 50');
+/* view dist  */ ATTRIB(Racer, height, float, 200);
 /* model         */ ATTRIB(Racer, mdl, string, "models/vehicles/wakizashi.dpm");
 /* model         */ ATTRIB(Racer, model, string, "models/vehicles/wakizashi.dpm");
 /* head_model */ ATTRIB(Racer, head_model, string, "null");
 /* hud_model  */ ATTRIB(Racer, hud_model, string, "models/vehicles/wakizashi_cockpit.dpm");
 /* tags       */ ATTRIB(Racer, tag_head, string, "");
 /* tags       */ ATTRIB(Racer, tag_hud, string, "");
-/* tags       */ ATTRIB(Racer, tag_hview, string, "tag_viewport");
+/* tags       */ ATTRIB(Racer, tag_view, string, "tag_viewport");
 /* netname    */ ATTRIB(Racer, netname, string, "racer");
 /* fullname   */ ATTRIB(Racer, vehicle_name, string, _("Racer"));
 /* icon       */ ATTRIB(Racer, m_icon, string, "vehicle_racer");
 ENDCLASS(Racer)
-
 REGISTER_VEHICLE(RACER, NEW(Racer));
 
-#include "../../weapons/all.qh"
-
-CLASS(RacerAttack, PortoLaunch)
-/* flags     */ ATTRIB(RacerAttack, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse   */ ATTRIB(RacerAttack, impulse, int, 3);
-/* refname   */ ATTRIB(RacerAttack, netname, string, "racercannon");
-/* wepname   */ ATTRIB(RacerAttack, message, string, _("Racer cannon"));
-ENDCLASS(RacerAttack)
-REGISTER_WEAPON(RACER, NEW(RacerAttack));
-
 #endif
 
 #ifdef IMPLEMENTATION
+
 #ifdef SVQC
-#include "../../effects/effects.qh"
-#include "../../triggers/trigger/impulse.qh"
-
-void racer_fire_cannon(string tagname);
-METHOD(RacerAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
-       SELFPARAM();
-       if (fire1)
-       if (weapon_prepareattack(0, 0)) {
-               W_SetupShot_Dir(self, v_forward, false, 0, W_Sound("lasergun_fire"), CH_WEAPON_B, 0);
-               racer_fire_cannon("tag_fire1");
-               weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(machinegun, sustained_refire), w_ready);
-       }
-       return true;
-}
+#include <common/triggers/trigger/impulse.qh>
 
-bool autocvar_g_vehicle_racer;
+bool autocvar_g_vehicle_racer = true;
 
-float autocvar_g_vehicle_racer_speed_afterburn;
-float autocvar_g_vehicle_racer_afterburn_cost;
+float autocvar_g_vehicle_racer_thinkrate = 0.05; // TODO: any higher causes it to sink in liquids
 
-float autocvar_g_vehicle_racer_waterburn_cost;
-float autocvar_g_vehicle_racer_waterburn_speed;
+float autocvar_g_vehicle_racer_speed_afterburn = 3000;
+// energy consumed per second
+float autocvar_g_vehicle_racer_afterburn_cost = 100;
 
-float autocvar_g_vehicle_racer_water_speed_forward;
-float autocvar_g_vehicle_racer_water_speed_strafe;
+float autocvar_g_vehicle_racer_waterburn_cost = 5;
+float autocvar_g_vehicle_racer_waterburn_speed = 750;
+
+float autocvar_g_vehicle_racer_water_speed_forward = 600;
+float autocvar_g_vehicle_racer_water_speed_strafe = 600;
 
 float autocvar_g_vehicle_racer_pitchlimit = 30;
 
 float autocvar_g_vehicle_racer_water_downforce = 0.03;
 float autocvar_g_vehicle_racer_water_upforcedamper = 15;
 
-float autocvar_g_vehicle_racer_anglestabilizer;
-float autocvar_g_vehicle_racer_downforce;
+float autocvar_g_vehicle_racer_anglestabilizer = 1.75;
+float autocvar_g_vehicle_racer_downforce = 0.01;
 
-float autocvar_g_vehicle_racer_speed_forward;
-float autocvar_g_vehicle_racer_speed_strafe;
-float autocvar_g_vehicle_racer_springlength;
-float autocvar_g_vehicle_racer_upforcedamper;
-float autocvar_g_vehicle_racer_friction;
+float autocvar_g_vehicle_racer_speed_forward = 650;
+float autocvar_g_vehicle_racer_speed_strafe = 650;
+float autocvar_g_vehicle_racer_springlength = 70;
+float autocvar_g_vehicle_racer_upforcedamper = 10;
+float autocvar_g_vehicle_racer_friction = 0.45;
 
 float autocvar_g_vehicle_racer_water_time = 5;
 
-float autocvar_g_vehicle_racer_hovertype;
-float autocvar_g_vehicle_racer_hoverpower;
-
-float autocvar_g_vehicle_racer_turnroll;
-float autocvar_g_vehicle_racer_turnspeed;
-float autocvar_g_vehicle_racer_pitchspeed;
-
-float autocvar_g_vehicle_racer_energy;
-float autocvar_g_vehicle_racer_energy_regen;
-float autocvar_g_vehicle_racer_energy_regen_pause;
-
-float autocvar_g_vehicle_racer_health;
-float autocvar_g_vehicle_racer_health_regen;
-float autocvar_g_vehicle_racer_health_regen_pause;
-
-float autocvar_g_vehicle_racer_shield;
-float autocvar_g_vehicle_racer_shield_regen;
-float autocvar_g_vehicle_racer_shield_regen_pause;
-
-float autocvar_g_vehicle_racer_cannon_cost;
-float autocvar_g_vehicle_racer_cannon_damage;
-float autocvar_g_vehicle_racer_cannon_radius;
-float autocvar_g_vehicle_racer_cannon_refire;
-float autocvar_g_vehicle_racer_cannon_speed;
-float autocvar_g_vehicle_racer_cannon_spread;
-float autocvar_g_vehicle_racer_cannon_force;
-
-float autocvar_g_vehicle_racer_rocket_accel;
-float autocvar_g_vehicle_racer_rocket_damage;
-float autocvar_g_vehicle_racer_rocket_radius;
-float autocvar_g_vehicle_racer_rocket_force;
-float autocvar_g_vehicle_racer_rocket_refire;
-float autocvar_g_vehicle_racer_rocket_speed;
-float autocvar_g_vehicle_racer_rocket_turnrate;
-
-float autocvar_g_vehicle_racer_rocket_locktarget;
-float autocvar_g_vehicle_racer_rocket_locking_time;
-float autocvar_g_vehicle_racer_rocket_locking_releasetime;
-float autocvar_g_vehicle_racer_rocket_locked_time;
-float autocvar_g_vehicle_racer_rocket_locked_maxangle;
-float autocvar_g_vehicle_racer_rocket_climbspeed;
-
-float autocvar_g_vehicle_racer_respawntime;
-
-float autocvar_g_vehicle_racer_blowup_radius;
-float autocvar_g_vehicle_racer_blowup_coredamage;
-float autocvar_g_vehicle_racer_blowup_edgedamage;
-float autocvar_g_vehicle_racer_blowup_forceintensity;
-
-float autocvar_g_vehicle_racer_bouncefactor;
-float autocvar_g_vehicle_racer_bouncestop;
-vector autocvar_g_vehicle_racer_bouncepain;
+float autocvar_g_vehicle_racer_collision_multiplier = 0.05;
+
+// 0 = hover, != 0 = maglev
+int autocvar_g_vehicle_racer_hovertype = 0;
+// NOTE!! x 4 (4 engines)
+float autocvar_g_vehicle_racer_hoverpower = 8000;
+
+float autocvar_g_vehicle_racer_turnroll = 30;
+float autocvar_g_vehicle_racer_turnspeed = 220;
+float autocvar_g_vehicle_racer_pitchspeed = 125;
+
+float autocvar_g_vehicle_racer_energy = 100;
+float autocvar_g_vehicle_racer_energy_regen = 50;
+float autocvar_g_vehicle_racer_energy_regen_pause = 1;
+
+float autocvar_g_vehicle_racer_health = 200;
+float autocvar_g_vehicle_racer_health_regen = 0;
+float autocvar_g_vehicle_racer_health_regen_pause = 0;
+
+float autocvar_g_vehicle_racer_shield = 100;
+float autocvar_g_vehicle_racer_shield_regen = 30;
+float autocvar_g_vehicle_racer_shield_regen_pause = 1;
+
+bool autocvar_g_vehicle_racer_rocket_locktarget = true;
+float autocvar_g_vehicle_racer_rocket_locking_time = 0.9;
+float autocvar_g_vehicle_racer_rocket_locking_releasetime = 0.5;
+float autocvar_g_vehicle_racer_rocket_locked_time = 4;
+
+float autocvar_g_vehicle_racer_respawntime = 35;
+
+float autocvar_g_vehicle_racer_blowup_radius = 250;
+float autocvar_g_vehicle_racer_blowup_coredamage = 250;
+float autocvar_g_vehicle_racer_blowup_edgedamage = 15;
+float autocvar_g_vehicle_racer_blowup_forceintensity = 250;
+
+// Factor of old velocity to keep after collision
+float autocvar_g_vehicle_racer_bouncefactor = 0.25;
+// if != 0, New veloctiy after bounce = 0 if new velocity < this
+float autocvar_g_vehicle_racer_bouncestop = 0;
+// "minspeed_for_pain speedchange_to_pain_factor max_damage"
+vector autocvar_g_vehicle_racer_bouncepain = '60 0.75 300';
 
 .float racer_watertime;
 
-var vector racer_force_from_tag(string tag_name, float spring_length, float max_power);
+var vector racer_force_from_tag(entity this, string tag_name, float spring_length, float max_power);
 
-void racer_align4point(float _delta)
-{SELFPARAM();
+void racer_align4point(entity this, float _delta)
+{
        vector push_vector;
        float fl_push, fr_push, bl_push, br_push;
 
-       push_vector  = racer_force_from_tag("tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+       push_vector  = racer_force_from_tag(this, "tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
        fr_push   = force_fromtag_normpower;
-       //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
+       //vehicles_sweap_collision(force_fromtag_origin, this.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-       push_vector += racer_force_from_tag("tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+       push_vector += racer_force_from_tag(this, "tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
        fl_push   = force_fromtag_normpower;
-       //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
+       //vehicles_sweap_collision(force_fromtag_origin, this.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-       push_vector += racer_force_from_tag("tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+       push_vector += racer_force_from_tag(this, "tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
        br_push   = force_fromtag_normpower;
-       //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
+       //vehicles_sweap_collision(force_fromtag_origin, this.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-       push_vector += racer_force_from_tag("tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+       push_vector += racer_force_from_tag(this, "tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
        bl_push   = force_fromtag_normpower;
-       //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
+       //vehicles_sweap_collision(force_fromtag_origin, this.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-       self.velocity += push_vector * _delta;
+       this.velocity += push_vector * _delta;
 
        float uforce = autocvar_g_vehicle_racer_upforcedamper;
 
-       int cont = pointcontents(self.origin - '0 0 64');
+       int cont = pointcontents(this.origin - '0 0 64');
        if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
        {
                uforce = autocvar_g_vehicle_racer_water_upforcedamper;
 
-               if(self.owner.BUTTON_CROUCH && time < self.air_finished)
-                       self.velocity_z += 30;
+               if(PHYS_INPUT_BUTTON_CROUCH(this.owner) && time < this.air_finished)
+                       this.velocity_z += 30;
                else
-                       self.velocity_z += 200;
+                       this.velocity_z += 200;
        }
 
 
        // Anti ocilation
-       if(self.velocity_z > 0)
-               self.velocity_z *= 1 - uforce * _delta;
+       if(this.velocity_z > 0)
+               this.velocity_z *= 1 - uforce * _delta;
 
        push_vector_x =  (fl_push - bl_push);
        push_vector_x += (fr_push - br_push);
@@ -182,426 +155,285 @@ void racer_align4point(float _delta)
        push_vector_z *= 360;
 
        // Apply angle diffrance
-       self.angles_z += push_vector_z * _delta;
-       self.angles_x += push_vector_x * _delta;
+       this.angles_z += push_vector_z * _delta;
+       this.angles_x += push_vector_x * _delta;
 
        // Apply stabilizer
-       self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
-       self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
-}
-
-void racer_fire_cannon(string tagname)
-{SELFPARAM();
-       vector v;
-       entity bolt;
-
-       v = gettaginfo(self, gettagindex(self, tagname));
-       bolt = vehicles_projectile(EFFECT_RACER_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
-                                                  v, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed,
-                                                  autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force,  0,
-                                                  DEATH_VH_WAKI_GUN, PROJECTILE_WAKICANNON, 0, true, true, self.owner);
-
-       // Fix z-aim (for chase mode)
-       v = normalize(trace_endpos - bolt.origin);
-       v_forward_z = v_z * 0.5;
-       bolt.velocity = v_forward * autocvar_g_vehicle_racer_cannon_speed;
+       this.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
+       this.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
 }
 
-void racer_rocket_groundhugger()
-{SELFPARAM();
-       vector olddir, newdir;
-       float oldvel, newvel;
-
-       self.nextthink  = time;
-
-       if(self.owner.deadflag != DEAD_NO || self.cnt < time)
-       {
-               self.use();
-               return;
-       }
-
-       if(!self.realowner.vehicle)
-       {
-               UpdateCSQCProjectile(self);
-               return;
-       }
-
-       olddir = normalize(self.velocity);
-       oldvel = vlen(self.velocity);
-       newvel = oldvel + self.lip;
-
-       tracebox(self.origin, self.mins, self.maxs, self.origin + olddir * 64, MOVE_WORLDONLY,self);
-       if(trace_fraction <= 0.5)
-       {
-               // Hitting somethign soon, just speed ahead
-               self.velocity = olddir * newvel;
-               UpdateCSQCProjectile(self);
-               return;
-       }
-
-       traceline(trace_endpos, trace_endpos - '0 0 64', MOVE_NORMAL, self);
-       if(trace_fraction != 1.0)
-       {
-               newdir = normalize(trace_endpos + '0 0 64' - self.origin) * autocvar_g_vehicle_racer_rocket_turnrate;
-               self.velocity = normalize(olddir + newdir) * newvel;
-       }
-       else
-       {
-               self.velocity = olddir * newvel;
-               self.velocity_z -= 1600 * sys_frametime; // 2x grav looks better for this one
-       }
-
-       int cont = pointcontents(self.origin - '0 0 32');
-       if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
-               self.velocity_z += 200;
-
-       UpdateCSQCProjectile(self);
-       return;
+void racer_fire_rocket_aim(entity player, string tagname, entity trg)
+{
+       entity racer = player.vehicle;
+       vector v = gettaginfo(racer, gettagindex(racer, tagname));
+       racer_fire_rocket(player, v, v_forward, trg);
 }
 
-void racer_rocket_tracker()
-{SELFPARAM();
-       vector olddir, newdir;
-       float oldvel, newvel;
-
-       self.nextthink  = time;
+bool racer_frame(entity this)
+{
+       entity vehic = this.vehicle;
+       return = true;
 
-       if (self.owner.deadflag != DEAD_NO || self.cnt < time)
-       {
-               self.use();
-               return;
-       }
-
-       if(!self.realowner.vehicle)
+       if(intermission_running)
        {
-               UpdateCSQCProjectile(self);
+               vehic.velocity = '0 0 0';
+               vehic.avelocity = '0 0 0';
                return;
        }
 
-       olddir = normalize(self.velocity);
-       oldvel = vlen(self.velocity);
-       newvel = oldvel + self.lip;
-       makevectors(vectoangles(olddir));
+       vehicles_frame(vehic, this);
 
-       float time_to_impact = min(vlen(self.enemy.origin - self.origin) / vlen(self.velocity), 1);
-       vector predicted_origin = self.enemy.origin + self.enemy.velocity * time_to_impact;
+       traceline(vehic.origin, vehic.origin + '0 0 1', MOVE_NOMONSTERS, this);
+       int cont = trace_dpstartcontents;
+       if(cont & DPCONTENTS_WATER)
+               vehic.air_finished = time + autocvar_g_vehicle_racer_water_time;
 
-       traceline(self.origin, self.origin + v_forward * 64 - '0 0 32', MOVE_NORMAL, self);
-       newdir = normalize(predicted_origin - self.origin);
-
-       //vector
-       float height_diff = predicted_origin_z - self.origin_z;
-
-       if(vlen(newdir - v_forward) > autocvar_g_vehicle_racer_rocket_locked_maxangle)
+       if(IS_DEAD(vehic))
        {
-               //bprint("Target lost!\n");
-               //dprint("OF:", ftos(vlen(newdir - v_forward)), "\n");
-               self.think = racer_rocket_groundhugger;
+               PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_ATCK2(this) = false;
                return;
        }
 
-       if(trace_fraction != 1.0 && trace_ent != self.enemy)
-               newdir_z += 16 * sys_frametime;
-
-       self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_racer_rocket_turnrate) * newvel;
-       self.velocity_z -= 800 * sys_frametime;
-       self.velocity_z += max(height_diff, autocvar_g_vehicle_racer_rocket_climbspeed) * sys_frametime ;
-
-       UpdateCSQCProjectile(self);
-       return;
-}
-
-void racer_fire_rocket(string tagname, entity trg)
-{SELFPARAM();
-       vector v = gettaginfo(self, gettagindex(self, tagname));
-       entity rocket = vehicles_projectile(EFFECT_RACER_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
-                                                  v, v_forward * autocvar_g_vehicle_racer_rocket_speed,
-                                                  autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3,
-                                                  DEATH_VH_WAKI_ROCKET, PROJECTILE_WAKIROCKET, 20, false, false, self.owner);
-
-       rocket.lip                        = autocvar_g_vehicle_racer_rocket_accel * sys_frametime;
-       rocket.wait                      = autocvar_g_vehicle_racer_rocket_turnrate;
-       rocket.nextthink                = time;
-       rocket.enemy                    = trg;
-       rocket.cnt                        = time + 15;
-
-       if(trg)
-               rocket.think                    = racer_rocket_tracker;
-       else
-               rocket.think                    = racer_rocket_groundhugger;
-}
-
-float racer_frame()
-{SELFPARAM();
-       entity player, racer;
-       vector df;
-       float ftmp;
-
-       if(intermission_running)
-       {
-               self.vehicle.velocity = '0 0 0';
-               self.vehicle.avelocity = '0 0 0';
-               return 1;
-       }
-
-       player  = self;
-       racer   = self.vehicle;
-       setself(racer);
-
-       vehicles_painframe();
+       racer_align4point(vehic, PHYS_INPUT_TIMELENGTH);
 
-       if(pointcontents(racer.origin) != CONTENT_WATER)
-               racer.air_finished = time + autocvar_g_vehicle_racer_water_time;
+       PHYS_INPUT_BUTTON_ZOOM(this) = PHYS_INPUT_BUTTON_CROUCH(this) = false;
 
-       if(racer.deadflag != DEAD_NO)
+       if(time >= vehic.vehicle_last_trace)
        {
-               setself(player);
-               player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
-               return 1;
+               crosshair_trace(this);
+               vehic.vehicle_last_trace = time + autocvar_g_vehicle_racer_thinkrate;
        }
 
-       racer_align4point(PHYS_INPUT_TIMELENGTH);
-
-       player.BUTTON_ZOOM = player.BUTTON_CROUCH = 0;
-
-       crosshair_trace(player);
-
-       racer.angles_x *= -1;
+       vehic.angles_x *= -1;
 
        // Yaw
-       ftmp = autocvar_g_vehicle_racer_turnspeed * PHYS_INPUT_TIMELENGTH;
-       ftmp = bound(-ftmp, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp);
-       racer.angles_y = anglemods(racer.angles_y + ftmp);
+       float ftmp = autocvar_g_vehicle_racer_turnspeed * PHYS_INPUT_TIMELENGTH;
+       ftmp = bound(-ftmp, shortangle_f(this.v_angle_y - vehic.angles_y, vehic.angles_y), ftmp);
+       vehic.angles_y = anglemods(vehic.angles_y + ftmp);
 
        // Roll
-       racer.angles_z += -ftmp * autocvar_g_vehicle_racer_turnroll * PHYS_INPUT_TIMELENGTH;
+       vehic.angles_z += -ftmp * autocvar_g_vehicle_racer_turnroll * PHYS_INPUT_TIMELENGTH;
 
        // Pitch
        ftmp = autocvar_g_vehicle_racer_pitchspeed  * PHYS_INPUT_TIMELENGTH;
-       ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - racer.angles_x, racer.angles_x), ftmp);
-       racer.angles_x = bound(-autocvar_g_vehicle_racer_pitchlimit, anglemods(racer.angles_x + ftmp), autocvar_g_vehicle_racer_pitchlimit);
+       ftmp = bound(-ftmp, shortangle_f(this.v_angle_x - vehic.angles_x, vehic.angles_x), ftmp);
+       vehic.angles_x = bound(-autocvar_g_vehicle_racer_pitchlimit, anglemods(vehic.angles_x + ftmp), autocvar_g_vehicle_racer_pitchlimit);
 
-       makevectors(racer.angles);
-       racer.angles_x *= -1;
+       makevectors(vehic.angles);
+       vehic.angles_x *= -1;
 
-       //ftmp = racer.velocity_z;
-       df = racer.velocity * -autocvar_g_vehicle_racer_friction;
-       //racer.velocity_z = ftmp;
+       //ftmp = vehic.velocity_z;
+       vector df = vehic.velocity * -autocvar_g_vehicle_racer_friction;
+       //vehic.velocity_z = ftmp;
 
-       int cont = pointcontents(racer.origin);
-       if(vlen(player.movement) != 0)
+       if(this.movement)
        {
-               if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
+               if(cont & DPCONTENTS_LIQUIDSMASK)
                {
-                       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); }
-                       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); }
+                       if(this.movement_x) { df += v_forward * ((this.movement_x > 0) ? autocvar_g_vehicle_racer_water_speed_forward : -autocvar_g_vehicle_racer_water_speed_forward); }
+                       if(this.movement_y) { df += v_right * ((this.movement_y > 0) ? autocvar_g_vehicle_racer_water_speed_strafe : -autocvar_g_vehicle_racer_water_speed_strafe); }
                }
                else
                {
-                       if(player.movement_x) { df += v_forward * ((player.movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward); }
-                       if(player.movement_y) { df += v_right * ((player.movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe); }
+                       if(this.movement_x) { df += v_forward * ((this.movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward); }
+                       if(this.movement_y) { df += v_right * ((this.movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe); }
                }
 
 #ifdef SVQC
-               if(self.sound_nexttime < time || self.sounds != 1)
+               if(vehic.sound_nexttime < time || vehic.sounds != 1)
                {
-                       self.sounds = 1;
-                       self.sound_nexttime = time + 10.922667; //soundlength("vehicles/racer_move.wav");
-                       sound (self, CH_TRIGGER_SINGLE, SND_VEH_RACER_MOVE, VOL_VEHICLEENGINE, ATTEN_NORM);
+                       vehic.sounds = 1;
+                       vehic.sound_nexttime = time + 10.922667; //soundlength("vehicles/racer_move.wav");
+                       sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_RACER_MOVE, VOL_VEHICLEENGINE, ATTEN_NORM);
                }
 #endif
        }
 #ifdef SVQC
        else
        {
-               if(self.sound_nexttime < time || self.sounds != 0)
+               if(vehic.sound_nexttime < time || vehic.sounds != 0)
                {
-                       self.sounds = 0;
-                       self.sound_nexttime = time + 11.888604; //soundlength("vehicles/racer_idle.wav");
-                       sound (self, CH_TRIGGER_SINGLE, SND_VEH_RACER_IDLE, VOL_VEHICLEENGINE, ATTEN_NORM);
+                       vehic.sounds = 0;
+                       vehic.sound_nexttime = time + 11.888604; //soundlength("vehicles/racer_idle.wav");
+                       sound (vehic, CH_TRIGGER_SINGLE, SND_VEH_RACER_IDLE, VOL_VEHICLEENGINE, ATTEN_NORM);
                }
        }
 #endif
 
        // Afterburn
-       if (PHYS_INPUT_BUTTON_JUMP(player) && racer.vehicle_energy >= (autocvar_g_vehicle_racer_afterburn_cost * PHYS_INPUT_TIMELENGTH))
+       if (PHYS_INPUT_BUTTON_JUMP(this) && vehic.vehicle_energy >= (autocvar_g_vehicle_racer_afterburn_cost * PHYS_INPUT_TIMELENGTH))
        {
 #ifdef SVQC
-               if(time - racer.wait > 0.2)
-                       pointparticles(particleeffectnum(EFFECT_RACER_BOOSTER), self.origin - v_forward * 32, v_forward  * vlen(self.velocity), 1);
+               if(time - vehic.wait > 0.2)
+                       pointparticles(EFFECT_RACER_BOOSTER, vehic.origin - v_forward * 32, v_forward  * vlen(vehic.velocity), 1);
 #endif
 
-               racer.wait = time;
+               vehic.wait = time;
 
-               if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
+               if(cont & DPCONTENTS_LIQUIDSMASK)
                {
-                       racer.vehicle_energy -= autocvar_g_vehicle_racer_waterburn_cost * PHYS_INPUT_TIMELENGTH;
+                       vehic.vehicle_energy -= autocvar_g_vehicle_racer_waterburn_cost * PHYS_INPUT_TIMELENGTH;
                        df += (v_forward * autocvar_g_vehicle_racer_waterburn_speed);
                }
                else
                {
-                       racer.vehicle_energy -= autocvar_g_vehicle_racer_afterburn_cost * PHYS_INPUT_TIMELENGTH;
+                       vehic.vehicle_energy -= autocvar_g_vehicle_racer_afterburn_cost * PHYS_INPUT_TIMELENGTH;
                        df += (v_forward * autocvar_g_vehicle_racer_speed_afterburn);
                }
 
 #ifdef SVQC
-               if(racer.invincible_finished < time)
+               if(vehic.invincible_finished < time)
                {
-                       traceline(racer.origin, racer.origin - '0 0 256', MOVE_NORMAL, self);
+                       traceline(vehic.origin, vehic.origin - '0 0 256', MOVE_NORMAL, vehic);
                        if(trace_fraction != 1.0)
-                               pointparticles(particleeffectnum(EFFECT_SMOKE_SMALL), trace_endpos, '0 0 0', 1);
+                               pointparticles(EFFECT_SMOKE_SMALL, trace_endpos, '0 0 0', 1);
 
-                       racer.invincible_finished = time + 0.1 + (random() * 0.1);
+                       vehic.invincible_finished = time + 0.1 + (random() * 0.1);
                }
 
-               if(racer.strength_finished < time)
+               if(vehic.strength_finished < time)
                {
-                       racer.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav");
-                       sound (racer.tur_head, CH_TRIGGER_SINGLE, SND_VEH_RACER_BOOST, VOL_VEHICLEENGINE, ATTEN_NORM);
+                       vehic.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav");
+                       sound (vehic.tur_head, CH_TRIGGER_SINGLE, SND_VEH_RACER_BOOST, VOL_VEHICLEENGINE, ATTEN_NORM);
                }
 #endif
        }
        else
        {
-               racer.strength_finished = 0;
-               sound (racer.tur_head, CH_TRIGGER_SINGLE, SND_Null, VOL_VEHICLEENGINE, ATTEN_NORM);
+               vehic.strength_finished = 0;
+               sound (vehic.tur_head, CH_TRIGGER_SINGLE, SND_Null, VOL_VEHICLEENGINE, ATTEN_NORM);
        }
 
-       if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
-               racer.racer_watertime = time;
+       if(cont & DPCONTENTS_LIQUIDSMASK)
+               vehic.racer_watertime = time;
 
        float dforce = autocvar_g_vehicle_racer_downforce;
-       if(time - racer.racer_watertime <= 3)
+       if(time - vehic.racer_watertime <= 3)
                dforce = autocvar_g_vehicle_racer_water_downforce;
 
-       df -= v_up * (vlen(racer.velocity) * dforce);
-       player.movement = racer.velocity += df * PHYS_INPUT_TIMELENGTH;
+       df -= v_up * (vlen(vehic.velocity) * dforce);
+       this.movement = vehic.velocity += df * PHYS_INPUT_TIMELENGTH;
 
 #ifdef SVQC
-       if(!forbidWeaponUse(player))
-       if(player.BUTTON_ATCK)
-       if(time > racer.attack_finished_single)
-       if(racer.vehicle_energy >= autocvar_g_vehicle_racer_cannon_cost)
-       {
-               racer.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost;
-               racer.wait = time;
+       setself(vehic);
 
-               crosshair_trace(player);
-               if(racer.cnt)
-               {
-                       racer_fire_cannon("tag_fire1");
-                       racer.cnt = 0;
-               }
-               else
-               {
-                       racer_fire_cannon("tag_fire2");
-                       racer.cnt = 1;
-               }
-               racer.attack_finished_single = time + autocvar_g_vehicle_racer_cannon_refire;
+       Weapon wep1 = WEP_RACER;
+       if (!forbidWeaponUse(this))
+       if (PHYS_INPUT_BUTTON_ATCK(this))
+       if (wep1.wr_checkammo1(wep1))
+       {
+               string tagname = (vehic.cnt)
+                   ? (vehic.cnt = 0, "tag_fire1")
+                   : (vehic.cnt = 1, "tag_fire2");
+               vector org = gettaginfo(vehic, gettagindex(vehic, tagname));
+               w_shotorg = org;
+               w_shotdir = v_forward;
+               // Fix z-aim (for chase mode)
+               crosshair_trace(this);
+               w_shotdir.z = normalize(trace_endpos - org).z * 0.5;
+               .entity weaponentity = weaponentities[0];
+               wep1.wr_think(wep1, vehic, weaponentity, 1);
        }
 
+       setself(this);
+
        if(autocvar_g_vehicle_racer_rocket_locktarget)
        {
-               vehicles_locktarget((1 / autocvar_g_vehicle_racer_rocket_locking_time) * frametime,
+               if(vehic.vehicle_last_trace == time + autocvar_g_vehicle_racer_thinkrate)
+               vehicles_locktarget(vehic, (1 / autocvar_g_vehicle_racer_rocket_locking_time) * frametime,
                                                 (1 / autocvar_g_vehicle_racer_rocket_locking_releasetime) * frametime,
                                                 autocvar_g_vehicle_racer_rocket_locked_time);
 
-               if(self.lock_target)
+               if(vehic.lock_target)
                {
-                       if(racer.lock_strength == 1)
-                               UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '1 0 0', 0);
-                       else if(self.lock_strength > 0.5)
-                               UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 1 0', 0);
-                       else if(self.lock_strength < 0.5)
-                               UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 0 1', 0);
+                       if(vehic.lock_strength == 1)
+                               UpdateAuxiliaryXhair(this, real_origin(vehic.lock_target), '1 0 0', 0);
+                       else if(vehic.lock_strength > 0.5)
+                               UpdateAuxiliaryXhair(this, real_origin(vehic.lock_target), '0 1 0', 0);
+                       else if(vehic.lock_strength < 0.5)
+                               UpdateAuxiliaryXhair(this, real_origin(vehic.lock_target), '0 0 1', 0);
                }
        }
 
-       if(!forbidWeaponUse(player))
-       if(time > racer.delay)
-       if(player.BUTTON_ATCK2)
+       if(!forbidWeaponUse(this))
+       if(time > vehic.delay)
+       if(PHYS_INPUT_BUTTON_ATCK2(this))
        {
-               racer.misc_bulletcounter += 1;
-               racer.delay = time + 0.3;
+               vehic.misc_bulletcounter += 1;
+               vehic.delay = time + 0.3;
 
-               if(racer.misc_bulletcounter == 1)
+               if(vehic.misc_bulletcounter == 1)
                {
-                       racer_fire_rocket("tag_rocket_r", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
-                       player.vehicle_ammo2 = 50;
+                       racer_fire_rocket_aim(this, "tag_rocket_r", (vehic.lock_strength == 1 && vehic.lock_target) ? vehic.lock_target : world);
+                       this.vehicle_ammo2 = 50;
                }
-               else if(racer.misc_bulletcounter == 2)
+               else if(vehic.misc_bulletcounter == 2)
                {
-                       racer_fire_rocket("tag_rocket_l", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
-                       racer.lock_strength  = 0;
-                       racer.lock_target       = world;
-                       racer.misc_bulletcounter = 0;
-                       racer.delay = time + autocvar_g_vehicle_racer_rocket_refire;
-                       racer.lip = time;
-                       player.vehicle_ammo2 = 0;
+                       racer_fire_rocket_aim(this, "tag_rocket_l", (vehic.lock_strength == 1 && vehic.lock_target) ? vehic.lock_target : world);
+                       vehic.lock_strength  = 0;
+                       vehic.lock_target       = world;
+                       vehic.misc_bulletcounter = 0;
+                       vehic.delay = time + autocvar_g_vehicle_racer_rocket_refire;
+                       vehic.lip = time;
+                       this.vehicle_ammo2 = 0;
                }
        }
-       else if(racer.misc_bulletcounter == 0)
-               player.vehicle_ammo2 = 100;
+       else if(vehic.misc_bulletcounter == 0)
+               this.vehicle_ammo2 = 100;
 
-       player.vehicle_reload2 = bound(0, 100 * ((time - racer.lip) / (racer.delay - racer.lip)), 100);
+       this.vehicle_reload2 = bound(0, 100 * ((time - vehic.lip) / (vehic.delay - vehic.lip)), 100);
 
-       if(racer.vehicle_flags  & VHF_SHIELDREGEN)
-               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);
+       if(vehic.vehicle_flags  & VHF_SHIELDREGEN)
+               vehicles_regen(vehic, vehic.dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime, true);
 
-       if(racer.vehicle_flags  & VHF_HEALTHREGEN)
-               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);
+       if(vehic.vehicle_flags  & VHF_HEALTHREGEN)
+               vehicles_regen(vehic, vehic.dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime, false);
 
-       if(racer.vehicle_flags  & VHF_ENERGYREGEN)
-               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);
+       if(vehic.vehicle_flags  & VHF_ENERGYREGEN)
+               vehicles_regen(vehic, vehic.wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime, false);
 
+       VEHICLE_UPDATE_PLAYER(this, vehic, health, racer);
+       VEHICLE_UPDATE_PLAYER(this, vehic, energy, racer);
 
-       VEHICLE_UPDATE_PLAYER(player, health, racer);
-       VEHICLE_UPDATE_PLAYER(player, energy, racer);
+       if(vehic.vehicle_flags & VHF_HASSHIELD)
+               VEHICLE_UPDATE_PLAYER(this, vehic, shield, racer);
 
-       if(racer.vehicle_flags & VHF_HASSHIELD)
-               VEHICLE_UPDATE_PLAYER(player, shield, racer);
-
-       player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
+       PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_ATCK2(this) = false;
 #endif
 
-       setorigin(player,racer.origin + '0 0 32');
-       player.velocity = racer.velocity;
-
-       setself(player);
-       return 1;
+       setorigin(this, vehic.origin + '0 0 32');
+       this.velocity = vehic.velocity;
 }
 
 void racer_think()
 {SELFPARAM();
-       self.nextthink = time;
-
-       float pushdeltatime = time - self.lastpushtime;
-       if (pushdeltatime > 0.15) pushdeltatime = 0;
-       self.lastpushtime = time;
-       if(!pushdeltatime) return;
+       this.nextthink = time + autocvar_g_vehicle_racer_thinkrate;
 
-       tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * autocvar_g_vehicle_racer_springlength), MOVE_NOMONSTERS, self);
+       tracebox(this.origin, this.mins, this.maxs, this.origin - ('0 0 1' * autocvar_g_vehicle_racer_springlength), MOVE_NOMONSTERS, this);
 
-       vector df = self.velocity * -autocvar_g_vehicle_racer_friction;
+       vector df = this.velocity * -autocvar_g_vehicle_racer_friction;
        df_z += (1 - trace_fraction) * autocvar_g_vehicle_racer_hoverpower + sin(time * 2) * (autocvar_g_vehicle_racer_springlength * 2);
 
        float forced = autocvar_g_vehicle_racer_upforcedamper;
 
-       int cont = pointcontents(self.origin - '0 0 64');
-       if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
+       //int cont = pointcontents(self.origin - '0 0 64');
+       traceline(this.origin - '0 0 64', this.origin - '0 0 64', MOVE_NOMONSTERS, this);
+       //if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
+       if(trace_dpstartcontents & DPCONTENTS_LIQUIDSMASK)
        {
                forced = autocvar_g_vehicle_racer_water_upforcedamper;
-               self.velocity_z += 200;
+               this.velocity_z += 200;
        }
 
-       self.velocity += df * pushdeltatime;
-       if(self.velocity_z > 0)
-               self.velocity_z *= 1 - forced * pushdeltatime;
+       this.velocity += df * autocvar_g_vehicle_racer_thinkrate;
+       if(this.velocity_z > 0)
+               this.velocity_z *= 1 - forced * autocvar_g_vehicle_racer_thinkrate;
 
-       self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime);
-       self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime);
+       this.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * autocvar_g_vehicle_racer_thinkrate);
+       this.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * autocvar_g_vehicle_racer_thinkrate);
 
-       CSQCMODEL_AUTOUPDATE(self);
+       CSQCMODEL_AUTOUPDATE(this);
 }
 
 void racer_exit(float eject)
@@ -627,7 +459,7 @@ void racer_exit(float eject)
        }
        else
        {
-               if(vlen(self.velocity) > 2 * autocvar_sv_maxairspeed)
+               if(vdist(self.velocity, >, 2 * autocvar_sv_maxairspeed))
                {
                        self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed * 2;
                        self.owner.velocity_z += 200;
@@ -644,7 +476,7 @@ void racer_exit(float eject)
                self.owner.oldvelocity = self.owner.velocity;
                setorigin(self.owner , spot);
        }
-       antilag_clear(self.owner);
+       antilag_clear(self.owner, CS(self.owner));
        self.owner = world;
 }
 
@@ -657,12 +489,13 @@ void racer_blowup()
                                        autocvar_g_vehicle_racer_blowup_edgedamage,
                                        autocvar_g_vehicle_racer_blowup_radius, world, world,
                                        autocvar_g_vehicle_racer_blowup_forceintensity,
-                                       DEATH_VH_WAKI_DEATH, world);
+                                       DEATH_VH_WAKI_DEATH.m_id, world);
 
        self.nextthink  = time + autocvar_g_vehicle_racer_respawntime;
        self.think        = vehicles_spawn;
        self.movetype   = MOVETYPE_NONE;
        self.effects    = EF_NODRAW;
+       self.solid = SOLID_NOT;
 
        self.colormod  = '0 0 0';
        self.avelocity = '0 0 0';
@@ -689,10 +522,10 @@ void racer_deadtouch()
                racer_blowup();
 }
 
-void spawnfunc_vehicle_racer()
-{SELFPARAM();
-       if(!autocvar_g_vehicle_racer) { remove(self); return; }
-       if(!vehicle_initialize(VEH_RACER, false)) { remove(self); return; }
+spawnfunc(vehicle_racer)
+{
+       if(!autocvar_g_vehicle_racer) { remove(this); return; }
+       if(!vehicle_initialize(this, VEH_RACER, false)) { remove(this); return; }
 }
 
 #endif // SVQC
@@ -706,17 +539,17 @@ void racer_draw()
        self.lastpushtime = time;
        if(!pushdeltatime) return;
 
-       tracebox(self.move_origin, self.mins, self.maxs, self.move_origin - ('0 0 1' * getstatf(STAT_VEH_RACER_SPRINGLENGTH)), MOVE_NOMONSTERS, self);
+       tracebox(self.move_origin, self.mins, self.maxs, self.move_origin - ('0 0 1' * STAT(VEH_RACER_SPRINGLENGTH)), MOVE_NOMONSTERS, self);
 
-       vector df = self.move_velocity * -getstatf(STAT_VEH_RACER_FRICTION);
-       df_z += (1 - trace_fraction) * getstatf(STAT_VEH_RACER_HOVERPOWER) + sin(time * 2) * (getstatf(STAT_VEH_RACER_SPRINGLENGTH) * 2);
+       vector df = self.move_velocity * -STAT(VEH_RACER_FRICTION);
+       df_z += (1 - trace_fraction) * STAT(VEH_RACER_HOVERPOWER) + sin(time * 2) * (STAT(VEH_RACER_SPRINGLENGTH) * 2);
 
-       float forced = getstatf(STAT_VEH_RACER_UPFORCEDAMPER);
+       float forced = STAT(VEH_RACER_UPFORCEDAMPER);
 
        int cont = pointcontents(self.move_origin - '0 0 64');
        if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
        {
-               forced = getstatf(STAT_VEH_RACER_WATER_UPFORCEDAMPER);
+               forced = STAT(VEH_RACER_WATER_UPFORCEDAMPER);
                self.move_velocity_z += 200;
        }
 
@@ -724,157 +557,148 @@ void racer_draw()
        if(self.move_velocity_z > 0)
                self.move_velocity_z *= 1 - forced * pushdeltatime;
 
-       self.move_angles_x *= 1 - (getstatf(STAT_VEH_RACER_ANGLESTABILIZER) * pushdeltatime);
-       self.move_angles_z *= 1 - (getstatf(STAT_VEH_RACER_ANGLESTABILIZER) * pushdeltatime);
+       self.move_angles_x *= 1 - (STAT(VEH_RACER_ANGLESTABILIZER) * pushdeltatime);
+       self.move_angles_z *= 1 - (STAT(VEH_RACER_ANGLESTABILIZER) * pushdeltatime);
 
        Movetype_Physics_MatchServer(false);
 }
 #endif
 #endif
 
-               METHOD(Racer, vr_impact, bool(Racer thisveh))
-               {
-               #ifdef SVQC
-                       if(autocvar_g_vehicle_racer_bouncepain)
-                               vehicles_impact(autocvar_g_vehicle_racer_bouncepain_x, autocvar_g_vehicle_racer_bouncepain_y, autocvar_g_vehicle_racer_bouncepain_z);
-               #endif
-                       return true;
-               }
+METHOD(Racer, vr_impact, void(Racer thisveh, entity instance))
+{
+#ifdef SVQC
+    if(autocvar_g_vehicle_racer_bouncepain)
+        vehicles_impact(instance, autocvar_g_vehicle_racer_bouncepain_x, autocvar_g_vehicle_racer_bouncepain_y, autocvar_g_vehicle_racer_bouncepain_z);
+#endif
+}
 
-               METHOD(Racer, vr_enter, bool(Racer thisveh))
-               {
-               #ifdef SVQC
-                       self.movetype = MOVETYPE_BOUNCE;
-                       self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health)  * 100;
-                       self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield)  * 100;
+METHOD(Racer, vr_enter, void(Racer thisveh, entity instance))
+{
+#ifdef SVQC
+    SELFPARAM();
+    self.movetype = MOVETYPE_BOUNCE;
+    self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health)  * 100;
+    self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield)  * 100;
+
+    if(self.owner.flagcarried)
+       setorigin(self.owner.flagcarried, '-190 0 96');
+#elif defined(CSQC)
+    SELFPARAM();
+    self.move_movetype = MOVETYPE_BOUNCE;
+#endif
+}
 
-                       if(self.owner.flagcarried)
-                          setorigin(self.owner.flagcarried, '-190 0 96');
-               #elif defined(CSQC)
+METHOD(Racer, vr_spawn, void(Racer thisveh, entity instance))
+{
+#ifdef SVQC
+    SELFPARAM();
+    if(self.scale != 0.5)
+    {
+        if(autocvar_g_vehicle_racer_hovertype != 0)
+            racer_force_from_tag = vehicles_force_fromtag_maglev;
+        else
+            racer_force_from_tag = vehicles_force_fromtag_hover;
+
+        // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel).
+        self.scale = 0.5;
+        setattachment(self.vehicle_hudmodel, self, "");
+        setattachment(self.vehicle_viewport, self, "tag_viewport");
+
+        self.mass                         = 900;
+    }
+
+    self.think           = racer_think;
+    self.nextthink       = time;
+    self.vehicle_health = autocvar_g_vehicle_racer_health;
+    self.vehicle_shield = autocvar_g_vehicle_racer_shield;
+
+    self.movetype        = MOVETYPE_TOSS;
+    self.solid           = SOLID_SLIDEBOX;
+    self.delay           = time;
+    self.scale           = 0.5;
+
+    self.PlayerPhysplug = racer_frame;
+
+    self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor;
+    self.bouncestop = autocvar_g_vehicle_racer_bouncestop;
+    self.damageforcescale = 0.5;
+    self.vehicle_health = autocvar_g_vehicle_racer_health;
+    self.vehicle_shield = autocvar_g_vehicle_racer_shield;
+#endif
+}
 
-                       self.move_movetype = MOVETYPE_BOUNCE;
-               #endif
+METHOD(Racer, vr_death, void(Racer thisveh, entity instance))
+{
+#ifdef SVQC
+    instance.SendEntity                = func_null; // stop networking this racer (for now)
+    instance.health                    = 0;
+    instance.event_damage      = func_null;
+    instance.solid                     = SOLID_CORPSE;
+    instance.takedamage                = DAMAGE_NO;
+    instance.deadflag          = DEAD_DYING;
+    instance.movetype          = MOVETYPE_BOUNCE;
+    instance.wait                      = time;
+    instance.delay                     = 2 + time + random() * 3;
+    instance.cnt                       = 1 + random() * 2;
+    instance.touch                     = racer_deadtouch;
+
+    Send_Effect(EFFECT_EXPLOSION_MEDIUM, instance.origin, '0 0 0', 1);
+
+    if(random() < 0.5)
+        instance.avelocity_z = 32;
+    else
+        instance.avelocity_z = -32;
+
+    instance.avelocity_x = -vlen(instance.velocity) * 0.2;
+    instance.velocity += '0 0 700';
+    instance.colormod = '-0.5 -0.5 -0.5';
+
+    instance.think = racer_blowup_think;
+    instance.nextthink = time;
+#endif
+}
 
-                       return true;
-               }
+#ifdef CSQC
+METHOD(Racer, vr_hud, void(Racer thisveh))
+{
+    Vehicles_drawHUD(VEH_RACER.m_icon, "vehicle_racer_weapon1", "vehicle_racer_weapon2",
+                     "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color,
+                     "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color);
+}
+METHOD(Racer, vr_crosshair, void(Racer thisveh))
+{
+    Vehicles_drawCrosshair(vCROSS_GUIDE);
+}
+#endif
+METHOD(Racer, vr_setup, void(Racer thisveh, entity instance))
+{
+#ifdef SVQC
+    instance.vehicle_exit = racer_exit;
 
-               METHOD(Racer, vr_spawn, bool(Racer thisveh))
-               {
-               #ifdef SVQC
-                       if(self.scale != 0.5)
-                       {
-                               if(autocvar_g_vehicle_racer_hovertype != 0)
-                                       racer_force_from_tag = vehicles_force_fromtag_maglev;
-                               else
-                                       racer_force_from_tag = vehicles_force_fromtag_hover;
-
-                               // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel).
-                               self.scale = 0.5;
-                               setattachment(self.vehicle_hudmodel, self, "");
-                               setattachment(self.vehicle_viewport, self, "tag_viewport");
-
-                               self.mass                          = 900;
-                       }
-
-                       self.think                = racer_think;
-                       self.nextthink    = time;
-                       self.vehicle_health = autocvar_g_vehicle_racer_health;
-                       self.vehicle_shield = autocvar_g_vehicle_racer_shield;
-
-                       self.movetype     = MOVETYPE_TOSS;
-                       self.solid                = SOLID_SLIDEBOX;
-                       self.delay                = time;
-                       self.scale                = 0.5;
-
-                       self.PlayerPhysplug = racer_frame;
-
-                       self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor;
-                       self.bouncestop = autocvar_g_vehicle_racer_bouncestop;
-                       self.damageforcescale = 0.5;
-                       self.vehicle_health = autocvar_g_vehicle_racer_health;
-                       self.vehicle_shield = autocvar_g_vehicle_racer_shield;
-               #endif
-                       return true;
-               }
+    // we have no need to network energy
+    if(autocvar_g_vehicle_racer_energy)
+    if(autocvar_g_vehicle_racer_energy_regen)
+        instance.vehicle_flags |= VHF_ENERGYREGEN;
 
-               METHOD(Racer, vr_death, bool(Racer thisveh))
-               {
-               #ifdef SVQC
-                       self.SendEntity         = func_null; // stop networking this racer (for now)
-                       self.health                     = 0;
-                       self.event_damage       = func_null;
-                       self.solid                      = SOLID_CORPSE;
-                       self.takedamage         = DAMAGE_NO;
-                       self.deadflag           = DEAD_DYING;
-                       self.movetype           = MOVETYPE_BOUNCE;
-                       self.wait                       = time;
-                       self.delay                      = 2 + time + random() * 3;
-                       self.cnt                        = 1 + random() * 2;
-                       self.touch                      = racer_deadtouch;
-
-                       Send_Effect(EFFECT_EXPLOSION_MEDIUM, self.origin, '0 0 0', 1);
-
-                       if(random() < 0.5)
-                               self.avelocity_z = 32;
-                       else
-                               self.avelocity_z = -32;
-
-                       self.avelocity_x = -vlen(self.velocity) * 0.2;
-                       self.velocity += '0 0 700';
-                       self.colormod = '-0.5 -0.5 -0.5';
-
-                       self.think = racer_blowup_think;
-                       self.nextthink = time;
-               #endif
-                       return true;
-               }
+    if(autocvar_g_vehicle_racer_shield)
+        instance.vehicle_flags |= VHF_HASSHIELD;
 
-#ifdef CSQC
-               METHOD(Racer, vr_hud, bool(Racer thisveh))
-               {
-                       Vehicles_drawHUD(VEH_RACER.m_icon, "vehicle_racer_weapon1", "vehicle_racer_weapon2",
-                                                        "vehicle_icon_ammo1", autocvar_hud_progressbar_vehicles_ammo1_color,
-                                                        "vehicle_icon_ammo2", autocvar_hud_progressbar_vehicles_ammo2_color,
-                                                        vCROSS_GUIDE);
-                       return true;
-               }
+    if(autocvar_g_vehicle_racer_shield_regen)
+        instance.vehicle_flags |= VHF_SHIELDREGEN;
+
+    if(autocvar_g_vehicle_racer_health_regen)
+        instance.vehicle_flags |= VHF_HEALTHREGEN;
+
+    instance.respawntime = autocvar_g_vehicle_racer_respawntime;
+    instance.vehicle_health = autocvar_g_vehicle_racer_health;
+    instance.vehicle_shield = autocvar_g_vehicle_racer_shield;
+    instance.max_health = instance.vehicle_health;
 #endif
-               METHOD(Racer, vr_setup, bool(Racer thisveh))
-               {
-               #ifdef SVQC
-                       self.vehicle_exit = racer_exit;
-               #endif
-
-               #ifdef SVQC
-                       // we have no need to network energy
-                       if(autocvar_g_vehicle_racer_energy)
-                       if(autocvar_g_vehicle_racer_energy_regen)
-                               self.vehicle_flags |= VHF_ENERGYREGEN;
-
-                       if(autocvar_g_vehicle_racer_shield)
-                               self.vehicle_flags |= VHF_HASSHIELD;
-
-                       if(autocvar_g_vehicle_racer_shield_regen)
-                               self.vehicle_flags |= VHF_SHIELDREGEN;
-
-                       if(autocvar_g_vehicle_racer_health_regen)
-                               self.vehicle_flags |= VHF_HEALTHREGEN;
-
-                       self.respawntime = autocvar_g_vehicle_racer_respawntime;
-                       self.vehicle_health = autocvar_g_vehicle_racer_health;
-                       self.vehicle_shield = autocvar_g_vehicle_racer_shield;
-                       self.max_health = self.vehicle_health;
-               #endif
-
-               #ifdef CSQC
-                       AuxiliaryXhair[0].axh_image = vCROSS_LOCK; // Rocket
-               #endif
-                       return true;
-               }
 
-               METHOD(Racer, vr_precache, bool(Racer thisveh))
-               {
-                       return true;
-               }
+#ifdef CSQC
+    AuxiliaryXhair[0].axh_image = vCROSS_LOCK; // Rocket
+#endif
+}
 
-#endif // REGISTER_VEHICLE
+#endif