#ifndef VEHICLE_RACER
#define VEHICLE_RACER
+#include "racer_weapon.qc"
+
CLASS(Racer, Vehicle)
/* spawnflags */ ATTRIB(Racer, spawnflags, int, VHF_DMGSHAKE | VHF_DMGROLL);
/* mins */ ATTRIB(Racer, mins, vector, '-120 -120 -40' * 0.5);
/* 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
+
+#include "racer_weapon.qc"
+
#ifdef SVQC
#include "../../effects/effects.qh"
#include "../../triggers/trigger/impulse.qh"
-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();
- 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_speed_afterburn;
float autocvar_g_vehicle_racer_shield_regen;
float autocvar_g_vehicle_racer_shield_regen_pause;
-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;
self.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_rocket_tracker()
-{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;
- makevectors(vectoangles(olddir));
-
- 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(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)
- {
- //bprint("Target lost!\n");
- //dprint("OF:", ftos(vlen(newdir - v_forward)), "\n");
- self.think = racer_rocket_groundhugger;
- 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(vector org, vector dir, entity trg)
-{SELFPARAM();
- entity rocket = vehicles_projectile(EFFECT_RACER_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
- 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.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;
-}
-
void racer_fire_rocket_aim(string tagname, entity trg)
{
SELFPARAM();
--- /dev/null
+#ifndef VEHICLE_RACER_WEAPON_H
+#define VEHICLE_RACER_WEAPON_H
+
+#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));
+
+// TODO: move into implementation
+#ifdef SVQC
+float autocvar_g_vehicle_racer_rocket_refire;
+void racer_fire_rocket(vector org, vector dir, entity trg);
+#endif
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+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_speed;
+float autocvar_g_vehicle_racer_rocket_turnrate;
+
+float autocvar_g_vehicle_racer_rocket_climbspeed;
+float autocvar_g_vehicle_racer_rocket_locked_maxangle;
+
+void racer_fire_rocket(vector org, vector dir, entity trg);
+METHOD(RacerAttack, wr_think, bool(entity thiswep, bool fire1, bool fire2))
+{
+ SELFPARAM();
+ 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;
+}
+
+void racer_rocket_tracker();
+void racer_rocket_groundhugger();
+
+void racer_fire_rocket(vector org, vector dir, entity trg)
+{SELFPARAM();
+ entity rocket = vehicles_projectile(EFFECT_RACER_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
+ 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.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;
+}
+
+void racer_rocket_tracker()
+{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;
+ makevectors(vectoangles(olddir));
+
+ 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(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)
+ {
+ //bprint("Target lost!\n");
+ //dprint("OF:", ftos(vlen(newdir - v_forward)), "\n");
+ self.think = racer_rocket_groundhugger;
+ 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_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;
+}
+
+#endif
+
+#endif
#define VEHICLE_RAPTOR
#include "raptor.qh"
+#include "raptor_weapons.qc"
+
CLASS(Raptor, Vehicle)
/* spawnflags */ ATTRIB(Raptor, spawnflags, int, VHF_DMGSHAKE | VHF_DMGROLL);
/* mins */ ATTRIB(Raptor, mins, vector, '-80 -80 0');
/* fullname */ ATTRIB(Raptor, vehicle_name, string, _("Raptor"));
/* icon */ ATTRIB(Raptor, m_icon, string, "vehicle_raptor");
ENDCLASS(Raptor)
-
REGISTER_VEHICLE(RAPTOR, NEW(Raptor));
-#include "../../weapons/all.qh"
-
-CLASS(RaptorCannon, PortoLaunch)
-/* flags */ ATTRIB(RaptorCannon, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse */ ATTRIB(RaptorCannon, impulse, int, 3);
-/* refname */ ATTRIB(RaptorCannon, netname, string, "raptorcannon");
-/* wepname */ ATTRIB(RaptorCannon, message, string, _("Raptor cannon"));
-ENDCLASS(RaptorCannon)
-REGISTER_WEAPON(RAPTOR, NEW(RaptorCannon));
-
-CLASS(RaptorBomb, PortoLaunch)
-/* flags */ ATTRIB(RaptorBomb, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse */ ATTRIB(RaptorBomb, impulse, int, 3);
-/* refname */ ATTRIB(RaptorBomb, netname, string, "raptorbomb");
-/* wepname */ ATTRIB(RaptorBomb, message, string, _("Raptor bomb"));
-ENDCLASS(RaptorBomb)
-REGISTER_WEAPON(RAPTOR_BOMB, NEW(RaptorBomb));
-
-CLASS(RaptorFlare, PortoLaunch)
-/* flags */ ATTRIB(RaptorFlare, spawnflags, int, WEP_TYPE_OTHER);
-/* impulse */ ATTRIB(RaptorFlare, impulse, int, 3);
-/* refname */ ATTRIB(RaptorFlare, netname, string, "raptorflare");
-/* wepname */ ATTRIB(RaptorFlare, message, string, _("Raptor flare"));
-ENDCLASS(RaptorFlare)
-REGISTER_WEAPON(RAPTOR_FLARE, NEW(RaptorFlare));
-
#endif
#ifdef IMPLEMENTATION
-#ifdef SVQC
-float autocvar_g_vehicle_raptor_cannon_cost;
-float autocvar_g_vehicle_raptor_cannon_damage;
-float autocvar_g_vehicle_raptor_cannon_radius;
-float autocvar_g_vehicle_raptor_cannon_refire;
-float autocvar_g_vehicle_raptor_cannon_speed;
-float autocvar_g_vehicle_raptor_cannon_spread;
-float autocvar_g_vehicle_raptor_cannon_force;
-
-METHOD(RaptorCannon, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
- SELFPARAM();
- bool isPlayer = IS_PLAYER(self);
- entity player = isPlayer ? self : self.owner;
- entity veh = player.vehicle;
- setself(player);
- // 1 [wait] 1 [wait] 2 [wait] 2 [wait] [wait]
- float t = autocvar_g_vehicle_raptor_cannon_refire * (1 + veh.misc_bulletcounter == 4);
- if (fire1)
- if (weapon_prepareattack(false, t)) {
- if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0);
- vector org = w_shotorg;
- vector dir = w_shotdir;
- if (veh) {
- veh.misc_bulletcounter += 1;
- org = (veh.misc_bulletcounter <= 2) ? gettaginfo(veh.gun1, gettagindex(veh.gun1, "fire1"))
- : (((veh.misc_bulletcounter == 4) ? veh.misc_bulletcounter = 0 : 0), gettaginfo(veh.gun2, gettagindex(veh.gun2, "fire1")));
- dir = v_forward;
- veh.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost;
- self.cnt = time;
- }
- vehicles_projectile(EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
- org, normalize(dir + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed,
- autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force, 0,
- DEATH_VH_RAPT_CANNON, PROJECTILE_RAPTORCANNON, 0, true, true, player);
- weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
- }
- setself(this);
- return true;
-}
-METHOD(RaptorCannon, 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_raptor_cannon_cost;
-}
+#include "raptor_weapons.qc"
-float autocvar_g_vehicle_raptor_bombs_refire;
-
-void raptor_bombdrop();
-METHOD(RaptorBomb, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
- SELFPARAM();
- bool isPlayer = IS_PLAYER(self);
- entity player = isPlayer ? self : self.owner;
- setself(player);
- if (fire2)
- if (weapon_prepareattack(false, autocvar_g_vehicle_raptor_bombs_refire)) {
- raptor_bombdrop();
- weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
- }
- setself(this);
- return true;
-}
-
-float autocvar_g_vehicle_raptor_flare_refire;
-float autocvar_g_vehicle_raptor_flare_lifetime;
-float autocvar_g_vehicle_raptor_flare_chase;
-float autocvar_g_vehicle_raptor_flare_range;
-
-void raptor_flare_think();
-void raptor_flare_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
-void raptor_flare_touch();
-
-METHOD(RaptorFlare, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
- SELFPARAM();
- bool isPlayer = IS_PLAYER(self);
- entity player = isPlayer ? self : self.owner;
- setself(player);
- if (fire2)
- if (weapon_prepareattack(true, autocvar_g_vehicle_raptor_flare_refire)) {
- for(int i = 0; i < 3; ++i) {
- entity _flare = spawn();
- setmodel(_flare, MDL_VEH_RAPTOR_FLARE);
- _flare.effects = EF_LOWPRECISION | EF_FLAME;
- _flare.scale = 0.5;
- setorigin(_flare, self.origin - '0 0 16');
- _flare.movetype = MOVETYPE_TOSS;
- _flare.gravity = 0.15;
- _flare.velocity = 0.25 * self.velocity + (v_forward + randomvec() * 0.25)* -500;
- _flare.think = raptor_flare_think;
- _flare.nextthink = time;
- _flare.owner = self;
- _flare.solid = SOLID_CORPSE;
- _flare.takedamage = DAMAGE_YES;
- _flare.event_damage = raptor_flare_damage;
- _flare.health = 20;
- _flare.tur_impacttime = time + autocvar_g_vehicle_raptor_flare_lifetime;
- _flare.touch = raptor_flare_touch;
- }
- weapon_thinkf(WFRAME_FIRE2, 0, w_ready);
- }
- setself(this);
- return true;
-}
+#ifdef SVQC
bool autocvar_g_vehicle_raptor;
float autocvar_g_vehicle_raptor_speed_down;
float autocvar_g_vehicle_raptor_friction;
-float autocvar_g_vehicle_raptor_bomblets;
-float autocvar_g_vehicle_raptor_bomblet_alt;
-float autocvar_g_vehicle_raptor_bomblet_time;
-float autocvar_g_vehicle_raptor_bomblet_damage;
-float autocvar_g_vehicle_raptor_bomblet_spread;
-float autocvar_g_vehicle_raptor_bomblet_edgedamage;
-float autocvar_g_vehicle_raptor_bomblet_radius;
-float autocvar_g_vehicle_raptor_bomblet_force;
-float autocvar_g_vehicle_raptor_bomblet_explode_delay;
-
float autocvar_g_vehicle_raptor_cannon_turnspeed;
float autocvar_g_vehicle_raptor_cannon_turnlimit;
float autocvar_g_vehicle_raptor_cannon_pitchlimit_up;
return vlen(self.origin - trace_endpos);
}
-void raptor_bomblet_boom()
-{SELFPARAM();
- RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage,
- autocvar_g_vehicle_raptor_bomblet_edgedamage,
- autocvar_g_vehicle_raptor_bomblet_radius, world, world,
- autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB, world);
- remove(self);
-}
-
-void raptor_bomblet_touch()
-{SELFPARAM();
- if(other == self.owner)
- return;
-
- PROJECTILE_TOUCH;
- self.think = raptor_bomblet_boom;
- self.nextthink = time + random() * autocvar_g_vehicle_raptor_bomblet_explode_delay;
-}
-
-void raptor_bomb_burst()
-{SELFPARAM();
- if(self.cnt > time)
- if(autocvar_g_vehicle_raptor_bomblet_alt)
- {
- self.nextthink = time;
- traceline(self.origin, self.origin + (normalize(self.velocity) * autocvar_g_vehicle_raptor_bomblet_alt), MOVE_NORMAL, self);
- if((trace_fraction == 1.0) || (vlen(self.origin - self.owner.origin) < autocvar_g_vehicle_raptor_bomblet_radius))
- {
- UpdateCSQCProjectile(self);
- return;
- }
- }
-
- entity bomblet;
- float i;
-
- Damage_DamageInfo(self.origin, 0, 0, 0, '0 0 0', DEATH_VH_RAPT_FRAGMENT, 0, self);
-
- for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i)
- {
- bomblet = spawn();
- setorigin(bomblet, self.origin);
-
- bomblet.movetype = MOVETYPE_TOSS;
- bomblet.touch = raptor_bomblet_touch;
- bomblet.think = raptor_bomblet_boom;
- bomblet.nextthink = time + 5;
- bomblet.owner = self.owner;
- bomblet.realowner = self.realowner;
- bomblet.velocity = normalize(normalize(self.velocity) + (randomvec() * autocvar_g_vehicle_raptor_bomblet_spread)) * vlen(self.velocity);
-
- PROJECTILE_MAKETRIGGER(bomblet);
- CSQCProjectile(bomblet, true, PROJECTILE_RAPTORBOMBLET, true);
- }
-
- remove(self);
-}
-
-void raptor_bombdrop()
-{SELFPARAM();
- entity bomb_1, bomb_2;
-
- bomb_1 = spawn();
- bomb_2 = spawn();
-
- setorigin(bomb_1, gettaginfo(self, gettagindex(self, "bombmount_left")));
- setorigin(bomb_2, gettaginfo(self, gettagindex(self, "bombmount_right")));
-
- bomb_1.movetype = bomb_2.movetype = MOVETYPE_BOUNCE;
- bomb_1.velocity = bomb_2.velocity = self.velocity;
- bomb_1.touch = bomb_2.touch = raptor_bomb_burst;
- bomb_1.think = bomb_2.think = raptor_bomb_burst;
- bomb_1.cnt = bomb_2.cnt = time + 10;
-
- if(autocvar_g_vehicle_raptor_bomblet_alt)
- bomb_1.nextthink = bomb_2.nextthink = time;
- else
- bomb_1.nextthink = bomb_2.nextthink = time + autocvar_g_vehicle_raptor_bomblet_time;
-
- bomb_1.owner = bomb_2.owner = self;
- bomb_1.realowner = bomb_2.realowner = self.owner;
- bomb_1.solid = bomb_2.solid = SOLID_BBOX;
- bomb_1.gravity = bomb_2.gravity = 1;
-
- PROJECTILE_MAKETRIGGER(bomb_1);
- PROJECTILE_MAKETRIGGER(bomb_2);
-
- CSQCProjectile(bomb_1, true, PROJECTILE_RAPTORBOMB, true);
- CSQCProjectile(bomb_2, true, PROJECTILE_RAPTORBOMB, true);
-}
-
-
void raptor_land()
{SELFPARAM();
float hgt;
self.owner = world;
}
-void raptor_flare_touch()
-{SELFPARAM();
- remove(self);
-}
-
-void raptor_flare_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{SELFPARAM();
- self.health -= damage;
- if(self.health <= 0)
- remove(self);
-}
-
-void raptor_flare_think()
-{SELFPARAM();
- self.nextthink = time + 0.1;
- entity _missile = findchainentity(enemy, self.owner);
- while(_missile)
- {
- if(_missile.flags & FL_PROJECTILE)
- if(vlen(self.origin - _missile.origin) < autocvar_g_vehicle_raptor_flare_range)
- if(random() > autocvar_g_vehicle_raptor_flare_chase)
- _missile.enemy = self;
- _missile = _missile.chain;
- }
-
- if(self.tur_impacttime < time)
- remove(self);
-}
-
float raptor_frame()
{SELFPARAM();
entity player, raptor;
#endif // SVQC
#ifdef CSQC
-void RaptorCBShellfragDraw()
-{SELFPARAM();
- if(wasfreed(self))
- return;
-
- Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
- self.move_avelocity += randomvec() * 15;
- self.renderflags = 0;
-
- if(self.cnt < time)
- self.alpha = bound(0, self.nextthink - time, 1);
-
- if(self.alpha < ALPHA_MIN_VISIBLE)
- remove(self);
-}
-
-void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
-{SELFPARAM();
- entity sfrag;
-
- sfrag = spawn();
- setmodel(sfrag, MDL_VEH_RAPTOR_CB_FRAGMENT);
- setorigin(sfrag, _org);
-
- sfrag.move_movetype = MOVETYPE_BOUNCE;
- sfrag.gravity = 0.15;
- sfrag.solid = SOLID_CORPSE;
-
- sfrag.draw = RaptorCBShellfragDraw;
-
- sfrag.move_origin = sfrag.origin = _org;
- sfrag.move_velocity = _vel;
- sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity);
- sfrag.angles = self.move_angles = _ang;
-
- sfrag.move_time = time;
- sfrag.damageforcescale = 4;
-
- sfrag.nextthink = time + 3;
- sfrag.cnt = time + 2;
- sfrag.alpha = 1;
- sfrag.drawmask = MASK_NORMAL;
-}
-
METHOD(Raptor, vr_hud, bool(Raptor thisveh))
{
string crosshair;
--- /dev/null
+#ifndef VEHICLE_RAPTOR_WEAPONS_H
+#define VEHICLE_RAPTOR_WEAPONS_H
+
+#include "../../weapons/all.qh"
+
+CLASS(RaptorCannon, PortoLaunch)
+/* flags */ ATTRIB(RaptorCannon, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse */ ATTRIB(RaptorCannon, impulse, int, 3);
+/* refname */ ATTRIB(RaptorCannon, netname, string, "raptorcannon");
+/* wepname */ ATTRIB(RaptorCannon, message, string, _("Raptor cannon"));
+ENDCLASS(RaptorCannon)
+REGISTER_WEAPON(RAPTOR, NEW(RaptorCannon));
+
+CLASS(RaptorBomb, PortoLaunch)
+/* flags */ ATTRIB(RaptorBomb, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse */ ATTRIB(RaptorBomb, impulse, int, 3);
+/* refname */ ATTRIB(RaptorBomb, netname, string, "raptorbomb");
+/* wepname */ ATTRIB(RaptorBomb, message, string, _("Raptor bomb"));
+ENDCLASS(RaptorBomb)
+REGISTER_WEAPON(RAPTOR_BOMB, NEW(RaptorBomb));
+
+CLASS(RaptorFlare, PortoLaunch)
+/* flags */ ATTRIB(RaptorFlare, spawnflags, int, WEP_TYPE_OTHER);
+/* impulse */ ATTRIB(RaptorFlare, impulse, int, 3);
+/* refname */ ATTRIB(RaptorFlare, netname, string, "raptorflare");
+/* wepname */ ATTRIB(RaptorFlare, message, string, _("Raptor flare"));
+ENDCLASS(RaptorFlare)
+REGISTER_WEAPON(RAPTOR_FLARE, NEW(RaptorFlare));
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+
+float autocvar_g_vehicle_raptor_cannon_cost;
+float autocvar_g_vehicle_raptor_cannon_damage;
+float autocvar_g_vehicle_raptor_cannon_radius;
+float autocvar_g_vehicle_raptor_cannon_refire;
+float autocvar_g_vehicle_raptor_cannon_speed;
+float autocvar_g_vehicle_raptor_cannon_spread;
+float autocvar_g_vehicle_raptor_cannon_force;
+
+float autocvar_g_vehicle_raptor_bomblets;
+float autocvar_g_vehicle_raptor_bomblet_alt;
+float autocvar_g_vehicle_raptor_bomblet_time;
+float autocvar_g_vehicle_raptor_bomblet_damage;
+float autocvar_g_vehicle_raptor_bomblet_spread;
+float autocvar_g_vehicle_raptor_bomblet_edgedamage;
+float autocvar_g_vehicle_raptor_bomblet_radius;
+float autocvar_g_vehicle_raptor_bomblet_force;
+float autocvar_g_vehicle_raptor_bomblet_explode_delay;
+
+METHOD(RaptorCannon, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+ SELFPARAM();
+ bool isPlayer = IS_PLAYER(self);
+ entity player = isPlayer ? self : self.owner;
+ entity veh = player.vehicle;
+ setself(player);
+ // 1 [wait] 1 [wait] 2 [wait] 2 [wait] [wait]
+ float t = autocvar_g_vehicle_raptor_cannon_refire * (1 + veh.misc_bulletcounter == 4);
+ if (fire1)
+ if (weapon_prepareattack(false, t)) {
+ if (isPlayer) W_SetupShot_Dir(player, v_forward, false, 0, SND(Null), CH_WEAPON_B, 0);
+ vector org = w_shotorg;
+ vector dir = w_shotdir;
+ if (veh) {
+ veh.misc_bulletcounter += 1;
+ org = (veh.misc_bulletcounter <= 2) ? gettaginfo(veh.gun1, gettagindex(veh.gun1, "fire1"))
+ : (((veh.misc_bulletcounter == 4) ? veh.misc_bulletcounter = 0 : 0), gettaginfo(veh.gun2, gettagindex(veh.gun2, "fire1")));
+ dir = v_forward;
+ veh.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost;
+ self.cnt = time;
+ }
+ vehicles_projectile(EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
+ org, normalize(dir + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed,
+ autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force, 0,
+ DEATH_VH_RAPT_CANNON, PROJECTILE_RAPTORCANNON, 0, true, true, player);
+ weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
+ }
+ setself(this);
+ return true;
+}
+METHOD(RaptorCannon, 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_raptor_cannon_cost;
+}
+
+float autocvar_g_vehicle_raptor_bombs_refire;
+
+void raptor_bombdrop();
+METHOD(RaptorBomb, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+ SELFPARAM();
+ bool isPlayer = IS_PLAYER(self);
+ entity player = isPlayer ? self : self.owner;
+ setself(player);
+ if (fire2)
+ if (weapon_prepareattack(false, autocvar_g_vehicle_raptor_bombs_refire)) {
+ raptor_bombdrop();
+ weapon_thinkf(WFRAME_FIRE1, 0, w_ready);
+ }
+ setself(this);
+ return true;
+}
+
+float autocvar_g_vehicle_raptor_flare_refire;
+float autocvar_g_vehicle_raptor_flare_lifetime;
+float autocvar_g_vehicle_raptor_flare_chase;
+float autocvar_g_vehicle_raptor_flare_range;
+
+void raptor_flare_think();
+void raptor_flare_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
+void raptor_flare_touch();
+
+METHOD(RaptorFlare, wr_think, bool(entity thiswep, bool fire1, bool fire2)) {
+ SELFPARAM();
+ bool isPlayer = IS_PLAYER(self);
+ entity player = isPlayer ? self : self.owner;
+ setself(player);
+ if (fire2)
+ if (weapon_prepareattack(true, autocvar_g_vehicle_raptor_flare_refire)) {
+ for(int i = 0; i < 3; ++i) {
+ entity _flare = spawn();
+ setmodel(_flare, MDL_VEH_RAPTOR_FLARE);
+ _flare.effects = EF_LOWPRECISION | EF_FLAME;
+ _flare.scale = 0.5;
+ setorigin(_flare, self.origin - '0 0 16');
+ _flare.movetype = MOVETYPE_TOSS;
+ _flare.gravity = 0.15;
+ _flare.velocity = 0.25 * self.velocity + (v_forward + randomvec() * 0.25)* -500;
+ _flare.think = raptor_flare_think;
+ _flare.nextthink = time;
+ _flare.owner = self;
+ _flare.solid = SOLID_CORPSE;
+ _flare.takedamage = DAMAGE_YES;
+ _flare.event_damage = raptor_flare_damage;
+ _flare.health = 20;
+ _flare.tur_impacttime = time + autocvar_g_vehicle_raptor_flare_lifetime;
+ _flare.touch = raptor_flare_touch;
+ }
+ weapon_thinkf(WFRAME_FIRE2, 0, w_ready);
+ }
+ setself(this);
+ return true;
+}
+
+
+void raptor_bomblet_boom()
+{SELFPARAM();
+ RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage,
+ autocvar_g_vehicle_raptor_bomblet_edgedamage,
+ autocvar_g_vehicle_raptor_bomblet_radius, world, world,
+ autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB, world);
+ remove(self);
+}
+
+void raptor_bomblet_touch()
+{SELFPARAM();
+ if(other == self.owner)
+ return;
+
+ PROJECTILE_TOUCH;
+ self.think = raptor_bomblet_boom;
+ self.nextthink = time + random() * autocvar_g_vehicle_raptor_bomblet_explode_delay;
+}
+
+void raptor_bomb_burst()
+{SELFPARAM();
+ if(self.cnt > time)
+ if(autocvar_g_vehicle_raptor_bomblet_alt)
+ {
+ self.nextthink = time;
+ traceline(self.origin, self.origin + (normalize(self.velocity) * autocvar_g_vehicle_raptor_bomblet_alt), MOVE_NORMAL, self);
+ if((trace_fraction == 1.0) || (vlen(self.origin - self.owner.origin) < autocvar_g_vehicle_raptor_bomblet_radius))
+ {
+ UpdateCSQCProjectile(self);
+ return;
+ }
+ }
+
+ entity bomblet;
+ float i;
+
+ Damage_DamageInfo(self.origin, 0, 0, 0, '0 0 0', DEATH_VH_RAPT_FRAGMENT, 0, self);
+
+ for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i)
+ {
+ bomblet = spawn();
+ setorigin(bomblet, self.origin);
+
+ bomblet.movetype = MOVETYPE_TOSS;
+ bomblet.touch = raptor_bomblet_touch;
+ bomblet.think = raptor_bomblet_boom;
+ bomblet.nextthink = time + 5;
+ bomblet.owner = self.owner;
+ bomblet.realowner = self.realowner;
+ bomblet.velocity = normalize(normalize(self.velocity) + (randomvec() * autocvar_g_vehicle_raptor_bomblet_spread)) * vlen(self.velocity);
+
+ PROJECTILE_MAKETRIGGER(bomblet);
+ CSQCProjectile(bomblet, true, PROJECTILE_RAPTORBOMBLET, true);
+ }
+
+ remove(self);
+}
+
+void raptor_bombdrop()
+{SELFPARAM();
+ entity bomb_1, bomb_2;
+
+ bomb_1 = spawn();
+ bomb_2 = spawn();
+
+ setorigin(bomb_1, gettaginfo(self, gettagindex(self, "bombmount_left")));
+ setorigin(bomb_2, gettaginfo(self, gettagindex(self, "bombmount_right")));
+
+ bomb_1.movetype = bomb_2.movetype = MOVETYPE_BOUNCE;
+ bomb_1.velocity = bomb_2.velocity = self.velocity;
+ bomb_1.touch = bomb_2.touch = raptor_bomb_burst;
+ bomb_1.think = bomb_2.think = raptor_bomb_burst;
+ bomb_1.cnt = bomb_2.cnt = time + 10;
+
+ if(autocvar_g_vehicle_raptor_bomblet_alt)
+ bomb_1.nextthink = bomb_2.nextthink = time;
+ else
+ bomb_1.nextthink = bomb_2.nextthink = time + autocvar_g_vehicle_raptor_bomblet_time;
+
+ bomb_1.owner = bomb_2.owner = self;
+ bomb_1.realowner = bomb_2.realowner = self.owner;
+ bomb_1.solid = bomb_2.solid = SOLID_BBOX;
+ bomb_1.gravity = bomb_2.gravity = 1;
+
+ PROJECTILE_MAKETRIGGER(bomb_1);
+ PROJECTILE_MAKETRIGGER(bomb_2);
+
+ CSQCProjectile(bomb_1, true, PROJECTILE_RAPTORBOMB, true);
+ CSQCProjectile(bomb_2, true, PROJECTILE_RAPTORBOMB, true);
+}
+
+void raptor_flare_touch()
+{SELFPARAM();
+ remove(self);
+}
+
+void raptor_flare_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{SELFPARAM();
+ self.health -= damage;
+ if(self.health <= 0)
+ remove(self);
+}
+
+void raptor_flare_think()
+{SELFPARAM();
+ self.nextthink = time + 0.1;
+ entity _missile = findchainentity(enemy, self.owner);
+ while(_missile)
+ {
+ if(_missile.flags & FL_PROJECTILE)
+ if(vlen(self.origin - _missile.origin) < autocvar_g_vehicle_raptor_flare_range)
+ if(random() > autocvar_g_vehicle_raptor_flare_chase)
+ _missile.enemy = self;
+ _missile = _missile.chain;
+ }
+
+ if(self.tur_impacttime < time)
+ remove(self);
+}
+
+#endif
+
+#ifdef CSQC
+
+void RaptorCBShellfragDraw()
+{SELFPARAM();
+ if(wasfreed(self))
+ return;
+
+ Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
+ self.move_avelocity += randomvec() * 15;
+ self.renderflags = 0;
+
+ if(self.cnt < time)
+ self.alpha = bound(0, self.nextthink - time, 1);
+
+ if(self.alpha < ALPHA_MIN_VISIBLE)
+ remove(self);
+}
+
+void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
+{SELFPARAM();
+ entity sfrag;
+
+ sfrag = spawn();
+ setmodel(sfrag, MDL_VEH_RAPTOR_CB_FRAGMENT);
+ setorigin(sfrag, _org);
+
+ sfrag.move_movetype = MOVETYPE_BOUNCE;
+ sfrag.gravity = 0.15;
+ sfrag.solid = SOLID_CORPSE;
+
+ sfrag.draw = RaptorCBShellfragDraw;
+
+ sfrag.move_origin = sfrag.origin = _org;
+ sfrag.move_velocity = _vel;
+ sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity);
+ sfrag.angles = self.move_angles = _ang;
+
+ sfrag.move_time = time;
+ sfrag.damageforcescale = 4;
+
+ sfrag.nextthink = time + 3;
+ sfrag.cnt = time + 2;
+ sfrag.alpha = 1;
+ sfrag.drawmask = MASK_NORMAL;
+}
+
+#endif
+
+#endif