+typedef struct
+{
+ unsigned char type; // 1/2/8 or other value if isn't used
+ int fieldoffset;
+}autosentstat_t;
+
+static autosentstat_t *vm_autosentstats = NULL; //[515]: it starts from 0, not 32
+static int vm_autosentstats_last;
+
+void VM_AutoSentStats_Clear (void)
+{
+ if(vm_autosentstats)
+ {
+ free(vm_autosentstats);
+ vm_autosentstats = NULL;
+ vm_autosentstats_last = -1;
+ }
+}
+
+//[515]: add check if even bigger ? "try to use two stats, cause it's too big" ?
+#define VM_SENDSTAT(a,b,c)\
+{\
+/* if((c))*/\
+ if((c)==(unsigned char)(c))\
+ {\
+ MSG_WriteByte((a), svc_updatestatubyte);\
+ MSG_WriteByte((a), (b));\
+ MSG_WriteByte((a), (c));\
+ }\
+ else\
+ {\
+ MSG_WriteByte((a), svc_updatestat);\
+ MSG_WriteByte((a), (b));\
+ MSG_WriteLong((a), (c));\
+ }\
+}\
+
+void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
+{
+ int i, v, *si;
+ char s[17];
+ const char *t;
+ qboolean send;
+ union
+ {
+ float f;
+ int i;
+ }k;
+
+ if(!vm_autosentstats)
+ return;
+
+ send = (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE && sv.protocol != PROTOCOL_DARKPLACES1 && sv.protocol != PROTOCOL_DARKPLACES2 && sv.protocol != PROTOCOL_DARKPLACES3 && sv.protocol != PROTOCOL_DARKPLACES4 && sv.protocol != PROTOCOL_DARKPLACES5);
+
+ for(i=0; i<vm_autosentstats_last+1 ;i++)
+ {
+ if(!vm_autosentstats[i].type)
+ continue;
+ switch(vm_autosentstats[i].type)
+ {
+ //string
+ case 1:
+ t = PRVM_E_STRING(ent, vm_autosentstats[i].fieldoffset);
+ if(t && t[0])
+ {
+ memset(s, 0, 17);
+ strlcpy(s, t, 16);
+ si = (int*)s;
+ if (!send)
+ {
+ stats[i+32] = si[0];
+ stats[i+33] = si[1];
+ stats[i+34] = si[2];
+ stats[i+35] = si[3];
+ }
+ else
+ {
+ VM_SENDSTAT(msg, i+32, si[0]);
+ VM_SENDSTAT(msg, i+33, si[1]);
+ VM_SENDSTAT(msg, i+34, si[2]);
+ VM_SENDSTAT(msg, i+35, si[3]);
+ }
+ }
+ break;
+ //float
+ case 2:
+ k.f = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
+ k.i = LittleLong (k.i);
+ if (!send)
+ stats[i+32] = k.i;
+ else
+ VM_SENDSTAT(msg, i+32, k.i);
+ break;
+ //integer
+ case 8:
+ v = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ?
+ if (!send)
+ stats[i+32] = v;
+ else
+ VM_SENDSTAT(msg, i+32, v);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+// void(float index, float type, .void field) SV_AddStat = #470;
+// Set up an auto-sent player stat.
+// Client's get thier own fields sent to them. Index may not be less than 32.
+// Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are:
+// 1: string (4 stats carrying a total of 16 charactures)
+// 2: float (one stat, float converted to an integer for transportation)
+// 8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
+void PF_SV_AddStat (void)
+{
+ int off, i;
+ unsigned char type;
+
+ if(!vm_autosentstats)
+ {
+ vm_autosentstats = malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t));
+ if(!vm_autosentstats)
+ {
+ Con_Printf("PF_SV_AddStat: not enough memory\n");
+ return;
+ }
+ }
+ i = PRVM_G_FLOAT(OFS_PARM0);
+ type = PRVM_G_FLOAT(OFS_PARM1);
+ off = PRVM_G_INT (OFS_PARM2);
+ i -= 32;
+
+ if(i < 0)
+ {
+ Con_Printf("PF_SV_AddStat: index may not be less than 32\n");
+ return;
+ }
+ if(i >= (MAX_CL_STATS-32))
+ {
+ Con_Printf("PF_SV_AddStat: index >= MAX_CL_STATS\n");
+ return;
+ }
+ if(i > (MAX_CL_STATS-32-4) && type == 1)
+ {
+ Con_Printf("PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
+ return;
+ }
+ vm_autosentstats[i].type = type;
+ vm_autosentstats[i].fieldoffset = off;
+ if(vm_autosentstats_last < i)
+ vm_autosentstats_last = i;
+}
+