+ // write a remove message if needed
+ // if already removed, do nothing
+ if (!sv2csqcents_version[csqc_clientnum][number])
+ return;
+ // if there isn't enough room to write the remove message, just return, as
+ // it will be handled in a later packet
+ if (msg->cursize + !*sectionstarted + 2 + 2 > msg->maxsize)
+ return;
+ // first write the message identifier if needed
+ if(!*sectionstarted)
+ {
+ *sectionstarted = 1;
+ MSG_WriteByte(msg, svc_csqcentities);
+ }
+ // write the remove message
+ MSG_WriteShort(msg, (unsigned short)number | 0x8000);
+ sv2csqcents_version[csqc_clientnum][number] = 0;
+}
+
+//[515]: we use only one array per-client for SendEntity feature
+void EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int numstates, const entity_state_t *states)
+{
+ int i, num;
+ qboolean sectionstarted = false;
+ const entity_state_t *n;
+
+ // if this server progs is not CSQC-aware, return early
+ if(prog->fieldoffsets.SendEntity < 0 || prog->fieldoffsets.Version < 0)
+ return;
+ // make sure there is enough room to store the svc_csqcentities byte,
+ // the terminator (0x0000) and at least one entity update
+ if (msg->cursize + 32 >= msg->maxsize)
+ return;
+ if(!sv2csqcents_version[csqc_clientnum])
+ EntityFrameCSQC_InitClientVersions(csqc_clientnum, false);
+
+ sv2csqcbuf = msg;
+ num = 1;
+ for (i = 0, n = states;i < numstates;i++, n++)
+ {
+ // all entities between the previous entity state and this one are dead
+ for (;num < n->number;num++)
+ if(sv2csqcents_version[csqc_clientnum][num])
+ EntityFrameCSQC_WriteState(msg, num, false, §ionstarted);
+ // update this entity
+ EntityFrameCSQC_WriteState(msg, num, true, §ionstarted);
+ // advance to next entity so the next iteration doesn't immediately remove it
+ num++;
+ }
+ // all remaining entities are dead
+ for (;num < prog->num_edicts;num++)
+ if(sv2csqcents_version[csqc_clientnum][num])
+ EntityFrameCSQC_WriteState(msg, num, false, §ionstarted);
+ if (sectionstarted)