From 8d97cb0d2c3c43f97f3bb74ab20c300eb7bb2753 Mon Sep 17 00:00:00 2001 From: TimePath Date: Thu, 1 Oct 2015 09:27:55 +1000 Subject: [PATCH] Vehicles: factor out attacks --- qcsrc/common/vehicles/vehicle/racer.qc | 197 +---------- qcsrc/common/vehicles/vehicle/racer_weapon.qc | 215 ++++++++++++ qcsrc/common/vehicles/vehicle/raptor.qc | 309 +---------------- .../common/vehicles/vehicle/raptor_weapons.qc | 321 ++++++++++++++++++ 4 files changed, 545 insertions(+), 497 deletions(-) create mode 100644 qcsrc/common/vehicles/vehicle/racer_weapon.qc create mode 100644 qcsrc/common/vehicles/vehicle/raptor_weapons.qc diff --git a/qcsrc/common/vehicles/vehicle/racer.qc b/qcsrc/common/vehicles/vehicle/racer.qc index dad0fd12e..da10b87d0 100644 --- a/qcsrc/common/vehicles/vehicle/racer.qc +++ b/qcsrc/common/vehicles/vehicle/racer.qc @@ -1,6 +1,8 @@ #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); @@ -16,74 +18,18 @@ CLASS(Racer, Vehicle) /* 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; @@ -130,20 +76,10 @@ 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_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; @@ -218,129 +154,6 @@ void racer_align4point(float _delta) 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(); diff --git a/qcsrc/common/vehicles/vehicle/racer_weapon.qc b/qcsrc/common/vehicles/vehicle/racer_weapon.qc new file mode 100644 index 000000000..79bb2d661 --- /dev/null +++ b/qcsrc/common/vehicles/vehicle/racer_weapon.qc @@ -0,0 +1,215 @@ +#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 diff --git a/qcsrc/common/vehicles/vehicle/raptor.qc b/qcsrc/common/vehicles/vehicle/raptor.qc index aa6f3096e..6d06cbc38 100644 --- a/qcsrc/common/vehicles/vehicle/raptor.qc +++ b/qcsrc/common/vehicles/vehicle/raptor.qc @@ -2,6 +2,8 @@ #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'); @@ -17,143 +19,15 @@ CLASS(Raptor, Vehicle) /* 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; @@ -171,16 +45,6 @@ float autocvar_g_vehicle_raptor_speed_up; 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; @@ -217,98 +81,6 @@ float raptor_altitude(float amax) 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; @@ -384,35 +156,6 @@ void raptor_exit(float eject) 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; @@ -1046,50 +789,6 @@ void spawnfunc_vehicle_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; diff --git a/qcsrc/common/vehicles/vehicle/raptor_weapons.qc b/qcsrc/common/vehicles/vehicle/raptor_weapons.qc new file mode 100644 index 000000000..24b885ea1 --- /dev/null +++ b/qcsrc/common/vehicles/vehicle/raptor_weapons.qc @@ -0,0 +1,321 @@ +#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 -- 2.39.2