4 qbool EntityFrame4_WriteFrame(sizebuf_t *msg, int maxsize, entityframe4_database_t *d, int numstates, const entity_state_t **states)
6 prvm_prog_t *prog = SVVM_prog;
7 const entity_state_t *e, *s;
8 entity_state_t inactiveentitystate;
11 unsigned char data[128];
13 // if there isn't enough space to accomplish anything, skip it
14 if (msg->cursize + 24 > maxsize)
18 memset(&buf, 0, sizeof(buf));
20 buf.maxsize = sizeof(data);
22 for (i = 0;i < MAX_ENTITY_HISTORY;i++)
23 if (!d->commit[i].numentities)
25 // if commit buffer full, just don't bother writing an update this frame
26 if (i == MAX_ENTITY_HISTORY)
28 d->currentcommit = d->commit + i;
30 // this state's number gets played around with later
31 inactiveentitystate = defaultstate;
33 d->currentcommit->numentities = 0;
34 d->currentcommit->framenum = ++d->latestframenumber;
35 MSG_WriteByte(msg, svc_entities);
36 MSG_WriteLong(msg, d->referenceframenum);
37 MSG_WriteLong(msg, d->currentcommit->framenum);
38 if (developer_networkentities.integer >= 10)
40 Con_Printf("send svc_entities num:%i ref:%i (database: ref:%i commits:", d->currentcommit->framenum, d->referenceframenum, d->referenceframenum);
41 for (i = 0;i < MAX_ENTITY_HISTORY;i++)
42 if (d->commit[i].numentities)
43 Con_Printf(" %i", d->commit[i].framenum);
46 if (d->currententitynumber >= prog->max_edicts)
49 startnumber = bound(1, d->currententitynumber, prog->max_edicts - 1);
50 MSG_WriteShort(msg, startnumber);
51 // reset currententitynumber so if the loop does not break it we will
52 // start at beginning next frame (if it does break, it will set it)
53 d->currententitynumber = 1;
54 for (i = 0, n = startnumber;n < prog->max_edicts;n++)
56 if (PRVM_serveredictfunction((&prog->edicts[n]), SendEntity))
58 // find the old state to delta from
59 e = EntityFrame4_GetReferenceEntity(d, n);
62 // entity exists, build an update (if empty there is no change)
63 // find the state in the list
64 for (;i < numstates && states[i]->number < n;i++);
70 EntityState_WriteUpdate(s, &buf, e);
74 inactiveentitystate.number = n;
75 s = &inactiveentitystate;
76 if (e->active == ACTIVE_NETWORK)
78 // entity used to exist but doesn't anymore, send remove
79 MSG_WriteShort(&buf, n | 0x8000);
82 // if the commit is full, we're done this frame
83 if (msg->cursize + buf.cursize > maxsize - 4)
85 // next frame we will continue where we left off
88 // add the entity to the commit
89 EntityFrame4_AddCommitEntity(d, s);
90 // if the message is empty, skip out now
93 // write the message to the packet
94 SZ_Write(msg, buf.data, buf.cursize);
97 d->currententitynumber = n;
99 // remove world message (invalid, and thus a good terminator)
100 MSG_WriteShort(msg, 0x8000);
101 // write the number of the end entity
102 MSG_WriteShort(msg, d->currententitynumber);
104 d->currentcommit = NULL;