]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/g_hook.qc
do NOT call cvar() again, do it right
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / g_hook.qc
index 93f7ed96cfa8b3be8a99e2eb91ac1ac3d1aaf305..ef379b9bc53bc0048d76bd335c4307c28f1b9735 100644 (file)
@@ -1,6 +1,6 @@
 /*============================================
 
-      Wazat's Nexuiz Grappling Hook
+      Wazat's Xonotic Grappling Hook
 
         Contact: Wazat1@gmail.com
 
@@ -114,10 +114,37 @@ void GrapplingHook_Stop()
        self.hook_length = -1;
 }
 
+.vector hook_start, hook_end;
+float GrapplingHookSend(entity to, float sf)
+{
+       WriteByte(MSG_ENTITY, ENT_CLIENT_HOOK);
+       sf = sf & 0x7F;
+       if(sound_allowed(MSG_BROADCAST, self.owner))
+               sf |= 0x80;
+       WriteByte(MSG_ENTITY, sf);
+       if(sf & 1)
+       {
+               WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+       }
+       if(sf & 2)
+       {
+               WriteCoord(MSG_ENTITY, self.hook_start_x);
+               WriteCoord(MSG_ENTITY, self.hook_start_y);
+               WriteCoord(MSG_ENTITY, self.hook_start_z);
+       }
+       if(sf & 4)
+       {
+               WriteCoord(MSG_ENTITY, self.hook_end_x);
+               WriteCoord(MSG_ENTITY, self.hook_end_y);
+               WriteCoord(MSG_ENTITY, self.hook_end_z);
+       }
+       return TRUE;
+}
+
 void GrapplingHookThink()
 {
-       float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch;
-       vector dir, org, end, v0, dv, v, myorg;
+       float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch, s;
+       vector dir, org, end, v0, dv, v, myorg, vs;
        if(self.owner.health <= 0 || self.owner.hook != self)   // how did that happen?
        {                                                                                                               // well, better fix it anyway
                remove(self);
@@ -133,8 +160,14 @@ void GrapplingHookThink()
 
        self.nextthink = time;
 
+       s = self.owner.cvar_cl_gunalign;
+       if(s != 1 && s != 2 && s != 4)
+               s = 3; // default value
+       --s;
+       vs = hook_shotorigin[s];
+
        makevectors(self.owner.v_angle);
-       org = self.owner.origin + self.owner.view_ofs + v_forward * hook_shotorigin_x + v_right * hook_shotorigin_y + v_up * hook_shotorigin_z;
+       org = self.owner.origin + self.owner.view_ofs + v_forward * vs_x + v_right * -vs_y + v_up * vs_z;
        myorg = WarpZone_RefSys_TransformOrigin(self.owner, self, org);
 
        if(self.hook_length < 0)
@@ -142,24 +175,24 @@ void GrapplingHookThink()
 
        if(self.state == 1)
        {
-               pullspeed = cvar("g_balance_grapplehook_speed_pull");//2000;
+               pullspeed = autocvar_g_balance_grapplehook_speed_pull;//2000;
                // speed the rope is pulled with
 
-               rubberforce = cvar("g_balance_grapplehook_force_rubber");//2000;
+               rubberforce = autocvar_g_balance_grapplehook_force_rubber;//2000;
                // force the rope will use if it is stretched
 
-               rubberforce_overstretch = cvar("g_balance_grapplehook_force_rubber_overstretch");//1000;
+               rubberforce_overstretch = autocvar_g_balance_grapplehook_force_rubber_overstretch;//1000;
                // force the rope will use if it is stretched
 
-               minlength = cvar("g_balance_grapplehook_length_min");//100;
+               minlength = autocvar_g_balance_grapplehook_length_min;//100;
                // minimal rope length
                // if the rope goes below this length, it isn't pulled any more
 
-               ropestretch = cvar("g_balance_grapplehook_stretch");//400;
+               ropestretch = autocvar_g_balance_grapplehook_stretch;//400;
                // if the rope is stretched by more than this amount, more rope is
                // given to you again
 
-               ropeairfriction = cvar("g_balance_grapplehook_airfriction");//0.2
+               ropeairfriction = autocvar_g_balance_grapplehook_airfriction;//0.2
                // while hanging on the rope, this friction component will help you a
                // bit to control the rope
 
@@ -167,7 +200,7 @@ void GrapplingHookThink()
                dist = vlen(dir);
                dir = normalize(dir);
 
-               if(cvar("g_grappling_hook_tarzan"))
+               if(autocvar_g_grappling_hook_tarzan)
                {
                        v = v0 = WarpZone_RefSys_TransformVelocity(self.owner, self, self.owner.velocity);
 
@@ -200,7 +233,7 @@ void GrapplingHookThink()
                                v = v + frametime * dir * spd * rubberforce;
 
                                dv = ((v - v0) * dir) * dir;
-                               if(cvar("g_grappling_hook_tarzan") >= 2)
+                               if(autocvar_g_grappling_hook_tarzan >= 2)
                                {
                                        if(self.aiment.movetype == MOVETYPE_WALK)
                                        {
@@ -208,7 +241,7 @@ void GrapplingHookThink()
                                                self.aiment.velocity = self.aiment.velocity - dv * 0.5;
                                                self.aiment.flags &~= FL_ONGROUND;
                                                self.aiment.pusher = self.owner;
-                                               self.aiment.pushltime = time + cvar("g_maxpushtime");
+                                               self.aiment.pushltime = time + autocvar_g_maxpushtime;
                                        }
                                }
 
@@ -235,7 +268,18 @@ void GrapplingHookThink()
        }
 
        makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0');
-       te_beam(self.owner, WarpZone_RefSys_TransformOrigin(self, self.owner, self.origin) + v_forward * (-9), org);
+       myorg = WarpZone_RefSys_TransformOrigin(self, self.owner, self.origin); // + v_forward * (-9);
+
+       if(myorg != self.hook_start)
+       {
+               self.SendFlags |= 2;
+               self.hook_start = myorg;
+       }
+       if(org != self.hook_end)
+       {
+               self.SendFlags |= 4;
+               self.hook_end = org;
+       }
 }
 
 void GrapplingHookTouch (void)
@@ -271,7 +315,7 @@ void GrapplingHook_Damage (entity inflictor, entity attacker, float damage, floa
                        if(attacker != self.owner)
                        {
                                self.owner.pusher = attacker;
-                               self.owner.pushltime = time + cvar("g_maxpushtime");
+                               self.owner.pushltime = time + autocvar_g_maxpushtime;
                        }
                        RemoveGrapplingHook(self.owner);
                }
@@ -282,15 +326,27 @@ void FireGrapplingHook (void)
 {
        local entity missile;
        local vector org;
+       float s;
+       vector vs;
 
        if((arena_roundbased && time < warmup) || (time < game_starttime))
                return;
 
        makevectors(self.v_angle);
 
+       s = self.cvar_cl_gunalign;
+       if(s != 1 && s != 2 && s != 4)
+               s = 3; // default value
+       --s;
+       vs = hook_shotorigin[s];
+
        // UGLY WORKAROUND: play this on CHAN_WEAPON2 so it can't cut off fire sounds
        sound (self, CHAN_WEAPON2, "weapons/hook_fire.wav", VOL_BASE, ATTN_NORM);
-       org = self.origin + self.view_ofs + v_forward * hook_shotorigin_x + v_right * hook_shotorigin_y + v_up * hook_shotorigin_z;
+       org = self.origin + self.view_ofs + v_forward * vs_x + v_right * -vs_y + v_up * vs_z;
+
+       tracebox(self.origin + self.view_ofs, '-3 -3 -3', '3 3 3', org, MOVE_NORMAL, self);
+       org = trace_endpos;
+
        pointparticles(particleeffectnum("grapple_muzzleflash"), org, '0 0 0', 1);
 
        missile = WarpZone_RefSys_SpawnSameRefSys(self);
@@ -301,13 +357,13 @@ void FireGrapplingHook (void)
        missile.movetype = MOVETYPE_FLY;
        PROJECTILE_MAKETRIGGER(missile);
 
-       setmodel (missile, "models/hook.md3"); // precision set below
+       //setmodel (missile, "models/hook.md3"); // precision set below
        setsize (missile, '-3 -3 -3', '3 3 3');
        setorigin (missile, org);
 
        missile.state = 0; // not latched onto anything
 
-       W_SetupProjectileVelocityEx(missile, v_forward, v_up, cvar("g_balance_grapplehook_speed_fly"), 0, 0, 0);
+       W_SetupProjectileVelocityEx(missile, v_forward, v_up, autocvar_g_balance_grapplehook_speed_fly, 0, 0, 0, FALSE);
 
        missile.angles = vectoangles (missile.velocity);
        //missile.glow_color = 250; // 244, 250
@@ -318,15 +374,19 @@ void FireGrapplingHook (void)
 
        missile.effects = /*EF_FULLBRIGHT | EF_ADDITIVE |*/ EF_LOWPRECISION;
 
-       missile.health = cvar("g_balance_grapplehook_health");//120
+       missile.health = autocvar_g_balance_grapplehook_health;//120
        missile.event_damage = GrapplingHook_Damage;
        missile.takedamage = DAMAGE_AIM;
        missile.damageforcescale = 0;
+
+       missile.hook_start = missile.hook_end = missile.origin;
+
+       Net_LinkEntity(missile, FALSE, 0, GrapplingHookSend);
 }
 
 //  void GrapplingHookFrame()
 //  {
-//         // this function has been modified for Nexuiz
+//         // this function has been modified for Xonotic
 // -       if (self.BUTTON_HOOK && g_grappling_hook)
 //         {
 // -               if (!self.hook && self.hook_time <= time && !self.button6_pressed_before)
@@ -434,14 +494,25 @@ void GrapplingHookFrame()
 void GrappleHookInit()
 {
        if(g_grappling_hook)
-               hook_shotorigin = '8 -8 -12';
+       {
+               hook_shotorigin[0] = '8 8 -12';
+               hook_shotorigin[1] = '8 8 -12';
+               hook_shotorigin[2] = '8 8 -12';
+               hook_shotorigin[3] = '8 8 -12';
+       }
        else
-               hook_shotorigin = shotorg_adjust('26.2148 9.2059 -15.9772', TRUE, FALSE);
+       {
+               weapon_action(WEP_HOOK, WR_PRECACHE);
+               hook_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 1);
+               hook_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 2);
+               hook_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 3);
+               hook_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 4);
+       }
 }
 
 void SetGrappleHookBindings()
 {
-       // this function has been modified for Nexuiz
+       // this function has been modified for Xonotic
        // don't remove these lines! old server or demos coud overwrite the new aliases
        stuffcmd(self, "alias +hook +button6\n");
        stuffcmd(self, "alias -hook -button6\n");