]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
items: use correct bboxes in CSQC
authorbones_was_here <bones_was_here@xonotic.au>
Fri, 21 Jul 2023 09:13:36 +0000 (19:13 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Thu, 14 Mar 2024 22:14:46 +0000 (08:14 +1000)
This only needs to send 2 bits because there's now only 3 item bbox sizes.
Fixes some prediction errors for items with physics (loot).

qcsrc/client/items/items.qc
qcsrc/common/items/item.qh
qcsrc/server/items/items.qc

index dba2c8ffcd15fbcbabda8296e7646b0d47a9fd08..b72269a9e4b36c36c1b34ee4a49d36b82da47e66 100644 (file)
@@ -15,6 +15,7 @@
 .float anim_start_time; // reusing for bob waveform synchronisation
 .vector angles_held; // reusing for (re)storing original angles
 .float wait, delay, pointtime; // reusing for despawn effects
+.vector m_mins, m_maxs; // reusing for storing standard bbox (same purpose as in SVQC itemdef)
 
 HashMap ENT_CLIENT_ITEM_simple;
 STATIC_INIT(ENT_CLIENT_ITEM_simple)
@@ -69,8 +70,7 @@ void ItemSetModel(entity this, bool wantsimple)
                LOG_WARNF("this.model is unset for item %s", this.classname);
        precache_model(this.model);
        _setmodel(this, this.model);
-       setsize(this, '-16 -16 0', '16 16 48');
-       // bones_was_here TODO: network proper box size for sv_legacy_bbox_expand 0
+       setsize(this, this.m_mins, this.m_maxs);
 }
 
 void ItemDraw(entity this)
@@ -137,9 +137,8 @@ void ItemDraw(entity this)
        if (bobheight != this.origin_z - this.oldorigin_z)
        {
                this.origin_z = this.oldorigin_z + bobheight;
-               this.mins_z = 0 - bobheight; // don't want the absmin and absmax to bob
-               this.maxs_z = 48 - bobheight;
-               // bones_was_here TODO: network proper box size for sv_legacy_bbox_expand 0
+               this.mins_z = this.m_mins.z - bobheight; // don't want the absmin and absmax to bob
+               this.maxs_z = this.m_maxs.z - bobheight;
        }
 
        // set alpha based on distance
@@ -235,13 +234,6 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
                this.angles = this.angles_held = ReadAngleVector();
        }
 
-       /* bones_was_here TODO: network proper box size for sv_legacy_bbox_expand 0
-       if(sf & ISF_SIZE)
-       {
-               setsize(this, '-16 -16 0', '16 16 48');
-       }
-       */
-
        if(sf & ISF_STATUS) // need to read/write status first so model can handle simple, fb etc.
        {
                int prevItemStatus = this.ItemStatus;
@@ -280,7 +272,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
                }
        }
 
-       if(sf & ISF_MODEL)
+       if(sf & ISF_SIZE || sf & ISF_SIZE2) // always true when it's spawned (in CSQC's perspective)
        {
                if(isnew)
                {
@@ -290,6 +282,22 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
                        this.entremove = ItemRemove;
                }
 
+               if(sf & ISF_SIZE && !(sf & ISF_SIZE2)) // Small
+               {
+                       this.m_mins = ITEM_S_MINS;
+                       this.m_maxs = ITEM_S_MAXS;
+               }
+               else if(!(sf & ISF_SIZE) && sf & ISF_SIZE2) // Large
+               {
+                       this.m_mins = ITEM_D_MINS;
+                       this.m_maxs = ITEM_L_MAXS;
+               }
+               else // Default
+               {
+                       this.m_mins = ITEM_D_MINS;
+                       this.m_maxs = ITEM_D_MAXS;
+               }
+
                this.fade_end = ReadShort();
 
                strcpy(this.mdl, ReadString());
@@ -323,7 +331,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
                SET_ONGROUND(this); // extra overkill
        }
 
-       if(sf & ISF_REMOVEFX && !(sf & ISF_SIZE) && !(sf & ISF_MODEL)) // TODO !isnew isn't reliable for this... are we double sending initialisations?
+       if(sf & ISF_REMOVEFX && !(sf & ISF_SIZE) && !(sf & ISF_SIZE2)) // TODO !isnew isn't reliable for this... are we double sending initialisations?
        {
                // no longer available to pick up, about to be removed
                if (this.drawmask) // this.alpha > 0
index deffed13da58e465f48238bd87daa02e5b5d6fbf..1b29d71bd526f773b2d0153e3e009dec3903ee39 100644 (file)
@@ -40,7 +40,7 @@ const int IT_PICKUPMASK                       = IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPER
 // item networking
 const int ISF_REMOVEFX          = BIT(0); // technically unnecessary (after the kludge in Item_Think() is reverted), but cheaper and cleaner than using ITS_AVAILABLE
 const int ISF_LOCATION          = BIT(1);
-const int ISF_MODEL             = BIT(2);
+const int ISF_SIZE2             = BIT(2);
 const int ISF_STATUS            = BIT(3);
 const int ISF_COLORMAP          = BIT(4);
 const int ISF_DROP              = BIT(5);
index f4853c5c7203c9d36c57ebcce6d2520c1b80a310..820f88ebfe6ee258efc592252ab4480b337d9203 100644 (file)
@@ -36,6 +36,24 @@ bool ItemSend(entity this, entity to, int sf)
        else
                sf &= ~ISF_DROP;
 
+       // if this item is being spawned (in CSQC's perspective)
+       // reuse ISF_SIZE and ISF_SIZE2 to also tell CSQC its bbox size
+       if(sf & ISF_SIZE)
+       {
+               if(this.maxs == ITEM_S_MAXS) // Small
+               {
+                       sf |= ISF_SIZE;
+                       sf &= ~ISF_SIZE2;
+               }
+               else if(this.maxs == ITEM_L_MAXS) // Large
+               {
+                       sf &= ~ISF_SIZE;
+                       sf |= ISF_SIZE2;
+               }
+               else // Default
+                       sf |= ISF_SIZE | ISF_SIZE2;
+       }
+
        WriteHeader(MSG_ENTITY, ENT_CLIENT_ITEM);
        WriteByte(MSG_ENTITY, sf);
 
@@ -50,13 +68,10 @@ bool ItemSend(entity this, entity to, int sf)
                WriteAngleVector(MSG_ENTITY, this.angles);
        }
 
-       // sets size on the client, unused on server
-       //if(sf & ISF_SIZE)
-
        if(sf & ISF_STATUS)
                WriteByte(MSG_ENTITY, this.ItemStatus);
 
-       if(sf & ISF_MODEL)
+       if(sf & ISF_SIZE || sf & ISF_SIZE2) // always true when it's spawned (in CSQC's perspective)
        {
                WriteShort(MSG_ENTITY, bound(0, this.fade_end, 32767));