]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Implement cl_gunoffset: adjusts position of first person weapon viewmodel
authorbones_was_here <bones_was_here@xonotic.au>
Tue, 22 Nov 2022 03:50:09 +0000 (13:50 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Tue, 13 Dec 2022 01:15:43 +0000 (11:15 +1000)
Fixes first person viewmodel casings being drawn on spectating clients
with r_drawviewmodel 0 set.

Fixes casing bitflag(s) being sent to clients other than the intended one(s).

Includes casing-related refactoring.

qcsrc/client/view.qc
qcsrc/client/view.qh
qcsrc/common/effects/qc/casings.qc
xonotic-client.cfg

index fce90d7bf67f5f11f63fdbb6e21ff9a4fd79d824..c61a86e2d069a63a5d62c1d684b4847ddbe67475 100644 (file)
@@ -313,6 +313,7 @@ void viewmodel_draw(entity this)
                {
                        this.name_last = name;
                        CL_WeaponEntity_SetModel(this, name, swap);
+                       this.origin += autocvar_cl_gunoffset;
                        this.viewmodel_origin = this.origin;
                        this.viewmodel_angles = this.angles;
                }
index 45959383bdf38c893dc30abad243237c01629e79..cd33ebfb6a1201e41f9caa706209c1cc2fcb3d92 100644 (file)
@@ -92,6 +92,7 @@ vector autocvar_cl_eventchase_viewoffset = '0 0 20';
 string autocvar__togglezoom;
 int autocvar_cl_nade_timer;
 bool autocvar_r_drawviewmodel;
+vector autocvar_cl_gunoffset;
 
 void calc_followmodel_ofs(entity view);
 
index c0c7f5ac98d41bc95cb90948d4234f84c007f6dc..08864459dbaed7c6a76fd8a85eda3d60efe07940 100644 (file)
@@ -22,10 +22,18 @@ void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float ran
        FOREACH_CLIENT(true, {
                if (!(CS_CVAR(it).cvar_cl_casings))
                        continue;
-               if (it == casingowner && !(CS_CVAR(it).cvar_r_drawviewmodel))
-                       continue;
 
-               msg_entity = it;
+               casingtype &= 0x3F; // reset any bitflags that were set for the previous client
+
+               if (it == casingowner || (IS_SPEC(it) && it.enemy == casingowner))
+               {
+                       if (!(CS_CVAR(it).cvar_r_drawviewmodel))
+                               continue;
+
+                       casingtype |= 0x40; // client will apply autocvar_cl_gunoffset in first person
+               }
+
+               msg_entity = it; // sound_allowed checks this
                if (!sound_allowed(MSG_ONE, it))
                        casingtype |= 0x80; // silent
 
@@ -133,27 +141,29 @@ void Casing_Damage(entity this, float thisdmg, int hittype, vector org, vector t
 
 NET_HANDLE(casings, bool isNew)
 {
-    int _state = ReadByte();
-    vector org = ReadVector();
-    vector vel = decompressShortVector(ReadShort());
-    vector ang;
-    ang_x = ReadByte() * 360 / 256;
-    ang_y = ReadByte() * 360 / 256;
-    ang_z = ReadByte() * 360 / 256;
+    Casing casing = ListNewChildRubble(CasingsNGibs, new(casing));
+
+    casing.state = ReadByte();
+    casing.origin = ReadVector();
+    casing.velocity = decompressShortVector(ReadShort());
+    casing.angles_x = ReadByte() * 360 / 256;
+    casing.angles_y = ReadByte() * 360 / 256;
+    casing.angles_z = ReadByte() * 360 / 256;
+
     return = true;
 
-    Casing casing = ListNewChildRubble(CasingsNGibs, new(casing));
-    casing.silent = (_state & 0x80);
-    casing.state = (_state & 0x7F);
-    casing.origin = org;
+    casing.silent = casing.state & 0x80;
+    if (casing.state & 0x40 && !autocvar_chase_active)
+        casing.origin += autocvar_cl_gunoffset.x * v_forward
+                       - autocvar_cl_gunoffset.y * v_right
+                       + autocvar_cl_gunoffset.z * v_up;
+    casing.state &= 0x3F; // the 2 most significant bits are reserved for the silent and casingowner bitflags
+
     setorigin(casing, casing.origin);
-    casing.velocity = vel;
-    casing.angles = ang;
     casing.drawmask = MASK_NORMAL;
-
     casing.draw = Casing_Draw;
     if (isNew) IL_PUSH(g_drawables, casing);
-    casing.velocity = casing.velocity + 2 * prandomvec();
+    casing.velocity += 2 * prandomvec();
     casing.avelocity = '0 250 0' + 100 * prandomvec();
     set_movetype(casing, MOVETYPE_BOUNCE);
     casing.bouncefactor = 0.25;
index d427b0f5a7fe73edb0ebd0510fb003778243a469..f85a05fa023c0c3f9b2caee0588e8ff528aa6a63 100644 (file)
@@ -307,6 +307,7 @@ r_shadow_realtime_world_importlightentitiesfrommap 0 // Whether build process us
 cl_decals_fadetime 5
 cl_decals_time 1
 seta cl_gunalign 3 "Gun alignment; 1 = center, 3 = right, 4 = left; requires reconnect"
+seta cl_gunoffset "0 0 0" "Adjust the weapon viewmodel position, applies only to your own first person view and is relative to cl_gunalign"
 seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
 seta cl_particlegibs 0 "simpler gibs"
 seta cl_gibs_damageforcescale 3.5 "force to push around gibs"