]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/vehicles/vehicle/racer.qc
Vehicles: fix racer cannon damage ownership
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / vehicles / vehicle / racer.qc
index 0606e9d38bcfde70470492b9b7ed8baf1c0f55ac..dad0fd12eebf362f764295f1c6d50e801255edb9 100644 (file)
@@ -1,25 +1,23 @@
 #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"
 
@@ -38,17 +36,53 @@ REGISTER_WEAPON(RACER, NEW(RacerAttack));
 #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;
 
@@ -96,14 +130,6 @@ 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;
@@ -192,23 +218,6 @@ void racer_align4point(float _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;
-}
-
 void racer_rocket_groundhugger()
 {SELFPARAM();
        vector olddir, newdir;
@@ -313,11 +322,10 @@ void racer_rocket_tracker()
        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);
 
@@ -333,6 +341,13 @@ void racer_fire_rocket(string tagname, entity trg)
                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;
@@ -480,26 +495,21 @@ float racer_frame()
        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)
@@ -528,12 +538,12 @@ float racer_frame()
 
                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;
@@ -734,11 +744,7 @@ void racer_draw()
 #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)
@@ -747,7 +753,7 @@ bool v_racer(Vehicle thisveh, int req)
                        return true;
                }
 
-               case VR_ENTER:
+               METHOD(Racer, vr_enter, bool(Racer thisveh))
                {
                #ifdef SVQC
                        self.movetype = MOVETYPE_BOUNCE;
@@ -764,7 +770,7 @@ bool v_racer(Vehicle thisveh, int req)
                        return true;
                }
 
-               case VR_SPAWN:
+               METHOD(Racer, vr_spawn, bool(Racer thisveh))
                {
                #ifdef SVQC
                        if(self.scale != 0.5)
@@ -803,7 +809,7 @@ bool v_racer(Vehicle thisveh, int req)
                        return true;
                }
 
-               case VR_DEATH:
+               METHOD(Racer, vr_death, bool(Racer thisveh))
                {
                #ifdef SVQC
                        self.SendEntity         = func_null; // stop networking this racer (for now)
@@ -836,7 +842,7 @@ bool v_racer(Vehicle thisveh, int req)
                }
 
 #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,
@@ -845,7 +851,7 @@ bool v_racer(Vehicle thisveh, int req)
                        return true;
                }
 #endif
-               case VR_SETUP:
+               METHOD(Racer, vr_setup, bool(Racer thisveh))
                {
                #ifdef SVQC
                        self.vehicle_exit = racer_exit;
@@ -878,13 +884,9 @@ bool v_racer(Vehicle thisveh, int req)
                        return true;
                }
 
-               case VR_PRECACHE:
+               METHOD(Racer, vr_precache, bool(Racer thisveh))
                {
                        return true;
                }
-       }
-
-       return true;
-}
 
 #endif // REGISTER_VEHICLE