#ifndef VEHICLE_RACER
#define VEHICLE_RACER
-#ifndef MENUQC
-int v_racer(entity, int);
-#endif
-REGISTER_VEHICLE_SIMPLE(
-/* VEH_##id */ RACER,
-/* spawnflags */ VHF_DMGSHAKE | VHF_DMGROLL,
-/* mins,maxs */ '-120 -120 -40' * 0.5, '120 120 40' * 0.5,
-/* model */ "models/vehicles/wakizashi.dpm",
-/* head_model */ "null",
-/* hud_model */ "models/vehicles/wakizashi_cockpit.dpm",
-/* tags */ "", "", "tag_viewport",
-/* netname */ "racer",
-/* fullname */ _("Racer")
-) {
- this.m_icon = "vehicle_racer";
-#ifndef MENUQC
- this.vehicle_func = v_racer;
-#endif
-}
+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);
+/* 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");
+/* 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"
#include "../../effects/effects.qh"
#include "../../triggers/trigger/impulse.qh"
-void racer_fire_cannon(string tagname);
-METHOD(RacerAttack, wr_think, bool(entity thiswep)) {
+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;
+
+void racer_fire_rocket(vector org, vector dir, entity trg);
+METHOD(RacerAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
SELFPARAM();
- if (self.BUTTON_ATCK)
- 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);
+ bool isPlayer = IS_PLAYER(self);
+ entity player = isPlayer ? self : self.owner;
+ entity veh = player.vehicle;
+ setself(player);
+ if (fire1)
+ if (weapon_prepareattack(false, autocvar_g_vehicle_racer_cannon_refire)) {
+ if (veh) {
+ veh.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost;
+ veh.wait = time;
+ }
+ if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0);
+ vector org = w_shotorg;
+ vector dir = w_shotdir;
+ entity bolt = vehicles_projectile(EFFECT_RACER_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
+ org, 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, player);
+ bolt.velocity = normalize(dir) * autocvar_g_vehicle_racer_cannon_speed;
+ weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
+ }
+ if (fire2)
+ if (!isPlayer || weapon_prepareattack(false, 0.2)) {
+ if (isPlayer) W_SetupShot_Dir(self, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0);
+ racer_fire_rocket(w_shotorg, w_shotdir, NULL);
+ weapon_thinkf(WFRAME_FIRE2, 0, w_ready);
}
+ setself(this);
return true;
}
+METHOD(RacerAttack, wr_checkammo1, bool(RacerAttack thiswep)) {
+ SELFPARAM();
+ bool isPlayer = IS_PLAYER(self);
+ entity player = isPlayer ? self : self.owner;
+ entity veh = player.vehicle;
+ return isPlayer || veh.vehicle_energy >= autocvar_g_vehicle_racer_cannon_cost;
+}
bool autocvar_g_vehicle_racer;
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;
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;
-}
-
void racer_rocket_groundhugger()
{SELFPARAM();
vector olddir, newdir;
return;
}
-void racer_fire_rocket(string tagname, entity trg)
+void racer_fire_rocket(vector org, vector dir, 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,
+ org, dir * 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.think = racer_rocket_groundhugger;
}
+void racer_fire_rocket_aim(string tagname, entity trg)
+{
+ SELFPARAM();
+ vector v = gettaginfo(self, gettagindex(self, tagname));
+ racer_fire_rocket(v, v_forward, trg);
+}
+
float racer_frame()
{SELFPARAM();
entity player, racer;
player.movement = racer.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)
+ Weapon wep1 = WEP_RACER;
+ if (!forbidWeaponUse(player))
+ if (player.BUTTON_ATCK)
+ if (wep1.wr_checkammo1(wep1))
{
- racer.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost;
- racer.wait = time;
-
+ string tagname = (racer.cnt)
+ ? (racer.cnt = 0, "tag_fire1")
+ : (racer.cnt = 1, "tag_fire2");
+ vector org = gettaginfo(self, gettagindex(self, tagname));
+ w_shotorg = org;
+ w_shotdir = v_forward;
+ // Fix z-aim (for chase mode)
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;
+ w_shotdir.z = normalize(trace_endpos - org).z * 0.5;
+ wep1.wr_think(wep1, true, false);
}
if(autocvar_g_vehicle_racer_rocket_locktarget)
if(racer.misc_bulletcounter == 1)
{
- racer_fire_rocket("tag_rocket_r", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
+ racer_fire_rocket_aim("tag_rocket_r", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
player.vehicle_ammo2 = 50;
}
else if(racer.misc_bulletcounter == 2)
{
- racer_fire_rocket("tag_rocket_l", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
+ racer_fire_rocket_aim("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;
#endif
#endif
-bool v_racer(Vehicle thisveh, int req)
-{SELFPARAM();
- switch(req)
- {
- case VR_IMPACT:
+ METHOD(Racer, vr_impact, bool(Racer thisveh))
{
#ifdef SVQC
if(autocvar_g_vehicle_racer_bouncepain)
return true;
}
- case VR_ENTER:
+ METHOD(Racer, vr_enter, bool(Racer thisveh))
{
#ifdef SVQC
self.movetype = MOVETYPE_BOUNCE;
return true;
}
- case VR_SPAWN:
+ METHOD(Racer, vr_spawn, bool(Racer thisveh))
{
#ifdef SVQC
if(self.scale != 0.5)
return true;
}
- case VR_DEATH:
+ METHOD(Racer, vr_death, bool(Racer thisveh))
{
#ifdef SVQC
self.SendEntity = func_null; // stop networking this racer (for now)
}
#ifdef CSQC
- case VR_HUD:
+ 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,
return true;
}
#endif
- case VR_SETUP:
+ METHOD(Racer, vr_setup, bool(Racer thisveh))
{
#ifdef SVQC
self.vehicle_exit = racer_exit;
return true;
}
- case VR_PRECACHE:
+ METHOD(Racer, vr_precache, bool(Racer thisveh))
{
return true;
}
- }
-
- return true;
-}
#endif // REGISTER_VEHICLE